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); }
nsresult nsXBLProtoImplAnonymousMethod::Execute(nsIContent* aBoundElement) { NS_PRECONDITION(IsCompiled(), "Can't execute uncompiled method"); if (!mJSMethodObject) { // Nothing to do here return NS_OK; } // Get the script context the same way // nsXBLProtoImpl::InstallImplementation does. nsIDocument* document = aBoundElement->GetOwnerDoc(); if (!document) { return NS_OK; } nsIScriptGlobalObject* global = document->GetScriptGlobalObject(); if (!global) { return NS_OK; } nsCOMPtr<nsIScriptContext> context = global->GetContext(); if (!context) { return NS_OK; } JSContext* cx = (JSContext*) context->GetNativeContext(); JSObject* globalObject = global->GetGlobalJSObject(); nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper; jsval v; nsresult rv = nsContentUtils::WrapNative(cx, globalObject, aBoundElement, &v, getter_AddRefs(wrapper)); NS_ENSURE_SUCCESS(rv, rv); JSObject* thisObject = JSVAL_TO_OBJECT(v); JSAutoRequest ar(cx); JSAutoEnterCompartment ac; if (!ac.enter(cx, thisObject)) return NS_ERROR_UNEXPECTED; // Clone the function object, using thisObject as the parent so "this" is in // the scope chain of the resulting function (for backwards compat to the // days when this was an event handler). JSObject* method = ::JS_CloneFunctionObject(cx, mJSMethodObject, thisObject); if (!method) return NS_ERROR_OUT_OF_MEMORY; // Now call the method // Use nsCxPusher to make sure we call ScriptEvaluated when we're done. nsCxPusher pusher; NS_ENSURE_STATE(pusher.Push(aBoundElement)); // Check whether it's OK to call the method. rv = nsContentUtils::GetSecurityManager()->CheckFunctionAccess(cx, method, thisObject); JSBool ok = JS_TRUE; if (NS_SUCCEEDED(rv)) { jsval retval; ok = ::JS_CallFunctionValue(cx, thisObject, OBJECT_TO_JSVAL(method), 0 /* argc */, nsnull /* argv */, &retval); } if (!ok) { // If a constructor or destructor threw an exception, it doesn't stop // anything else. We just report it. Note that we need to set aside the // frame chain here, since the constructor invocation is not related to // whatever is on the stack right now, really. JSBool saved = JS_SaveFrameChain(cx); JS_ReportPendingException(cx); if (saved) JS_RestoreFrameChain(cx); return NS_ERROR_FAILURE; } return NS_OK; }
int ExecShellScript(const char * file, int argc, char** argv, JSContext * context, JSObject * env, jsval * vp) { register FILE * filep; register int c; filep = fopen(file, "rb"); if (!filep) { JS_ReportError(context, "%s: %s", file, "No such file or directory"); return 0; } if (getc(filep) == '#' && getc(filep) == '!') { c = 1; while (c != EOF && c != '\n') c = getc(filep); ungetc(c, filep); } else { fclose(filep); JS_ReportError(context, "%s: %s", file, "is not a shell script"); return 0; } JSObject* argsObj = JS_NewArrayObject(context, 0, NULL); JS_DefineProperty(context, env, "parameter", OBJECT_TO_JSVAL(argsObj), NULL, NULL, 0); JSString* str = JS_NewStringCopyZ(context, file); JS_DefineElement(context, argsObj, 0, STRING_TO_JSVAL(str), NULL, NULL, JSPROP_ENUMERATE); int i; for (i = 0; i < argc; i++) { str = JS_NewStringCopyZ(context, argv[i]); JS_DefineElement(context, argsObj, i + 1, STRING_TO_JSVAL(str), NULL, NULL, JSPROP_ENUMERATE); } setenv(SMASH_RESOURCE_PATH_ENV_ID, GET_STRING_DEF(SMASH_RESOURCE_PATH), 0); JS_InitCTypesClass(context, env); JS_DefineFunctions(context, env, shell_functions); JS_DefineProperties(context, env, shell_properties); jsval fun; JS_GetProperty(context, env, "system", &fun); JS_DefineFunction(context, JSVAL_TO_OBJECT(fun), "read", ShellSystemRead, 1, JSPROP_ENUMERATE); JS_DefineFunction(context, JSVAL_TO_OBJECT(fun), "write", ShellSystemWrite, 2, JSPROP_ENUMERATE); jsval fun2; JS_GetProperty(context, env, "echo", &fun2); JS_DefineFunction(context, JSVAL_TO_OBJECT(fun2), "error", ShellEchoError, 1, JSPROP_ENUMERATE); jsval fun3; JS_GetProperty(context, env, "setFileContent", &fun3); JS_DefineFunction(context, JSVAL_TO_OBJECT(fun3), "append", ShellSetFileContentAppend, 2, JSPROP_ENUMERATE); #ifdef SMASH_MAIN_LOADER //ExecScriptFile(context, env, GET_STRING_DEF(SMASH_MAIN_LOADER), NULL); #endif #ifdef SMASH_SHELL_LOADER ExecScriptFile(context, env, GET_STRING_DEF(SMASH_SHELL_LOADER), NULL); #endif JSObject * jsTemp = JS_CompileFileHandle(context, env, file, filep); fclose(filep); if (jsTemp) { return JS_ExecuteScript(context, env, jsTemp, vp); } else { JS_ReportPendingException(context); return 1; } }
JSBool __Core_include (JSContext* cx, std::string path) { if (__Core_isIncluded(path)) { #ifdef DEBUG std::cerr << "(already included) " << path << "." << std::endl; #endif return JS_TRUE; } if (path.substr(path.length()-3) == ".js") { struct stat pathStat; if (stat(path.c_str(), &pathStat) == -1) { #ifdef DEBUG std::cerr << "(javascript) "; #endif std::cerr << path << " not found." << std::endl; return JS_FALSE; } std::string cachePath = path + "c"; struct stat cacheStat; if (!stat(cachePath.c_str(), &cacheStat)) { if (cacheStat.st_mtime >= pathStat.st_mtime) { try { lulzJS::Script script(cx, cachePath, lulzJS::Script::Bytecode); script.execute(); } catch (std::exception e) { } if (JS_IsExceptionPending(cx)) { JS_ReportPendingException(cx); return JS_FALSE; } } } #ifdef DEBUG std::cerr << "(javascript) path: " << path << std::endl; #endif try { lulzJS::Script script(cx, path, lulzJS::Script::Text); script.execute(); if (JS_IsExceptionPending(cx)) { JS_ReportPendingException(cx); return JS_FALSE; } script.save(cachePath, lulzJS::Script::Bytecode); } catch (std::runtime_error e) { JS_ReportPendingException(cx); return JS_FALSE; } } else if (path.substr(path.length()-3) == ".so") { #ifdef DEBUG std::cerr << "(object) path: " << path << std::endl; #endif struct stat test; if (stat(path.c_str(), &test)) { #ifdef DEBUG std::cerr << "(object) "; #endif std::cerr << path << " not found." << std::endl; return JS_FALSE; } PRLibrary* lib = PR_LoadLibrary(path.c_str()); if (!lib) { char* error = new char[PR_GetErrorTextLength()]; PR_GetErrorText(error); std::cerr << error << std::endl; delete [] error; return JS_FALSE; } JSBool (*exec)(JSContext*) = (JSBool (*)(JSContext*)) PR_FindSymbol(lib, "exec"); if (exec == NULL || !(*exec)(cx)) { #ifdef DEBUG std::cerr << "Couldn't retrieve the symbol." << std::endl; #endif std::cerr << "The initialization of the module failed." << std::endl; return JS_FALSE; } } else { #ifdef DEBUG std::cerr << "(module) path: " << path << std::endl; #endif struct stat test; if (stat(path.c_str(), &test)) { #ifdef DEBUG std::cerr << "(module) "; #endif std::cerr << path << " not found." << std::endl; return JS_FALSE; } if (!__Core_include(cx, path + "/init.js")) { return JS_FALSE; } } included.push_back(path); return JS_TRUE; }
bool js_cocos2dx_extension_EventListenerAssetsManagerEx_create(JSContext *cx, uint32_t argc, jsval *vp) { JS::CallArgs args = JS::CallArgsFromVp(argc, vp); bool ok = true; if (argc == 2) { cocos2d::extension::AssetsManagerEx* arg0 = nullptr; std::function<void (cocos2d::extension::EventAssetsManagerEx *)> arg1; do { if (args.get(0).isNull()) { arg0 = nullptr; break; } if (!args.get(0).isObject()) { ok = false; break; } js_proxy_t *jsProxy; JS::RootedObject tmpObj(cx, args.get(0).toObjectOrNull()); jsProxy = jsb_get_js_proxy(tmpObj); arg0 = (cocos2d::extension::AssetsManagerEx*)(jsProxy ? jsProxy->ptr : NULL); JSB_PRECONDITION2( arg0, cx, false, "Invalid Native Object"); } while (0); do { if(JS_TypeOfValue(cx, args.get(1)) == JSTYPE_FUNCTION) { JS::RootedObject jstarget(cx, args.thisv().toObjectOrNull()); std::shared_ptr<JSFunctionWrapper> func(new JSFunctionWrapper(cx, jstarget, args.get(1))); auto lambda = [=](cocos2d::extension::EventAssetsManagerEx* larg0) -> void { JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET jsval largv[1]; do { if (larg0) { js_type_class_t* typeClass = js_get_type_from_native<cocos2d::extension::EventAssetsManagerEx>(larg0); largv[0] = OBJECT_TO_JSVAL(jsb_get_or_create_weak_jsobject(cx, larg0, typeClass, "cocos2d::extension::EventAssetsManagerEx")); } else { largv[0] = JSVAL_NULL; } } while (0); JS::RootedValue rval(cx); bool succeed = func->invoke(1, &largv[0], &rval); if (!succeed && JS_IsExceptionPending(cx)) { JS_ReportPendingException(cx); } removeJSObject(cx, larg0); }; arg1 = lambda; } else { arg1 = nullptr; } } while(0) ; JSB_PRECONDITION2(ok, cx, false, "js_cocos2dx_extension_EventListenerAssetsManagerEx_create : Error processing arguments"); cocos2d::extension::EventListenerAssetsManagerEx* ret = cocos2d::extension::EventListenerAssetsManagerEx::create(arg0, arg1); jsval jsret = JSVAL_NULL; if (ret) { JS::RootedObject jsobj(cx, js_get_or_create_jsobject<cocos2d::extension::EventListenerAssetsManagerEx>(cx, ret)); jsret = OBJECT_TO_JSVAL(jsobj); } else { jsret = JSVAL_NULL; } args.rval().set(jsret); return true; } JS_ReportError(cx, "js_cocos2dx_extension_EventListenerAssetsManagerEx_create : wrong number of arguments"); return false; }
nsresult WebCL_reportJSError (JSContext* cx, char const* aMsg, ...) { D_METHOD_START; nsresult rv = NS_OK; size_t sze = INITIAL_MSG_BUF_SIZE; char* msgBuf = NULL; va_list ap; while (true) { char* tmp = msgBuf; msgBuf = (char*)realloc (msgBuf, sze); if (!msgBuf) { if (tmp) free (tmp); return NS_ERROR_OUT_OF_MEMORY; } tmp = 0; va_start (ap, aMsg); int n = vsnprintf(msgBuf, sze, aMsg, ap); va_end (ap); if (n >= 0 && n < (int)sze) { // Successfull operation break; } else if (n > (int)sze) { // n more bytes needed for buffer sze = n + 1; } else if (n == -1) { // glibc 2.1 return -1 on truncate, grow the buffer and retry sze *= 2; } else { // Unexpected error occurred. D_LOG (LOG_LEVEL_WARNING, "Failed to format the message."); free (msgBuf); return NS_ERROR_FAILURE; } } nsCOMPtr<nsIXPConnect> xpc; JSBool ignored = JS_TRUE; if (!cx) { nsCOMPtr<nsIThreadJSContextStack> stack; stack = do_GetService ("@mozilla.org/js/xpc/ContextStack;1", &rv); if (NS_FAILED(rv)) goto done; cx = stack->GetSafeJSContext (); NS_ENSURE_TRUE (cx, NS_ERROR_FAILURE); } xpc = do_GetService (nsIXPConnect::GetCID (), &rv); if (NS_FAILED(rv)) goto done; JS_BeginRequest (cx); ignored = JS_EnterLocalRootScope (cx); (void)ignored; D_LOG (LOG_LEVEL_ERROR, "Reporting error to JS: \"%s\"", msgBuf); #if 1 JS_ReportError(cx, msgBuf); #else // JS_SetPendingException NOTE: caller must return with NS_OK or we'll just // get the usual MOZ exception msg { JSString *str = JS_NewStringCopyZ(cx, msgBuf); JS_SetPendingException (cx, STRING_TO_JSVAL(str)); JS_ReportPendingException (cx); //JSErrorReport* report = JS_ErrorFromException (cx, STRING_TO_JSVAL(str)); jsval expVal; if (JS_GetPendingException (cx, &expVal)) { JSErrorReport* report = JS_ErrorFromException (cx, expVal); fprintf(stderr, "report: %p\n", (void*)report); if (report) JS_ThrowReportedError (cx, "Fooooools!", report); } } // TODO: Figure out a way to throw real JS exceptions with // custom information. Currently, only generic XPCOM // error-generated exception is thrown and the error // message reported by this function is written on the // JS error console. #endif JS_LeaveLocalRootScope (cx); JS_EndRequest(cx); done: free (msgBuf); return rv; }