int main() { JSRuntime *rt; JSContext *jscontext; JSObject *glob; nsresult rv; gErrFile = stderr; gOutFile = stdout; { nsCOMPtr<nsIServiceManager> servMan; NS_InitXPCOM2(getter_AddRefs(servMan), nsnull, nsnull); // get the JSRuntime from the runtime svc, if possible nsCOMPtr<nsIJSRuntimeService> rtsvc = do_GetService("@mozilla.org/js/xpc/RuntimeService;1", &rv); if(NS_FAILED(rv) || NS_FAILED(rtsvc->GetRuntime(&rt)) || !rt) DIE("FAILED to get a JSRuntime"); jscontext = JS_NewContext(rt, 8192); if(!jscontext) DIE("FAILED to create a JSContext"); JS_SetErrorReporter(jscontext, my_ErrorReporter); nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID(), &rv)); if(!xpc) DIE("FAILED to get xpconnect service\n"); nsCOMPtr<nsIJSContextStack> cxstack = do_GetService("@mozilla.org/js/xpc/ContextStack;1", &rv); if(NS_FAILED(rv)) DIE("FAILED to get the nsThreadJSContextStack service!\n"); if(NS_FAILED(cxstack->Push(jscontext))) DIE("FAILED to push the current jscontext on the nsThreadJSContextStack service!\n"); // XXX I'd like to replace this with code that uses a wrapped xpcom object // as the global object. The old TextXPC did this. The support for this // is not working now in the new xpconnect code. { JSAutoRequest ar(jscontext); glob = JS_NewCompartmentAndGlobalObject(jscontext, &global_class, NULL); if (!glob) DIE("FAILED to create global object"); JSAutoEnterCompartment ac; if (!ac.enter(jscontext, glob)) DIE("FAILED to enter compartment"); if (!JS_InitStandardClasses(jscontext, glob)) DIE("FAILED to init standard classes"); if (!JS_DefineFunctions(jscontext, glob, glob_functions)) DIE("FAILED to define global functions"); if (NS_FAILED(xpc->InitClasses(jscontext, glob))) DIE("FAILED to init xpconnect classes"); } /**********************************************/ // run the tests... TestCategoryManmager(); TestSecurityManager(jscontext, glob, xpc); TestArgFormatter(jscontext, glob, xpc); TestThreadJSContextStack(jscontext); /**********************************************/ if(NS_FAILED(cxstack->Pop(nsnull))) DIE("FAILED to pop the current jscontext from the nsThreadJSContextStack service!\n"); { JSAutoRequest ar(jscontext); JS_ClearScope(jscontext, glob); JS_GC(jscontext); JS_GC(jscontext); } JS_DestroyContext(jscontext); xpc->DebugDump(4); cxstack = nsnull; // release service held by nsCOMPtr xpc = nsnull; // release service held by nsCOMPtr rtsvc = nsnull; // release service held by nsCOMPtr } rv = NS_ShutdownXPCOM( NULL ); NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM FAILED"); return 0; }
JSBool gjs_console_interact(JSContext *context, uintN argc, jsval *vp) { JSObject *object = JS_THIS_OBJECT(context, vp); gboolean eof = FALSE; JSObject *script = NULL; jsval result; JSString *str; GString *buffer = NULL; char *temp_buf = NULL; gunichar2 *u16_buffer; glong u16_buffer_len; int lineno; int startline; GError *error = NULL; FILE *file = stdin; JS_SetErrorReporter(context, gjs_console_error_reporter); /* It's an interactive filehandle; drop into read-eval-print loop. */ lineno = 1; do { /* * 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; buffer = g_string_new(""); do { if (!gjs_console_readline(context, &temp_buf, file, startline == lineno ? "gjs> " : ".... ")) { eof = JS_TRUE; break; } g_string_append(buffer, temp_buf); g_free(temp_buf); lineno++; /* Note in this case, we are trying to parse the buffer as * ISO-8859-1 which is broken for non-ASCII. */ } while (!JS_BufferIsCompilableUnit(context, object, buffer->str, buffer->len)); if ((u16_buffer = g_utf8_to_utf16 (buffer->str, buffer->len, NULL, &u16_buffer_len, &error)) == NULL) { g_printerr ("%s\n", error->message); g_clear_error (&error); continue; } script = JS_CompileUCScript(context, object, u16_buffer, u16_buffer_len, "typein", startline); g_free (u16_buffer); if (script) JS_ExecuteScript(context, object, script, &result); if (JS_GetPendingException(context, &result)) { str = JS_ValueToString(context, result); JS_ClearPendingException(context); } else if (JSVAL_IS_VOID(result)) { goto next; } else { str = JS_ValueToString(context, result); } if (str) { char *display_str; display_str = gjs_value_debug_string(context, result); if (display_str != NULL) { g_fprintf(stdout, "%s\n", display_str); g_free(display_str); } } next: g_string_free(buffer, TRUE); } while (!eof); g_fprintf(stdout, "\n"); if (file != stdin) fclose(file); return JS_TRUE; }
JSCLAutoErrorReporterSetter(JSContext* cx, JSErrorReporter reporter) {mContext = cx; mOldReporter = JS_SetErrorReporter(cx, reporter);}
~JSCLAutoErrorReporterSetter() {JS_SetErrorReporter(mContext, mOldReporter);}
int main(int argc, const char *argv[]) { static JSFunctionSpec myjs_global_functions[]={ JS_FS("rand",myjs_rand,0,0), JS_FS("srand",myjs_srand,0,0), JS_FS("system",myjs_system,0,0), JS_FS_END }; /* JS variables. */ JSRuntime *rt; JSContext *cx; JSObject *global; /* Create a JS runtime. */ rt = JS_NewRuntime(8L * 1024L * 1024L,JS_NO_HELPER_THREADS); if (rt == NULL) return 1; /* Create a context. */ cx = JS_NewContext(rt, 8192); if (cx == NULL) return 1; JS_SetOptions(cx, JSOPTION_VAROBJFIX | JSOPTION_METHODJIT); JS_SetVersion(cx, JSVERSION_LATEST); JS_SetErrorReporter(cx, reportError); /* Create the global object in a new compartment. */ global = JS_NewGlobalObject(cx, &global_class, NULL); if (global == NULL) return 1; /* Populate the global object with the standard globals, like Object and Array. */ if (!JS_InitStandardClasses(cx, global)) return 1; if(!JS_DefineFunctions(cx,global,myjs_global_functions)) return JS_FALSE; /* Your application code here. This may include JSAPI calls * to create your own custom JavaScript objects and to run scripts. * * The following example code creates a literal JavaScript script, * evaluates it, and prints the result to stdout. * * Errors are conventionally saved in a JSBool variable named ok. */ char *script = "var a=ss;"; jsval rval; JSString *str; JSBool ok; const char *filename = "noname"; uint32_t lineno = 0; ok = JS_EvaluateScript(cx, global, script, strlen(script), filename, lineno, &rval); if (!ok) return 1; str = JS_ValueToString(cx, rval); printf("%s\n", JS_EncodeString(cx, str)); /* End of your application code */ /* Clean things up and shut down SpiderMonkey. */ JS_DestroyContext(cx); JS_DestroyRuntime(rt); JS_ShutDown(); return 0; }
int main() { std::string a = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbccccccccccccaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; std::string output; ZopfliOptions options; ZopfliInitOptions(&options); snappy::Compress(a.data(), a.size(), &output); if(!checkhash((unsigned char *)output.data(), output.size(), (char *)"0x5a8f06cf6817a74bc75c3c8290196928acb04c189ecdd192a93eb3c3")) { std::cout<<"Something wrong\n"; } unsigned char b[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbccccccccccccaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; unsigned char *out = NULL; size_t outsize = 0; ZopfliCompress(&options, ZOPFLI_FORMAT_GZIP, b, a.size(), &out, &outsize); if(!checkhash(out, outsize, (char *)"0x0f66ce213d2d27067ff9ffa8bbde2dd06d7f3e687549fad846169e16")) { std::cout<<"Something wrong\n"; } HangulInputContext* ic; const char* p = "dekde"; const ucschar* commit; ic = hangul_ic_new("2y"); while (*p != '\0') { hangul_ic_process(ic, *p); p++; } commit = hangul_ic_get_commit_string(ic); int len = wcslen((const wchar_t*)commit); if(!checkhash((unsigned char*)commit, len * sizeof(const wchar_t), (char *)"0xc9bf9374fbc9f4989afd0af7ac9824a4dcc768b33bfa3bb38e42617b")) { std::cout<<"Something wrong\n"; } hangul_ic_delete(ic); static JSClass global_class = { "global", JSCLASS_NEW_RESOLVE | JSCLASS_GLOBAL_FLAGS, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub, JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, NULL, JSCLASS_NO_OPTIONAL_MEMBERS }; JSRuntime *rt = JS_NewRuntime(8 * 1024 * 1024); JSContext *cx = JS_NewContext(rt, 8192); JS_SetOptions(cx, JSOPTION_VAROBJFIX); JS_SetErrorReporter(cx, reportError); JSObject *global = JS_NewCompartmentAndGlobalObject(cx, &global_class, NULL); JS_SetGlobalObject(cx, global); if (!JS_InitStandardClasses(cx, global)) { return 1; } char source[] = "Math.random()"; jsval rval; cx->rngSeed = 31337; JS_EvaluateScript(cx, global, source, strlen(source), "none", 10, &rval); double nums[2]; nums[0] = JSVAL_TO_DOUBLE(rval); JS_EvaluateScript(cx, global, source, strlen(source), "none", 10, &rval); nums[1] = JSVAL_TO_DOUBLE(rval); if(!checkhash((unsigned char*)nums, 2 * sizeof(double), (char *)"0x61b35e8d466f24ee1ea502350ec6f5d1134fe6ec543c17845fa62f8a")) { std::cout<<"Something wrong\n"; } JS_DestroyContext(cx); JS_DestroyRuntime(rt); JS_ShutDown(); mtprngParam mt; byte bay[] = "qqqqqqqqqqqqqqqq"; byte result[100]; for(int i=0; i< 100; i++) { result[i] = 0; } mtprngSetup(&mt); mtprngSeed(&mt, bay, 16); mtprngNext(&mt, result, 100); if(!checkhash((unsigned char*)&result, 100, (char *)"0x7754dfd27fe6fa00551861ff41e4f48315bd89bef6da652f182ce2d6")) { std::cout<<"Something wrong\n"; } ranlib::ChiSquare<double> gen(4); gen.seed(31337); double f[16]; for(int i = 0; i<16; i++) { f[i] = gen.random(); } if(!checkhash((unsigned char*)&f, 16 * sizeof(double), (char *)"0xd19d0c167fe93b11004c0167c226d2e92c17dfa36ffb243f39824098")) { std::cout<<"Something wrong\n"; } Botan::byte pass[] = "aaaabbbb"; Botan::PBKDF* pbkdf = Botan::get_pbkdf("PBKDF2(SHA-256)"); Botan::OctetString aes_key = pbkdf->derive_key(32, "pass1337", pass, 8, 31337); std::string aa = aes_key.as_string(); if(!checkhash((unsigned char*)aa.c_str(), aa.size(), (char *)"0x0c33d122ed50848a676539ae48eb84db0dcbf69e9ee857094755f2d7")) { std::cout<<"Something wrong\n"; } std::cout<<"Answer is RUCTF_"; checkhash((unsigned char*)together, pos, (char *)""); return 0; }
int main(int argc, const char *argv[]) { /* JS variables. */ JSRuntime* rt; JSContext* cx; JSObject* global; /* Create a JS runtime. */ rt = JS_NewRuntime(8L * 1024L * 1024L); if (rt == NULL) return 1; /* Create a context. */ cx = JS_NewContext(rt, 8192); if (cx == NULL) return 1; JS_SetOptions(cx, JSOPTION_VAROBJFIX | JSOPTION_METHODJIT); JS_SetVersion(cx, JSVERSION_LATEST); JS_SetErrorReporter(cx, reportError); /* Create the global object in a new compartment. */ global = JS_NewCompartmentAndGlobalObject(cx, &global_class, NULL); if (global == NULL) return 1; /* Populate the global object with the standard globals, like Object and Array. */ if (!JS_InitStandardClasses(cx, global)) return 1; JSObject* alpha = JS_DefineObject(cx, global, "alpha", NULL, NULL, 0); /* Attach the global functions */ if (!JS_DefineFunctions(cx, alpha, global_functions)) return 1; /* expose the binding functions for require to use */ JSObject* bindings = JS_DefineObject(cx, alpha, "bindings", NULL, NULL, 0); if (!JS_DefineFunctions(cx, bindings, binding_functions)) return 1; /* Set global on alpha */ jsval global_val = OBJECT_TO_JSVAL(global); if (!JS_SetProperty(cx, alpha, "global", &global_val)) return 1; /* Set args on alpha */ JSObject* args = JS_NewArrayObject(cx, 0, NULL); jsval args_val = OBJECT_TO_JSVAL(args); if (!JS_SetProperty(cx, alpha, "args", &args_val)) return 1; int index; for (index = 0; index < argc; index++) { jsval arg = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, argv[index])); if (!JS_SetElement(cx, args, index, &arg)) return 1; } /* Bootstrap using the code in main.js */ JS_EvaluateScript(cx, global, embedded_src_main_js, strlen(embedded_src_main_js), "main.js", 1, NULL); /* Cleanup. */ JS_DestroyContext(cx); JS_DestroyRuntime(rt); JS_ShutDown(); return 0; }
static JSBool InitExceptionObject(JSContext *cx, JSObject *obj, JSString *message, JSString *filename, uintN lineno) { JSCheckAccessOp checkAccess; JSErrorReporter older; JSExceptionState *state; jschar *stackbuf; size_t stacklen, stackmax; JSStackFrame *fp; jsval callerid, v; JSBool ok; JSString *argsrc, *stack; uintN i, ulineno; const char *cp; char ulnbuf[11]; if (!JS_DefineProperty(cx, obj, js_message_str, STRING_TO_JSVAL(message), NULL, NULL, JSPROP_ENUMERATE)) { return JS_FALSE; } if (!JS_DefineProperty(cx, obj, js_filename_str, STRING_TO_JSVAL(filename), NULL, NULL, JSPROP_ENUMERATE)) { return JS_FALSE; } if (!JS_DefineProperty(cx, obj, js_lineno_str, INT_TO_JSVAL(lineno), NULL, NULL, JSPROP_ENUMERATE)) { return JS_FALSE; } /* * Set the 'stack' property. * * First, set aside any error reporter for cx and save its exception state * so we can suppress any checkAccess failures. Such failures should stop * the backtrace procedure, not result in a failure of this constructor. */ checkAccess = cx->runtime->checkObjectAccess; if (checkAccess) { older = JS_SetErrorReporter(cx, NULL); state = JS_SaveExceptionState(cx); } #ifdef __GNUC__ /* suppress bogus gcc warnings */ else { older = NULL; state = NULL; } #endif callerid = ATOM_KEY(cx->runtime->atomState.callerAtom); /* * Prepare to allocate a jschar buffer at stackbuf, where stacklen indexes * the next free jschar slot, and with room for at most stackmax non-null * jschars. If stackbuf is non-null, it always contains an extra slot for * the null terminator we'll store at the end, as a backstop. * * All early returns must goto done after this point, till the after-loop * cleanup code has run! */ stackbuf = NULL; stacklen = stackmax = 0; ok = JS_TRUE; #define APPEND_CHAR_TO_STACK(c) \ JS_BEGIN_MACRO \ if (stacklen == stackmax) { \ void *ptr_; \ stackmax = stackmax ? 2 * stackmax : 64; \ ptr_ = JS_realloc(cx, stackbuf, (stackmax+1) * sizeof(jschar)); \ if (!ptr_) { \ ok = JS_FALSE; \ goto done; \ } \ stackbuf = ptr_; \ } \ stackbuf[stacklen++] = (c); \ JS_END_MACRO #define APPEND_STRING_TO_STACK(str) \ JS_BEGIN_MACRO \ JSString *str_ = str; \ size_t length_ = JSSTRING_LENGTH(str_); \ if (stacklen + length_ > stackmax) { \ void *ptr_; \ stackmax = JS_BIT(JS_CeilingLog2(stacklen + length_)); \ ptr_ = JS_realloc(cx, stackbuf, (stackmax+1) * sizeof(jschar)); \ if (!ptr_) { \ ok = JS_FALSE; \ goto done; \ } \ stackbuf = ptr_; \ } \ js_strncpy(stackbuf + stacklen, JSSTRING_CHARS(str_), length_); \ stacklen += length_; \ JS_END_MACRO for (fp = cx->fp; fp; fp = fp->down) { if (checkAccess) { v = (fp->fun && fp->argv) ? fp->argv[-2] : JSVAL_NULL; if (!JSVAL_IS_PRIMITIVE(v)) { ok = checkAccess(cx, fp->fun->object, callerid, JSACC_READ, &v); if (!ok) { ok = JS_TRUE; break; } } } if (fp->fun) { if (fp->fun->atom) APPEND_STRING_TO_STACK(ATOM_TO_STRING(fp->fun->atom)); APPEND_CHAR_TO_STACK('('); for (i = 0; i < fp->argc; i++) { /* Avoid toSource bloat and fallibility for object types. */ v = fp->argv[i]; if (JSVAL_IS_PRIMITIVE(v)) { argsrc = js_ValueToSource(cx, v); } else if (JSVAL_IS_FUNCTION(cx, v)) { /* XXX Avoid function decompilation bloat for now. */ argsrc = JS_GetFunctionId(JS_ValueToFunction(cx, v)); if (!argsrc) argsrc = js_ValueToSource(cx, v); } else { /* XXX Avoid toString on objects, it takes too long and uses too much memory, for too many classes (see Mozilla bug 166743). */ char buf[100]; JS_snprintf(buf, sizeof buf, "[object %s]", OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(v))->name); argsrc = JS_NewStringCopyZ(cx, buf); } if (!argsrc) { ok = JS_FALSE; goto done; } if (i > 0) APPEND_CHAR_TO_STACK(','); APPEND_STRING_TO_STACK(argsrc); } APPEND_CHAR_TO_STACK(')'); } APPEND_CHAR_TO_STACK('@'); if (fp->script && fp->script->filename) { for (cp = fp->script->filename; *cp; cp++) APPEND_CHAR_TO_STACK(*cp); } APPEND_CHAR_TO_STACK(':'); if (fp->script && fp->pc) { ulineno = js_PCToLineNumber(fp->script, fp->pc); JS_snprintf(ulnbuf, sizeof ulnbuf, "%u", ulineno); for (cp = ulnbuf; *cp; cp++) APPEND_CHAR_TO_STACK(*cp); } else { APPEND_CHAR_TO_STACK('0'); } APPEND_CHAR_TO_STACK('\n'); } #undef APPEND_CHAR_TO_STACK #undef APPEND_STRING_TO_STACK done: if (checkAccess) { if (ok) JS_RestoreExceptionState(cx, state); else JS_DropExceptionState(cx, state); JS_SetErrorReporter(cx, older); } if (!ok) { JS_free(cx, stackbuf); return JS_FALSE; } if (!stackbuf) { stack = cx->runtime->emptyString; } else { /* NB: if stackbuf was allocated, it has room for the terminator. */ JS_ASSERT(stacklen <= stackmax); if (stacklen < stackmax) { /* * Realloc can fail when shrinking on some FreeBSD versions, so * don't use JS_realloc here; simply let the oversized allocation * be owned by the string in that rare case. */ void *shrunk = realloc(stackbuf, (stacklen+1) * sizeof(jschar)); if (shrunk) stackbuf = shrunk; } stackbuf[stacklen] = 0; stack = js_NewString(cx, stackbuf, stacklen, 0); if (!stack) { JS_free(cx, stackbuf); return JS_FALSE; } } return JS_DefineProperty(cx, obj, js_stack_str, STRING_TO_JSVAL(stack), NULL, NULL, JSPROP_ENUMERATE); }
void* vm_run(void* arg) { vm_ptr vm = (vm_ptr) arg; JSContext* cx; JSObject* gl; job_ptr job; ENTERM resp; int flags; cx = JS_NewContext(vm->runtime, vm->stack_size); if(cx == NULL) { fprintf(stderr, "Failed to create context.\n"); goto done; } JS_BeginRequest(cx); flags = 0; flags |= JSOPTION_VAROBJFIX; flags |= JSOPTION_STRICT; flags |= JSVERSION_LATEST; flags |= JSOPTION_COMPILE_N_GO; flags |= JSOPTION_XML; JS_SetOptions(cx, JS_GetOptions(cx) | flags); gl = JS_NewObject(cx, &global_class, NULL, NULL); if(gl == NULL) { fprintf(stderr, "Failed to create global object.\n"); goto done; } if(!JS_InitStandardClasses(cx, gl)) { fprintf(stderr, "Failed to initialize classes.\n"); goto done; } if(!install_jserl(cx, gl)) { fprintf(stderr, "Failed to install erlang object."); goto done; } JS_SetErrorReporter(cx, vm_report_error); JS_SetContextPrivate(cx, (void*) vm); JS_EndRequest(cx); while(1) { job = queue_pop(vm->jobs); if(job->type == job_close) { job_destroy(job); break; } JS_BeginRequest(cx); assert(vm->curr_job == NULL && "vm already has a job set."); vm->curr_job = job; if(job->type == job_eval) { resp = vm_eval(cx, gl, job); } else if(job->type == job_call) { resp = vm_call(cx, gl, job); } else { assert(0 && "Invalid job type."); } vm->curr_job = NULL; JS_EndRequest(cx); JS_MaybeGC(cx); // XXX: If pid is not alive, we just ignore it. enif_send(NULL, &(job->pid), job->env, resp); job_destroy(job); } done: JS_BeginRequest(cx); if(cx != NULL) JS_DestroyContext(cx); return NULL; }
JSBool gjs_console_interact(JSContext *context, unsigned argc, jsval *vp) { JSObject *object = JS_THIS_OBJECT(context, vp); gboolean eof = FALSE; jsval result; JSString *str; GString *buffer = NULL; char *temp_buf = NULL; int lineno; int startline; FILE *file = stdin; JS_SetErrorReporter(context, gjs_console_error_reporter); /* It's an interactive filehandle; drop into read-eval-print loop. */ lineno = 1; do { /* * 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; buffer = g_string_new(""); do { if (!gjs_console_readline(context, &temp_buf, file, startline == lineno ? "cjs> " : ".... ")) { eof = JS_TRUE; break; } g_string_append(buffer, temp_buf); g_free(temp_buf); lineno++; } while (!JS_BufferIsCompilableUnit(context, object, buffer->str, buffer->len)); JS::CompileOptions options(context); options.setUTF8(true) .setFileAndLine("typein", startline); js::RootedObject rootedObj(context, object); JS::Evaluate(context, rootedObj, options, buffer->str, buffer->len, &result); gjs_schedule_gc_if_needed(context); if (JS_GetPendingException(context, &result)) { str = JS_ValueToString(context, result); JS_ClearPendingException(context); } else if (JSVAL_IS_VOID(result)) { goto next; } else { str = JS_ValueToString(context, result); } if (str) { char *display_str; display_str = gjs_value_debug_string(context, result); if (display_str != NULL) { g_fprintf(stdout, "%s\n", display_str); g_free(display_str); } } next: g_string_free(buffer, TRUE); } while (!eof); g_fprintf(stdout, "\n"); if (file != stdin) fclose(file); return JS_TRUE; }
void SG_vc_hooks__execute( SG_context* pCtx, const char* psz_js, SG_vhash* pvh_params, SG_vhash** ppvh_result ) { jsval rval; JSContext* cx = NULL; JSObject* glob = NULL; SG_vhash* pvh_result = NULL; JSObject* jso_params = NULL; SG_NULLARGCHECK_RETURN(psz_js); SG_jscore__new_runtime(pCtx, NULL, global_functions, SG_FALSE, NULL); SG_ERR_CHECK_CURRENT_DISREGARD(SG_ERR_ALREADY_INITIALIZED); SG_ERR_CHECK( SG_jscore__new_context(pCtx, &cx, &glob, NULL) ); //This should tell the javascript engine how to report javascript errors to our jsglue. JS_SetErrorReporter(cx,SG_jsglue__error_reporter); if(!JS_EvaluateScript(cx, glob, psz_js, (uintN) strlen(psz_js), "hook_script", 1, &rval)) { SG_ERR_CHECK_CURRENT; SG_ERR_THROW2(SG_ERR_UNSPECIFIED, (pCtx, "An error occurred evaluating hook")); } // note that we don't care about the rval from eval of the script { jsval params; jsval rval; if (pvh_params) { jso_params = JS_NewObject(cx, NULL, NULL, NULL); if(!jso_params) SG_ERR_THROW2(SG_ERR_MALLOCFAILED, (pCtx, "Failed to create new JS object for params to vc hook.")); params = OBJECT_TO_JSVAL(jso_params); SG_ERR_CHECK( sg_jsglue__copy_vhash_into_jsobject(pCtx, cx, pvh_params, jso_params) ); } else { params = JSVAL_NULL; } if(!JS_CallFunctionName(cx, glob, "hook", 1, ¶ms, &rval)) { SG_ERR_CHECK_CURRENT; SG_ERR_THROW2(SG_ERR_UNSPECIFIED, (pCtx, "An error occurred calling JS hook")); } if (JSVAL_IS_OBJECT(rval)) { SG_ERR_CHECK( sg_jsglue__jsobject_to_vhash(pCtx, cx, JSVAL_TO_OBJECT(rval), &pvh_result) ); } } if (ppvh_result) { *ppvh_result = pvh_result; pvh_result = NULL; } fail: if (cx) { SG_ERR_IGNORE( SG_jsglue__set_sg_context(NULL, cx) ); JS_EndRequest(cx); JS_DestroyContext(cx); } SG_VHASH_NULLFREE(pCtx, pvh_result); }
JSProperty * js_SetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) { JSRuntime *rt; JSScope *scope, *protoScope; JSProperty *prop, *protoProp; PRHashNumber hash; JSSymbol *sym, *protoSym; JSObject *proto, *assignobj; jsval pval, aval, rval; jsint slot; JSErrorReporter older; JSString *str; rt = cx->runtime; PR_ASSERT(JS_IS_RUNTIME_LOCKED(rt)); #ifdef SCOPE_TABLE_NOTYET /* XXX hash recompute */ /* XXX protoProp->getter, protoProp->setter, protoProp->flags */ scope = js_MutateScope(cx, obj, id, getter, setter, flags, &prop); #endif scope = js_GetMutableScope(cx, obj); if (!scope) return NULL; /* Handle old bug that treated empty string as zero index. */ CHECK_FOR_FUNNY_INDEX(id); hash = js_HashValue(id); sym = scope->ops->lookup(cx, scope, id, hash); if (sym) { prop = sym_property(sym); #if JS_HAS_OBJ_WATCHPOINT if (!prop) { /* * Deleted property place-holder, could have a watchpoint that * holds the deleted-but-watched property. */ prop = js_FindWatchPoint(rt, obj, js_IdToValue(id)); } #endif } else { prop = NULL; } if (!prop) { /* Find a prototype property with the same id. */ proto = OBJ_GET_PROTO(obj); protoProp = NULL; while (proto) { protoScope = (JSScope *)proto->map; protoSym = protoScope->ops->lookup(cx, protoScope, id, hash); if (protoSym) { protoProp = sym_property(protoSym); if (protoProp) break; } proto = OBJ_GET_PROTO(proto); } /* Make a new property descriptor with the right heritage. */ if (protoProp) { prop = js_NewProperty(cx, scope, id, protoProp->getter, protoProp->setter, protoProp->flags | JSPROP_ENUMERATE); prop->id = protoProp->id; } else { prop = js_NewProperty(cx, scope, id, scope->map.clasp->getProperty, scope->map.clasp->setProperty, JSPROP_ENUMERATE); } if (!prop) return NULL; if (!obj->map->clasp->addProperty(cx, obj, prop->id, vp)) { js_DestroyProperty(cx, prop); return NULL; } /* Initialize new properties to undefined. */ obj->slots[prop->slot] = JSVAL_VOID; if (sym) { /* Null-valued symbol left behind from a delete operation. */ sym->entry.value = js_HoldProperty(cx, prop); } } if (!sym) { /* Need a new symbol as well as a new property. */ sym = scope->ops->add(cx, scope, id, prop); if (!sym) return NULL; #if JS_BUG_AUTO_INDEX_PROPS { jsval id2 = INT_TO_JSVAL(prop->slot - JSSLOT_START); if (!scope->ops->add(cx, scope, id2, prop)) { scope->ops->remove(cx, scope, id); return NULL; } PROPERTY_CACHE_FILL(cx, &rt->propertyCache, obj, id2, prop); } #endif PROPERTY_CACHE_FILL(cx, &rt->propertyCache, obj, id, prop); } /* Get the current property value from its slot. */ PR_ASSERT(prop->slot < obj->map->freeslot); slot = prop->slot; pval = obj->slots[slot]; /* Evil overloaded operator assign() hack. */ if (JSVAL_IS_OBJECT(pval)) { assignobj = JSVAL_TO_OBJECT(pval); if (assignobj) { older = JS_SetErrorReporter(cx, NULL); if (js_GetProperty(cx, assignobj, (jsval)rt->atomState.assignAtom, &aval) && JSVAL_IS_FUNCTION(aval) && js_Call(cx, assignobj, aval, 1, vp, &rval)) { *vp = rval; JS_SetErrorReporter(cx, older); prop->flags |= JSPROP_ASSIGNHACK; return prop; } JS_SetErrorReporter(cx, older); } } /* Check for readonly *after* the assign() hack. */ if (prop->flags & JSPROP_READONLY) { if (!JSVERSION_IS_ECMA(cx->version)) { str = js_ValueToSource(cx, js_IdToValue(id)); if (str) { JS_ReportError(cx, "%s is read-only", JS_GetStringBytes(str)); } } return NULL; } /* Let the setter modify vp before copying from it to obj->slots[slot]. */ if (!prop->setter(cx, obj, prop->id, vp)) return NULL; GC_POKE(cx, pval); obj->slots[slot] = *vp; /* Setting a property makes it enumerable. */ prop->flags |= JSPROP_ENUMERATE; return prop; }
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; }
JSJavaThreadState * jsj_enter_js(JNIEnv *jEnv, void* applet_obj, jobject java_wrapper_obj, JSContext **cxp, JSObject **js_objp, JSErrorReporter *old_error_reporterp, void **pNSIPrincipaArray, int numPrincipals, void *pNSISecurityContext) { JSContext *cx; char *err_msg; JSObject *js_obj; JSJavaThreadState *jsj_env; cx = NULL; err_msg = NULL; /* Invoke callback, presumably used to implement concurrency constraints */ if (JSJ_callbacks && JSJ_callbacks->enter_js_from_java) { #ifdef OJI if (!JSJ_callbacks->enter_js_from_java(jEnv, &err_msg, pNSIPrincipaArray, numPrincipals, pNSISecurityContext,applet_obj)) #else if (!JSJ_callbacks->enter_js_from_java(jEnv, &err_msg)) #endif goto entry_failure; } /* Check the JSObject pointer in the wrapper object. */ if (js_objp) { #ifdef PRESERVE_JSOBJECT_IDENTITY #if JS_BYTES_PER_LONG == 8 js_obj = (JSObject *)((*jEnv)->GetLongField(jEnv, java_wrapper_obj, njJSObject_long_internal)); #else js_obj = (JSObject *)((*jEnv)->GetIntField(jEnv, java_wrapper_obj, njJSObject_internal)); #endif #else /* !PRESERVE_JSOBJECT_IDENTITY */ js_obj = jsj_UnwrapJSObjectWrapper(jEnv, java_wrapper_obj); #endif /* PRESERVE_JSOBJECT_IDENTITY */ JS_ASSERT(js_obj); if (!js_obj) goto error; *js_objp = js_obj; } /* Get the per-thread state corresponding to the current Java thread */ jsj_env = jsj_MapJavaThreadToJSJavaThreadState(jEnv, &err_msg); if (!jsj_env) goto error; /* Get the JSContext that we're supposed to use for this Java thread */ cx = jsj_env->cx; if (!cx) { /* We called spontaneously into JS from Java, rather than from JS into Java and back into JS. Invoke a callback to obtain/create a JSContext for us to use. */ if (JSJ_callbacks && JSJ_callbacks->map_jsj_thread_to_js_context) { #ifdef OJI cx = JSJ_callbacks->map_jsj_thread_to_js_context(jsj_env, applet_obj, jEnv, &err_msg); #else cx = JSJ_callbacks->map_jsj_thread_to_js_context(jsj_env, jEnv, &err_msg); #endif if (!cx) goto error; } else { err_msg = JS_smprintf("Unable to find/create JavaScript execution " "context for JNI thread 0x%08x", jEnv); goto error; } } *cxp = cx; /* * Capture all JS error reports so that they can be thrown into the Java * caller as an instance of netscape.javascript.JSException. */ *old_error_reporterp = JS_SetErrorReporter(cx, capture_js_error_reports_for_java); #ifdef JSJ_THREADSAFE JS_BeginRequest(cx); #endif return jsj_env; error: /* Invoke callback, presumably used to implement concurrency constraints */ if (JSJ_callbacks && JSJ_callbacks->exit_js) JSJ_callbacks->exit_js(jEnv, cx); entry_failure: if (err_msg) { if (cx) JS_ReportError(cx, err_msg); else jsj_LogError(err_msg); free(err_msg); } return NULL; }
PyObject* Context_new(PyTypeObject* type, PyObject* args, PyObject* kwargs) { Context* self = NULL; Runtime* runtime = NULL; PyObject* global = NULL; if(!PyArg_ParseTuple( args, "O!|O", RuntimeType, &runtime, &global )) goto error; if(global != NULL && !PyMapping_Check(global)) { PyErr_SetString(PyExc_TypeError, "Global handler must provide item access."); 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. * * To make sure that the context stays alive we'll add a * reference to the Context* anytime we wrap a Python * object for use in JS. * */ 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; // 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; }
void gjstest_test_func_gjs_jsapi_util_error_throw(void) { JSRuntime *runtime; JSContext *context; JSObject *global; jsval exc, value, previous; const char *s; /* create a runtime just to avoid tangling this test with all the * code surrounding how we create one normally in context.c */ runtime = JS_NewRuntime(1024*1024 /* max bytes */); context = JS_NewContext(runtime, 8192); JS_BeginRequest(context); global = JS_NewObject(context, NULL, NULL, NULL); JS_SetGlobalObject(context, global); JS_InitStandardClasses(context, global); JS_SetErrorReporter(context, test_error_reporter); /* Test that we can throw */ gjs_throw(context, "This is an exception %d", 42); g_assert(JS_IsExceptionPending(context)); exc = JSVAL_VOID; JS_GetPendingException(context, &exc); g_assert(exc != JSVAL_VOID); value = JSVAL_VOID; JS_GetProperty(context, JSVAL_TO_OBJECT(exc), "message", &value); g_assert(JSVAL_IS_STRING(value)); /* JS_GetStringBytes() is broken for non-ASCII but that's OK here */ s = JS_GetStringBytes(JSVAL_TO_STRING(value)); g_assert(s != NULL); if (strcmp(s, "This is an exception 42") != 0) { g_error("Exception has wrong message '%s'", s); } /* keep this around before we clear it */ previous = exc; JS_AddRoot(context, &previous); JS_ClearPendingException(context); g_assert(!JS_IsExceptionPending(context)); /* Check that we don't overwrite a pending exception */ JS_SetPendingException(context, previous); g_assert(JS_IsExceptionPending(context)); gjs_throw(context, "Second different exception %s", "foo"); g_assert(JS_IsExceptionPending(context)); exc = JSVAL_VOID; JS_GetPendingException(context, &exc); g_assert(exc != JSVAL_VOID); g_assert(exc == previous); JS_RemoveRoot(context, &previous); JS_EndRequest(context); JS_DestroyContext(context); JS_DestroyRuntime(runtime); JS_ShutDown(); }
static JSBool InitExnPrivate(JSContext *cx, JSObject *exnObject, JSString *message, JSString *filename, uintN lineno, JSErrorReport *report) { JSSecurityCallbacks *callbacks; JSCheckAccessOp checkAccess; JSErrorReporter older; JSExceptionState *state; jsval callerid, v; JSStackFrame *fp, *fpstop; size_t stackDepth, valueCount, size; JSBool overflow; JSExnPrivate *priv; JSStackTraceElem *elem; jsval *values; JS_ASSERT(OBJ_GET_CLASS(cx, exnObject) == &js_ErrorClass); /* * Prepare stack trace data. * * Set aside any error reporter for cx and save its exception state * so we can suppress any checkAccess failures. Such failures should stop * the backtrace procedure, not result in a failure of this constructor. */ callbacks = JS_GetSecurityCallbacks(cx); checkAccess = callbacks ? callbacks->checkObjectAccess : NULL; older = JS_SetErrorReporter(cx, NULL); state = JS_SaveExceptionState(cx); callerid = ATOM_KEY(cx->runtime->atomState.callerAtom); stackDepth = 0; valueCount = 0; for (fp = js_GetTopStackFrame(cx); fp; fp = fp->down) { if (fp->fun && fp->argv) { v = JSVAL_NULL; if (checkAccess && !checkAccess(cx, fp->callee(), callerid, JSACC_READ, &v)) { break; } valueCount += fp->argc; } ++stackDepth; } JS_RestoreExceptionState(cx, state); JS_SetErrorReporter(cx, older); fpstop = fp; size = offsetof(JSExnPrivate, stackElems); overflow = (stackDepth > ((size_t)-1 - size) / sizeof(JSStackTraceElem)); size += stackDepth * sizeof(JSStackTraceElem); overflow |= (valueCount > ((size_t)-1 - size) / sizeof(jsval)); size += valueCount * sizeof(jsval); if (overflow) { js_ReportAllocationOverflow(cx); return JS_FALSE; } priv = (JSExnPrivate *)cx->malloc(size); if (!priv) return JS_FALSE; /* * We initialize errorReport with a copy of report after setting the * private slot, to prevent GC accessing a junk value we clear the field * here. */ priv->errorReport = NULL; priv->message = message; priv->filename = filename; priv->lineno = lineno; priv->stackDepth = stackDepth; values = GetStackTraceValueBuffer(priv); elem = priv->stackElems; for (fp = js_GetTopStackFrame(cx); fp != fpstop; fp = fp->down) { if (!fp->fun) { elem->funName = NULL; elem->argc = 0; } else { elem->funName = fp->fun->atom ? ATOM_TO_STRING(fp->fun->atom) : cx->runtime->emptyString; elem->argc = fp->argc; memcpy(values, fp->argv, fp->argc * sizeof(jsval)); values += fp->argc; } elem->ulineno = 0; elem->filename = NULL; if (fp->script) { elem->filename = fp->script->filename; if (fp->regs) elem->ulineno = js_FramePCToLineNumber(cx, fp); } ++elem; } JS_ASSERT(priv->stackElems + stackDepth == elem); JS_ASSERT(GetStackTraceValueBuffer(priv) + valueCount == values); exnObject->setPrivate(priv); if (report) { /* * Construct a new copy of the error report struct. We can't use the * error report struct that was passed in, because it's allocated on * the stack, and also because it may point to transient data in the * JSTokenStream. */ priv->errorReport = CopyErrorReport(cx, report); if (!priv->errorReport) { /* The finalizer realeases priv since it is in the private slot. */ return JS_FALSE; } } return JS_TRUE; }
MozJSImplScope::MozJSImplScope(MozJSScriptEngine* engine) : _engine(engine), _mr(), _runtime(_mr._runtime), _context(_mr._context), _globalProto(_context), _global(_globalProto.getProto()), _funcs(), _pendingKill(false), _opId(0), _opCtx(nullptr), _pendingGC(false), _connectState(ConnectState::Not), _status(Status::OK()), _quickExit(false), _binDataProto(_context), _bsonProto(_context), _countDownLatchProto(_context), _cursorProto(_context), _cursorHandleProto(_context), _dbCollectionProto(_context), _dbPointerProto(_context), _dbQueryProto(_context), _dbProto(_context), _dbRefProto(_context), _jsThreadProto(_context), _maxKeyProto(_context), _minKeyProto(_context), _mongoExternalProto(_context), _mongoHelpersProto(_context), _mongoLocalProto(_context), _nativeFunctionProto(_context), _numberIntProto(_context), _numberLongProto(_context), _numberDecimalProto(_context), _objectProto(_context), _oidProto(_context), _regExpProto(_context), _timestampProto(_context) { kCurrentScope = this; // The default is quite low and doesn't seem to directly correlate with // malloc'd bytes. Set it to MAX_INT here and catching things in the // jscustomallocator.cpp JS_SetGCParameter(_runtime, JSGC_MAX_BYTES, 0xffffffff); JS_SetInterruptCallback(_runtime, _interruptCallback); JS_SetGCCallback(_runtime, _gcCallback, this); JS_SetContextPrivate(_context, this); JSAutoRequest ar(_context); JS_SetErrorReporter(_runtime, _reportError); JSAutoCompartment ac(_context, _global); _checkErrorState(JS_InitStandardClasses(_context, _global)); installBSONTypes(); execSetup(JSFiles::assert); execSetup(JSFiles::types); // install process-specific utilities in the global scope (dependancy: types.js, assert.js) if (_engine->getScopeInitCallback()) _engine->getScopeInitCallback()(*this); // install global utility functions installGlobalUtils(*this); _mongoHelpersProto.install(_global); }
/* Converts perl values to equivalent JS values */ JSBool PJS_ReflectPerl2JS( pTHX_ JSContext *cx, JSObject *pobj, SV *ref, jsval *rval ) { PJS_Context *pcx = PJS_GET_CONTEXT(cx); JSObject *newobj = NULL; if(++pcx->svconv % 2000 == 0) { JSErrorReporter older; ENTER; SAVETMPS; /* Scope for finalizers */ older = JS_SetErrorReporter(cx, NULL); if(pcx->svconv > 10000) { JS_GC(cx); pcx->svconv = 0; } else JS_MaybeGC(cx); JS_SetErrorReporter(cx, older); FREETMPS; LEAVE; } if(SvROK(ref)) { MAGIC *mg; /* First check old jsvisitors */ if((newobj = PJS_IsPerlVisitor(aTHX_ pcx, SvRV(ref)))) { PJS_DEBUG("Old jsvisitor returns\n"); *rval = OBJECT_TO_JSVAL(newobj); return JS_TRUE; } if(SvMAGICAL(SvRV(ref)) && (mg = mg_find(SvRV(ref), PERL_MAGIC_tied)) && mg->mg_obj && sv_derived_from(mg->mg_obj, PJS_BOXED_PACKAGE)) { PJS_DEBUG1("A magical ref %s, shortcircuit!\n", SvPV_nolen((SV*)mg->mg_obj)); ref = mg->mg_obj; } if(sv_derived_from(ref, PJS_BOXED_PACKAGE)) { SV **fref = av_fetch((AV *)SvRV(SvRV(ref)), 2, 0); assert(sv_derived_from(*fref, PJS_RAW_JSVAL)); *rval = (jsval)SvIV(SvRV(*fref)); return JS_TRUE; } if(sv_derived_from(ref, PJS_BOOLEAN)) { *rval = SvTRUE(SvRV(ref)) ? JSVAL_TRUE : JSVAL_FALSE; return JS_TRUE; } if(sv_isobject(ref)) { newobj = PJS_NewPerlObject(aTHX_ cx, pobj, ref); if(newobj) { *rval = OBJECT_TO_JSVAL(newobj); return JS_TRUE; } return JS_FALSE; } } SvGETMAGIC(ref); if(!SvOK(ref)) /* undef */ *rval = JSVAL_VOID; else if(SvIOK(ref) || SvIOKp(ref)) { if(SvIV(ref) <= JSVAL_INT_MAX) *rval = INT_TO_JSVAL(SvIV(ref)); else JS_NewDoubleValue(cx, (double) SvIV(ref), rval); } else if(SvNOK(ref)) JS_NewDoubleValue(cx, SvNV(ref), rval); else if(SvPOK(ref) || SvPOKp(ref)) { STRLEN len; char *str; SV *temp=NULL; if(SvREADONLY(ref)) { temp = newSVsv(ref); str = PJS_SvPV(temp, len); } else str = PJS_SvPV(ref, len); JSString *jstr = ((int)len >= 0) ? JS_NewStringCopyN(cx, str, len) : JS_NewUCStringCopyN(cx, (jschar *)str, -(int)len); sv_free(temp); if(!jstr) return JS_FALSE; *rval = STRING_TO_JSVAL(jstr); } else if(SvROK(ref)) { /* Plain reference */ I32 type = SvTYPE(SvRV(ref)); if(type == SVt_PVHV) newobj = PJS_NewPerlHash(aTHX_ cx, pobj, ref); else if(type == SVt_PVAV) newobj = PJS_NewPerlArray(aTHX_ cx, pobj, ref); else if(type == SVt_PVCV) newobj = PJS_NewPerlSub(aTHX_ cx, pobj, ref); else newobj = PJS_NewPerlScalar(aTHX_ cx, pobj, ref); if(!newobj) return JS_FALSE; *rval = OBJECT_TO_JSVAL(newobj); } else { warn("I have no idea what perl send us (it's of type %i), I'll pretend it's undef", SvTYPE(ref)); *rval = JSVAL_VOID; } return JS_TRUE; }