JSDScript* jsd_FindJSDScript( JSDContext* jsdc, JSScript *script ) { JS_ASSERT(JSD_SCRIPTS_LOCKED(jsdc)); return (JSDScript*) JS_HashTableLookup(jsdc->scriptsTable, (void *)script); }
JSDObject* jsd_GetJSDObjectForJSObject(JSDContext* jsdc, JSObject* jsobj) { JSDObject* jsdobj; JSD_LOCK_OBJECTS(jsdc); jsdobj = (JSDObject*) JS_HashTableLookup(jsdc->objectsTable, jsobj); JSD_UNLOCK_OBJECTS(jsdc); 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; }
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; } }