Explorar o código

ncd: NCDModule: have the interpreter initialize the mem pointer itself. This allows us to remove the 'mem'
pointer of struct statement and use the one in NCDModuleInst.

ambrop7 %!s(int64=13) %!d(string=hai) anos
pai
achega
075b6c643a
Modificáronse 3 ficheiros con 27 adicións e 28 borrados
  1. 10 11
      ncd/NCDInterpreter.c
  2. 9 12
      ncd/NCDModule.c
  3. 8 5
      ncd/NCDModule.h

+ 10 - 11
ncd/NCDInterpreter.c

@@ -64,7 +64,6 @@
 struct statement {
     NCDModuleInst inst;
     NCDValMem args_mem;
-    char *mem;
     int mem_size;
     int i;
     int state;
@@ -493,7 +492,7 @@ int process_new (NCDInterpreter *interp, NCDInterpProcess *iprocess, NCDModulePr
         ps->i = i;
         ps->state = SSTATE_FORGOTTEN;
         ps->mem_size = NCDInterpProcess_StatementPreallocSize(iprocess, i);
-        ps->mem = (ps->mem_size == 0 ? NULL : mem + NCDInterpProcess_StatementPreallocOffset(iprocess, i));
+        ps->inst.mem = mem + NCDInterpProcess_StatementPreallocOffset(iprocess, i);
     }
     
     // init timer
@@ -527,7 +526,7 @@ void process_free (struct process *p, NCDModuleProcess **out_mp)
     for (int i = 0; i < p->num_statements; i++) {
         struct statement *ps = &p->statements[i];
         if (statement_mem_is_allocated(ps)) {
-            free(ps->mem);
+            free(ps->inst.mem);
         }
     }
     
@@ -867,7 +866,6 @@ void process_advance (struct process *p)
         statement_log(ps, BLOG_ERROR, "failed to allocate memory");
         goto fail1;
     }
-    char *mem = (module->alloc_size == 0 ? NULL : ps->mem);
     
     // set statement state CHILD
     ps->state = SSTATE_CHILD;
@@ -881,7 +879,7 @@ void process_advance (struct process *p)
     process_assert_pointers(p);
     
     // initialize module instance
-    NCDModuleInst_Init(&ps->inst, module, mem, object_ptr, args, &p->interp->module_params);
+    NCDModuleInst_Init(&ps->inst, module, object_ptr, args, &p->interp->module_params);
     return;
     
 fail1:
@@ -1029,16 +1027,17 @@ int statement_allocate_memory (struct statement *ps, int alloc_size)
     ASSERT(alloc_size >= 0)
     
     if (alloc_size > statement_mem_size(ps)) {
-        if (statement_mem_is_allocated(ps)) {
-            free(ps->mem);
-        }
-        
-        if (!(ps->mem = malloc(alloc_size))) {
+        char *new_mem = malloc(alloc_size);
+        if (!new_mem) {
             statement_log(ps, BLOG_ERROR, "malloc failed");
-            ps->mem_size = 0;
             return 0;
         }
         
+        if (statement_mem_is_allocated(ps)) {
+            free(ps->inst.mem);
+        }
+        
+        ps->inst.mem = new_mem;
         ps->mem_size = -alloc_size;
     }
     

+ 9 - 12
ncd/NCDModule.c

@@ -66,13 +66,13 @@ static void inst_assert_backend (NCDModuleInst *n)
            n->state == STATE_DYING)
 }
 
-void NCDModuleInst_Init (NCDModuleInst *n, const struct NCDModule *m, void *mem, const NCDObject *method_object, NCDValRef args, const struct NCDModuleInst_params *params)
+void NCDModuleInst_Init (NCDModuleInst *n, const struct NCDModule *m, const NCDObject *method_object, NCDValRef args, const struct NCDModuleInst_params *params)
 {
     ASSERT(m)
     ASSERT(m->func_new2)
     ASSERT(m->alloc_size >= 0)
     ASSERT(m->base_type_id >= 0)
-    ASSERT(!!mem == m->alloc_size > 0)
+    ASSERT(n->mem)
     ASSERT(NCDVal_IsList(args))
     ASSERT(params)
     ASSERT(params->func_event)
@@ -88,9 +88,6 @@ void NCDModuleInst_Init (NCDModuleInst *n, const struct NCDModule *m, void *mem,
     n->m = m;
     n->params = params;
     
-    // set initial instance argument
-    n->inst_user = mem;
-    
     // set initial state
     n->state = STATE_DOWN_CLEAN;
     
@@ -103,7 +100,7 @@ void NCDModuleInst_Init (NCDModuleInst *n, const struct NCDModule *m, void *mem,
     new_params.method_user = (method_object ? method_object->user : NULL);
     new_params.args = args;
     
-    n->m->func_new2(n->inst_user, n, &new_params);
+    n->m->func_new2(n->mem, n, &new_params);
 }
 
 void NCDModuleInst_Free (NCDModuleInst *n)
@@ -124,7 +121,7 @@ void NCDModuleInst_Die (NCDModuleInst *n)
         return;
     }
     
-    n->m->func_die(n->inst_user);
+    n->m->func_die(n->mem);
     return;
 }
 
