]> git.mxchange.org Git - simgear.git/blobdiff - simgear/nasal/misc.c
cppbind::Ghost: improve compiler error message for wrong usage.
[simgear.git] / simgear / nasal / misc.c
index f74ca95e22eb4f8709c1f8d2dc2b66e29035ad0e..5a531d536d7d2a0cd0bccfb1c92a2323c8cbeb18 100644 (file)
@@ -7,13 +7,29 @@
 
 void naFree(void* m) { free(m); }
 void* naAlloc(int n) { return malloc(n); }
+void* naRealloc(void* b, int n) { return realloc(b, n); }
 void naBZero(void* m, int n) { memset(m, 0, n); }
 
+void naTempSave(naContext c, naRef r)
+{
+    int i;
+    if(!IS_OBJ(r)) return;
+    if(c->ntemps >= c->tempsz) {
+        struct naObj** newtemps;
+        c->tempsz *= 2;
+        newtemps = naAlloc(c->tempsz * sizeof(struct naObj*));
+        for(i=0; i<c->ntemps; i++)
+            newtemps[i] = c->temps[i];
+        naFree(c->temps);
+        c->temps = newtemps;
+    }
+    c->temps[c->ntemps++] = PTR(r).obj;
+}
+
 naRef naObj(int type, struct naObj* o)
 {
     naRef r;
-    r.ref.reftag = NASAL_REFTAG;
-    r.ref.ptr.obj = o;
+    SETPTR(r, o);
     o->type = type;
     return r;
 }
@@ -49,34 +65,36 @@ naRef naStringValue(naContext c, naRef r)
 
 naRef naNew(struct Context* c, int type)
 {
+    naRef result;
     if(c->nfree[type] == 0)
         c->free[type] = naGC_get(&globals->pools[type],
                                  OBJ_CACHE_SZ, &c->nfree[type]);
-    naRef result = naObj(type, c->free[type][--c->nfree[type]]);
-    naVec_append(c->temps, result);
+    result = naObj(type, c->free[type][--c->nfree[type]]);
+    naTempSave(c, result);
     return result;
 }
 
 naRef naNewString(struct Context* c)
 {
     naRef s = naNew(c, T_STR);
-    s.ref.ptr.str->len = 0;
-    s.ref.ptr.str->data = 0;
-    s.ref.ptr.str->hashcode = 0;
+    PTR(s).str->emblen = 0;
+    PTR(s).str->data.ref.len = 0;
+    PTR(s).str->data.ref.ptr = 0;
+    PTR(s).str->hashcode = 0;
     return s;
 }
 
 naRef naNewVector(struct Context* c)
 {
     naRef r = naNew(c, T_VEC);
-    r.ref.ptr.vec->rec = 0;
+    PTR(r).vec->rec = 0;
     return r;
 }
 
 naRef naNewHash(struct Context* c)
 {
     naRef r = naNew(c, T_HASH);
-    r.ref.ptr.hash->rec = 0;
+    PTR(r).hash->rec = 0;
     return r;
 }
 
@@ -88,59 +106,88 @@ naRef naNewCode(struct Context* c)
 naRef naNewCCode(struct Context* c, naCFunction fptr)
 {
     naRef r = naNew(c, T_CCODE);
-    r.ref.ptr.ccode->fptr = fptr;
+    PTR(r).ccode->fptr = fptr;
+    PTR(r).ccode->fptru = 0;
+    return r;
+}
+
+naRef naNewCCodeU(struct Context* c, naCFunctionU fptr, void* user_data)
+{
+    return naNewCCodeUD(c, fptr, user_data, 0);
+}
+
+naRef naNewCCodeUD( struct Context* c,
+                    naCFunctionU fptr,
+                    void* user_data,
+                    void (*destroy)(void*) )
+{
+    naRef r = naNew(c, T_CCODE);
+    PTR(r).ccode->fptru = fptr;
+    PTR(r).ccode->user_data = user_data;
+    PTR(r).ccode->destroy = destroy;
     return r;
 }
 
 naRef naNewFunc(struct Context* c, naRef code)
 {
     naRef func = naNew(c, T_FUNC);
-    func.ref.ptr.func->code = code;
-    func.ref.ptr.func->namespace = naNil();
-    func.ref.ptr.func->next = naNil();
+    PTR(func).func->code = code;
+    PTR(func).func->namespace = naNil();
+    PTR(func).func->next = naNil();
     return func;
 }
 
 naRef naNewGhost(naContext c, naGhostType* type, void* ptr)
