Load(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { uintN i; JSString *str; const char *filename; JSScript *script; JSBool ok; jsval result; FILE *file; for (i = 0; i < argc; i++) { str = JS_ValueToString(cx, argv[i]); if (!str) return JS_FALSE; argv[i] = STRING_TO_JSVAL(str); filename = JS_GetStringBytes(str); file = fopen(filename, "r"); script = JS_CompileFileHandleForPrincipals(cx, obj, filename, file, gJSPrincipals); if (!script) ok = JS_FALSE; else { ok = !compileOnly ? JS_ExecuteScript(cx, obj, script, &result) : JS_TRUE; JS_DestroyScript(cx, script); } if (!ok) return JS_FALSE; } return JS_TRUE; }
JS_STATIC_DLL_CALLBACK(JSBool) js__load(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval) { uintN i; JSString * str; const char * filename; JSScript * script; JSBool ok; jsval result; for (i = 0; i < argc; i++) { str = JS_ValueToString(cx, argv[i]); if (!str) return JS_FALSE; argv[i] = STRING_TO_JSVAL(str); filename = JS_GetStringBytes(str); script = JS_CompileFile(cx, obj, filename); if (!script) { ok = JS_FALSE; } else { ok = JS_ExecuteScript(cx, obj, script, &result); JS_DestroyScript(cx, script); } if (!ok) return JS_FALSE; } return JS_TRUE; }
/* 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); }
char *sm_eval(jaegermonkey_vm *vm, const char *filename, const char *code, int handle_retval) { char *retval = NULL; JSScript *script; jsval result; begin_request(vm); script = JS_CompileScript(vm->context, vm->global, code, strlen(code), filename, 1); jaegermonkey_error *error = (jaegermonkey_error *) JS_GetContextPrivate(vm->context); if (error == NULL) { JS_ClearPendingException(vm->context); JS_ExecuteScript(vm->context, vm->global, script, &result); vm->invoke_count++; error = (jaegermonkey_error *) JS_GetContextPrivate(vm->context); if (error == NULL) { if (handle_retval) { if (JSVAL_IS_STRING(result)) { JSString *str = JS_ValueToString(vm->context, result); retval = copy_jsstring(str); } else if(strcmp(JS_GetStringBytes(JS_ValueToString(vm->context, result)), "undefined") == 0) { retval = copy_string("{\"error\": \"Expression returned undefined\", \"lineno\": 0, \"source\": \"unknown\"}"); } else { retval = copy_string("{\"error\": \"non-JSON return value\", \"lineno\": 0, \"source\": \"unknown\"}"); } } JS_DestroyScript(vm->context, script); } else { retval = error_to_json(error); free_error(error); JS_SetContextPrivate(vm->context, NULL); } } else { retval = error_to_json(error); free_error(error); JS_SetContextPrivate(vm->context, NULL); } if (vm->invoke_count > 200) { JS_GC(vm->context); vm->invoke_count = 0; } else { JS_MaybeGC(vm->context); } end_request(vm); return retval; }
JSBool systemInclude(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) {// begin systemInclude // default return value *rval = BOOLEAN_TO_JSVAL(false); if(argc != 1) return JS_FALSE; if(JSVAL_IS_STRING(argv[0]) == false) return JS_FALSE; struct stat sbFileInfo; const char *pIncludeFile = JS_GetStringBytes(JSVAL_TO_STRING(argv[0])); // make sure we haven't included this already to avoid a recursive // dependency loop char *pTempStr = new char[PATH_MAX+1]; if(realpath(pIncludeFile,pTempStr) == NULL) {// begin can't resolve path JS_ReportError(cx, "include() can't resolve the path of \"%s\".", pIncludeFile); return JS_FALSE; }// end can't resolve path std::string sRealPath = pTempStr; if(stat(sRealPath.c_str() , &sbFileInfo) != 0) {// begin can't stat file JS_ReportError(cx, "include() Can't stat \"%s\" errno(%i).", sRealPath.c_str(), errno); return JS_FALSE; }// end can't stat file for(int i = 0;i < g_vIncludes.size();i++) {// begin check previous includes if(g_vIncludes[i] == sRealPath) {// begin found printf("include() Warning: Duplicated include of \"%s\"...ignoring.\n",sRealPath.c_str()); return JS_TRUE; }// end found }// end check previous includes g_vIncludes.push_back(sRealPath); JSScript *pJSScript = JS_CompileFile(cx, obj, sRealPath.c_str()); jsval lastRval; if(pJSScript != NULL) {// begin execute external file JSBool ok = JS_ExecuteScript(cx, obj, pJSScript, &lastRval); JS_DestroyScript(cx,pJSScript); *rval = BOOLEAN_TO_JSVAL(ok); }// end execute external file else {// begin error including JS_ReportError(cx, "include() Cannot compile file \"%s\"", pIncludeFile); return JS_FALSE; }// end error including return JS_TRUE; }// end systemInclude
void js_usescript_gc(JSContext *cx, JSObject *obj) { func("%u:%s:%s",__LINE__,__FILE__,__FUNCTION__); JSScript *script; void *p = JS_GetInstancePrivate(cx, obj, &UseScriptClass, NULL); if(!p) return; script = (JSScript*)p; notice("destroy script %p of %p", script, obj); JS_SetPrivate(cx, obj, NULL); JS_ClearScope(cx, obj); JS_DestroyScript(cx, script); }
void DLLCALL js_EvalOnExit(JSContext *cx, JSObject *obj, js_branch_t* branch) { char* p; jsval rval; JSScript* script; while((p=strListPop(&branch->exit_func))!=NULL) { if((script=JS_CompileScript(cx, obj, p, strlen(p), NULL, 0))!=NULL) { JS_ExecuteScript(cx, obj, script, &rval); JS_DestroyScript(cx, script); } } strListFree(&branch->exit_func); }
NS_IMETHODIMP nsJSSh::ExecuteBuffer() { #ifdef DEBUG // nsCOMPtr<nsIThread> thread; // nsIThread::GetCurrent(getter_AddRefs(thread)); // printf("executing on thread %p\n", thread.get()); #endif JS_BeginRequest(mJSContext); JS_ClearPendingException(mJSContext); JSPrincipals *jsprincipals; mPrincipal->GetJSPrincipals(mJSContext, &jsprincipals); if(NS_FAILED(mContextStack->Push(mJSContext))) { NS_ERROR("failed to push the current JSContext on the nsThreadJSContextStack"); return NS_ERROR_FAILURE; } JSScript *script = JS_CompileScriptForPrincipals(mJSContext, mContextObj, jsprincipals, mBuffer, mBufferPtr, "interactive", 0); if (script) { jsval result; if (JS_ExecuteScript(mJSContext, mContextObj, script, &result) && result!=JSVAL_VOID && mOutput) { // XXX for some wrapped native objects the following code will crash; probably because the // native object is getting released before we reach this: JSString *str = JS_ValueToString(mJSContext, result); if (str) { nsDependentString chars(reinterpret_cast<const PRUnichar*> (JS_GetStringChars(str)), JS_GetStringLength(str)); NS_ConvertUTF16toUTF8 cstr(chars); PRUint32 bytesWritten; mOutput->Write(cstr.get(), cstr.Length(), &bytesWritten); } } JS_DestroyScript(mJSContext, script); } JSContext *oldcx; mContextStack->Pop(&oldcx); NS_ASSERTION(oldcx == mJSContext, "JS thread context push/pop mismatch"); JSPRINCIPALS_DROP(mJSContext, jsprincipals); JS_EndRequest(mJSContext); return NS_OK; }
bool parseECMAScript(const char *name) {// begin parseECMAScript jsval rval; uintN lineno = 0; jscu=0; printf("Spidermonkey compiling \"%s\"\n",name); JSScript *pJSScript = JS_CompileFile(g_pCx, g_pObject, name); if(pJSScript != NULL) {// begin execute external file printf("Spidermonkey executing \"%s\"\n",name); JSBool ok = JS_ExecuteScript(g_pCx, g_pObject, pJSScript, &rval); JS_DestroyScript(g_pCx,pJSScript); }// end execute external file A_Resync(); return jscu; }// end parseECMAScript
bool parseECMAScript(const char *name) {// begin parseECMAScript jsval rval; uintN lineno = 0; g_bJSSuccess = 0; printf("Spidermonkey compiling \"%s\"...",name); FILE *file = fopen(name, "r"); JSScript *pJSScript = JS_CompileFileHandle(g_pCx, g_pObject, name, file);; #warning potential leak here /* In normal operation the file is closed by JS_CompileFileHandle (jsapi.c:3772) JS_CompileFileHandleForPrincipals (jsapi.c:3795) CompileTokenStream (jsapi.c:3609) js_CloseTokenStream (jsscan.c:322) */ /* DOUBLE CLOSE fclose(file); */ printf("Done.\n"); if(pJSScript != NULL) {// begin execute external file char curDir[PATH_MAX + 1]; char scriptPath[strlen(name) + 1]; strcpy(scriptPath, name); ADM_PathStripName(scriptPath); getcwd(curDir, PATH_MAX); chdir(scriptPath); printf("Spidermonkey executing \"%s\"...",name); JSBool ok = JS_ExecuteScript(g_pCx, g_pObject, pJSScript, &rval); JS_DestroyScript(g_pCx,pJSScript); printf("Done.\n"); chdir(curDir); }// end execute external file // Run garbage collector now, it is safe JS_GC(g_pCx); A_Resync(); return g_bJSSuccess; }// end parseECMAScript
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); }
static void ProcessFile(JSContext *cx, JSObject *obj, const char *filename, FILE *file, JSBool forceTTY) { JSScript *script; jsval result; int lineno, startline; JSBool ok, hitEOF; char *bufp, buffer[4096]; JSString *str; if (forceTTY) { file = stdin; } else if (!isatty(fileno(file))) { /* * It's not interactive - just execute it. * * Support the UNIX #! shell hack; gobble the first line if it starts * with '#'. TODO - this isn't quite compatible with sharp variables, * as a legal js program (using sharp variables) might start with '#'. * But that would require multi-character lookahead. */ int ch = fgetc(file); if (ch == '#') { while((ch = fgetc(file)) != EOF) { if(ch == '\n' || ch == '\r') break; } } ungetc(ch, file); DoBeginRequest(cx); script = JS_CompileFileHandleForPrincipals(cx, obj, filename, file, gJSPrincipals); if (script) { if (!compileOnly) (void)JS_ExecuteScript(cx, obj, script, &result); JS_DestroyScript(cx, script); } DoEndRequest(cx); return; } /* It's an interactive filehandle; drop into read-eval-print loop. */ lineno = 1; hitEOF = JS_FALSE; do { bufp = buffer; *bufp = '\0'; /* * Accumulate lines until we get a 'compilable unit' - one that either * generates an error (before running out of source) or that compiles * cleanly. This should be whenever we get a complete statement that * coincides with the end of a line. */ startline = lineno; do { if (!GetLine(cx, bufp, file, startline == lineno ? "js> " : "")) { hitEOF = JS_TRUE; break; } bufp += strlen(bufp); lineno++; } while (!JS_BufferIsCompilableUnit(cx, obj, buffer, strlen(buffer))); DoBeginRequest(cx); /* Clear any pending exception from previous failed compiles. */ JS_ClearPendingException(cx); script = JS_CompileScriptForPrincipals(cx, obj, gJSPrincipals, buffer, strlen(buffer), "typein", startline); if (script) { JSErrorReporter older; if (!compileOnly) { ok = JS_ExecuteScript(cx, obj, script, &result); if (ok && result != JSVAL_VOID) { /* Suppress error reports from JS_ValueToString(). */ older = JS_SetErrorReporter(cx, NULL); str = JS_ValueToString(cx, result); JS_SetErrorReporter(cx, older); if (str) fprintf(gOutFile, "%s\n", JS_GetStringBytes(str)); else ok = JS_FALSE; } } JS_DestroyScript(cx, script); } DoEndRequest(cx); } while (!hitEOF && !gQuitting); fprintf(gOutFile, "\n"); }
PRBool CreateFakeBrowserWindow(JSContext* cx, JSObject* parent, nsIPrincipal* systemPrincipal) { nsresult rv; jsval value; nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID()); if (xpc == nsnull) { JS_ReportError(cx, "Adblock Plus: Coult not retrieve nsIXPConnect - wrong Gecko version?"); return PR_FALSE; } rv = xpc->FlagSystemFilenamePrefix("adblockplus.dll/"); if (NS_FAILED(rv)) { JS_ReportError(cx, "Adblock Plus: Failed to enable protection for inline JavaScript"); return PR_FALSE; } JSObject* obj = JS_NewObject(cx, nsnull, nsnull, parent); if (obj == nsnull) { JS_ReportError(cx, "Adblock Plus: Failed to create fake browser window object - out of memory?"); return PR_FALSE; } JS_SetGlobalObject(cx, obj); // Have to loop through the methods manually because JS_DefineFunctions won't do anything for some reason for (JSFunctionSpec *fs = window_methods; fs->name; fs++) { JSFunction *fun = JS_DefineFunction(cx, obj, fs->name, fs->call, fs->nargs, fs->flags); if (!fun) { JS_ReportError(cx, "Adblock Plus: Failed to attach native methods to fake browser window"); return PR_FALSE; } } if (!JS_DefineProperties(cx, obj, window_properties)) { JS_ReportError(cx, "Adblock Plus: Failed to attach native properties to fake browser window"); return PR_FALSE; } JSPrincipals* principals; rv = systemPrincipal->GetJSPrincipals(cx, &principals); if (NS_FAILED(rv)) { JS_ReportError(cx, "Adblock Plus: Could not convert system principal into JavaScript principals"); return PR_FALSE; } for (int i = 0; includes[i]; i += 2) { JSScript* inlineScript = JS_CompileScriptForPrincipals(cx, obj, principals, includes[i+1], strlen(includes[i+1]), includes[i], 1); if (inlineScript == nsnull) { JS_ReportError(cx, "Adblock Plus: Failed to compile %s", includes[i]); return PR_FALSE; } if (!JS_ExecuteScript(cx, obj, inlineScript, &value)) { JS_ReportError(cx, "Adblock Plus: Failed to execute %s", includes[i]); return PR_FALSE; } JS_DestroyScript(cx, inlineScript); } JSPRINCIPALS_DROP(cx, principals); nsCOMPtr<nsISupports> wrapped; rv = xpc->WrapJS(cx, obj, NS_GET_IID(nsISupports), getter_AddRefs(wrapped)); if (NS_FAILED(rv)) { JS_ReportError(cx, "Adblock Plus: Failed to create XPConnect wrapper for fake browser window"); return PR_FALSE; } fakeBrowserWindow = do_QueryInterface(wrapped); if (fakeBrowserWindow == nsnull) { JS_ReportError(cx, "Adblock Plus: Failed to QI fake browser window"); return PR_FALSE; } jsval readerVal; JS_GetProperty(cx, obj, "_dtdReader", &readerVal); if (readerVal == JSVAL_VOID) { JS_ReportError(cx, "Adblock Plus: Failed to retrieve DTD reader object"); return PR_FALSE; } JSObject* reader = JSVAL_TO_OBJECT(readerVal); for (int i = 0; i < NUM_LABELS; i++) { JSString* str = JS_NewStringCopyZ(cx, context_labels[i]); if (str == nsnull) { JS_ReportError(cx, "Adblock Plus: Could not create JavaScript string for '%s' - out of memory?", context_labels[i]); return PR_FALSE; } jsval args[] = {STRING_TO_JSVAL(str)}; jsval retval; if (!JS_CallFunctionName(cx, reader, "getEntity", 1, args, &retval)) { JS_ReportError(cx, "Adblock Plus: Failed to retrieve entity '%s' from overlay.dtd", context_labels[i]); return PR_FALSE; } str = JS_ValueToString(cx, retval); if (str == nsnull) { JS_ReportError(cx, "Adblock Plus: Could not convert return value of _dtdReader.getEntity() to string"); return PR_FALSE; } strcpy_s(labelValues[i], sizeof(labelValues[i]), JS_GetStringBytes(str)); } return PR_TRUE; }
static JSBool obj_eval(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { JSStackFrame *fp, *caller; JSBool ok; JSString *str; const char *file; uintN line; JSPrincipals *principals; JSScript *script; #if JS_HAS_EVAL_THIS_SCOPE JSObject *callerScopeChain; JSBool implicitWith; #endif if (!JSVAL_IS_STRING(argv[0])) { *rval = argv[0]; return JS_TRUE; } fp = cx->fp; caller = fp->down; #if !JS_BUG_EVAL_THIS_FUN /* Ensure that this flows into eval from the calling function, if any. */ fp->thisp = caller->thisp; #endif #if JS_HAS_SHARP_VARS fp->sharpArray = caller->sharpArray; #endif #if JS_HAS_EVAL_THIS_SCOPE /* If obj.eval(str), emulate 'with (obj) eval(str)' in the calling frame. */ callerScopeChain = caller->scopeChain; implicitWith = (callerScopeChain != obj && (callerScopeChain->map->clasp != &js_WithClass || OBJ_GET_PROTO(callerScopeChain) != obj)); if (implicitWith) { obj = js_NewObject(cx, &js_WithClass, obj, callerScopeChain); if (!obj) return JS_FALSE; caller->scopeChain = obj; } #endif #if !JS_BUG_EVAL_THIS_SCOPE /* Compile using caller's current scope object (might be a function). */ obj = caller->scopeChain; #endif str = JSVAL_TO_STRING(argv[0]); if (caller->script) { file = caller->script->filename; line = js_PCToLineNumber(caller->script, caller->pc); principals = caller->script->principals; } else { file = NULL; line = 0; principals = NULL; } script = JS_CompileUCScriptForPrincipals(cx, obj, principals, str->chars, str->length, file, line); if (!script) { ok = JS_FALSE; goto out; } #if !JS_BUG_EVAL_THIS_SCOPE /* Interpret using caller's new scope object (might be a Call object). */ obj = caller->scopeChain; #endif ok = js_Execute(cx, obj, script, fp, rval); JS_DestroyScript(cx, script); out: #if JS_HAS_EVAL_THIS_SCOPE if (implicitWith) { /* Restore OBJ_GET_PARENT(obj) not callerScopeChain in case of Call. */ caller->scopeChain = OBJ_GET_PARENT(obj); } #endif return ok; }