static JSDObject* _createJSDObject(JSDContext* jsdc, JSContext *cx, JSObject *obj) { JSDObject* jsdobj; JSStackFrame* fp; JSStackFrame* iter = NULL; const char* newURL; jsbytecode* pc; JS_ASSERT(JSD_OBJECTS_LOCKED(jsdc)); jsdobj = (JSDObject*) calloc(1, sizeof(JSDObject)); if (jsdobj) { JS_INIT_CLIST(&jsdobj->links); JS_APPEND_LINK(&jsdobj->links, &jsdc->objectsList); jsdobj->obj = obj; JS_HashTableAdd(jsdc->objectsTable, obj, jsdobj); if (jsdc->flags & JSD_DISABLE_OBJECT_TRACE) return jsdobj; /* walk the stack to find js frame (if any) causing creation */ while (NULL != (fp = JS_FrameIterator(cx, &iter))) { if( !JS_IsNativeFrame(cx, fp) ) { JSScript* script = JS_GetFrameScript(cx, fp); if( !script ) continue; newURL = JS_GetScriptFilename(cx, script); if( newURL ) jsdobj->newURL = jsd_AddAtom(jsdc, newURL); pc = JS_GetFramePC(cx, fp); if( pc ) jsdobj->newLineno = JS_PCToLineNumber(cx, script, pc); break; } } } return jsdobj; }
static JSDObject* _createJSDObject(JSDContext* jsdc, JSContext *cx, JSObject *obj) { JSDObject* jsdobj; JSStackFrame* fp; JSStackFrame* iter = NULL; const char* newURL; jsbytecode* pc; JS_ASSERT(JSD_OBJECTS_LOCKED(jsdc)); jsdobj = (JSDObject*) calloc(1, sizeof(JSDObject)); if (jsdobj) { JS_INIT_CLIST(&jsdobj->links); JS_APPEND_LINK(&jsdobj->links, &jsdc->objectsList); jsdobj->obj = obj; JS_HashTableAdd(jsdc->objectsTable, obj, jsdobj); } return jsdobj; }
VALUE make_ruby_land_proxy(JohnsonRuntime* runtime, jsval value, const char const* root_name) { RubyLandProxy * our_proxy = (RubyLandProxy *)JS_HashTableLookup(runtime->jsids, (void *)value); if (our_proxy) { // if we already have a proxy, return it return apply_conversions(our_proxy->self); } else { // otherwise make one and cache it VALUE proxy = Data_Make_Struct((strncmp(root_name, "JSScriptProxy", strlen("JSScriptProxy")) ? proxy_class : script_class), RubyLandProxy, 0, finalize, our_proxy); JSContext * context = johnson_get_current_context(runtime); PREPARE_RUBY_JROOTS(context, 1); JROOT(value); VALUE rb_runtime = (VALUE)JS_GetRuntimePrivate(runtime->js); rb_iv_set(proxy, "@runtime", rb_runtime); our_proxy->runtime = runtime; our_proxy->key = (void *)value; our_proxy->self = proxy; // root the value for JS GC and lookups JCHECK(JS_AddNamedRootRT(runtime->js, &(our_proxy->key), root_name)); // put the proxy OID in the id map JCHECK(JS_HashTableAdd(runtime->jsids, (void *)value, (void *)our_proxy)); VALUE final_proxy = JPROTECT(apply_wrappers, proxy); our_proxy->self = final_proxy; JRETURN_RUBY(JPROTECT(apply_conversions, final_proxy)); } }
JSDAtom* jsd_AddAtom(JSDContext* jsdc, const char* str) { JSDAtom* atom; if(!str) { MOZ_ASSERT(0); return nullptr; } JSD_LOCK_ATOMS(jsdc); atom = (JSDAtom*) JS_HashTableLookup(jsdc->atoms, str); if( atom ) atom->refcount++; else { atom = (JSDAtom*) malloc(sizeof(JSDAtom)); if( atom ) { atom->str = strdup(str); atom->refcount = 1; if(!JS_HashTableAdd(jsdc->atoms, atom->str, atom)) { free(atom->str); free(atom); atom = nullptr; } } } JSD_UNLOCK_ATOMS(jsdc); return atom; }
static JSDScript* _newJSDScript(JSDContext* jsdc, JSContext *cx, JSScript *script_) { JS::RootedScript script(cx, script_); if ( JS_GetScriptIsSelfHosted(script) ) return NULL; JSDScript* jsdscript; unsigned lineno; const char* raw_filename; JS_ASSERT(JSD_SCRIPTS_LOCKED(jsdc)); /* these are inlined javascript: urls and we can't handle them now */ lineno = (unsigned) JS_GetScriptBaseLineNumber(cx, script); if( lineno == 0 ) return NULL; jsdscript = (JSDScript*) calloc(1, sizeof(JSDScript)); if( ! jsdscript ) return NULL; raw_filename = JS_GetScriptFilename(cx,script); JS_HashTableAdd(jsdc->scriptsTable, (void *)script, (void *)jsdscript); JS_APPEND_LINK(&jsdscript->links, &jsdc->scripts); jsdscript->jsdc = jsdc; jsdscript->script = script; jsdscript->lineBase = lineno; jsdscript->lineExtent = (unsigned)NOT_SET_YET; jsdscript->data = NULL; #ifndef LIVEWIRE jsdscript->url = (char*) jsd_BuildNormalizedURL(raw_filename); #else jsdscript->app = LWDBG_GetCurrentApp(); if( jsdscript->app && raw_filename ) { jsdscript->url = jsdlw_BuildAppRelativeFilename(jsdscript->app, raw_filename); if( function ) { JSString* funid = JS_GetFunctionId(function); char* funbytes; const char* funnanme; if( fuinid ) { funbytes = JS_EncodeString(cx, funid); funname = funbytes ? funbytes : ""; } else { funbytes = NULL; funname = "anonymous"; } jsdscript->lwscript = LWDBG_GetScriptOfFunction(jsdscript->app,funname); JS_Free(cx, funbytes); /* also, make sure this file is added to filelist if is .js file */ if( HasFileExtention(raw_filename,"js") || HasFileExtention(raw_filename,"sjs") ) { jsdlw_PreLoadSource(jsdc, jsdscript->app, raw_filename, JS_FALSE); } } else { jsdscript->lwscript = LWDBG_GetCurrentTopLevelScript(); } } #endif JS_INIT_CLIST(&jsdscript->hooks); return jsdscript; }
static JSDScript* _newJSDScript(JSDContext* jsdc, JSContext *cx, JSScript *script, JSFunction* function) { JSDScript* jsdscript; uintN lineno; const char* raw_filename; JS_ASSERT(JSD_SCRIPTS_LOCKED(jsdc)); /* these are inlined javascript: urls and we can't handle them now */ lineno = (uintN) JS_GetScriptBaseLineNumber(cx, script); if( lineno == 0 ) return NULL; jsdscript = (JSDScript*) calloc(1, sizeof(JSDScript)); if( ! jsdscript ) return NULL; raw_filename = JS_GetScriptFilename(cx,script); JS_HashTableAdd(jsdc->scriptsTable, (void *)script, (void *)jsdscript); JS_APPEND_LINK(&jsdscript->links, &jsdc->scripts); jsdscript->jsdc = jsdc; jsdscript->script = script; jsdscript->function = function; jsdscript->lineBase = lineno; jsdscript->lineExtent = (uintN)NOT_SET_YET; jsdscript->data = NULL; #ifndef LIVEWIRE jsdscript->url = (char*) jsd_BuildNormalizedURL(raw_filename); #else jsdscript->app = LWDBG_GetCurrentApp(); if( jsdscript->app && raw_filename ) { jsdscript->url = jsdlw_BuildAppRelativeFilename(jsdscript->app, raw_filename); if( function ) { jsdscript->lwscript = LWDBG_GetScriptOfFunction(jsdscript->app, JS_GetFunctionName(function)); /* also, make sure this file is added to filelist if is .js file */ if( HasFileExtention(raw_filename,"js") || HasFileExtention(raw_filename,"sjs") ) { jsdlw_PreLoadSource(jsdc, jsdscript->app, raw_filename, JS_FALSE); } } else { jsdscript->lwscript = LWDBG_GetCurrentTopLevelScript(); } } #endif JS_INIT_CLIST(&jsdscript->hooks); return jsdscript; }
JSBool make_js_land_proxy(JohnsonRuntime* runtime, VALUE value, jsval* retval) { jsval base_value = (jsval)JS_HashTableLookup(runtime->rbids, (void *)value); JSContext * context = johnson_get_current_context(runtime); PREPARE_JROOTS(context, 2); jsval johnson = JSVAL_NULL; JCHECK(evaluate_js_property_expression(runtime, "Johnson", &johnson)); JROOT(johnson); if (base_value) { JCHECK(JS_CallFunctionName(context, johnson, "applyConversions", 1, &base_value, retval)); JRETURN; } else { JSObject *jsobj; JSClass *klass = &JSLandProxyClass; if (T_CLASS == TYPE(value)) klass = &JSLandClassProxyClass; // FIXME: hack; should happen in Rubyland if (T_STRUCT == TYPE(value)) rb_funcall(Johnson_SpiderMonkey_JSLandProxy(), rb_intern("treat_all_properties_as_methods"), 1, value); bool callable_p = Qtrue == rb_funcall(value, rb_intern("respond_to?"), 1, rb_str_new2("call")); if (callable_p) klass = &JSLandCallableProxyClass; JCHECK((jsobj = JS_NewObject(context, klass, NULL, NULL))); JROOT(jsobj); JCHECK(JS_SetPrivate(context, jsobj, (void*)value)); JCHECK(JS_DefineFunction(context, jsobj, "__noSuchMethod__", method_missing, 2, 0)); JCHECK(JS_DefineFunction(context, jsobj, "toArray", to_array, 0, 0)); JCHECK(JS_DefineFunction(context, jsobj, "toString", to_string, 0, 0)); base_value = OBJECT_TO_JSVAL(jsobj); // root the ruby value for GC VALUE ruby_runtime = (VALUE)JS_GetRuntimePrivate(runtime->js); rb_funcall(ruby_runtime, rb_intern("add_gcthing"), 1, value); jsval wrapped_value = JSVAL_NULL; JCHECK(JS_CallFunctionName(context, johnson, "applyWrappers", 1, &base_value, &wrapped_value)); // put the proxy OID in the id map JCHECK(JS_HashTableAdd(runtime->rbids, (void *)value, (void *)(wrapped_value))); JCHECK(JS_CallFunctionName(context, johnson, "applyConversions", 1, &wrapped_value, retval)); JRETURN; } }