static Function * link_code (JSVirtualMachine *vm, unsigned char *code, unsigned int code_len, unsigned int consts_offset) { unsigned char *cp, *end; JSInt32 i; Compiled **reloc; unsigned int cpos; Function *f; unsigned char *fixed_code; /* Terminate the code with op `done'. */ fixed_code = js_malloc (vm, code_len + 1); memcpy (fixed_code, code, code_len); fixed_code[code_len] = 1; /* op `done' */ cp = fixed_code; end = fixed_code + code_len + 1; /* Alloc function closure. */ f = js_vm_alloc_destroyable (vm, sizeof (*f)); f->destroy = function_destroy; /* Allocate space for our compiled code. <length> is enought. */ f->code = js_malloc (vm, (code_len + 1) * sizeof (Compiled)); reloc = js_calloc (vm, code_len + 1, sizeof (Compiled *)); /* Link phase 1: constants and symbols. */ cpos = 0; while (cp < end) { switch (*cp++) { /* include c1switch.h */ #include "c1switch.h" /* end include c1switch.h */ } } f->length = cpos; /* Link phase 2: relative jumps. */ cp = fixed_code; cpos = 0; while (cp < end) { switch (*cp++) { /* include c2switch.h */ #include "c2switch.h" /* end include c2switch.h */ } } /* Handle debug info. */ /* XXX */ js_free (reloc); js_free (fixed_code); return f; }
JSBuiltinInfo *js_vm_builtin_info_create(JSVirtualMachine * vm) { JSNode prototype; JSBuiltinInfo *i = js_vm_alloc_destroyable(vm, sizeof(*i)); i->destroy = destroy_builtin_info; i->prototype = js_vm_object_new(vm); /* * Set the __proto__ property to null. We have no prototype object * above us. */ prototype.type = JS_NULL; js_vm_object_store_property(vm, i->prototype, vm->syms.s___proto__, &prototype); return i; }
void js_vm_builtin_create(JSVirtualMachine * vm, JSNode * result, JSBuiltinInfo * info, void *instance_context) { result->type = JS_BUILTIN; result->u.vbuiltin = js_vm_alloc_destroyable(vm, sizeof(JSBuiltin)); result->u.vbuiltin->destroy = destroy_builtin; result->u.vbuiltin->info = info; if (instance_context) { JSNode prototype; result->u.vbuiltin->instance_context = instance_context; result->u.vbuiltin->prototype = js_vm_object_new(vm); /* Set the __proto__ chain. */ prototype.type = JS_OBJECT; prototype.u.vobject = info->prototype; js_vm_object_store_property(vm, result->u.vbuiltin->prototype, vm->syms.s___proto__, &prototype); } }
int js_vm_switch0_exec (JSVirtualMachine *vm, JSByteCode *bc, JSSymtabEntry *symtab, unsigned int num_symtab_entries, unsigned int consts_offset, unsigned int anonymous_function_offset, /*unsigned char *debug_info, unsigned int debug_info_len,*/ JSNode *object, JSNode *func, unsigned int argc, JSNode *argv) { int i; unsigned int ui; Function *global_f = NULL; Function *f; unsigned char *code = NULL; char buf[512]; if (bc) { /* Executing byte-code. */ /* Find the code section. */ for (i = 0; i < bc->num_sects; i++) if (bc->sects[i].type == JS_BCST_CODE) code = bc->sects[i].data; assert (code != NULL); /* Enter all functions to the known functions of the VM. */ for (i = 0; i < num_symtab_entries; i++) { /* Need one function. */ f = js_vm_alloc_destroyable (vm, sizeof (*f)); f->destroy = function_destroy; f->name = js_strdup (vm, symtab[i].name); f->length = symtab[i + 1].offset - symtab[i].offset + 1; f->code = js_malloc (vm, f->length); memcpy (f->code, code + symtab[i].offset, f->length - 1); f->code[f->length - 1] = 1; /* op `done' */ /* Link the code to our environment. */ link_code (vm, f->code, f->length, consts_offset); if (strcmp (symtab[i].name, JS_GLOBAL_NAME) == 0) global_f = f; else { int is_anonymous = 0; /* Check for the anonymous function. */ if (symtab[i].name[0] == '.' && symtab[i].name[1] == 'F' && symtab[i].name[2] == ':') is_anonymous = 1; if (vm->verbose > 3) { sprintf_P (buf, vmswt0_string_0, symtab[i].name, symtab[i].offset, symtab[i + 1].offset - symtab[i].offset); if (is_anonymous) sprintf_P (buf + strlen (buf), vmswt0_string_1, anonymous_function_offset); strcat (buf, JS_HOST_LINE_BREAK); //js_iostream_write (vm->s_stderr, buf, strlen (buf)); } if (is_anonymous) { sprintf (buf, ".F:%u", (unsigned int) atoi (symtab[i].name + 3) + anonymous_function_offset); ui = js_vm_intern (vm, buf); } else ui = js_vm_intern (vm, symtab[i].name); vm->globals[ui].type = JS_FUNC; vm->globals[ui].u.vfunction = js_vm_make_function (vm, f); } } } else { /* Applying arguments to function. */ if (func->type != JS_FUNC) { sprintf_P (vm->error, vmswt0_string_2); return 0; } if (vm->verbose > 1) { sprintf_P (buf, vmswt0_string_3, JS_HOST_LINE_BREAK); //js_iostream_write (vm->s_stderr, buf, strlen (buf)); } f = func->u.vfunction->implementation; execute_code (vm, object, f, argc, argv); } if (global_f) { if (vm->verbose > 1) { sprintf_P (buf, vmswt0_string_4, global_f->name, JS_HOST_LINE_BREAK); //js_iostream_write (vm->s_stderr, buf, strlen (buf)); } /* Execute. */ execute_code (vm, NULL, global_f, 0, NULL); } return 1; }