Beispiel #1
0
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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
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++;
}
Beispiel #4
0
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);
}
Beispiel #5
0
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;
}
Beispiel #6
0
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);
}
Beispiel #7
0
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++;
}
Beispiel #8
0
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++;
}
Beispiel #9
0
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;
}
Beispiel #10
0
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;
}
Beispiel #11
0
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;
}
Beispiel #12
0
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;
}