Example #1
0
void
js_builtin_core (JSVirtualMachine *vm)
{
  int i;
  JSNode *n;

  /* Properties. */

  n = &vm->globals[js_vm_intern (vm, "NaN")];
  n->type = JS_NAN;

  n = &vm->globals[js_vm_intern (vm, "Infinity")];
  JS_MAKE_POSITIVE_INFINITY (n);

  /* Global methods. */
  for (i = 0; global_methods[i].name; i++)
    {
      JSBuiltinInfo *info;

      info = js_vm_builtin_info_create (vm);
      info->global_method_proc = global_methods[i].method;

      n = &vm->globals[js_vm_intern (vm, global_methods[i].name)];
      js_vm_builtin_create (vm, n, info, NULL);
    }
}
Example #2
0
static void
js_core_globals (JSInterpPtr interp)
{
  JSNode *n;
  JSBuiltinInfo *info;
  JSVirtualMachine *vm = interp->vm;

  /* Command `error'. */

  info = js_vm_builtin_info_create (vm);
  info->global_method_proc = error_global_method;

  n = &interp->vm->globals[js_vm_intern (interp->vm, "error")];
  js_vm_builtin_create (interp->vm, n, info, interp);

  if (!interp->options.no_compiler)
    {
      /* Command `eval'. */

      info = js_vm_builtin_info_create (vm);
      info->global_method_proc = eval_global_method;

      n = &interp->vm->globals[js_vm_intern (interp->vm, "eval")];

      js_vm_builtin_create (interp->vm, n, info, interp);
    }

  /* Command `load'. */

  info = js_vm_builtin_info_create (vm);
  info->global_method_proc = load_global_method;

  n = &interp->vm->globals[js_vm_intern (interp->vm, "load")];
  js_vm_builtin_create (interp->vm, n, info, interp);
}
Example #3
0
void
js_builtin_Number (JSVirtualMachine *vm)
{
    NumberCtx *ctx;
    JSNode *n;
    JSBuiltinInfo *info;

    ctx = js_calloc (vm, 1, sizeof (*ctx));

    ctx->s_MAX_VALUE		= js_vm_intern (vm, "MAX_VALUE");
    ctx->s_MIN_VALUE		= js_vm_intern (vm, "MIN_VALUE");
    ctx->s_NaN			= js_vm_intern (vm, "NaN");
    ctx->s_NEGATIVE_INFINITY	= js_vm_intern (vm, "NEGATIVE_INFINITY");
    ctx->s_POSITIVE_INFINITY	= js_vm_intern (vm, "POSITIVE_INFINITY");

    info = js_vm_builtin_info_create (vm);
    vm->prim[JS_INTEGER]	= info;
    vm->prim[JS_FLOAT]	= info;
    vm->prim[JS_NAN]	= info;

    info->method_proc 		= method;
    info->property_proc		= property;
    info->obj_context		= ctx;
    info->obj_context_delete	= js_free;

    /* Define it. */
    n = &vm->globals[js_vm_intern (vm, "Number")];
    js_vm_builtin_create (vm, n, info, NULL);
}
Example #4
0
int
js_create_global_method (JSInterpPtr interp, char *name,
			 JSGlobalMethodProc proc, void *context,
			 JSFreeProc context_free_proc)
{
  JSNode *n = &interp->vm->globals[js_vm_intern (interp->vm, name)];
  JSVirtualMachine *vm = interp->vm;
  int result = 1;

  /* Need one toplevel here. */
  {
    JSErrorHandlerFrame handler;

    /* We must create the toplevel ourself. */
    memset (&handler, 0, sizeof (handler));
    handler.next = vm->error_handler;
    vm->error_handler = &handler;

    if (setjmp (vm->error_handler->error_jmp))
      /* An error occurred. */
      result = 0;
    else
      {
	JSBuiltinInfo *info;
	JSGlobalMethodContext *ctx;

	/* Context. */
	ctx = js_calloc (vm, 1, sizeof (*ctx));

	ctx->proc = proc;
	ctx->context = context;
	ctx->free_proc = context_free_proc;
	ctx->interp = interp;

	/* Info. */
	info = js_vm_builtin_info_create (vm);
	info->global_method_proc = js_global_method_stub;

	/* Create the builtin. */
	js_vm_builtin_create (interp->vm, n, info, ctx);
      }

    /* Pop the error handler. */
    vm->error_handler = vm->error_handler->next;
  }

  return result;
}
Example #5
0
void
js_builtin_Function (JSVirtualMachine *vm)
{
  JSNode *n;
  JSBuiltinInfo *info;

  info = js_vm_builtin_info_create (vm);
  vm->prim[JS_FUNC] = info;

  info->method_proc	= method;
  info->property_proc	= property;

  /* Define it. */
  n = &vm->globals[js_vm_intern (vm, "Function")];
  js_vm_builtin_create (vm, n, info, NULL);
}
Example #6
0
void init_builtin_digitalio(JSVirtualMachine *vm) {
	JSBuiltinInfo *info;
	JSNode *n;
	unsigned char i;

	struct {
		char *name;
		JSBuiltinGlobalMethod method;
	} global_methods[] = {
		{"pinMode", pinMode_global_method},
		{"digitalWrite", digitalWrite_global_method},
		{"digitalRead", digitalRead_global_method},
		{NULL, NULL}
	};

	for (i = 0; global_methods[i].name; i++) {
		info = js_vm_builtin_info_create(vm);
		info->global_method_proc = global_methods[i].method;

		n = &vm->globals[js_vm_intern(vm, global_methods[i].name)];
		js_vm_builtin_create(vm, n, info, NULL);
	}
}
Example #7
0
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;
}
Example #8
0
void
js_ext_curses (JSInterpPtr interp)
{
  CursesCtx *ctx;
  JSBuiltinInfo *info;
  JSNode *n;
  JSVirtualMachine *vm = interp->vm;

  /* Class context. */
  ctx = js_calloc (vm, 1, sizeof (*ctx));

  ctx->s_addstr 		= js_vm_intern (vm, "addstr");
  ctx->s_attron 		= js_vm_intern (vm, "attron");
  ctx->s_attroff 		= js_vm_intern (vm, "attroff");
  ctx->s_beep	 		= js_vm_intern (vm, "beep");
  ctx->s_cbreak 		= js_vm_intern (vm, "cbreak");
  ctx->s_clear	 		= js_vm_intern (vm, "clear");
  ctx->s_clrtobot 		= js_vm_intern (vm, "clrtobot");
  ctx->s_clrtoeol 		= js_vm_intern (vm, "clrtoeol");
  ctx->s_echo	 		= js_vm_intern (vm, "echo");
  ctx->s_endwin 		= js_vm_intern (vm, "endwin");
  ctx->s_getch	 		= js_vm_intern (vm, "getch");
  ctx->s_initscr 		= js_vm_intern (vm, "initscr");
  ctx->s_keypad 		= js_vm_intern (vm, "keypad");
  ctx->s_move	 		= js_vm_intern (vm, "move");
  ctx->s_mvaddstr 		= js_vm_intern (vm, "mvaddstr");
  ctx->s_mvaddsubstr 		= js_vm_intern (vm, "mvaddsubstr");
  ctx->s_mvgetch	 	= js_vm_intern (vm, "mvgetch");
  ctx->s_nocbreak 		= js_vm_intern (vm, "nocbreak");
  ctx->s_noecho 		= js_vm_intern (vm, "noecho");
  ctx->s_refresh 		= js_vm_intern (vm, "refresh");
  ctx->s_standend		= js_vm_intern (vm, "standend");
  ctx->s_standout		= js_vm_intern (vm, "standout");

  ctx->s_LINES	 		= js_vm_intern (vm, "LINES");
  ctx->s_COLS	 		= js_vm_intern (vm, "COLS");

  /* Object information. */
  info = js_vm_builtin_info_create (vm);

  info->method_proc		= method;
  info->property_proc		= property;
  info->obj_context		= ctx;
  info->obj_context_delete	= js_free;

  /* Define it. */
  n = &vm->globals[js_vm_intern (vm, "Curses")];
  js_vm_builtin_create (vm, n, info, NULL);
}
Example #9
0
void
js_get_var (JSInterpPtr interp, char *name, JSType *value)
{
  JSNode *n = &interp->vm->globals[js_vm_intern (interp->vm, name)];
  JS_COPY ((JSNode *) value, n);
}
Example #10
0
int
js_vm_call_method(JSVirtualMachine * vm, JSNode * object,
				  const char *method_name, unsigned int argc, JSNode * argv)
{
	int result = 1;
	JSNode *saved_sp;
	JSErrorHandlerFrame *handler, *saved_handler;
	JSSymbol symbol;

	/* Initialize error handler. */

	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)) {
		/* An error occurred. */
		if(vm->error_handler->thrown.type == JS_INTEGER) {
			result = vm->error_handler->thrown.u.vinteger;
		} else {
			result = 0;
		}
	} else {
		/* Intern the method name. */
		symbol = js_vm_intern(vm, method_name);

		/* Clear error message and old exec result. */
#ifdef JS_RUNTIME_WARNING
		vm->error[0] = '\0';
#endif
		vm->exec_result.type = JS_UNDEFINED;

		/* What kind of object was called? */

		if (object->type == JS_BUILTIN) {
			if (object->u.vbuiltin->info->method_proc) {
				if ((*object->u.vbuiltin->info->method_proc) (vm,
															  object->u.
															  vbuiltin->
															  info,
															  object->u.
															  vbuiltin->
															  instance_context,
															  symbol, &vm->exec_result, argv)
					== JS_PROPERTY_UNKNOWN) {
#ifdef JS_RUNTIME_WARNING
					sprintf(vm->error, "call_method: unknown method");
#endif
					result = 0;
				}
			} else {
#ifdef JS_RUNTIME_WARNING
				sprintf(vm->error, "illegal builtin object for call_method");
#endif
				result = 0;
			}
		} else if (object->type == JS_OBJECT) {
			JSNode method;

			/* Fetch the method's implementation. */
			if (js_vm_object_load_property(vm, object->u.vobject, symbol, &method)
				== JS_PROPERTY_FOUND) {
				/* The property has been defined in the object. */
				if (method.type != JS_FUNC) {
#ifdef JS_RUNTIME_WARNING
					sprintf(vm->error, "call_method: unknown method");
#endif
					result = 0;
				} else {
					JS_PROFILING_ON();
					result =
						(*vm->dispatch_execute) (vm, NULL, NULL, 0, 0, 0,
#ifdef JS_RUNTIME_DEBUG
												 NULL, 0,
#endif
												 object, &method, argc, argv);
				}
			} else
				/* Let the built-in Object handle this. */
				goto to_builtin_please;
		} else if (vm->prim[object->type]) {
			/* The primitive language types. */
		  to_builtin_please:
			if ((*vm->prim[object->type]->method_proc) (vm,
														vm->prim[object->
																 type],
														object, symbol, &vm->exec_result, argv)
				== JS_PROPERTY_UNKNOWN) {
#ifdef JS_RUNTIME_WARNING
				sprintf(vm->error, "call_method: unknown method");
#endif
				result = 0;
			}
		} else {
#ifdef JS_RUNTIME_WARNING
			sprintf(vm->error, "illegal object for call_method");
#endif
			result = 0;
		}
	}

	JS_PROFILING_OFF();

	/* 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;
}
Example #11
0
JSVirtualMachine *js_vm_create(
	unsigned int stack_size
#ifdef JS_RUNTIME_WARNING
	, unsigned int verbose
#endif
#ifdef JS_RUNTIME_DEBUG
	, int stacktrace_on_error
#endif
#ifdef JS_IOSTREAM
	, JSIOStream * s_stdin, JSIOStream * s_stdout, JSIOStream * s_stderr
#endif
) {
	JSVirtualMachine *vm;
	vm = js_calloc(NULL, 1, sizeof(*vm));
	if (vm == NULL)
		return NULL;
#ifdef JS_RUNTIME_WARNING
	vm->verbose = verbose;
	vm->warn_undef = 1;
#endif
#ifdef JS_RUNTIME_DEBUG
	vm->stacktrace_on_error = stacktrace_on_error;
#endif

	/* Set the system streams. */
