Esempio n. 1
0
spidermonkey_vm *sm_initialize(long thread_stack, long heap_size) {
  spidermonkey_vm *vm = ejs_alloc(sizeof(spidermonkey_vm));
  spidermonkey_state *state = ejs_alloc(sizeof(spidermonkey_state));
  state->branch_count = 0;
  state->error = NULL;
  state->terminate = 0;
  int gc_size = (int) heap_size * 0.25;
  vm->runtime = JS_NewRuntime(MAX_GC_SIZE);
  JS_SetGCParameter(vm->runtime, JSGC_MAX_BYTES, heap_size);
  JS_SetGCParameter(vm->runtime, JSGC_MAX_MALLOC_BYTES, gc_size);
  vm->context = JS_NewContext(vm->runtime, 8192);
  JS_SetScriptStackQuota(vm->context, thread_stack);

  begin_request(vm);
  JS_SetOptions(vm->context, JSOPTION_VAROBJFIX);
  JS_SetOptions(vm->context, JSOPTION_STRICT);
  JS_SetOptions(vm->context, JSOPTION_COMPILE_N_GO);
  JS_SetOptions(vm->context, JSVERSION_LATEST);
  vm->global = JS_NewCompartmentAndGlobalObject(vm->context, &global_class, NULL);
  JS_InitStandardClasses(vm->context, vm->global);
  JS_SetErrorReporter(vm->context, on_error);
  JS_SetOperationCallback(vm->context, on_branch);
  JS_SetContextPrivate(vm->context, state);
  JSNative funptr = (JSNative) &js_log;
  JS_DefineFunction(vm->context, JS_GetGlobalObject(vm->context), "ejsLog", funptr,
                    0, 0);
  end_request(vm);

  return vm;
}
Esempio n. 2
0
/* Execute a string in its own context (away from Synchronet objects) */
static JSBool
js_eval(JSContext *parent_cx, uintN argc, jsval *arglist)
{
	jsval *argv=JS_ARGV(parent_cx, arglist);
	char*			buf;
	size_t			buflen;
	JSString*		str;
    JSObject*		script;
	JSContext*		cx;
	JSObject*		obj;
	JSErrorReporter	reporter;

	JS_SET_RVAL(cx, arglist, JSVAL_VOID);

	if(argc<1)
		return(JS_TRUE);

	if((str=JS_ValueToString(parent_cx, argv[0]))==NULL)
		return(JS_FALSE);
	JSSTRING_TO_MSTRING(parent_cx, str, buf, &buflen);
	HANDLE_PENDING(parent_cx);
	if(buf==NULL)
		return(JS_TRUE);

	if((cx=JS_NewContext(JS_GetRuntime(parent_cx),JAVASCRIPT_CONTEXT_STACK))==NULL) {
		free(buf);
		return(JS_FALSE);
	}

	/* Use the error reporter from the parent context */
	reporter=JS_SetErrorReporter(parent_cx,NULL);
	JS_SetErrorReporter(parent_cx,reporter);
	JS_SetErrorReporter(cx,reporter);

	/* Use the operation callback from the parent context */
	JS_SetContextPrivate(cx, JS_GetContextPrivate(parent_cx));
	JS_SetOperationCallback(cx, JS_GetOperationCallback(parent_cx));

	if((obj=JS_NewCompartmentAndGlobalObject(cx, &eval_class, NULL))==NULL
		|| !JS_InitStandardClasses(cx,obj)) {
		JS_DestroyContext(cx);
		free(buf);
		return(JS_FALSE);
	}

	if((script=JS_CompileScript(cx, obj, buf, buflen, NULL, 0))!=NULL) {
		jsval	rval;

		JS_ExecuteScript(cx, obj, script, &rval);
		JS_SET_RVAL(cx, arglist, rval);
	}
	free(buf);

	JS_DestroyContext(cx);

    return(JS_TRUE);
}
Esempio n. 3
0
/** Our "Operation Callback" multiplexes this Spidermonkey facility. It is called automatically by Spidermonkey, and is
 *  triggered on a regular interval by gpsee_asyncCallbackTriggerThreadFunc() */
