unsigned int js_vm_intern_with_len(JSVirtualMachine * vm, const char *name, unsigned int len) { JSHashBucket *b; unsigned int pos = js_count_hash(name, len) % JS_HASH_TABLE_SIZE; for (b = vm->globals_hash[pos]; b; b = b->next) if (strcmp(b->name, name) == 0) return b->u.ui; b = js_malloc(vm, sizeof(*b)); b->name = js_strdup(vm, name); b->next = vm->globals_hash[pos]; vm->globals_hash[pos] = b; /* Alloc space from the globals array. */ if (vm->num_globals >= vm->globals_alloc) { // CHANGE alloc times to 16 vm->globals = js_realloc(vm, vm->globals, (vm->globals_alloc + 16) * sizeof(JSNode)); vm->globals_alloc += 16; } /* Initialize symbol's name spaces. */ vm->globals[vm->num_globals].type = JS_UNDEFINED; b->u.ui = vm->num_globals++; return b->u.ui; }
static void addlocal(JF, js_Ast *ident, int reuse) { const char *name = ident->string; if (J->strict) { if (!strcmp(name, "arguments")) jsC_error(J, ident, "redefining 'arguments' is not allowed in strict mode"); if (!strcmp(name, "eval")) jsC_error(J, ident, "redefining 'eval' is not allowed in strict mode"); } if (reuse || J->strict) { int i; for (i = 0; i < F->varlen; ++i) { if (!strcmp(F->vartab[i], name)) { if (reuse) return; if (J->strict) jsC_error(J, ident, "duplicate formal parameter '%s'", name); } } } if (F->varlen >= F->varcap) { F->varcap = F->varcap ? F->varcap * 2 : 16; F->vartab = js_realloc(J, F->vartab, F->varcap * sizeof *F->vartab); } F->vartab[F->varlen++] = name; }
static int addfunction(JF, js_Function *value) { if (F->funlen >= F->funcap) { F->funcap = F->funcap ? F->funcap * 2 : 16; F->funtab = js_realloc(J, F->funtab, F->funcap * sizeof *F->funtab); } F->funtab[F->funlen] = value; return F->funlen++; }
static void textpush(js_State *J, Rune c) { int n = runelen(c); if (J->lexbuf.len + n > J->lexbuf.cap) { J->lexbuf.cap = J->lexbuf.cap * 2; J->lexbuf.text = js_realloc(J, J->lexbuf.text, J->lexbuf.cap); } J->lexbuf.len += runetochar(J->lexbuf.text + J->lexbuf.len, &c); }
static void emitraw(JF, int value) { if (value != (js_Instruction)value) js_syntaxerror(J, "integer overflow in instruction coding"); if (F->codelen >= F->codecap) { F->codecap = F->codecap ? F->codecap * 2 : 64; F->code = js_realloc(J, F->code, F->codecap * sizeof *F->code); } F->code[F->codelen++] = value; }
static void Ap_join(js_State *J) { char * volatile out = NULL; const char *sep; const char *r; int seplen; int k, n, len; len = js_getlength(J, 0); if (js_isdefined(J, 1)) { sep = js_tostring(J, 1); seplen = strlen(sep); } else { sep = ","; seplen = 1; } if (len == 0) { js_pushliteral(J, ""); return; } if (js_try(J)) { js_free(J, out); js_throw(J); } n = 1; for (k = 0; k < len; ++k) { js_getindex(J, 0, k); if (js_isundefined(J, -1) || js_isnull(J, -1)) r = ""; else r = js_tostring(J, -1); n += strlen(r); if (k == 0) { out = js_malloc(J, n); strcpy(out, r); } else { n += seplen; out = js_realloc(J, out, n); strcat(out, sep); strcat(out, r); } js_pop(J, 1); } js_pushstring(J, out); js_endtry(J); js_free(J, out); }
static int addnumber(JF, double value) { int i; for (i = 0; i < F->numlen; ++i) if (F->numtab[i] == value) return i; if (F->numlen >= F->numcap) { F->numcap = F->numcap ? F->numcap * 2 : 16; F->numtab = js_realloc(J, F->numtab, F->numcap * sizeof *F->numtab); } F->numtab[F->numlen] = value; return F->numlen++; }
static int addstring(JF, const char *value) { int i; for (i = 0; i < F->strlen; ++i) if (!strcmp(F->strtab[i], value)) return i; if (F->strlen >= F->strcap) { F->strcap = F->strcap ? F->strcap * 2 : 16; F->strtab = js_realloc(J, F->strtab, F->strcap * sizeof *F->strtab); } F->strtab[F->strlen] = value; return F->strlen++; }
static void addlocal(JF, const char *name, int reuse) { if (reuse) { unsigned int i; for (i = 0; i < F->varlen; ++i) if (!strcmp(F->vartab[i], name)) return; } if (F->varlen >= F->varcap) { F->varcap = F->varcap ? F->varcap * 2 : 16; F->vartab = js_realloc(J, F->vartab, F->varcap * sizeof *F->vartab); } F->vartab[F->varlen++] = name; }
char* read_until_eof(FILE* f, uint32_t* len) { size_t cap = 4096; size_t idx = 0; char* buff = js_alloc(cap); while(!feof(stdin)) { idx += fread(buff + idx, 1, 4096, f); if(idx >= cap) { cap *= 2; buff = js_realloc(buff, cap); } } *len = idx; return buff; }
bool XDRBuffer::grow(size_t n) { JS_ASSERT(n > size_t(limit - cursor)); const size_t MEM_BLOCK = 8192; size_t offset = cursor - base; size_t newCapacity = JS_ROUNDUP(offset + n, MEM_BLOCK); if (isUint32Overflow(newCapacity)) { JS_ReportErrorNumber(cx(), js_GetErrorMessage, NULL, JSMSG_TOO_BIG_TO_ENCODE); return false; } void *data = js_realloc(base, newCapacity); if (!data) { js_ReportOutOfMemory(cx()); return false; } base = static_cast<uint8_t *>(data); cursor = base + offset; limit = base + newCapacity; return true; }
int js_vm_execute(JSVirtualMachine * vm, JSByteCode * bc) { int i, sect; unsigned int ui; unsigned char *cp; unsigned int consts_offset; char buf[256]; JSSymtabEntry *symtab = NULL; unsigned int num_symtab_entries = 0; unsigned int code_len = 0; JSNode *saved_sp; JSErrorHandlerFrame *handler, *saved_handler; int result = 1; #ifdef JS_RUNTIME_DEBUG unsigned char *debug_info; unsigned int debug_info_len; #endif unsigned int anonymous_function_offset; /* We need a toplevel over the whole function. */ saved_sp = vm->sp; saved_handler = vm->error_handler; handler = js_calloc(NULL, 1, sizeof(*handler)); if (handler == NULL) { #ifdef JS_RUNTIME_WARNING sprintf(vm->error, "VM: out of memory"); #endif return 0; } handler->next = vm->error_handler; vm->error_handler = handler; if (setjmp(vm->error_handler->error_jmp)) { /* Ok, we had an error down there somewhere. */ if(vm->error_handler->thrown.type == JS_INTEGER) { result = vm->error_handler->thrown.u.vinteger; } else { result = 0; } } else { /* The main stuffs for the execute. */ /* Process constants. */ consts_offset = vm->num_consts; anonymous_function_offset = vm->anonymous_function_next_id; for (sect = 0; sect < bc->num_sects; sect++) if (bc->sects[sect].type == JS_BCST_CONSTANTS) { cp = bc->sects[sect].data; for (ui = 0; ui < bc->sects[sect].length;) { JSNode *c; /* Check that we still have space for this constant. */ if (vm->num_consts >= vm->consts_alloc) { // CHANGE alloc times to 16 vm->consts = js_realloc(vm, vm->consts, (vm->consts_alloc + 16) * sizeof(JSNode)); vm->consts_alloc += 16; } c = &vm->consts[vm->num_consts++]; /* Process this constant. */ c->type = (JSNodeType) cp[ui++]; switch (c->type) { case JS_NULL: break; case JS_BOOLEAN: c->u.vboolean = cp[ui++]; break; case JS_STRING: c->u.vstring = js_vm_alloc(vm, sizeof(*c->u.vstring)); c->u.vstring->staticp = 1; c->u.vstring->prototype = NULL; JS_BC_READ_INT32(cp + ui, c->u.vstring->len); ui += 4; c->u.vstring->data = js_malloc(vm, c->u.vstring->len + 1); memcpy(c->u.vstring->data, cp + ui, c->u.vstring->len); c->u.vstring->data[c->u.vstring->len] = '\0'; ui += c->u.vstring->len; break; case JS_INTEGER: JS_BC_READ_INT32(cp + ui, c->u.vinteger); ui += 4; break; case JS_FLOAT: memcpy(&c->u.vfloat, cp + ui, sizeof(JSFloat)); ui += sizeof(JSFloat); break; case JS_SYMBOL: for (i = 0; cp[ui]; ui++, i++) buf[i] = cp[ui]; buf[i] = '\0'; /* Eat the trailing '\0' from the data. */ ui++; if (buf[0] == '.' && buf[1] == 'F' && buf[2] == ':') //sprintf(buf + 3, "%u", vm->anonymous_function_next_id++); vm->anonymous_function_next_id++; /* Intern symbol. */ c->u.vsymbol = js_vm_intern(vm, buf); break; #if 0 case JS_BUILTIN: /* Regular expression. */ { unsigned char flags; unsigned int length; flags = cp[ui++]; JS_BC_READ_INT32 (cp + ui, length); ui += 4; js_builtin_RegExp_new (vm, cp + ui, length, flags, 1, NULL, c); ui += length; } break; #endif case JS_NAN: /* Nothing here. */ break; default: case JS_IPTR: #ifdef JS_RUNTIME_WARNING sprintf(buf, "js_vm_execute(): unknown constant type %d%s", c->type, JS_HOST_LINE_BREAK); #ifdef JS_IOSTREAM js_iostream_write(vm->s_stderr, buf, strlen(buf)); js_iostream_flush(vm->s_stderr); #else fwrite(buf, strlen(buf), 1, stderr); #endif #endif abort(); break; } } /* All done with the constants. */ break; } /* Check how long the code section is. */ for (sect = 0; sect < bc->num_sects; sect++) if (bc->sects[sect].type == JS_BCST_CODE) { code_len = bc->sects[sect].length; break; } /* Process symbol table. */ for (sect = 0; sect < bc->num_sects; sect++) if (bc->sects[sect].type == JS_BCST_SYMTAB) { JSSymtabEntry *se; char buf[257]; cp = bc->sects[sect].data; /* The number of symbols. */ JS_BC_READ_INT32(cp, num_symtab_entries); symtab = js_calloc(vm, num_symtab_entries + 1, sizeof(*symtab)); /* Make the terminator by hand. */ symtab[num_symtab_entries].offset = code_len; /* Enter symbols. */ se = symtab; for (ui = 4; ui < bc->sects[sect].length; se++) { for (i = 0; cp[ui]; ui++, i++) buf[i] = cp[ui]; buf[i] = '\0'; se->name = js_strdup(vm, buf); ui++; JS_BC_READ_INT32(cp + ui, se->offset); ui += 4; } break; } /* Check if we have debugging information. */ #ifdef JS_RUNTIME_DEBUG debug_info = NULL; debug_info_len = 0; for (sect = 0; sect < bc->num_sects; sect++) if (bc->sects[sect].type == JS_BCST_DEBUG) { debug_info = bc->sects[sect].data; debug_info_len = bc->sects[sect].length; } #endif /* Clear error message and old exec result. */ #ifdef JS_RUNTIME_WARNING vm->error[0] = '\0'; #endif vm->exec_result.type = JS_UNDEFINED; JS_PROFILING_ON(); /* Execute. */ result = (*vm->dispatch_execute) (vm, bc, symtab, num_symtab_entries, consts_offset, anonymous_function_offset, #ifdef JS_RUNTIME_DEBUG debug_info, debug_info_len, #endif NULL, NULL, 0, NULL); } JS_PROFILING_OFF(); if (symtab) { for (ui = 0; ui < num_symtab_entries; ui++) js_free(symtab[ui].name); js_free(symtab); } /* Pop all error handler frames from the handler chain. */ for (; vm->error_handler != saved_handler; vm->error_handler = handler) { handler = vm->error_handler->next; js_free(vm->error_handler); } /* Restore virtual machine's idea about the stack top. */ vm->sp = saved_sp; return result; }