Ejemplo n.º 1
0
void *
js_vm_realloc (JSVirtualMachine *vm, void *ptr, unsigned int new_size)
{
  JSHeapMemoryBlock *b;
  void *nptr;

  if (ptr == NULL)
    return js_vm_alloc (vm, new_size);

  /* Can be use the old block? */

  b = (JSHeapMemoryBlock *) ((unsigned char *) ptr
			     - sizeof (JSHeapMemoryBlock));

  if (b->size >= new_size)
    /* Yes we can. */
    return ptr;

  /* No we can't.  Must allocate a new one. */
  nptr = js_vm_alloc (vm, new_size);
  memcpy (nptr, ptr, b->size < new_size ? b->size : new_size);

  js_vm_free (vm, ptr);

  return nptr;
}
Ejemplo n.º 2
0
static void
hash_insert (JSVirtualMachine *vm, JSObject *obj, const char *name,
	     unsigned int name_len, int pos)
{
  unsigned int hash;
  JSObjectPropHashBucket *b;

  hash = js_count_hash (name, name_len) % HASH_SIZE;
  for (b = obj->hash[hash]; b; b = b->next)
    if (b->len == name_len
	&& memcmp (b->data, name, name_len) == 0)
      {
	/* Ok, we already have a bucket */
	b->value = pos;
	return;
      }

  /* Create a new bucket. */
  b = js_vm_alloc (vm, sizeof (*b));
  b->len = name_len;
  b->data = js_vm_alloc (vm, b->len);
  memcpy (b->data, name, b->len);

  b->value = pos;

  b->next = obj->hash[hash];
  obj->hash[hash] = b;

  obj->hash_lengths[hash]++;
}
Ejemplo n.º 3
0
JSObject *
js_vm_object_new (JSVirtualMachine *vm)
{
  JSObject *obj;

  obj = js_vm_alloc (vm, sizeof (*obj));
  obj->hash = NULL;
  obj->num_props = 0;
  obj->props = NULL;

  return obj;
}
Ejemplo n.º 4
0
static void
hash_create (JSVirtualMachine *vm, JSObject *obj)
{
  int i;

  obj->hash = js_vm_alloc (vm, HASH_SIZE * sizeof (JSObjectPropHashBucket *));
  memset (obj->hash, 0, HASH_SIZE * sizeof (JSObjectPropHashBucket *));

  obj->hash_lengths = js_vm_alloc (vm, HASH_SIZE * sizeof (unsigned int));
  memset (obj->hash_lengths, 0, HASH_SIZE * sizeof (unsigned int));

  /* Insert all known properties to the hash. */
  for (i = 0; i < obj->num_props; i++)
    if (obj->props[i].name != JS_SYMBOL_NULL)
      {
	const char *name;

	name = js_vm_symname (vm, obj->props[i].name);
	hash_insert (vm, obj, name, strlen (name), i);
      }
}
Ejemplo n.º 5
0
void *
js_vm_alloc_destroyable (JSVirtualMachine *vm, unsigned int size)
{
  unsigned char *bi;
  JSHeapMemoryBlock *b;

  bi = js_vm_alloc (vm, size);
  memset (bi, 0, size);

  b = (JSHeapMemoryBlock *) (bi - sizeof (JSHeapMemoryBlock));
  b->flag_destroyable = 1;

  return bi;
}
Ejemplo n.º 6
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;
}