/* Execute a string in its own context (away from Synchronet objects) */ static JSBool js_eval(JSContext *parent_cx, JSObject *parent_obj, uintN argc, jsval *argv, jsval *rval) { char* buf; size_t buflen; JSString* str; JSScript* script; JSContext* cx; JSObject* obj; JSErrorReporter reporter; #ifndef EVAL_BRANCH_CALLBACK JSBranchCallback callback; #endif if(argc<1) return(JS_TRUE); if((str=JS_ValueToString(parent_cx, argv[0]))==NULL) return(JS_FALSE); if((buf=JS_GetStringBytes(str))==NULL) return(JS_FALSE); buflen=JS_GetStringLength(str); if((cx=JS_NewContext(JS_GetRuntime(parent_cx),JAVASCRIPT_CONTEXT_STACK))==NULL) 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); #ifdef EVAL_BRANCH_CALLBACK JS_SetContextPrivate(cx, JS_GetPrivate(parent_cx, parent_obj)); JS_SetBranchCallback(cx, js_BranchCallback); #else /* Use the branch callback from the parent context */ JS_SetContextPrivate(cx, JS_GetContextPrivate(parent_cx)); callback=JS_SetBranchCallback(parent_cx,NULL); JS_SetBranchCallback(parent_cx, callback); JS_SetBranchCallback(cx, callback); #endif if((obj=JS_NewObject(cx, NULL, NULL, NULL))==NULL || !JS_InitStandardClasses(cx,obj)) { JS_DestroyContext(cx); return(JS_FALSE); } if((script=JS_CompileScript(cx, obj, buf, buflen, NULL, 0))!=NULL) { JS_ExecuteScript(cx, obj, script, rval); JS_DestroyScript(cx, script); } JS_DestroyContext(cx); return(JS_TRUE); }
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_NewObject(vm->context, &global_class, NULL, NULL); JS_InitStandardClasses(vm->context, vm->global); JS_SetErrorReporter(vm->context, on_error); JS_SetBranchCallback(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, JSFUN_FAST_NATIVE); end_request(vm); return vm; }
static void setup_safeguard(struct ecmascript_interpreter *interpreter, JSContext *ctx) { interpreter->exec_start = time(NULL); JS_SetBranchCallback(ctx, safeguard); }
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); }
/* * call-seq: * native_initialize(options={}) * * Initializes the native spidermonkey values. */ static VALUE initialize_native(VALUE self, VALUE rb_runtime, VALUE UNUSED(options)) { JohnsonContext* context; JohnsonRuntime* runtime; Data_Get_Struct(self, JohnsonContext, context); Data_Get_Struct(rb_runtime, JohnsonRuntime, runtime); if ((context->js = JS_NewContext(runtime->js, 8192L))) { // See if the runtime already has a shared global object. JSObject* global = runtime->global; // If it does, use it. If not, if (!global) // create one of our global objects. global = johnson_create_global_object(context->js); // Manually set the context's global object. JS_SetGlobalObject(context->js, global); JS_SetErrorReporter(context->js, report_js_error); JS_SetBranchCallback(context->js, branch_callback); JS_SetContextPrivate(context->js, (void *)self); JS_SetOptions(context->js, JS_GetOptions(context->js) | JSOPTION_DONT_REPORT_UNCAUGHT #ifdef JSOPTION_VAROBJFIX | JSOPTION_VAROBJFIX #endif // #ifdef JSOPTION_XML // | JSOPTION_XML // #endif ); // Success. return init_spidermonkey_extensions(context, self); } if (context->js) JS_DestroyContext(context->js); rb_raise(rb_eRuntimeError, "Failed to initialize SpiderMonkey context"); }
PyObject* Context_new(PyTypeObject* type, PyObject* args, PyObject* kwargs) { Context* self = NULL; Runtime* runtime = NULL; PyObject* global = NULL; PyObject* access = NULL; PyObject* alertlist = NULL; char* keywords[] = {"runtime", "glbl", "access", "alertlist", NULL}; if(!PyArg_ParseTupleAndKeywords( args, kwargs, "O!|OOO", keywords, RuntimeType, &runtime, &global, &access, &alertlist )) goto error; if(global == Py_None) global = NULL; if(access == Py_None) access = NULL; if(alertlist == Py_None) alertlist = NULL; if(global != NULL && !PyMapping_Check(global)) { PyErr_SetString(PyExc_TypeError, "Global handler must provide item access."); goto error; } if(access != NULL && !PyCallable_Check(access)) { PyErr_SetString(PyExc_TypeError, "Access handler must be callable."); goto error; } if(alertlist != NULL && !PyList_Check(alertlist)) { PyErr_SetString(PyExc_TypeError, "Alert list must be a list object."); goto error; } self = (Context*) type->tp_alloc(type, 0); if(self == NULL) goto error; // Tracking what classes we've installed in // the context. self->classes = (PyDictObject*) PyDict_New(); if(self->classes == NULL) goto error; self->objects = (PySetObject*) PySet_New(NULL); if(self->objects == NULL) goto error; self->cx = JS_NewContext(runtime->rt, 8192); if(self->cx == NULL) { PyErr_SetString(PyExc_RuntimeError, "Failed to create JSContext."); goto error; } JS_BeginRequest(self->cx); /* * Notice that we don't add a ref to the Python context for * the copy stored on the JSContext*. I'm pretty sure this * would cause a cyclic dependancy that would prevent * garbage collection from happening on either side of the * bridge. * */ JS_SetContextPrivate(self->cx, self); // Setup the root of the property lookup doodad. self->root = JS_NewObject(self->cx, &js_global_class, NULL, NULL); if(self->root == NULL) { PyErr_SetString(PyExc_RuntimeError, "Error creating root object."); goto error; } if(!JS_InitStandardClasses(self->cx, self->root)) { PyErr_SetString(PyExc_RuntimeError, "Error initializing JS VM."); goto error; } // Don't setup the global handler until after the standard classes // have been initialized. // XXX: Does anyone know if finalize is called if new fails? if(global != NULL) Py_INCREF(global); self->global = global; if(access != NULL) Py_INCREF(access); self->access = access; if(alertlist != NULL) Py_INCREF(alertlist); self->alertlist = alertlist; // Setup counters for resource limits self->branch_count = 0; self->max_time = 0; self->start_time = 0; self->max_heap = 0; JS_SetBranchCallback(self->cx, branch_cb); JS_SetErrorReporter(self->cx, report_error_cb); Py_INCREF(runtime); self->rt = runtime; goto success; error: if(self != NULL && self->cx != NULL) JS_EndRequest(self->cx); Py_XDECREF(self); self = NULL; success: if(self != NULL && self->cx != NULL) JS_EndRequest(self->cx); return (PyObject*) self; }
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); }