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; }
SpnArray *spn_array_new(void) { SpnArray *array = spn_object_new(&spn_class_array); array->vector = NULL; array->count = 0; array->allocsize = 0; return array; }
SpnString *spn_string_new_nocopy_len(const char *cstr, size_t len, int dealloc) { SpnString *str = spn_object_new(&spn_class_string); str->dealloc = dealloc; str->len = len; str->cstr = (char *)(cstr); str->ishashed = 0; return str; }
SpnFunction *spn_func_new_native(const char *name, int (*fn)(SpnValue *, int, SpnValue *, void *)) { SpnFunction *func = spn_object_new(&spn_class_func); func->native = 1; func->topprg = 0; func->is_closure = 0; func->nwords = 0; /* unused */ func->name = name; func->env = NULL; /* unused */ func->readsymtab = 0; /* unused */ func->symtab = NULL; /* unused */ func->upvalues = NULL; /* unused */ func->repr.fn = fn; 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; }
SpnFunction *spn_func_new_script(const char *name, spn_uword *bc, SpnFunction *env) { SpnFunction *func = spn_object_new(&spn_class_func); assert(env->topprg); /* environment must be a top-level program */ assert(env->readsymtab); /* must've already run top-level program */ func->native = 0; func->topprg = 0; func->is_closure = 0; func->nwords = 0; /* unused */ func->name = name; func->env = env; func->readsymtab = 0; /* unused */ func->symtab = env->symtab; /* weak pointer */ func->upvalues = NULL; /* unused */ func->repr.bc = bc; /* weak pointer */ return func; }