@@ -137,7 +134,7 @@ void NCDModuleInst_Clean (NCDModuleInst *n)
         n->state = STATE_DOWN_CLEAN;
             
         if (n->m->func_clean) {
-            n->m->func_clean(n->inst_user);
+            n->m->func_clean(n->mem);
             return;
         }
     }
@@ -174,10 +171,10 @@ static int object_func_getvar (NCDModuleInst *n, NCD_string_id_t name, NCDValMem
     
     int res;
     if (n->m->func_getvar2) {
-        res = n->m->func_getvar2(n->inst_user, name, mem, out_value);
+        res = n->m->func_getvar2(n->mem, name, mem, out_value);
     } else {
         const char *name_str = NCDStringIndex_Value(n->params->iparams->string_index, name);
-        res = n->m->func_getvar(n->inst_user, name_str, mem, out_value);
+        res = n->m->func_getvar(n->mem, name_str, mem, out_value);
     }
     ASSERT(res == 0 || res == 1)
     ASSERT(res == 0 || (NCDVal_Assert(*out_value), 1))
@@ -193,7 +190,7 @@ static int object_func_getobj (NCDModuleInst *n, NCD_string_id_t name, NCDObject
         return 0;
     }
     
-    int res = n->m->func_getobj(n->inst_user, name, out_object);
+    int res = n->m->func_getobj(n->mem, name, out_object);
     ASSERT(res == 0 || res == 1)
     
     return res;
@@ -214,7 +211,7 @@ void * NCDModuleInst_Backend_GetUser (NCDModuleInst *n)
            n->state == STATE_UP ||
            n->state == STATE_DYING)
     
-    return n->inst_user;
+    return n->mem;
 }
 
 void NCDModuleInst_Backend_Up (NCDModuleInst *n)

+ 8 - 5
ncd/NCDModule.h

@@ -343,7 +343,7 @@ struct NCDModuleInst_iparams {
 typedef struct NCDModuleInst_s {
     const struct NCDModule *m;
     const struct NCDModuleInst_params *params;
-    void *inst_user;
+    void *mem;
     int state;
     int is_error;
     DebugObject d_obj;
@@ -375,11 +375,14 @@ typedef struct NCDModuleProcess_s {
  * The Backend methods are the module backend interface and are documented
  * independently with their own logical states.
  * 
+ * NOTE: the instance structure \a n should have the member 'mem' initialized
+ * to point to preallocated memory for the statement. This memory must be
+ * at least m->prealloc_size big and must be properly aligned for any object.
+ * The 'mem' pointer is never modified by NCDModuleInst, so that the interpreter
+ * can use it as outside the lifetime of NCDModuleInst.
+ * 
  * @param n the instance
  * @param m structure of module functions implementing the module backend
- * @param mem preallocated memory for the instance. If m->prealloc_size == 0, this must be NULL;
- *            if it is >0, it must point to a block of memory with at least that many bytes available,
- *            and properly aligned for any object.
  * @param method_object the base object if the module being initialized is a method, otherwise NULL.
  *                      The caller must ensure that this object is of the type expected by the module
  *                      being initialized.
@@ -388,7 +391,7 @@ typedef struct NCDModuleProcess_s {
  * @param user argument to callback functions
  * @param params more parameters, see {@link NCDModuleInst_params}
  */
-void NCDModuleInst_Init (NCDModuleInst *n, const struct NCDModule *m, void *mem, const NCDObject *method_object, NCDValRef args, const struct NCDModuleInst_params *params);
+void NCDModuleInst_Init (NCDModuleInst *n, const struct NCDModule *m, const NCDObject *method_object, NCDValRef args, const struct NCDModuleInst_params *params);
 
 /**
  * Frees the instance.