#ifdef JS_IOSTREAM
	vm->s_stdin = s_stdin;
	vm->s_stdout = s_stdout;
	vm->s_stderr = s_stderr;
#endif

	/* Resolve the dispatch method. */
	vm->dispatch_execute = js_vm_switch0_exec;
#ifdef JS_RUNTIME_DEBUG
	vm->dispatch_func_name = js_vm_switch0_func_name;
	vm->dispatch_debug_position = js_vm_switch0_debug_position;
#endif

	vm->stack_size = stack_size;
	vm->stack = js_malloc(NULL, vm->stack_size * sizeof(*vm->stack));
	if (vm->stack == NULL) {
		js_free(vm);
		return NULL;
	}

	/* Set the initial stack pointer. */
	vm->sp = vm->stack + vm->stack_size - 1;

	vm->gc.trigger = GC_TRIGGER;

	/* We need a toplevel here. */
	{
		JSErrorHandlerFrame handler;
		int result = 1;

		memset(&handler, 0, sizeof(handler));
		handler.next = vm->error_handler;
		vm->error_handler = &handler;

		if (setjmp(vm->error_handler->error_jmp))
			/* An error occurred. */
			result = 0;
		else {
			/* Intern some commonly used symbols. */
			vm->syms.s___proto__ = js_vm_intern(vm, "__proto__");
			vm->syms.s_prototype = js_vm_intern(vm, "prototype");
			vm->syms.s_toSource = js_vm_intern(vm, "toSource");
			vm->syms.s_toString = js_vm_intern(vm, "toString");
			vm->syms.s_valueOf = js_vm_intern(vm, "valueOf");

			/* Intern system built-in objects. */
			intern_builtins(vm);
		}

		/* Pop the error handler. */
		vm->error_handler = vm->error_handler->next;

		if (result == 0) {
			/* Argh, the initialization failed. */
			js_vm_destroy(vm);
			return NULL;
		}
	}

	return vm;
}
Example #12
0
int
js_vm_apply(JSVirtualMachine * vm, char *func_name, JSNode * func, unsigned int argc, JSNode * argv)
{
	int result = 1;
	JSNode *saved_sp;
	JSErrorHandlerFrame *handler, *saved_handler;

	/* Initialize error handler. */

	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)) {
		/* An error occurred. */
		if(vm->error_handler->thrown.type == JS_INTEGER) {
			result = vm->error_handler->thrown.u.vinteger;
		} else {
			result = 0;
		}
	} else {
		/* Clear error message and old exec result. */
#ifdef JS_RUNTIME_WARNING
		vm->error[0] = '\0';
#endif
		vm->exec_result.type = JS_UNDEFINED;

		if (func_name)
			/* Lookup the function. */
			func = &vm->globals[js_vm_intern(vm, func_name)];

		/* Check what kind of function should be called. */
		if (func->type == JS_FUNC) {
			JS_PROFILING_ON();

			/* Call function. */
			result = (*vm->dispatch_execute) (vm, NULL, NULL, 0, 0, 0,
#ifdef JS_RUNTIME_DEBUG
											  NULL, 0,
#endif
											  NULL, func, argc, argv);
		} else if (func->type == JS_BUILTIN && func->u.vbuiltin->info->global_method_proc != NULL) {
			(*func->u.vbuiltin->info->global_method_proc) (vm,
														   func->u.
														   vbuiltin->info,
														   func->u.
														   vbuiltin->
														   instance_context,
														   &vm->exec_result, argv);
		} else {
#ifdef JS_RUNTIME_WARNING
			if (func_name)
				sprintf(vm->error, "undefined function `%s' in apply", func_name);
			else
				sprintf(vm->error, "undefiend function in apply");
#endif

			result = 0;
		}
	}

	JS_PROFILING_OFF();

	/* 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;
}
Example #13
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;
}
Example #14
0
int
js_vm_switch_exec (JSVirtualMachine *vm, JSByteCode *bc, JSSymtabEntry *symtab,
		   unsigned int num_symtab_entries,
		   unsigned int consts_offset,
		   unsigned char *debug_info, unsigned int debug_info_len,
		   char *func_name, JSNode *func,
		   unsigned int argc, JSNode *argv)
{
  int i;
  unsigned int ui;
  Function *global_f = NULL;
  Function *f;
  unsigned char *code = NULL;

  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++)
	{
	  /* Link the code to our environment. */
	  f = link_code (vm, code + symtab[i].offset,
			 symtab[i + 1].offset - symtab[i].offset,
			 consts_offset);
	  f->name = js_strdup (vm, symtab[i].name);

	  if (strcmp (symtab[i].name, JS_GLOBAL_NAME) == 0)
	    global_f = f;
	  else
	    {
	      if (vm->verbose > 3)
		printf ("VM: link: %s(): start=%d, length=%d\n",
			symtab[i].name, symtab[i].offset,
			symtab[i + 1].offset - symtab[i].offset);
	      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
    {
      JSNode *n;

      /* Applying arguments to function. */

      if (func_name)
	{
	  /* Lookup function. */
	  JSSymbol sym;

	  sym = js_vm_intern (vm, func_name);
	  n = &vm->globals[sym];
	  if (n->type != JS_FUNC)
	    {
	      sprintf (vm->error, "undefined function `%s' in apply",
		       func_name);
	      return 0;
	    }

	  if (vm->verbose > 1)
	    printf ("VM: calling %s()\n", func_name);
	}
      else
	{
	  /* Use the function the caller gave us. */
	  n = func;
	  if (n->type != JS_FUNC)
	    {
	      sprintf (vm->error, "illegal function in apply");
	      return 0;
	    }

	  if (vm->verbose > 1)
	    printf ("VM: calling function\n");
	}
      f = n->u.vfunction->implementation;

      execute_code (vm, f, argc, argv);
    }

  if (global_f)
    {
      if (vm->verbose > 1)
	printf ("VM: exec: %s\n", global_f->name);

      /* Execute. */
      execute_code (vm, global_f, 0, NULL);
    }

  return 1;
}
Example #15
0
void
js_builtin_Array (JSVirtualMachine *vm)
{
  ArrayCtx *ctx;
  JSNode *n;
  JSBuiltinInfo *info;

  ctx = js_calloc (vm, 1, sizeof (*ctx));

  ctx->s_concat		= js_vm_intern (vm, "concat");
  ctx->s_join		= js_vm_intern (vm, "join");
  ctx->s_pop		= js_vm_intern (vm, "pop");
  ctx->s_push		= js_vm_intern (vm, "push");
  ctx->s_reverse	= js_vm_intern (vm, "reverse");
  ctx->s_shift		= js_vm_intern (vm, "shift");
  ctx->s_slice		= js_vm_intern (vm, "slice");
  ctx->s_splice		= js_vm_intern (vm, "splice");
  ctx->s_sort		= js_vm_intern (vm, "sort");
  ctx->s_unshift	= js_vm_intern (vm, "unshift");

  ctx->s_length		= js_vm_intern (vm, "length");

  info = js_vm_builtin_info_create (vm);
  vm->prim[JS_ARRAY] = info;

  info->method_proc		= method;
  info->property_proc		= property;
  info->new_proc		= new_proc;
  info->obj_context		= ctx;
  info->obj_context_delete	= js_free;

  /* Define it. */
  n = &vm->globals[js_vm_intern (vm, "Array")];
  js_vm_builtin_create (vm, n, info, NULL);
}