From 0bd08a362a52cbaef96273dac77ddb8a4a42b5c0 Mon Sep 17 00:00:00 2001 From: Graham Nelson Date: Mon, 8 Nov 2021 10:16:46 +0000 Subject: [PATCH] Finished tidying the C object model --- docs/BasicInformExtrasKit/S-msc.html | 1 - docs/WorldModelKit/S-ord.html | 1 - docs/building-module/1-tv.html | 2 - docs/final-module/2-cg.html | 6 +- docs/final-module/5-ccn.html | 8 +- docs/final-module/5-com.html | 327 ++++++++++-------- docs/final-module/5-crf.html | 4 +- inform7/Figures/memory-diagnostics.txt | 10 +- inform7/Figures/timings-diagnostics.txt | 26 +- .../Sections/Miscellany.i6t | 1 - .../WorldModelKit/Sections/OrderOfPlay.i6t | 1 - inform7/Internal/Miscellany/inform7_clib.c | 178 ++++------ inform7/Internal/Miscellany/inform7_clib.h | 51 +-- inter/building-module/Chapter 1/The Veneer.w | 2 - inter/final-module/Chapter 5/C Conditions.w | 8 +- inter/final-module/Chapter 5/C Object Model.w | 320 +++++++++-------- inter/final-module/Chapter 5/C References.w | 4 +- 17 files changed, 498 insertions(+), 452 deletions(-) diff --git a/docs/BasicInformExtrasKit/S-msc.html b/docs/BasicInformExtrasKit/S-msc.html index 0c31d87e1..da8965450 100644 --- a/docs/BasicInformExtrasKit/S-msc.html +++ b/docs/BasicInformExtrasKit/S-msc.html @@ -83,7 +83,6 @@ before it is known how they will be used. #ifdef TARGET_GLULX; VM_PreInitialise(); #Endif; #Ifdef LanguageInitialise; LanguageInitialise(); #Endif; -CreatePropertyOffsets(); HeapInitialise(); Create a completely unused memory allocation heap StackFramingInitialise(); Create an empty stack CreateDynamicRelations(); Create relation structures on the heap diff --git a/docs/WorldModelKit/S-ord.html b/docs/WorldModelKit/S-ord.html index 3d929c7cd..fe10e62ab 100644 --- a/docs/WorldModelKit/S-ord.html +++ b/docs/WorldModelKit/S-ord.html @@ -165,7 +165,6 @@ where he is, the surprise will not be spoiled. real_location = nothing; location = nothing; -CreatePropertyOffsets(); HeapInitialise(); Create a completely unused memory allocation heap StackFramingInitialise(); Create an empty stack CreateDynamicRelations(); Create relation structures on the heap diff --git a/docs/building-module/1-tv.html b/docs/building-module/1-tv.html index e77ca7247..28798e25c 100644 --- a/docs/building-module/1-tv.html +++ b/docs/building-module/1-tv.html @@ -91,7 +91,6 @@ function togglePopup(material_id) { enum ASM_NEG_RTRUE_VSYMB enum ASM_NEG_RFALSE_VSYMB enum RESPONSETEXTS_VSYMB -enum CREATEPROPERTYOFFSETS_VSYMB enum KINDHIERARCHY_VSYMB enum NO_RESPONSES_VSYMB @@ -117,7 +116,6 @@ function togglePopup(material_id) { Veneer::index(I, ASM_NEG_RFALSE_VSYMB, I"__assembly_negated_rfalse_label", I"?~rfalse"); Veneer::index(I, RESPONSETEXTS_VSYMB, I"ResponseTexts", NULL); - Veneer::index(I, CREATEPROPERTYOFFSETS_VSYMB, I"CreatePropertyOffsets", NULL); Veneer::index(I, KINDHIERARCHY_VSYMB, I"KindHierarchy", NULL); Veneer::index(I, NO_RESPONSES_VSYMB, I"NO_RESPONSES", NULL); } diff --git a/docs/final-module/2-cg.html b/docs/final-module/2-cg.html index 089af018f..1f50222ed 100644 --- a/docs/final-module/2-cg.html +++ b/docs/final-module/2-cg.html @@ -433,7 +433,7 @@ but for now about 10 layers is plenty.

-segmentation_pos CodeGen::select(code_generation *gen, int i) {
+segmentation_pos CodeGen::select(code_generation *gen, int i) {
     return CodeGen::select_layered(gen, i, 1);
 }
 
@@ -450,7 +450,7 @@ but for now about 10 layers is plenty.
     return previous_pos;
 }
 
