From 5832e8038bf657c4eda87a575566d110adb07b48 Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Thu, 6 Jan 2022 21:08:17 -0800 Subject: [PATCH] Grudgingly moved to separate files for SVGs. --- .gitignore | 2 +- doc/render.py | 19 ++- doc/wrapping-upb.md | 304 ++--------------------------------------- doc/wrapping-upb/1.svg | 42 ++++++ doc/wrapping-upb/2.svg | 47 +++++++ doc/wrapping-upb/3.svg | 64 +++++++++ doc/wrapping-upb/4.svg | 139 +++++++++++++++++++ 7 files changed, 320 insertions(+), 297 deletions(-) create mode 100644 doc/wrapping-upb/1.svg create mode 100644 doc/wrapping-upb/2.svg create mode 100644 doc/wrapping-upb/3.svg create mode 100644 doc/wrapping-upb/4.svg diff --git a/.gitignore b/.gitignore index c9bd5becf8..91ccf906c4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -*.s?? +*.sw? obj/ lib/ bazel-* diff --git a/doc/render.py b/doc/render.py index a4444e640c..017978c8e7 100755 --- a/doc/render.py +++ b/doc/render.py @@ -2,6 +2,8 @@ import subprocess import sys +import shutil +import os if len(sys.argv) < 2: print("Must pass a filename argument") @@ -9,11 +11,18 @@ if len(sys.argv) < 2: in_filename = sys.argv[1] out_filename = in_filename.replace(".in.md", ".md") +out_dir = in_filename.replace(".in.md", "") if in_filename == out_filename: print("File must end in .in.md") sys.exit(1) +if os.path.isdir(out_dir): + shutil.rmtree(out_dir) + +os.mkdir(out_dir) +file_num = 1 + with open(out_filename, "wb") as out_file, open(in_filename, "rb") as in_file: for line in in_file: if line.startswith(b"```dot"): @@ -24,9 +33,11 @@ with open(out_filename, "wb") as out_file, open(in_filename, "rb") as in_file: break dot_lines.append(dot_line) dot_input = b"".join(dot_lines) - svg = subprocess.check_output(['dot', '-Tsvg'], input=dot_input) - out_file.write(b"
") - out_file.write(svg) - out_file.write(b"
") + svg_filename = out_dir + "/" + str(file_num) + ".svg" + svg = subprocess.check_output(['dot', '-Tsvg', '-o', svg_filename], input=dot_input) + out_file.write(b"
\n") + out_file.write(b"\n" % (svg_filename.encode('utf-8'))) + out_file.write(b"
\n") + file_num += 1 else: out_file.write(line) diff --git a/doc/wrapping-upb.md b/doc/wrapping-upb.md index a10c051c40..3483e94e3d 100644 --- a/doc/wrapping-upb.md +++ b/doc/wrapping-upb.md @@ -178,102 +178,19 @@ upb defines data structures in C to represent messages, arrays (repeated fields), and maps. A protobuf message is a hierarchical tree of these objects. For example, a relatively simple protobuf tree might look something like this: -
- - - - - -G - - -upb_msg - -upb Message - - - -upb_msg2 - -upb Message - - - -upb_msg->upb_msg2 - - - - - -upb_array - -upb Array - - - -upb_msg->upb_array - - - - - +
+
+ All upb objects are allocated from an arena. An arena lets you allocate objects individually, but you cannot free individual objects; you can only free the arena as a whole. When the arena is freed, all of the individual objects allocated from that arena are freed together. -
- - - - - -G - -cluster_0 - -upb Arena - - - -upb_msg - -upb Message - - - -upb_array - -upb Array - - - -upb_msg->upb_array - - - - - -upb_msg2 - -upb Message - - - -upb_msg->upb_msg2 - - - - - +
+
+ In simple cases, the entire tree of objects will all live in a single arena. This has the nice property that there cannot be any dangling pointers between objects, since all objects are freed at the same time. @@ -282,71 +199,10 @@ However upb allows you to create links between any two objects, whether or not they are in the same arena. The library does not know or care what arenas the objects are in when you create links between them. -
- - - - - -G - -cluster_0 - -upb Arena 1 - - -cluster_1 - -upb Arena 2 - - - -upb_msg - -upb Message 1 - - - -upb_array - -upb Array - - - -upb_msg->upb_array - - - - - -upb_msg2 - -upb Message 2 - - - -upb_msg->upb_msg2 - - - - - -upb_msg3 - -upb Message 3 - - - -upb_msg2->upb_msg3 - - - - - +
+
+ When objects are on separate arenas, it is the user's responsibility to ensure that there are no dangling pointers. In the example above, this means Arena 2 must outlive Message 1 and Message 2. @@ -364,146 +220,10 @@ GC'd until all of the C objects in that arena have become unreachable. For this example, we will assume we are wrapping upb in Python: -
- - - - - -G - -cluster_1 - -upb Arena - - -cluster_python - - - -cluster_01 - - - - -upb_msg - -upb Message - - - -upb_array - -upb Array - - - -upb_msg->upb_array - - - - - -upb_msg2 - -upb Message - - - -upb_msg->upb_msg2 - - - - - - - - -py_upb_msg - -Python Message - - - -py_upb_msg->upb_msg - - - - - -py_upb_arena - -Python Arena - - - -py_upb_msg->py_upb_arena - - - - - -py_upb_msg2 - -Python Message - - - -py_upb_msg2->upb_msg2 - - - - - -py_upb_msg2->py_upb_arena - - - - - -py_upb_arena->dummy - - - - - -key -raw ptr -unique ptr -shared (GC) ptr - - - -key2 -  -  -  - - - -key:e->key2:w - - - - - -key:e->key2:w - - - - - -key:e->key2:w - - - - - - +
+
+ In this example we have three different kinds of pointers: * **raw ptr**: This is a pointer that carries no ownership. diff --git a/doc/wrapping-upb/1.svg b/doc/wrapping-upb/1.svg new file mode 100644 index 0000000000..32b56348fc --- /dev/null +++ b/doc/wrapping-upb/1.svg @@ -0,0 +1,42 @@ + + + + + + +G + + +upb_msg + +upb Message + + + +upb_msg2 + +upb Message + + + +upb_msg->upb_msg2 + + + + + +upb_array + +upb Array + + + +upb_msg->upb_array + + + + + diff --git a/doc/wrapping-upb/2.svg b/doc/wrapping-upb/2.svg new file mode 100644 index 0000000000..3ff8b719dd --- /dev/null +++ b/doc/wrapping-upb/2.svg @@ -0,0 +1,47 @@ + + + + + + +G + +cluster_0 + +upb Arena + + + +upb_msg + +upb Message + + + +upb_array + +upb Array + + + +upb_msg->upb_array + + + + + +upb_msg2 + +upb Message + + + +upb_msg->upb_msg2 + + + + + diff --git a/doc/wrapping-upb/3.svg b/doc/wrapping-upb/3.svg new file mode 100644 index 0000000000..7a0c05ef74 --- /dev/null +++ b/doc/wrapping-upb/3.svg @@ -0,0 +1,64 @@ + + + + + + +G + +cluster_0 + +upb Arena 1 + + +cluster_1 + +upb Arena 2 + + + +upb_msg + +upb Message 1 + + + +upb_array + +upb Array + + + +upb_msg->upb_array + + + + + +upb_msg2 + +upb Message 2 + + + +upb_msg->upb_msg2 + + + + + +upb_msg3 + +upb Message 3 + + + +upb_msg2->upb_msg3 + + + + + diff --git a/doc/wrapping-upb/4.svg b/doc/wrapping-upb/4.svg new file mode 100644 index 0000000000..ff2b4fc25f --- /dev/null +++ b/doc/wrapping-upb/4.svg @@ -0,0 +1,139 @@ + + + + + + +G + +cluster_1 + +upb Arena + + +cluster_python + + + +cluster_01 + + + + +upb_msg + +upb Message + + + +upb_array + +upb Array + + + +upb_msg->upb_array + + + + + +upb_msg2 + +upb Message + + + +upb_msg->upb_msg2 + + + + + + + + +py_upb_msg + +Python Message + + + +py_upb_msg->upb_msg + + + + + +py_upb_arena + +Python Arena + + + +py_upb_msg->py_upb_arena + + + + + +py_upb_msg2 + +Python Message + + + +py_upb_msg2->upb_msg2 + + + + + +py_upb_msg2->py_upb_arena + + + + + +py_upb_arena->dummy + + + + + +key +raw ptr +unique ptr +shared (GC) ptr + + + +key2 +  +  +  + + + +key:e->key2:w + + + + + +key:e->key2:w + + + + + +key:e->key2:w + + + + + +