Просмотр исходного кода

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 13 лет назад
Родитель
Сommit
075b6c643a
3 измененных файлов с 27 добавлено и 28 удалено
  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.