SPN_API SpnFunction *spn_func_new_closure(SpnFunction *prototype) { SpnFunction *func = spn_object_new(&spn_class_func); /* only a Sparkling function can be used as the prototype * of a closure, native ones can't. A top-level program * cannot be used to form a closure either. */ assert(prototype->native == 0); assert(prototype->topprg == 0); assert(prototype->is_closure == 0); func->native = 0; func->topprg = 0; func->is_closure = 1; func->nwords = 0; /* unused */ /* func->symtab is always a weak pointer for closures, * because the prototype is never a top-level program, * and only function objects that represent a top-level * program have a strong symbol table pointer. */ func->name = prototype->name; /* weak pointer */ func->env = prototype->env; /* weak pointer */ func->readsymtab = 0; /* unused */ func->symtab = prototype->symtab; /* weak pointer */ func->upvalues = spn_array_new(); func->repr = prototype->repr; return func; }
SpnFunction *spn_func_new_topprg(const char *name, spn_uword *bc, size_t nwords) { SpnFunction *func = spn_object_new(&spn_class_func); func->native = 0; func->topprg = 1; func->is_closure = 0; func->nwords = nwords; func->name = name; func->env = func; /* top program's environment is itself */ func->readsymtab = 0; func->symtab = spn_array_new(); func->upvalues = NULL; /* unused */ func->repr.bc = bc; /* strong pointer */ return func; }
/* convenience value constructor */ SpnValue spn_makearray(void) { return makeobject(spn_array_new()); }