JSBool gpsee_operationCallback(JSContext *cx)
{
  gpsee_runtime_t *grt = (gpsee_runtime_t *) JS_GetRuntimePrivate(JS_GetRuntime(cx));
  GPSEEAsyncCallback *cb;

  /* The callbacks registered with GPSEE may want to invoke JSAPI functionality, which might toss us back out
   * to another invocation of gpsee_operationCallback(). The JSAPI docs for "operation callbacks" [1] suggest
   * removing the operation callback before calling JSAPI functionality from within an operation callback,
   * then resetting it when we're done making JSAPI calls. Since it's rather inexpensive, we'll just do it here
   * and then consumers of gpsee_addAsyncCallback() needn't worry about it (we don't want them touching that
   * callback slot anyway! 
   *
   * [1] https://developer.mozilla.org/en/JS_SetOperationCallback
   *
   * Another side note: we do it before if(cb) because if gpsee_asyncCallbacks is empty, we want to uninstall our
   * operation callback altogether. */
  JS_SetOperationCallback(cx, NULL);

  cb = grt->asyncCallbacks;
  if (cb)
  {
    GPSEEAsyncCallback *next;
    do
    {
      /* Save the 'next' link in case the callback deletes itself */
      next = cb->next;
      /* Invoke callback */
      if (!((*(cb->callback))(cb->cx, cb->userdata, cb)))
        /* Propagate exceptions */
        return JS_FALSE;
    }
    while ((cb = next));

    /* Reinstall our operation callback */
    JS_SetOperationCallback(cx, gpsee_operationCallback);

    return JS_TRUE;
  }

  return JS_TRUE;
}
Esempio n. 4
0
static JSBool
js_OperationCallback(JSContext *cx)
{
	JSBool	ret;
	sbbs_t*		sbbs;

	JS_SetOperationCallback(cx, NULL);
	if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) {
		JS_SetOperationCallback(cx, js_OperationCallback);
		return(JS_FALSE);
	}

	if(sbbs->js_callback.auto_terminate && !sbbs->online) {
		JS_ReportWarning(cx,"Disconnected");
		sbbs->js_callback.counter=0;
		JS_SetOperationCallback(cx, js_OperationCallback);
		return(JS_FALSE);
	}

	ret=js_CommonOperationCallback(cx,&sbbs->js_callback);
	JS_SetOperationCallback(cx, js_OperationCallback);
	return ret;
}
Esempio n. 5
0
JsExecutionContext::JsExecutionContext(JsParser *jsParser)
{
  parser = jsParser;
  /* Create a new runtime environment. */
  rt = JS_NewRuntime(8L * 1024L * 1024L);
  if (!rt) {
    error("JsParser :: error creating runtime");
    return; /* XXX should return int or ptr! */
  }

  /* Create a new context. */
  cx = JS_NewContext(rt, STACK_CHUNK_SIZE);
  /* if global_context does not have a value, end the program here */
  if (cx == NULL) {
    error("JsParser :: error creating context");
    return;
  }

  JS_BeginRequest(cx);
  // Store a reference to ourselves in the context ...
  JS_SetContextPrivate(cx, parser);

  /* Set a more strict error checking */
  JS_SetOptions(cx, JSOPTION_VAROBJFIX); // | JSOPTION_STRICT);

  /* Set the branch callback */
#if defined JSOPTION_NATIVE_BRANCH_CALLBACK
  JS_SetBranchCallback(cx, js_static_branch_callback);
#else
  JS_SetOperationCallback(cx, js_static_branch_callback);
#endif

  /* Set the error reporter */
  JS_SetErrorReporter(cx, js_error_reporter);

  /* Create the global object here */
  //  JS_SetGlobalObject(global_context, global_object);
  //  this is done in init_class / JS_InitStandardClasses.
  obj = JS_NewObject(cx, &global_class, NULL, NULL);
  init_class();
  JS_EndRequest(cx);
  // deassociate this context from the creating thread
  // so that it can be used in other threads
  // https://developer.mozilla.org/en/SpiderMonkey/JSAPI_Reference/JS_NewContext
  JS_ClearContextThread(cx);
  /** register SIGINT signal */
  //   signal(SIGINT, js_sigint_handler);
}
Esempio n. 6
0
long sbbs_t::js_execfile(const char *cmd, const char* startup_dir, JSObject* scope)
{
	char*		p;
	char*		args=NULL;
	char*		fname;
	int			argc=0;
	char		cmdline[MAX_PATH+1];
	char		path[MAX_PATH+1];
	JSObject*	js_scope=scope;
	JSObject*	js_script=NULL;
	jsval		rval;
	int32		result=0;

	if(js_cx==NULL) {
		errormsg(WHERE,ERR_CHK,"JavaScript support",0);
		errormsg(WHERE,ERR_EXEC,cmd,0);
		return -1;
	}

	SAFECOPY(cmdline,cmd);
	p=strchr(cmdline,' ');
	if(p!=NULL) {
		*p=0;
		args=p+1;
	}
	fname=cmdline;

	path[0]=0;
	if(strcspn(fname,"/\\")==strlen(fname)) {
		if(startup_dir!=NULL && *startup_dir)
			SAFEPRINTF3(path,"%s%s%s",startup_dir,fname,js_ext(fname));
		if(path[0]==0 || !fexistcase(path)) {
			SAFEPRINTF3(path,"%s%s%s",cfg.mods_dir,fname,js_ext(fname));
			if(cfg.mods_dir[0]==0 || !fexistcase(path))
				SAFEPRINTF3(path,"%s%s%s",cfg.exec_dir,fname,js_ext(fname));
		}
	} else
		SAFECOPY(path,fname);

	if(!fexistcase(path)) {
		errormsg(WHERE,ERR_OPEN,path,O_RDONLY);
		return -1;
	}

	JS_BEGINREQUEST(js_cx);
	if(js_scope==NULL)
		js_scope=JS_NewObject(js_cx, NULL, NULL, js_glob);

	if(js_scope!=NULL) {

		JSObject* argv=JS_NewArrayObject(js_cx, 0, NULL);

		JS_DefineProperty(js_cx, js_scope, "argv", OBJECT_TO_JSVAL(argv)
			,NULL,NULL,JSPROP_READONLY|JSPROP_ENUMERATE);

		/* TODO: Handle quoted "one arg" syntax here? */
		if(args!=NULL && argv!=NULL) {
			while(*args) {
				p=strchr(args,' ');
				if(p!=NULL)
					*p=0;
				while(*args && *args==' ') args++; /* Skip spaces */
				JSString* arg = JS_NewStringCopyZ(js_cx, args);
				if(arg==NULL)
					break;
				jsval val=STRING_TO_JSVAL(arg);
				if(!JS_SetElement(js_cx, argv, argc, &val))
					break;
				argc++;
				if(p==NULL)	/* last arg */
					break;
				args+=(strlen(args)+1);
			}
		}
		JS_DefineProperty(js_cx, js_scope, "argc", INT_TO_JSVAL(argc)
			,NULL,NULL,JSPROP_READONLY|JSPROP_ENUMERATE);

		JS_ClearPendingException(js_cx);

		js_script=JS_CompileFile(js_cx, js_scope, path);
	}

	if(js_scope==NULL || js_script==NULL) {
		JS_ReportPendingException(js_cx);	/* Added Feb-2-2006, rswindell */
		JS_ENDREQUEST(js_cx);
		errormsg(WHERE,"compiling",path,0);
		return -1;
	}

	if(scope==NULL) {
		js_callback.counter=0;	// Reset loop counter

#if JS_VERSION>180
		JS_SetOperationCallback(js_cx, js_OperationCallback);
#else
		JS_SetBranchCallback(js_cx, js_BranchCallback);
#endif

		js_PrepareToExecute(js_cx, js_glob, path, startup_dir);
	}
	JS_ExecuteScript(js_cx, js_scope, js_script, &rval);

	if(scope==NULL) {
		JS_GetProperty(js_cx, js_scope, "exit_code", &rval);
		if(rval!=JSVAL_VOID)
			JS_ValueToInt32(js_cx,rval,&result);

		js_EvalOnExit(js_cx, js_scope, &js_callback);
	}

	JS_ReportPendingException(js_cx);	/* Added Dec-4-2005, rswindell */

	JS_DestroyScript(js_cx, js_script);

	if(scope==NULL)
		JS_ClearScope(js_cx, js_scope);

	JS_GC(js_cx);

	JS_ENDREQUEST(js_cx);

	return(result);
}
Esempio n. 7
0
static PyObject *spindly_js(PyObject *self, PyObject *args) {
    JSRuntime *runtime;
    JSContext *context;
    JSObject *global;

    char *script;
    Py_ssize_t script_length;
    PyObject *params = NULL;
    int timeout = 10;

    jsval rvalue;

    int error = 0;
    struct watchdog *wd = NULL;

    if (!PyArg_ParseTuple(args, "s#|Oi:js", &script, &script_length, &params, &timeout)) {
        return NULL;
    }
    if (params != NULL && !PyDict_Check(params)) {
        return PyErr_Format(PyExc_TypeError, "params must be a dict");
    }

    runtime = JS_NewRuntime(1024L * 1024L);
    if (!runtime) {
        return PyErr_Format(PyExc_SystemError, "unable to initialize JS runtime\n");
    }

    context = JS_NewContext(runtime, 8192);
    if (!context) {
        JS_DestroyRuntime(runtime);
        return PyErr_Format(PyExc_SystemError, "unable to initialize JS context\n");
    }

    JS_SetContextPrivate(context, &error);
    JS_SetOptions(context, JSOPTION_VAROBJFIX);
    JS_SetVersion(context, JSVERSION_LATEST);
    JS_SetErrorReporter(context, raise_python_exception);
    JS_SetOperationCallback(context, js_destroy);

    global = JS_NewCompartmentAndGlobalObject(context, &global_class, NULL);
    JS_InitStandardClasses(context, global);

    if (params != NULL) {
        populate_javascript_object(context, global, params);
    }

    if (timeout > 0) {
        wd = run_watchdog(context, timeout);
        if (wd == NULL) {
            shutdown(runtime, context);
            return PyErr_Format(PyExc_SystemError, "unable to initialize JS watchdog\n");
        }
    }

    JSBool retval = JS_EvaluateScript(context, global, script, script_length, "spindly", 1, &rvalue);
    if (wd) {
        shutdown_watchdog(wd);
    }

    if (retval == JS_FALSE || error == 1) {
        shutdown(runtime, context);
        return NULL;
    }

    PyObject *obj = to_python_object(context, rvalue);
    shutdown(runtime, context);
    return obj;
}
Esempio n. 8
0
void *
spidermonkey_get_interpreter(struct ecmascript_interpreter *interpreter)
{
	JSContext *ctx;
	JSObject *window_obj, *document_obj, *forms_obj, *history_obj, *location_obj,
	         *statusbar_obj, *menubar_obj, *navigator_obj;

	assert(interpreter);
	if (!js_module_init_ok) return NULL;

	ctx = JS_NewContext(spidermonkey_runtime,
			    8192 /* Stack allocation chunk size */);
	if (!ctx)
		return NULL;
	interpreter->backend_data = ctx;
	JS_SetContextPrivate(ctx, interpreter);
	JS_SetOptions(ctx, JSOPTION_VAROBJFIX | JSOPTION_JIT | JSOPTION_METHODJIT);
	JS_SetVersion(ctx, JSVERSION_LATEST);
	JS_SetErrorReporter(ctx, error_reporter);
#if defined(CONFIG_ECMASCRIPT_SMJS_HEARTBEAT)
	JS_SetOperationCallback(ctx, heartbeat_callback);
#endif

	window_obj = JS_NewCompartmentAndGlobalObject(ctx, (JSClass *) &window_class, NULL);
	if (!window_obj) goto release_and_fail;
	if (!JS_InitStandardClasses(ctx, window_obj)) goto release_and_fail;
	if (!JS_DefineProperties(ctx, window_obj, (JSPropertySpec *) window_props))
		goto release_and_fail;
	if (!spidermonkey_DefineFunctions(ctx, window_obj, window_funcs))
		goto release_and_fail;
	if (!JS_SetPrivate(ctx, window_obj, interpreter->vs)) /* to @window_class */
		goto release_and_fail;

	document_obj = spidermonkey_InitClass(ctx, window_obj, NULL,
					      (JSClass *) &document_class, NULL, 0,
					      (JSPropertySpec *) document_props,
					      document_funcs,
					      NULL, NULL);
	if (!document_obj) goto release_and_fail;

	forms_obj = spidermonkey_InitClass(ctx, document_obj, NULL,
					   (JSClass *) &forms_class, NULL, 0,
					   (JSPropertySpec *) forms_props,
					   forms_funcs,
					   NULL, NULL);
	if (!forms_obj) goto release_and_fail;

	history_obj = spidermonkey_InitClass(ctx, window_obj, NULL,
					     (JSClass *) &history_class, NULL, 0,
					     (JSPropertySpec *) NULL,
					     history_funcs,
					     NULL, NULL);
	if (!history_obj) goto release_and_fail;

	location_obj = spidermonkey_InitClass(ctx, window_obj, NULL,
					      (JSClass *) &location_class, NULL, 0,
					      (JSPropertySpec *) location_props,
					      location_funcs,
					      NULL, NULL);
	if (!location_obj) goto release_and_fail;

	menubar_obj = JS_InitClass(ctx, window_obj, NULL,
				   (JSClass *) &menubar_class, NULL, 0,
				   (JSPropertySpec *) unibar_props, NULL,
				   NULL, NULL);
	if (!menubar_obj) goto release_and_fail;
	if (!JS_SetPrivate(ctx, menubar_obj, "t")) /* to @menubar_class */
		goto release_and_fail;

	statusbar_obj = JS_InitClass(ctx, window_obj, NULL,
				     (JSClass *) &statusbar_class, NULL, 0,
				     (JSPropertySpec *) unibar_props, NULL,
				     NULL, NULL);
	if (!statusbar_obj) goto release_and_fail;
	if (!JS_SetPrivate(ctx, statusbar_obj, "s")) /* to @statusbar_class */
		goto release_and_fail;

	navigator_obj = JS_InitClass(ctx, window_obj, NULL,
				     (JSClass *) &navigator_class, NULL, 0,
				     (JSPropertySpec *) navigator_props, NULL,
				     NULL, NULL);
	if (!navigator_obj) goto release_and_fail;

	return ctx;

release_and_fail:
	spidermonkey_put_interpreter(interpreter);
	return NULL;
}