+{
+    naRef ghost;
+    // ensure 'simple' ghost users don't see garbage for these fields
+    type->get_member = 0;
+    type->set_member = 0;
+    
+    ghost = naNew(c, T_GHOST);
+    PTR(ghost).ghost->gtype = type;
+    PTR(ghost).ghost->ptr = ptr;
+    return ghost;
+}
+
+naRef naNewGhost2(naContext c, naGhostType* t, void* ptr)
 {
     naRef ghost = naNew(c, T_GHOST);
-    ghost.ref.ptr.ghost->gtype = type;
-    ghost.ref.ptr.ghost->ptr = ptr;
+    PTR(ghost).ghost->gtype = t;
+    PTR(ghost).ghost->ptr = ptr;
     return ghost;
 }
 
 naGhostType* naGhost_type(naRef ghost)
 {
     if(!IS_GHOST(ghost)) return 0;
-    return ghost.ref.ptr.ghost->gtype;
+    return PTR(ghost).ghost->gtype;
 }
 
 void* naGhost_ptr(naRef ghost)
 {
     if(!IS_GHOST(ghost)) return 0;
-    return ghost.ref.ptr.ghost->ptr;
+    return PTR(ghost).ghost->ptr;
 }
 
 naRef naNil()
 {
-    naRef r;
-    r.ref.reftag = NASAL_REFTAG;
-    r.ref.ptr.obj = 0;
+    naRef r; 
+    SETPTR(r, 0);
     return r;
 }
 
 naRef naNum(double num)
 {
     naRef r;
-    r.ref.reftag = ~NASAL_REFTAG;
-    r.num = num;
+    SETNUM(r, num);
     return r;
 }
 
 int naEqual(naRef a, naRef b)
 {
     double na=0, nb=0;
-    if(IS_REF(a) && IS_REF(b) && a.ref.ptr.obj == b.ref.ptr.obj)
+    if(IS_REF(a) && IS_REF(b) && PTR(a).obj == PTR(b).obj)
         return 1; // Object identity (and nil == nil)
     if(IS_NIL(a) || IS_NIL(b))
         return 0;
@@ -162,12 +209,13 @@ int naEqual(naRef a, naRef b)
 int naStrEqual(naRef a, naRef b)
 {
     int i;
-    if(!(IS_STR(a) && IS_STR(b)))
+    char *ap, *bp;
+    if(!IS_STR(a) || !IS_STR(b) || naStr_len(a) != naStr_len(b))
         return 0;
-    if(a.ref.ptr.str->len != b.ref.ptr.str->len)
-        return 0;
-    for(i=0; i<a.ref.ptr.str->len; i++)
-        if(a.ref.ptr.str->data[i] != b.ref.ptr.str->data[i])
+    ap = naStr_data(a);
+    bp = naStr_data(b);
+    for(i=0; i<naStr_len(a); i++)
+        if(ap[i] != bp[i])
             return 0;
     return 1;
 }
@@ -186,52 +234,35 @@ int naTypeSize(int type)
     return 0x7fffffff; // Make sure the answer is nonsense :)
 }
 
-int naIsNil(naRef r)
-{
-    return IS_NIL(r);
-}
-
-int naIsNum(naRef r)
-{
-    return IS_NUM(r);
-}
-
-int naIsString(naRef r)
-{
-    return (!IS_NIL(r))&&IS_STR(r);
-}
-
-int naIsScalar(naRef r)
-{
-    return IS_SCALAR(r);
-}
-
-int naIsVector(naRef r)
-{
-    return (!IS_NIL(r))&&IS_VEC(r);
-}
-
-int naIsHash(naRef r)
-{
-    return (!IS_NIL(r))&&IS_HASH(r);
-}
-
-int naIsFunc(naRef r)
-{
-    return (!IS_NIL(r))&&IS_FUNC(r);
-}
-
-int naIsCode(naRef r)
+int naIsNil(naRef r)    { return IS_NIL(r); }
+int naIsNum(naRef r)    { return IS_NUM(r); }
+int naIsString(naRef r) { return IS_STR(r); }
+int naIsScalar(naRef r) { return IS_SCALAR(r); }
+int naIsVector(naRef r) { return IS_VEC(r); }
+int naIsHash(naRef r)   { return IS_HASH(r); }
+int naIsFunc(naRef r)   { return IS_FUNC(r); }
+int naIsCode(naRef r)   { return IS_CODE(r); }
+int naIsCCode(naRef r)  { return IS_CCODE(r); }
+int naIsGhost(naRef r)  { return IS_GHOST(r); }
+int naIsIdentical(naRef l, naRef r) { return IDENTICAL(l, r); }
+
+void naSetUserData(naContext c, void* p) { c->userData = p; }
+void* naGetUserData(naContext c)
 {
-    return IS_CODE(r);
+    if(c->userData) return c->userData;
+    return c->callParent ? naGetUserData(c->callParent) : 0;
 }
 
-int naIsCCode(naRef r)
+void naAddSym(naContext c, naRef ns, char *sym, naRef val)
 {
-    return IS_CCODE(r);
+    naRef name = naStr_fromdata(naNewString(c), sym, strlen(sym));
+    naHash_set(ns, naInternSymbol(name), val);
 }
 
-int naIsGhost(naRef r)
+naRef naGenLib(naContext c, naCFuncItem *fns)
 {
-    return IS_GHOST(r);
+    naRef ns = naNewHash(c);
+    for(/**/; fns->name; fns++)
+        naAddSym(c, ns, fns->name, naNewFunc(c, naNewCCode(c, fns->func)));
+    return ns;
 }