-void CodeGen::deselect(code_generation *gen, segmentation_pos saved) {
+void CodeGen::deselect(code_generation *gen, segmentation_pos saved) {
     if (gen->segmentation.temporarily_diverted) internal_error("poorly timed deselection");
     gen->segmentation.pos = saved;
 }
@@ -476,7 +476,7 @@ if it has been "temporarily diverted" then the regiular selection is ignored.
 

-text_stream *CodeGen::current(code_generation *gen) {
+text_stream *CodeGen::current(code_generation *gen) {
     if (gen->segmentation.temporarily_diverted)
         return gen->segmentation.temporarily_diverted_to;
     if (gen->segmentation.pos.current_segment == NULL) return NULL;
diff --git a/docs/final-module/5-ccn.html b/docs/final-module/5-ccn.html
index 5eb51a7cb..12452b882 100644
--- a/docs/final-module/5-ccn.html
+++ b/docs/final-module/5-ccn.html
@@ -108,9 +108,7 @@ and handling that requires the mechanism below.
             C_GEN_DATA(objdata.value_ranges_needed) = TRUE;
             C_GEN_DATA(objdata.value_property_holders_needed) = TRUE;
             WRITE("(i7_provides_gprop(proc, "); VNODE_1C; WRITE(", ");
-            VNODE_2C; WRITE(", "); VNODE_3C; WRITE(", ");
-            WRITE("i7_mgl_OBJECT_TY, i7_mgl_value_ranges, i7_mgl_value_property_holders, ");
-            WRITE("i7_mgl_A_door_to, i7_mgl_COL_HSIZE))");
+            VNODE_2C; WRITE(", "); VNODE_3C; WRITE("))");
             break;
         case EQ_BIP: case NE_BIP: case GT_BIP: case GE_BIP: case LT_BIP: case LE_BIP:
         case OFCLASS_BIP: case IN_BIP: case NOTIN_BIP:
@@ -193,13 +191,11 @@ the latter would be universally true, which is useless.
     }
 
     if (bip == PROPERTYVALUE_BIP) {
-        WRITE("(i7_read_gprop(proc, ", test_fn);
+        WRITE("(i7_read_gprop_value(proc, ", test_fn);
         Vanilla::node(gen, K); WRITE(", ");
         Compile first comparand2.1;
         WRITE(", ");
         Compile second comparand2.2;
-        WRITE(", i7_mgl_OBJECT_TY, i7_mgl_value_ranges, i7_mgl_value_property_holders, ");
-        WRITE("i7_mgl_A_door_to, i7_mgl_COL_HSIZE");
         WRITE("))");
     } else if (Str::len(test_fn) > 0) {
         WRITE("(%S(proc, ", test_fn);
diff --git a/docs/final-module/5-com.html b/docs/final-module/5-com.html
index aeb55f002..f21340006 100644
--- a/docs/final-module/5-com.html
+++ b/docs/final-module/5-com.html
@@ -74,7 +74,7 @@ function togglePopup(material_id) {
     
 

How objects, classes and properties are compiled to C.

-
+

§1. Introduction.

@@ -130,6 +130,7 @@ function togglePopup(material_id) { CObjectModel::write_i7_initialise_object_tree(gen); CObjectModel::define_object_value_regions(gen); CObjectModel::compile_ofclass_array(gen); + CObjectModel::compile_gprop_functions(gen); segmentation_pos saved = CodeGen::select(gen, c_ids_and_maxima_I7CGS); text_stream *OUT = CodeGen::current(gen); WRITE("#define i7_max_objects I7VAL_STRINGS_BASE\n"); @@ -940,18 +941,32 @@ which we will then need to write in return FALSE; }
-

§27. Let's start with property array (for inline properties) and property length. +

§27. Let's start with property address and property length; while actual property +values live inside process memory, the addresses showing where they are in that +memory, and how many bytes they take up, are held in (static) arrays. Note that +although multiple processes running the same I7 story would have multiple values +for these properties, which likely differ at any given time, they would be at +the same address and of the same length in each.

+#define I7_MAX_PROPERTY_IDS 1000
+typedef struct i7_property_set {
+    i7word_t address[I7_MAX_PROPERTY_IDS];
+    i7word_t len[I7_MAX_PROPERTY_IDS];
+} i7_property_set;
+i7_property_set i7_properties[];
+
 i7word_t i7_prop_addr(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr);
 i7word_t i7_prop_len(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr);
 
-

Note that lengths are returned in bytes, not words, hence the multiplication by 4. +

Lengths are returned in bytes, not words, hence the multiplication by 4.

+i7_property_set i7_properties[i7_max_objects];
+
 i7word_t i7_prop_len(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr_array) {
     i7word_t pr = i7_read_word(proc, pr_array, 1);
     if ((obj <= 0) || (obj >= i7_max_objects) ||
@@ -967,7 +982,28 @@ which we will then need to write in }
 
-

§28. Now i7_move, which moves obj in the object tree so that it becomes the +

§28. The address array can be used to determine whether a runtime object or class +provides a given property: if the address is nonzero then it does. +

+ +
+int i7_provides(i7process_t *proc, i7word_t owner_id, i7word_t prop_id);
+
+ +
+int i7_provides(i7process_t *proc, i7word_t owner_id, i7word_t pr_array) {
+    i7word_t prop_id = i7_read_word(proc, pr_array, 1);
+    if ((owner_id <= 0) || (owner_id >= i7_max_objects) ||
+        (prop_id < 0) || (prop_id >= i7_no_property_ids)) return 0;
+    while (owner_id != 1) {
+        if (i7_properties[(int) owner_id].address[(int) prop_id] != 0) return 1;
+        owner_id = i7_class_of[owner_id];
+    }
+    return 0;
+}
+
+ +

§29. Now i7_move, which moves obj in the object tree so that it becomes the eldest child of to, unless to is zero, in which case it is removed from the tree.

@@ -1003,7 +1039,7 @@ the tree. }
-

§29. Now the four ways to interrogate the object containment tree: +

§30. Now the four ways to interrogate the object containment tree:

@@ -1036,26 +1072,43 @@ the tree.
 }
 
-

§30. Reading and writing properties. So here is the run-time storage for property values, and simple code to read -and write them. +

§31. And the implementation of "is obj1 directly a child of obj2?"

-i7word_t fn_i7_mgl_CreatePropertyOffsets(i7process_t *proc);
-void i7_write_prop_value(i7process_t *proc, i7word_t owner_id, i7word_t prop_id, i7word_t val);
-i7word_t i7_read_prop_value(i7process_t *proc, i7word_t owner_id, i7word_t pr_array);
-i7word_t i7_change_prop_value(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr, i7word_t to, int way);
-void i7_give(i7process_t *proc, i7word_t owner, i7word_t prop, i7word_t val);
-#define I7_MAX_PROPERTY_IDS 1000
-typedef struct i7_property_set {
-    i7word_t address[I7_MAX_PROPERTY_IDS];
-    i7word_t len[I7_MAX_PROPERTY_IDS];
-} i7_property_set;
-i7_property_set i7_properties[];
+int i7_in(i7process_t *proc, i7word_t obj1, i7word_t obj2);
 
-i7_property_set i7_properties[i7_max_objects];
+int i7_in(i7process_t *proc, i7word_t obj1, i7word_t obj2) {
+    if (i7_metaclass(proc, obj1) != i7_mgl_Object) return 0;
+    if (obj2 == 0) return 0;
+    if (proc->state.object_tree_parent[obj1] == obj2) return 1;
+    return 0;
+}
+
+ +

§32. Reading, writing and changing object properties.

+ +
+i7word_t i7_read_prop_value(i7process_t *proc, i7word_t owner_id, i7word_t pr_array);
+void i7_write_prop_value(i7process_t *proc, i7word_t owner_id, i7word_t prop_id, i7word_t val);
+i7word_t i7_change_prop_value(i7process_t *proc, i7word_t owner_id, i7word_t prop_id,
+    i7word_t val, int way);
+
+ +
+i7word_t i7_read_prop_value(i7process_t *proc, i7word_t owner_id, i7word_t pr_array) {
+    i7word_t prop_id = i7_read_word(proc, pr_array, 1);
+    if ((owner_id <= 0) || (owner_id >= i7_max_objects) ||
+        (prop_id < 0) || (prop_id >= i7_no_property_ids)) return 0;
+    while (i7_properties[(int) owner_id].address[(int) prop_id] == 0) {
+        owner_id = i7_class_of[owner_id];
+        if (owner_id == i7_mgl_Class) return 0;
+    }
+    i7word_t address = i7_properties[(int) owner_id].address[(int) prop_id];
+    return i7_read_word(proc, address, 0);
+}
 
 void i7_write_prop_value(i7process_t *proc, i7word_t owner_id, i7word_t pr_array, i7word_t val) {
     i7word_t prop_id = i7_read_word(proc, pr_array, 1);
@@ -1071,162 +1124,154 @@ and write them.
         i7_fatal_exit(proc);
     }
 }
-
- -

§31. And here sre the functions called by the above primitives: -

-
-i7word_t i7_read_prop_value(i7process_t *proc, i7word_t owner_id, i7word_t pr_array) {
-    i7word_t prop_id = i7_read_word(proc, pr_array, 1);
-    if ((owner_id <= 0) || (owner_id >= i7_max_objects) ||
-        (prop_id < 0) || (prop_id >= i7_no_property_ids)) return 0;
-    while (i7_properties[(int) owner_id].address[(int) prop_id] == 0) {
-        owner_id = i7_class_of[owner_id];
-        if (owner_id == i7_mgl_Class) return 0;
-    }
-    i7word_t address = i7_properties[(int) owner_id].address[(int) prop_id];
-    return i7_read_word(proc, address, 0);
-}
-
-i7word_t i7_change_prop_value(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr, i7word_t to, int way) {
+i7word_t i7_change_prop_value(i7process_t *proc, i7word_t obj, i7word_t pr,
+    i7word_t to, int way) {
     i7word_t val = i7_read_prop_value(proc, obj, pr), new_val = val;
     switch (way) {
-        case i7_lvalue_SET:      i7_write_prop_value(proc, obj, pr, to); new_val = to; break;
-        case i7_lvalue_PREDEC:   new_val = val-1; i7_write_prop_value(proc, obj, pr, val-1); break;
-        case i7_lvalue_POSTDEC:  new_val = val; i7_write_prop_value(proc, obj, pr, val-1); break;
-        case i7_lvalue_PREINC:   new_val = val+1; i7_write_prop_value(proc, obj, pr, val+1); break;
-        case i7_lvalue_POSTINC:  new_val = val; i7_write_prop_value(proc, obj, pr, val+1); break;
-        case i7_lvalue_SETBIT:   new_val = val | new_val; i7_write_prop_value(proc, obj, pr, new_val); break;
-        case i7_lvalue_CLEARBIT: new_val = val &(~new_val); i7_write_prop_value(proc, obj, pr, new_val); break;
+        case i7_lvalue_SET:
+            i7_write_prop_value(proc, obj, pr, to); new_val = to; break;
+        case i7_lvalue_PREDEC:
+            new_val = val-1; i7_write_prop_value(proc, obj, pr, val-1); break;
+        case i7_lvalue_POSTDEC:
+            new_val = val; i7_write_prop_value(proc, obj, pr, val-1); break;
+        case i7_lvalue_PREINC:
+            new_val = val+1; i7_write_prop_value(proc, obj, pr, val+1); break;
+        case i7_lvalue_POSTINC:
+            new_val = val; i7_write_prop_value(proc, obj, pr, val+1); break;
+        case i7_lvalue_SETBIT:
+            new_val = val | new_val; i7_write_prop_value(proc, obj, pr, new_val); break;
+        case i7_lvalue_CLEARBIT:
+            new_val = val &(~new_val); i7_write_prop_value(proc, obj, pr, new_val); break;
     }
     return new_val;
 }
-
-void i7_give(i7process_t *proc, i7word_t owner, i7word_t prop, i7word_t val) {
-    i7_write_prop_value(proc, owner, prop, val);
-}
 
-

§32.

+

§33. Reading, writing and changing general properties. And these are the exactly analogous functions which more generally read, write +or change properties which can be held by either objects or enumerated instances — +in other words, all properties. The additional kind argument K is then needed +to distinguish these cases (since the obj values for different kinds may well +coincide). +

+ +

The functions themselves are simple enough, but there is a complication, which +is that they need to use addresses which vary from one compilation to another; +so they cannot be written straightforwardly into our C library, which has to +be the same for all compilations. We get around this by compiling wrapper +functions in our story-file C which supply the necessary information and then +call clumsy but static functions in the C library; but this is all transparent +to the user, who should call only these: +

-int i7_has(i7process_t *proc, i7word_t obj, i7word_t either_or);
-int i7_provides(i7process_t *proc, i7word_t owner_id, i7word_t prop_id);
-int i7_in(i7process_t *proc, i7word_t obj1, i7word_t obj2);
+int i7_provides_gprop(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t p);
+i7word_t i7_read_gprop_value(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr);
+void i7_write_gprop_value(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t p,
+    i7word_t val);
+void i7_change_gprop_value(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t p,
+    i7word_t val, i7word_t form);
+
+ +

§34. So here are the dynamic wrappers. +

+ +
+void CObjectModel::compile_gprop_functions(code_generation *gen) {
+    segmentation_pos saved = CodeGen::select(gen, c_function_declarations_I7CGS);
+    text_stream *OUT = CodeGen::current(gen);
+    WRITE("int i7_provides_gprop(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t p) {\n");
+    WRITE("    return i7_provides_gprop_inner(proc, K, obj, p, i7_mgl_OBJECT_TY,\n");
+    WRITE("         i7_mgl_value_ranges, i7_mgl_value_property_holders, i7_mgl_COL_HSIZE);\n");
+    WRITE("}\n");
+    WRITE("i7word_t i7_read_gprop_value(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t p) {\n");
+    WRITE("    return i7_read_gprop_value_inner(proc, K, obj, p, i7_mgl_OBJECT_TY,\n");
+    WRITE("         i7_mgl_value_ranges, i7_mgl_value_property_holders, i7_mgl_COL_HSIZE);\n");
+    WRITE("}\n");
+    WRITE("void i7_write_gprop_value(i7process_t *proc, i7word_t K, i7word_t obj,\n");
+    WRITE("    i7word_t p, i7word_t val) {\n");
+    WRITE("    i7_write_gprop_value_inner(proc, K, obj, p, val, i7_mgl_OBJECT_TY,\n");
+    WRITE("         i7_mgl_value_ranges, i7_mgl_value_property_holders, i7_mgl_COL_HSIZE);\n");
+    WRITE("}\n");
+    WRITE("void i7_change_gprop_value(i7process_t *proc, i7word_t K, i7word_t obj,\n");
+    WRITE("    i7word_t p, i7word_t val, i7word_t form) {\n");
+    WRITE("    i7_change_gprop_value_inner(proc, K, obj, p, val, form, i7_mgl_OBJECT_TY,\n");
+    WRITE("         i7_mgl_value_ranges, i7_mgl_value_property_holders, i7_mgl_COL_HSIZE);\n");
+    WRITE("}\n");
+    CodeGen::deselect(gen, saved);
+}
+
+

§35. And these are the static functions in the C library which they call: +

+ +
+int i7_provides_gprop_inner(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t p,
+    i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges,
+    i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_COL_HSIZE);
+i7word_t i7_read_gprop_value_inner(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr,
+    i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges,
+    i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_COL_HSIZE);
+void i7_write_gprop_value_inner(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t p,
+    i7word_t val, i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges,
+    i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_COL_HSIZE);
+void i7_change_gprop_value_inner(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t p,
+    i7word_t val, i7word_t form, i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges,
+    i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_COL_HSIZE);
 
-int i7_has(i7process_t *proc, i7word_t obj, i7word_t either_or) {
-    if (i7_read_prop_value(proc, obj, either_or)) return 1;
-    return 0;
-}
-
-int i7_provides(i7process_t *proc, i7word_t owner_id, i7word_t pr_array) {
-    i7word_t prop_id = i7_read_word(proc, pr_array, 1);
-    if ((owner_id <= 0) || (owner_id >= i7_max_objects) ||
-        (prop_id < 0) || (prop_id >= i7_no_property_ids)) return 0;
-    while (owner_id != 1) {
-        if (i7_properties[(int) owner_id].address[(int) prop_id] != 0)
-            return 1;
-        owner_id = i7_class_of[owner_id];
-    }
-    return 0;
-}
-
-int i7_in(i7process_t *proc, i7word_t obj1, i7word_t obj2) {
-    if (i7_metaclass(proc, obj1) != i7_mgl_Object) return 0;
-    if (obj2 == 0) return 0;
-    if (proc->state.object_tree_parent[obj1] == obj2) return 1;
-    return 0;
-}
-
- -
-void i7_provides_gprop_inner(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t p, i7word_t *val,
-    i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_A_door_to, i7word_t i7_mgl_COL_HSIZE);
-int i7_provides_gprop(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t p,
-    i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_A_door_to, i7word_t i7_mgl_COL_HSIZE);
-void i7_read_gprop_inner(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t p, i7word_t *val,
-    i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_A_door_to, i7word_t i7_mgl_COL_HSIZE);
-void i7_write_gprop_inner(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t p, i7word_t val, i7word_t form,
-    i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_A_door_to, i7word_t i7_mgl_COL_HSIZE);
-
- -
-void i7_provides_gprop_inner(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr, i7word_t *val,
-    i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_A_door_to, i7word_t i7_mgl_COL_HSIZE) {
+int i7_provides_gprop_inner(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr,
+    i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges,
+    i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_COL_HSIZE) {
     if (K == i7_mgl_OBJECT_TY) {
-        if (((obj) && ((i7_metaclass(proc, obj) == i7_mgl_Object)))) {
-            if (((i7_read_word(proc, pr, 0) == 2) || (i7_provides(proc, obj, pr)))) {
-                if (val) *val = 1;
-            } else {
-                if (val) *val = 0;
-            }
-        } else {
-            if (val) *val = 0;
-        }
+        if ((((obj) && ((i7_metaclass(proc, obj) == i7_mgl_Object)))) &&
+            (((i7_read_word(proc, pr, 0) == 2) || (i7_provides(proc, obj, pr)))))
+            return 1;
     } else {
         if ((((obj >= 1)) && ((obj <= i7_read_word(proc, i7_mgl_value_ranges, K))))) {
             i7word_t holder = i7_read_word(proc, i7_mgl_value_property_holders, K);
-            if (((holder) && ((i7_provides(proc, holder, pr))))) {
-                if (val) *val = 1;
-            } else {
-                if (val) *val = 0;
-            }
-        } else {
-            if (val) *val = 0;
+            if (((holder) && ((i7_provides(proc, holder, pr))))) return 1;
         }
     }
+    return 0;
 }
 
-int i7_provides_gprop(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr,
-    i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_A_door_to, i7word_t i7_mgl_COL_HSIZE) {
+i7word_t i7_read_gprop_value_inner(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr,
+    i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges,
+    i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_COL_HSIZE) {
     i7word_t val = 0;
-    i7_provides_gprop_inner(proc, K, obj, pr, &val, i7_mgl_OBJECT_TY, i7_mgl_value_ranges, i7_mgl_value_property_holders, i7_mgl_A_door_to, i7_mgl_COL_HSIZE);
+    if ((K == i7_mgl_OBJECT_TY)) {
+        return (i7word_t) i7_read_prop_value(proc, obj, pr);
+    } else {
+        i7word_t holder = i7_read_word(proc, i7_mgl_value_property_holders, K);
+        return (i7word_t) i7_read_word(proc,
+            i7_read_prop_value(proc, holder, pr), (obj + i7_mgl_COL_HSIZE));
+    }
     return val;
 }
 
-void i7_read_gprop_inner(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr, i7word_t *val,
-    i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_A_door_to, i7word_t i7_mgl_COL_HSIZE) {
+void i7_write_gprop_value_inner(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr,
+    i7word_t val, i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges,
+    i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_COL_HSIZE) {
     if ((K == i7_mgl_OBJECT_TY)) {
-        if ((i7_read_word(proc, pr, 0) == 2)) {
-            if ((i7_has(proc, obj, pr))) {
-                if (val) *val =  1;
-            } else {
-                if (val) *val =  0;
-            }
-        } else {
-            if (val) *val = (i7word_t) i7_read_prop_value(proc, obj, pr);
-        }
+        i7_write_prop_value(proc, obj, pr, val);
     } else {
         i7word_t holder = i7_read_word(proc, i7_mgl_value_property_holders, K);
-        if (val) *val = (i7word_t) i7_read_word(proc, i7_read_prop_value(proc, holder, pr), (obj + i7_mgl_COL_HSIZE));
+        i7_write_word(proc,
+            i7_read_prop_value(proc, holder, pr), (obj + i7_mgl_COL_HSIZE), val);
     }
 }
 
-i7word_t i7_read_gprop(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr,
-    i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_A_door_to, i7word_t i7_mgl_COL_HSIZE) {
-    i7word_t val = 0;
-    i7_read_gprop_inner(proc, K, obj, pr, &val, i7_mgl_OBJECT_TY, i7_mgl_value_ranges, i7_mgl_value_property_holders, i7_mgl_A_door_to, i7_mgl_COL_HSIZE);
-    return val;
-}
-
-void i7_write_gprop_inner(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr, i7word_t val, i7word_t form,
-    i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_A_door_to, i7word_t i7_mgl_COL_HSIZE) {
+void i7_change_gprop_value_inner(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr,
+    i7word_t val, i7word_t form,
+    i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges,
+    i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_COL_HSIZE) {
     if ((K == i7_mgl_OBJECT_TY)) {
-        if ((i7_read_word(proc, pr, 0) == 2)) {
-            if (val) {
-                i7_change_prop_value(proc, K, obj, pr, 1, form);
-            } else {
-                i7_change_prop_value(proc, K, obj, pr, 0, form);
-            }
-        } else {
-            (i7_change_prop_value(proc, K, obj, pr, val, form));
-        }
+        i7_change_prop_value(proc, obj, pr, val, form);
     } else {
         i7word_t holder = i7_read_word(proc, i7_mgl_value_property_holders, K);
-        (i7_change_word(proc, i7_read_prop_value(proc, holder, pr), (obj + i7_mgl_COL_HSIZE), val, form));
+        i7_change_word(proc,
+            i7_read_prop_value(proc, holder, pr), (obj + i7_mgl_COL_HSIZE), val, form);
     }
 }
 
diff --git a/docs/final-module/5-crf.html b/docs/final-module/5-crf.html index a5af65f25..43ff7e9bd 100644 --- a/docs/final-module/5-crf.html +++ b/docs/final-module/5-crf.html @@ -197,14 +197,12 @@ calling functions.
     WRITE("(");
-    WRITE("i7_write_gprop_inner(proc, ");
+    WRITE("i7_change_gprop_value(proc, ");
         Vanilla::node(gen, InterTree::first_child(storage_ref)); WRITE(", ");
         Vanilla::node(gen, InterTree::second_child(storage_ref)); WRITE(", ");
         Vanilla::node(gen, InterTree::third_child(storage_ref)); WRITE(", ");
     if (val_supplied) { VNODE_2C; } else { WRITE("0"); }
     WRITE(", %S", store_form);
-    WRITE(", i7_mgl_OBJECT_TY, i7_mgl_value_ranges, i7_mgl_value_property_holders, ");
-    WRITE("i7_mgl_A_door_to, i7_mgl_COL_HSIZE");
     WRITE("))");
 
diff --git a/inform7/Figures/memory-diagnostics.txt b/inform7/Figures/memory-diagnostics.txt index 215f34d43..f26a6c04b 100644 --- a/inform7/Figures/memory-diagnostics.txt +++ b/inform7/Figures/memory-diagnostics.txt @@ -1,6 +1,6 @@ -Total memory consumption was 399939K = 391 MB +Total memory consumption was 399937K = 391 MB -61.0% was used for 2018880 objects, in 379612 frames in 305 x 800K = 244000K = 238 MB: +61.0% was used for 2018780 objects, in 379611 frames in 305 x 800K = 244000K = 238 MB: 10.2% inter_tree_node_array 58 x 8192 = 475136 objects, 41813824 bytes 7.2% text_stream_array 5254 x 100 = 525400 objects, 29590528 bytes @@ -21,7 +21,7 @@ Total memory consumption was 399939K = 391 MB 0.3% dictionary 33302 objects, 1598496 bytes 0.3% match_trie_array 11 x 1000 = 11000 objects, 1496352 bytes 0.3% i6_schema_array 23 x 100 = 2300 objects, 1380736 bytes - 0.3% dict_entry_array 397 x 100 = 39700 objects, 1283104 bytes + 0.3% dict_entry_array 396 x 100 = 39600 objects, 1279872 bytes 0.2% map_data 670 objects, 1125600 bytes 0.2% id_body 941 objects, 1076504 bytes 0.2% adjective_meaning 202 objects, 1000304 bytes @@ -238,7 +238,7 @@ Total memory consumption was 399939K = 391 MB 38.9% was used for memory not allocated for objects: - 20.4% text stream storage 83672424 bytes in 543411 claims + 20.4% text stream storage 83669748 bytes in 543391 claims 4.4% dictionary storage 18323456 bytes in 33302 claims ---- sorting 736 bytes in 3 claims 1.7% source text 7200000 bytes in 3 claims @@ -256,5 +256,5 @@ Total memory consumption was 399939K = 391 MB ---- code generation workspace for objects 1336 bytes in 4 claims ---- emitter array storage 161792 bytes in 2062 claims -18.7% was overhead - 76684256 bytes = 74886K = 73 MB +18.7% was overhead - 76687488 bytes = 74890K = 73 MB diff --git a/inform7/Figures/timings-diagnostics.txt b/inform7/Figures/timings-diagnostics.txt index 1f0dbd4a5..6a012b1f1 100644 --- a/inform7/Figures/timings-diagnostics.txt +++ b/inform7/Figures/timings-diagnostics.txt @@ -1,28 +1,28 @@ 100.0% in inform7 run - 55.1% in compilation to Inter - 39.7% in //Sequence::undertake_queued_tasks// + 54.4% in compilation to Inter + 39.2% in //Sequence::undertake_queued_tasks// 3.4% in //MajorNodes::pre_pass// 2.5% in //MajorNodes::pass_1// - 2.1% in //RTPhrasebook::compile_entries// - 1.4% in //ImperativeDefinitions::assess_all// + 2.0% in //RTPhrasebook::compile_entries// + 1.3% in //ImperativeDefinitions::assess_all// 1.1% in //RTKindConstructors::compile// 0.4% in //MajorNodes::pass_2// 0.4% in //Sequence::undertake_queued_tasks// - 0.4% in //Sequence::undertake_queued_tasks// 0.4% in //World::stage_V// 0.2% in //ImperativeDefinitions::compile_first_block// + 0.2% in //Sequence::undertake_queued_tasks// 0.1% in //CompletionModule::compile// 0.1% in //InferenceSubjects::emit_all// 0.1% in //RTKindConstructors::compile_permissions// 0.1% in //Task::make_built_in_kind_constructors// 0.1% in //World::stages_II_and_III// - 2.0% not specifically accounted for - 42.8% in running Inter pipeline - 12.6% in step preparation - 9.6% in inter step 7/16: consolidate-text - 8.1% in inter step 2/16: link + 1.9% not specifically accounted for + 43.7% in running Inter pipeline + 13.1% in step preparation + 10.1% in inter step 7/16: consolidate-text + 7.9% in inter step 2/16: link 6.4% in inter step 16/16: generate inform6 -> auto.inf - 1.5% in inter step 11/16: make-identifiers-unique + 1.6% in inter step 11/16: make-identifiers-unique 0.4% in inter step 12/16: reconcile-verbs 0.2% in inter step 10/16: detect-indirect-calls 0.2% in inter step 14/16: eliminate-redundant-operations @@ -33,5 +33,5 @@ 0.1% in inter step 4/16: parse-linked-matter 0.1% in inter step 5/16: resolve-conditional-compilation 2.1% not specifically accounted for - 1.7% in supervisor - 0.3% not specifically accounted for + 1.6% in supervisor + 0.2% not specifically accounted for diff --git a/inform7/Internal/Inter/BasicInformExtrasKit/Sections/Miscellany.i6t b/inform7/Internal/Inter/BasicInformExtrasKit/Sections/Miscellany.i6t index d28d66b79..ec48411e5 100644 --- a/inform7/Internal/Inter/BasicInformExtrasKit/Sections/Miscellany.i6t +++ b/inform7/Internal/Inter/BasicInformExtrasKit/Sections/Miscellany.i6t @@ -42,7 +42,6 @@ before it is known how they will be used. #ifdef TARGET_GLULX; VM_PreInitialise(); #Endif; #Ifdef LanguageInitialise; LanguageInitialise(); #Endif; -! CreatePropertyOffsets(); HeapInitialise(); ! Create a completely unused memory allocation heap StackFramingInitialise(); ! Create an empty stack CreateDynamicRelations(); ! Create relation structures on the heap diff --git a/inform7/Internal/Inter/WorldModelKit/Sections/OrderOfPlay.i6t b/inform7/Internal/Inter/WorldModelKit/Sections/OrderOfPlay.i6t index 884b2ce68..067d528e5 100644 --- a/inform7/Internal/Inter/WorldModelKit/Sections/OrderOfPlay.i6t +++ b/inform7/Internal/Inter/WorldModelKit/Sections/OrderOfPlay.i6t @@ -110,7 +110,6 @@ where he is, the surprise will not be spoiled. real_location = nothing; location = nothing; -! CreatePropertyOffsets(); HeapInitialise(); ! Create a completely unused memory allocation heap StackFramingInitialise(); ! Create an empty stack CreateDynamicRelations(); ! Create relation structures on the heap diff --git a/inform7/Internal/Miscellany/inform7_clib.c b/inform7/Internal/Miscellany/inform7_clib.c index 730810237..18a6cc875 100644 --- a/inform7/Internal/Miscellany/inform7_clib.c +++ b/inform7/Internal/Miscellany/inform7_clib.c @@ -821,6 +821,8 @@ void i7_empty_object_tree(i7process_t *proc) { proc->state.object_tree_sibling[i] = 0; } } +i7_property_set i7_properties[i7_max_objects]; + i7word_t i7_prop_len(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr_array) { i7word_t pr = i7_read_word(proc, pr_array, 1); if ((obj <= 0) || (obj >= i7_max_objects) || @@ -835,6 +837,16 @@ i7word_t i7_prop_addr(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr_a return i7_properties[(int) obj].address[(int) pr]; } +int i7_provides(i7process_t *proc, i7word_t owner_id, i7word_t pr_array) { + i7word_t prop_id = i7_read_word(proc, pr_array, 1); + if ((owner_id <= 0) || (owner_id >= i7_max_objects) || + (prop_id < 0) || (prop_id >= i7_no_property_ids)) return 0; + while (owner_id != 1) { + if (i7_properties[(int) owner_id].address[(int) prop_id] != 0) return 1; + owner_id = i7_class_of[owner_id]; + } + return 0; +} void i7_move(i7process_t *proc, i7word_t obj, i7word_t to) { if ((obj <= 0) || (obj >= i7_max_objects)) return; int p = proc->state.object_tree_parent[obj]; @@ -879,7 +891,23 @@ i7word_t i7_sibling(i7process_t *proc, i7word_t id) { if (i7_metaclass(proc, id) != i7_mgl_Object) return 0; return proc->state.object_tree_sibling[id]; } -i7_property_set i7_properties[i7_max_objects]; +int i7_in(i7process_t *proc, i7word_t obj1, i7word_t obj2) { + if (i7_metaclass(proc, obj1) != i7_mgl_Object) return 0; + if (obj2 == 0) return 0; + if (proc->state.object_tree_parent[obj1] == obj2) return 1; + return 0; +} +i7word_t i7_read_prop_value(i7process_t *proc, i7word_t owner_id, i7word_t pr_array) { + i7word_t prop_id = i7_read_word(proc, pr_array, 1); + if ((owner_id <= 0) || (owner_id >= i7_max_objects) || + (prop_id < 0) || (prop_id >= i7_no_property_ids)) return 0; + while (i7_properties[(int) owner_id].address[(int) prop_id] == 0) { + owner_id = i7_class_of[owner_id]; + if (owner_id == i7_mgl_Class) return 0; + } + i7word_t address = i7_properties[(int) owner_id].address[(int) prop_id]; + return i7_read_word(proc, address, 0); +} void i7_write_prop_value(i7process_t *proc, i7word_t owner_id, i7word_t pr_array, i7word_t val) { i7word_t prop_id = i7_read_word(proc, pr_array, 1); @@ -895,134 +923,80 @@ void i7_write_prop_value(i7process_t *proc, i7word_t owner_id, i7word_t pr_array i7_fatal_exit(proc); } } -i7word_t i7_read_prop_value(i7process_t *proc, i7word_t owner_id, i7word_t pr_array) { - i7word_t prop_id = i7_read_word(proc, pr_array, 1); - if ((owner_id <= 0) || (owner_id >= i7_max_objects) || - (prop_id < 0) || (prop_id >= i7_no_property_ids)) return 0; - while (i7_properties[(int) owner_id].address[(int) prop_id] == 0) { - owner_id = i7_class_of[owner_id]; - if (owner_id == i7_mgl_Class) return 0; - } - i7word_t address = i7_properties[(int) owner_id].address[(int) prop_id]; - return i7_read_word(proc, address, 0); -} -i7word_t i7_change_prop_value(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr, i7word_t to, int way) { +i7word_t i7_change_prop_value(i7process_t *proc, i7word_t obj, i7word_t pr, + i7word_t to, int way) { i7word_t val = i7_read_prop_value(proc, obj, pr), new_val = val; switch (way) { - case i7_lvalue_SET: i7_write_prop_value(proc, obj, pr, to); new_val = to; break; - case i7_lvalue_PREDEC: new_val = val-1; i7_write_prop_value(proc, obj, pr, val-1); break; - case i7_lvalue_POSTDEC: new_val = val; i7_write_prop_value(proc, obj, pr, val-1); break; - case i7_lvalue_PREINC: new_val = val+1; i7_write_prop_value(proc, obj, pr, val+1); break; - case i7_lvalue_POSTINC: new_val = val; i7_write_prop_value(proc, obj, pr, val+1); break; - case i7_lvalue_SETBIT: new_val = val | new_val; i7_write_prop_value(proc, obj, pr, new_val); break; - case i7_lvalue_CLEARBIT: new_val = val &(~new_val); i7_write_prop_value(proc, obj, pr, new_val); break; + case i7_lvalue_SET: + i7_write_prop_value(proc, obj, pr, to); new_val = to; break; + case i7_lvalue_PREDEC: + new_val = val-1; i7_write_prop_value(proc, obj, pr, val-1); break; + case i7_lvalue_POSTDEC: + new_val = val; i7_write_prop_value(proc, obj, pr, val-1); break; + case i7_lvalue_PREINC: + new_val = val+1; i7_write_prop_value(proc, obj, pr, val+1); break; + case i7_lvalue_POSTINC: + new_val = val; i7_write_prop_value(proc, obj, pr, val+1); break; + case i7_lvalue_SETBIT: + new_val = val | new_val; i7_write_prop_value(proc, obj, pr, new_val); break; + case i7_lvalue_CLEARBIT: + new_val = val &(~new_val); i7_write_prop_value(proc, obj, pr, new_val); break; } return new_val; } - -void i7_give(i7process_t *proc, i7word_t owner, i7word_t prop, i7word_t val) { - i7_write_prop_value(proc, owner, prop, val); -} - -int i7_has(i7process_t *proc, i7word_t obj, i7word_t either_or) { - if (i7_read_prop_value(proc, obj, either_or)) return 1; - return 0; -} - -int i7_provides(i7process_t *proc, i7word_t owner_id, i7word_t pr_array) { - i7word_t prop_id = i7_read_word(proc, pr_array, 1); - if ((owner_id <= 0) || (owner_id >= i7_max_objects) || - (prop_id < 0) || (prop_id >= i7_no_property_ids)) return 0; - while (owner_id != 1) { - if (i7_properties[(int) owner_id].address[(int) prop_id] != 0) - return 1; - owner_id = i7_class_of[owner_id]; - } - return 0; -} - -int i7_in(i7process_t *proc, i7word_t obj1, i7word_t obj2) { - if (i7_metaclass(proc, obj1) != i7_mgl_Object) return 0; - if (obj2 == 0) return 0; - if (proc->state.object_tree_parent[obj1] == obj2) return 1; - return 0; -} - - -void i7_provides_gprop_inner(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr, i7word_t *val, - i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_A_door_to, i7word_t i7_mgl_COL_HSIZE) { +int i7_provides_gprop_inner(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr, + i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, + i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_COL_HSIZE) { if (K == i7_mgl_OBJECT_TY) { - if (((obj) && ((i7_metaclass(proc, obj) == i7_mgl_Object)))) { - if (((i7_read_word(proc, pr, 0) == 2) || (i7_provides(proc, obj, pr)))) { - if (val) *val = 1; - } else { - if (val) *val = 0; - } - } else { - if (val) *val = 0; - } + if ((((obj) && ((i7_metaclass(proc, obj) == i7_mgl_Object)))) && + (((i7_read_word(proc, pr, 0) == 2) || (i7_provides(proc, obj, pr))))) + return 1; } else { if ((((obj >= 1)) && ((obj <= i7_read_word(proc, i7_mgl_value_ranges, K))))) { i7word_t holder = i7_read_word(proc, i7_mgl_value_property_holders, K); - if (((holder) && ((i7_provides(proc, holder, pr))))) { - if (val) *val = 1; - } else { - if (val) *val = 0; - } - } else { - if (val) *val = 0; + if (((holder) && ((i7_provides(proc, holder, pr))))) return 1; } } + return 0; } -int i7_provides_gprop(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr, - i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_A_door_to, i7word_t i7_mgl_COL_HSIZE) { +i7word_t i7_read_gprop_value_inner(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr, + i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, + i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_COL_HSIZE) { i7word_t val = 0; - i7_provides_gprop_inner(proc, K, obj, pr, &val, i7_mgl_OBJECT_TY, i7_mgl_value_ranges, i7_mgl_value_property_holders, i7_mgl_A_door_to, i7_mgl_COL_HSIZE); + if ((K == i7_mgl_OBJECT_TY)) { + return (i7word_t) i7_read_prop_value(proc, obj, pr); + } else { + i7word_t holder = i7_read_word(proc, i7_mgl_value_property_holders, K); + return (i7word_t) i7_read_word(proc, + i7_read_prop_value(proc, holder, pr), (obj + i7_mgl_COL_HSIZE)); + } return val; } -void i7_read_gprop_inner(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr, i7word_t *val, - i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_A_door_to, i7word_t i7_mgl_COL_HSIZE) { +void i7_write_gprop_value_inner(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr, + i7word_t val, i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, + i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_COL_HSIZE) { if ((K == i7_mgl_OBJECT_TY)) { - if ((i7_read_word(proc, pr, 0) == 2)) { - if ((i7_has(proc, obj, pr))) { - if (val) *val = 1; - } else { - if (val) *val = 0; - } - } else { - if (val) *val = (i7word_t) i7_read_prop_value(proc, obj, pr); - } + i7_write_prop_value(proc, obj, pr, val); } else { i7word_t holder = i7_read_word(proc, i7_mgl_value_property_holders, K); - if (val) *val = (i7word_t) i7_read_word(proc, i7_read_prop_value(proc, holder, pr), (obj + i7_mgl_COL_HSIZE)); + i7_write_word(proc, + i7_read_prop_value(proc, holder, pr), (obj + i7_mgl_COL_HSIZE), val); } } -i7word_t i7_read_gprop(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr, - i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_A_door_to, i7word_t i7_mgl_COL_HSIZE) { - i7word_t val = 0; - i7_read_gprop_inner(proc, K, obj, pr, &val, i7_mgl_OBJECT_TY, i7_mgl_value_ranges, i7_mgl_value_property_holders, i7_mgl_A_door_to, i7_mgl_COL_HSIZE); - return val; -} - -void i7_write_gprop_inner(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr, i7word_t val, i7word_t form, - i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_A_door_to, i7word_t i7_mgl_COL_HSIZE) { +void i7_change_gprop_value_inner(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr, + i7word_t val, i7word_t form, + i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, + i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_COL_HSIZE) { if ((K == i7_mgl_OBJECT_TY)) { - if ((i7_read_word(proc, pr, 0) == 2)) { - if (val) { - i7_change_prop_value(proc, K, obj, pr, 1, form); - } else { - i7_change_prop_value(proc, K, obj, pr, 0, form); - } - } else { - (i7_change_prop_value(proc, K, obj, pr, val, form)); - } + i7_change_prop_value(proc, obj, pr, val, form); } else { i7word_t holder = i7_read_word(proc, i7_mgl_value_property_holders, K); - (i7_change_word(proc, i7_read_prop_value(proc, holder, pr), (obj + i7_mgl_COL_HSIZE), val, form)); + i7_change_word(proc, + i7_read_prop_value(proc, holder, pr), (obj + i7_mgl_COL_HSIZE), val, form); } } i7word_t i7_call_0(i7process_t *proc, i7word_t id) { diff --git a/inform7/Internal/Miscellany/inform7_clib.h b/inform7/Internal/Miscellany/inform7_clib.h index 7994f37ff..cc479fbdf 100644 --- a/inform7/Internal/Miscellany/inform7_clib.h +++ b/inform7/Internal/Miscellany/inform7_clib.h @@ -178,35 +178,44 @@ void i7_print_dword(i7process_t *proc, i7word_t at); i7word_t i7_metaclass(i7process_t *proc, i7word_t id); int i7_ofclass(i7process_t *proc, i7word_t id, i7word_t cl_id); void i7_empty_object_tree(i7process_t *proc); -i7word_t i7_prop_addr(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr); -i7word_t i7_prop_len(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr); -void i7_move(i7process_t *proc, i7word_t obj, i7word_t to); -i7word_t i7_parent(i7process_t *proc, i7word_t id); -i7word_t i7_child(i7process_t *proc, i7word_t id); -i7word_t i7_children(i7process_t *proc, i7word_t id); -i7word_t i7_sibling(i7process_t *proc, i7word_t id); -i7word_t fn_i7_mgl_CreatePropertyOffsets(i7process_t *proc); -void i7_write_prop_value(i7process_t *proc, i7word_t owner_id, i7word_t prop_id, i7word_t val); -i7word_t i7_read_prop_value(i7process_t *proc, i7word_t owner_id, i7word_t pr_array); -i7word_t i7_change_prop_value(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr, i7word_t to, int way); -void i7_give(i7process_t *proc, i7word_t owner, i7word_t prop, i7word_t val); #define I7_MAX_PROPERTY_IDS 1000 typedef struct i7_property_set { i7word_t address[I7_MAX_PROPERTY_IDS]; i7word_t len[I7_MAX_PROPERTY_IDS]; } i7_property_set; i7_property_set i7_properties[]; -int i7_has(i7process_t *proc, i7word_t obj, i7word_t either_or); + +i7word_t i7_prop_addr(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr); +i7word_t i7_prop_len(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr); int i7_provides(i7process_t *proc, i7word_t owner_id, i7word_t prop_id); +void i7_move(i7process_t *proc, i7word_t obj, i7word_t to); +i7word_t i7_parent(i7process_t *proc, i7word_t id); +i7word_t i7_child(i7process_t *proc, i7word_t id); +i7word_t i7_children(i7process_t *proc, i7word_t id); +i7word_t i7_sibling(i7process_t *proc, i7word_t id); int i7_in(i7process_t *proc, i7word_t obj1, i7word_t obj2); -void i7_provides_gprop_inner(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t p, i7word_t *val, - i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_A_door_to, i7word_t i7_mgl_COL_HSIZE); -int i7_provides_gprop(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t p, - i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_A_door_to, i7word_t i7_mgl_COL_HSIZE); -void i7_read_gprop_inner(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t p, i7word_t *val, - i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_A_door_to, i7word_t i7_mgl_COL_HSIZE); -void i7_write_gprop_inner(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t p, i7word_t val, i7word_t form, - i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_A_door_to, i7word_t i7_mgl_COL_HSIZE); +i7word_t i7_read_prop_value(i7process_t *proc, i7word_t owner_id, i7word_t pr_array); +void i7_write_prop_value(i7process_t *proc, i7word_t owner_id, i7word_t prop_id, i7word_t val); +i7word_t i7_change_prop_value(i7process_t *proc, i7word_t owner_id, i7word_t prop_id, + i7word_t val, int way); +int i7_provides_gprop(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t p); +i7word_t i7_read_gprop_value(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr); +void i7_write_gprop_value(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t p, + i7word_t val); +void i7_change_gprop_value(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t p, + i7word_t val, i7word_t form); +int i7_provides_gprop_inner(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t p, + i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, + i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_COL_HSIZE); +i7word_t i7_read_gprop_value_inner(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr, + i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, + i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_COL_HSIZE); +void i7_write_gprop_value_inner(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t p, + i7word_t val, i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, + i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_COL_HSIZE); +void i7_change_gprop_value_inner(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t p, + i7word_t val, i7word_t form, i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, + i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_COL_HSIZE); i7word_t i7_gen_call(i7process_t *proc, i7word_t id, i7word_t *args, int argc); i7word_t i7_call_0(i7process_t *proc, i7word_t id); i7word_t i7_call_1(i7process_t *proc, i7word_t id, i7word_t v); diff --git a/inter/building-module/Chapter 1/The Veneer.w b/inter/building-module/Chapter 1/The Veneer.w index fe9b761e3..226faa3ef 100644 --- a/inter/building-module/Chapter 1/The Veneer.w +++ b/inter/building-module/Chapter 1/The Veneer.w @@ -24,7 +24,6 @@ @e ASM_NEG_RFALSE_VSYMB @e RESPONSETEXTS_VSYMB -@e CREATEPROPERTYOFFSETS_VSYMB @e KINDHIERARCHY_VSYMB @e NO_RESPONSES_VSYMB @@ -50,7 +49,6 @@ void Veneer::create_indexes(inter_tree *I) { Veneer::index(I, ASM_NEG_RFALSE_VSYMB, I"__assembly_negated_rfalse_label", I"?~rfalse"); Veneer::index(I, RESPONSETEXTS_VSYMB, I"ResponseTexts", NULL); - Veneer::index(I, CREATEPROPERTYOFFSETS_VSYMB, I"CreatePropertyOffsets", NULL); Veneer::index(I, KINDHIERARCHY_VSYMB, I"KindHierarchy", NULL); Veneer::index(I, NO_RESPONSES_VSYMB, I"NO_RESPONSES", NULL); } diff --git a/inter/final-module/Chapter 5/C Conditions.w b/inter/final-module/Chapter 5/C Conditions.w index 8fea648cc..399f56aad 100644 --- a/inter/final-module/Chapter 5/C Conditions.w +++ b/inter/final-module/Chapter 5/C Conditions.w @@ -32,9 +32,7 @@ int CConditions::invoke_primitive(code_generation *gen, inter_ti bip, inter_tree C_GEN_DATA(objdata.value_ranges_needed) = TRUE; C_GEN_DATA(objdata.value_property_holders_needed) = TRUE; WRITE("(i7_provides_gprop(proc, "); VNODE_1C; WRITE(", "); - VNODE_2C; WRITE(", "); VNODE_3C; WRITE(", "); - WRITE("i7_mgl_OBJECT_TY, i7_mgl_value_ranges, i7_mgl_value_property_holders, "); - WRITE("i7_mgl_A_door_to, i7_mgl_COL_HSIZE))"); + VNODE_2C; WRITE(", "); VNODE_3C; WRITE("))"); break; case EQ_BIP: case NE_BIP: case GT_BIP: case GE_BIP: case LT_BIP: case LE_BIP: case OFCLASS_BIP: case IN_BIP: case NOTIN_BIP: @@ -113,13 +111,11 @@ void CConditions::comparison_r(code_generation *gen, } if (bip == PROPERTYVALUE_BIP) { - WRITE("(i7_read_gprop(proc, ", test_fn); + WRITE("(i7_read_gprop_value(proc, ", test_fn); Vanilla::node(gen, K); WRITE(", "); @; WRITE(", "); @; - WRITE(", i7_mgl_OBJECT_TY, i7_mgl_value_ranges, i7_mgl_value_property_holders, "); - WRITE("i7_mgl_A_door_to, i7_mgl_COL_HSIZE"); WRITE("))"); } else if (Str::len(test_fn) > 0) { WRITE("(%S(proc, ", test_fn); diff --git a/inter/final-module/Chapter 5/C Object Model.w b/inter/final-module/Chapter 5/C Object Model.w index d3b623f6a..ca60c25b1 100644 --- a/inter/final-module/Chapter 5/C Object Model.w +++ b/inter/final-module/Chapter 5/C Object Model.w @@ -56,6 +56,7 @@ void CObjectModel::end(code_generation *gen) { CObjectModel::write_i7_initialise_object_tree(gen); CObjectModel::define_object_value_regions(gen); CObjectModel::compile_ofclass_array(gen); + CObjectModel::compile_gprop_functions(gen); segmentation_pos saved = CodeGen::select(gen, c_ids_and_maxima_I7CGS); text_stream *OUT = CodeGen::current(gen); WRITE("#define i7_max_objects I7VAL_STRINGS_BASE\n"); @@ -795,16 +796,30 @@ int CObjectModel::invoke_primitive(code_generation *gen, inter_ti bip, inter_tre return FALSE; } -@ Let's start with property array (for inline properties) and property length. +@ Let's start with property address and property length; while actual property +values live inside process memory, the addresses showing where they are in that +memory, and how many bytes they take up, are held in (static) arrays. Note that +although multiple processes running the same I7 story would have multiple values +for these properties, which likely differ at any given time, they would be at +the same address and of the same length in each. = (text to inform7_clib.h) +#define I7_MAX_PROPERTY_IDS 1000 +typedef struct i7_property_set { + i7word_t address[I7_MAX_PROPERTY_IDS]; + i7word_t len[I7_MAX_PROPERTY_IDS]; +} i7_property_set; +i7_property_set i7_properties[]; + i7word_t i7_prop_addr(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr); i7word_t i7_prop_len(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr); = -Note that lengths are returned in bytes, not words, hence the multiplication by 4. +Lengths are returned in bytes, not words, hence the multiplication by 4. = (text to inform7_clib.c) +i7_property_set i7_properties[i7_max_objects]; + i7word_t i7_prop_len(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr_array) { i7word_t pr = i7_read_word(proc, pr_array, 1); if ((obj <= 0) || (obj >= i7_max_objects) || @@ -819,6 +834,26 @@ i7word_t i7_prop_addr(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr_a return i7_properties[(int) obj].address[(int) pr]; } +@ The address array can be used to determine whether a runtime object or class +provides a given property: if the address is nonzero then it does. + += (text to inform7_clib.h) +int i7_provides(i7process_t *proc, i7word_t owner_id, i7word_t prop_id); += + += (text to inform7_clib.c) +int i7_provides(i7process_t *proc, i7word_t owner_id, i7word_t pr_array) { + i7word_t prop_id = i7_read_word(proc, pr_array, 1); + if ((owner_id <= 0) || (owner_id >= i7_max_objects) || + (prop_id < 0) || (prop_id >= i7_no_property_ids)) return 0; + while (owner_id != 1) { + if (i7_properties[(int) owner_id].address[(int) prop_id] != 0) return 1; + owner_id = i7_class_of[owner_id]; + } + return 0; +} += + @ Now |i7_move|, which moves |obj| in the object tree so that it becomes the eldest child of |to|, unless |to| is zero, in which case it is removed from the tree. @@ -886,26 +921,42 @@ i7word_t i7_sibling(i7process_t *proc, i7word_t id) { } = -@h Reading and writing properties. -So here is the run-time storage for property values, and simple code to read -and write them. +@ And the implementation of "is |obj1| directly a child of |obj2|?" = (text to inform7_clib.h) -i7word_t fn_i7_mgl_CreatePropertyOffsets(i7process_t *proc); -void i7_write_prop_value(i7process_t *proc, i7word_t owner_id, i7word_t prop_id, i7word_t val); -i7word_t i7_read_prop_value(i7process_t *proc, i7word_t owner_id, i7word_t pr_array); -i7word_t i7_change_prop_value(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr, i7word_t to, int way); -void i7_give(i7process_t *proc, i7word_t owner, i7word_t prop, i7word_t val); -#define I7_MAX_PROPERTY_IDS 1000 -typedef struct i7_property_set { - i7word_t address[I7_MAX_PROPERTY_IDS]; - i7word_t len[I7_MAX_PROPERTY_IDS]; -} i7_property_set; -i7_property_set i7_properties[]; +int i7_in(i7process_t *proc, i7word_t obj1, i7word_t obj2); = = (text to inform7_clib.c) -i7_property_set i7_properties[i7_max_objects]; +int i7_in(i7process_t *proc, i7word_t obj1, i7word_t obj2) { + if (i7_metaclass(proc, obj1) != i7_mgl_Object) return 0; + if (obj2 == 0) return 0; + if (proc->state.object_tree_parent[obj1] == obj2) return 1; + return 0; +} += + +@h Reading, writing and changing object properties. + += (text to inform7_clib.h) +i7word_t i7_read_prop_value(i7process_t *proc, i7word_t owner_id, i7word_t pr_array); +void i7_write_prop_value(i7process_t *proc, i7word_t owner_id, i7word_t prop_id, i7word_t val); +i7word_t i7_change_prop_value(i7process_t *proc, i7word_t owner_id, i7word_t prop_id, + i7word_t val, int way); += + += (text to inform7_clib.c) +i7word_t i7_read_prop_value(i7process_t *proc, i7word_t owner_id, i7word_t pr_array) { + i7word_t prop_id = i7_read_word(proc, pr_array, 1); + if ((owner_id <= 0) || (owner_id >= i7_max_objects) || + (prop_id < 0) || (prop_id >= i7_no_property_ids)) return 0; + while (i7_properties[(int) owner_id].address[(int) prop_id] == 0) { + owner_id = i7_class_of[owner_id]; + if (owner_id == i7_mgl_Class) return 0; + } + i7word_t address = i7_properties[(int) owner_id].address[(int) prop_id]; + return i7_read_word(proc, address, 0); +} void i7_write_prop_value(i7process_t *proc, i7word_t owner_id, i7word_t pr_array, i7word_t val) { i7word_t prop_id = i7_read_word(proc, pr_array, 1); @@ -921,164 +972,151 @@ void i7_write_prop_value(i7process_t *proc, i7word_t owner_id, i7word_t pr_array i7_fatal_exit(proc); } } -= -@ And here sre the functions called by the above primitives: - -= (text to inform7_clib.c) -i7word_t i7_read_prop_value(i7process_t *proc, i7word_t owner_id, i7word_t pr_array) { - i7word_t prop_id = i7_read_word(proc, pr_array, 1); - if ((owner_id <= 0) || (owner_id >= i7_max_objects) || - (prop_id < 0) || (prop_id >= i7_no_property_ids)) return 0; - while (i7_properties[(int) owner_id].address[(int) prop_id] == 0) { - owner_id = i7_class_of[owner_id]; - if (owner_id == i7_mgl_Class) return 0; - } - i7word_t address = i7_properties[(int) owner_id].address[(int) prop_id]; - return i7_read_word(proc, address, 0); -} - -i7word_t i7_change_prop_value(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr, i7word_t to, int way) { +i7word_t i7_change_prop_value(i7process_t *proc, i7word_t obj, i7word_t pr, + i7word_t to, int way) { i7word_t val = i7_read_prop_value(proc, obj, pr), new_val = val; switch (way) { - case i7_lvalue_SET: i7_write_prop_value(proc, obj, pr, to); new_val = to; break; - case i7_lvalue_PREDEC: new_val = val-1; i7_write_prop_value(proc, obj, pr, val-1); break; - case i7_lvalue_POSTDEC: new_val = val; i7_write_prop_value(proc, obj, pr, val-1); break; - case i7_lvalue_PREINC: new_val = val+1; i7_write_prop_value(proc, obj, pr, val+1); break; - case i7_lvalue_POSTINC: new_val = val; i7_write_prop_value(proc, obj, pr, val+1); break; - case i7_lvalue_SETBIT: new_val = val | new_val; i7_write_prop_value(proc, obj, pr, new_val); break; - case i7_lvalue_CLEARBIT: new_val = val &(~new_val); i7_write_prop_value(proc, obj, pr, new_val); break; + case i7_lvalue_SET: + i7_write_prop_value(proc, obj, pr, to); new_val = to; break; + case i7_lvalue_PREDEC: + new_val = val-1; i7_write_prop_value(proc, obj, pr, val-1); break; + case i7_lvalue_POSTDEC: + new_val = val; i7_write_prop_value(proc, obj, pr, val-1); break; + case i7_lvalue_PREINC: + new_val = val+1; i7_write_prop_value(proc, obj, pr, val+1); break; + case i7_lvalue_POSTINC: + new_val = val; i7_write_prop_value(proc, obj, pr, val+1); break; + case i7_lvalue_SETBIT: + new_val = val | new_val; i7_write_prop_value(proc, obj, pr, new_val); break; + case i7_lvalue_CLEARBIT: + new_val = val &(~new_val); i7_write_prop_value(proc, obj, pr, new_val); break; } return new_val; } - -void i7_give(i7process_t *proc, i7word_t owner, i7word_t prop, i7word_t val) { - i7_write_prop_value(proc, owner, prop, val); -} - = -@ +@h Reading, writing and changing general properties. +And these are the exactly analogous functions which more generally read, write +or change properties which can be held by either objects or enumerated instances -- +in other words, all properties. The additional kind argument |K| is then needed +to distinguish these cases (since the |obj| values for different kinds may well +coincide). + +The functions themselves are simple enough, but there is a complication, which +is that they need to use addresses which vary from one compilation to another; +so they cannot be written straightforwardly into our C library, which has to +be the same for all compilations. We get around this by compiling wrapper +functions in our story-file C which supply the necessary information and then +call clumsy but static functions in the C library; but this is all transparent +to the user, who should call only these: = (text to inform7_clib.h) -int i7_has(i7process_t *proc, i7word_t obj, i7word_t either_or); -int i7_provides(i7process_t *proc, i7word_t owner_id, i7word_t prop_id); -int i7_in(i7process_t *proc, i7word_t obj1, i7word_t obj2); +int i7_provides_gprop(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t p); +i7word_t i7_read_gprop_value(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr); +void i7_write_gprop_value(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t p, + i7word_t val); +void i7_change_gprop_value(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t p, + i7word_t val, i7word_t form); += + +@ So here are the dynamic wrappers. + += +void CObjectModel::compile_gprop_functions(code_generation *gen) { + segmentation_pos saved = CodeGen::select(gen, c_function_declarations_I7CGS); + text_stream *OUT = CodeGen::current(gen); + WRITE("int i7_provides_gprop(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t p) {\n"); + WRITE(" return i7_provides_gprop_inner(proc, K, obj, p, i7_mgl_OBJECT_TY,\n"); + WRITE(" i7_mgl_value_ranges, i7_mgl_value_property_holders, i7_mgl_COL_HSIZE);\n"); + WRITE("}\n"); + WRITE("i7word_t i7_read_gprop_value(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t p) {\n"); + WRITE(" return i7_read_gprop_value_inner(proc, K, obj, p, i7_mgl_OBJECT_TY,\n"); + WRITE(" i7_mgl_value_ranges, i7_mgl_value_property_holders, i7_mgl_COL_HSIZE);\n"); + WRITE("}\n"); + WRITE("void i7_write_gprop_value(i7process_t *proc, i7word_t K, i7word_t obj,\n"); + WRITE(" i7word_t p, i7word_t val) {\n"); + WRITE(" i7_write_gprop_value_inner(proc, K, obj, p, val, i7_mgl_OBJECT_TY,\n"); + WRITE(" i7_mgl_value_ranges, i7_mgl_value_property_holders, i7_mgl_COL_HSIZE);\n"); + WRITE("}\n"); + WRITE("void i7_change_gprop_value(i7process_t *proc, i7word_t K, i7word_t obj,\n"); + WRITE(" i7word_t p, i7word_t val, i7word_t form) {\n"); + WRITE(" i7_change_gprop_value_inner(proc, K, obj, p, val, form, i7_mgl_OBJECT_TY,\n"); + WRITE(" i7_mgl_value_ranges, i7_mgl_value_property_holders, i7_mgl_COL_HSIZE);\n"); + WRITE("}\n"); + CodeGen::deselect(gen, saved); +} + +@ And these are the static functions in the C library which they call: + += (text to inform7_clib.h) +int i7_provides_gprop_inner(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t p, + i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, + i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_COL_HSIZE); +i7word_t i7_read_gprop_value_inner(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr, + i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, + i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_COL_HSIZE); +void i7_write_gprop_value_inner(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t p, + i7word_t val, i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, + i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_COL_HSIZE); +void i7_change_gprop_value_inner(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t p, + i7word_t val, i7word_t form, i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, + i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_COL_HSIZE); = = (text to inform7_clib.c) -int i7_has(i7process_t *proc, i7word_t obj, i7word_t either_or) { - if (i7_read_prop_value(proc, obj, either_or)) return 1; - return 0; -} - -int i7_provides(i7process_t *proc, i7word_t owner_id, i7word_t pr_array) { - i7word_t prop_id = i7_read_word(proc, pr_array, 1); - if ((owner_id <= 0) || (owner_id >= i7_max_objects) || - (prop_id < 0) || (prop_id >= i7_no_property_ids)) return 0; - while (owner_id != 1) { - if (i7_properties[(int) owner_id].address[(int) prop_id] != 0) - return 1; - owner_id = i7_class_of[owner_id]; - } - return 0; -} - -int i7_in(i7process_t *proc, i7word_t obj1, i7word_t obj2) { - if (i7_metaclass(proc, obj1) != i7_mgl_Object) return 0; - if (obj2 == 0) return 0; - if (proc->state.object_tree_parent[obj1] == obj2) return 1; - return 0; -} - - -= - -= (text to inform7_clib.h) -void i7_provides_gprop_inner(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t p, i7word_t *val, - i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_A_door_to, i7word_t i7_mgl_COL_HSIZE); -int i7_provides_gprop(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t p, - i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_A_door_to, i7word_t i7_mgl_COL_HSIZE); -void i7_read_gprop_inner(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t p, i7word_t *val, - i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_A_door_to, i7word_t i7_mgl_COL_HSIZE); -void i7_write_gprop_inner(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t p, i7word_t val, i7word_t form, - i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_A_door_to, i7word_t i7_mgl_COL_HSIZE); -= - -= (text to inform7_clib.c) -void i7_provides_gprop_inner(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr, i7word_t *val, - i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_A_door_to, i7word_t i7_mgl_COL_HSIZE) { +int i7_provides_gprop_inner(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr, + i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, + i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_COL_HSIZE) { if (K == i7_mgl_OBJECT_TY) { - if (((obj) && ((i7_metaclass(proc, obj) == i7_mgl_Object)))) { - if (((i7_read_word(proc, pr, 0) == 2) || (i7_provides(proc, obj, pr)))) { - if (val) *val = 1; - } else { - if (val) *val = 0; - } - } else { - if (val) *val = 0; - } + if ((((obj) && ((i7_metaclass(proc, obj) == i7_mgl_Object)))) && + (((i7_read_word(proc, pr, 0) == 2) || (i7_provides(proc, obj, pr))))) + return 1; } else { if ((((obj >= 1)) && ((obj <= i7_read_word(proc, i7_mgl_value_ranges, K))))) { i7word_t holder = i7_read_word(proc, i7_mgl_value_property_holders, K); - if (((holder) && ((i7_provides(proc, holder, pr))))) { - if (val) *val = 1; - } else { - if (val) *val = 0; - } - } else { - if (val) *val = 0; + if (((holder) && ((i7_provides(proc, holder, pr))))) return 1; } } + return 0; } -int i7_provides_gprop(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr, - i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_A_door_to, i7word_t i7_mgl_COL_HSIZE) { +i7word_t i7_read_gprop_value_inner(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr, + i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, + i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_COL_HSIZE) { i7word_t val = 0; - i7_provides_gprop_inner(proc, K, obj, pr, &val, i7_mgl_OBJECT_TY, i7_mgl_value_ranges, i7_mgl_value_property_holders, i7_mgl_A_door_to, i7_mgl_COL_HSIZE); + if ((K == i7_mgl_OBJECT_TY)) { + return (i7word_t) i7_read_prop_value(proc, obj, pr); + } else { + i7word_t holder = i7_read_word(proc, i7_mgl_value_property_holders, K); + return (i7word_t) i7_read_word(proc, + i7_read_prop_value(proc, holder, pr), (obj + i7_mgl_COL_HSIZE)); + } return val; } -void i7_read_gprop_inner(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr, i7word_t *val, - i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_A_door_to, i7word_t i7_mgl_COL_HSIZE) { +void i7_write_gprop_value_inner(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr, + i7word_t val, i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, + i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_COL_HSIZE) { if ((K == i7_mgl_OBJECT_TY)) { - if ((i7_read_word(proc, pr, 0) == 2)) { - if ((i7_has(proc, obj, pr))) { - if (val) *val = 1; - } else { - if (val) *val = 0; - } - } else { - if (val) *val = (i7word_t) i7_read_prop_value(proc, obj, pr); - } + i7_write_prop_value(proc, obj, pr, val); } else { i7word_t holder = i7_read_word(proc, i7_mgl_value_property_holders, K); - if (val) *val = (i7word_t) i7_read_word(proc, i7_read_prop_value(proc, holder, pr), (obj + i7_mgl_COL_HSIZE)); + i7_write_word(proc, + i7_read_prop_value(proc, holder, pr), (obj + i7_mgl_COL_HSIZE), val); } } -i7word_t i7_read_gprop(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr, - i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_A_door_to, i7word_t i7_mgl_COL_HSIZE) { - i7word_t val = 0; - i7_read_gprop_inner(proc, K, obj, pr, &val, i7_mgl_OBJECT_TY, i7_mgl_value_ranges, i7_mgl_value_property_holders, i7_mgl_A_door_to, i7_mgl_COL_HSIZE); - return val; -} - -void i7_write_gprop_inner(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr, i7word_t val, i7word_t form, - i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_A_door_to, i7word_t i7_mgl_COL_HSIZE) { +void i7_change_gprop_value_inner(i7process_t *proc, i7word_t K, i7word_t obj, i7word_t pr, + i7word_t val, i7word_t form, + i7word_t i7_mgl_OBJECT_TY, i7word_t i7_mgl_value_ranges, + i7word_t i7_mgl_value_property_holders, i7word_t i7_mgl_COL_HSIZE) { if ((K == i7_mgl_OBJECT_TY)) { - if ((i7_read_word(proc, pr, 0) == 2)) { - if (val) { - i7_change_prop_value(proc, K, obj, pr, 1, form); - } else { - i7_change_prop_value(proc, K, obj, pr, 0, form); - } - } else { - (i7_change_prop_value(proc, K, obj, pr, val, form)); - } + i7_change_prop_value(proc, obj, pr, val, form); } else { i7word_t holder = i7_read_word(proc, i7_mgl_value_property_holders, K); - (i7_change_word(proc, i7_read_prop_value(proc, holder, pr), (obj + i7_mgl_COL_HSIZE), val, form)); + i7_change_word(proc, + i7_read_prop_value(proc, holder, pr), (obj + i7_mgl_COL_HSIZE), val, form); } } = diff --git a/inter/final-module/Chapter 5/C References.w b/inter/final-module/Chapter 5/C References.w index d189114c4..be2efa6a8 100644 --- a/inter/final-module/Chapter 5/C References.w +++ b/inter/final-module/Chapter 5/C References.w @@ -98,14 +98,12 @@ calling functions. @ = WRITE("("); - WRITE("i7_write_gprop_inner(proc, "); + WRITE("i7_change_gprop_value(proc, "); Vanilla::node(gen, InterTree::first_child(storage_ref)); WRITE(", "); Vanilla::node(gen, InterTree::second_child(storage_ref)); WRITE(", "); Vanilla::node(gen, InterTree::third_child(storage_ref)); WRITE(", "); if (val_supplied) { VNODE_2C; } else { WRITE("0"); } WRITE(", %S", store_form); - WRITE(", i7_mgl_OBJECT_TY, i7_mgl_value_ranges, i7_mgl_value_property_holders, "); - WRITE("i7_mgl_A_door_to, i7_mgl_COL_HSIZE"); WRITE("))"); @ =