// todo: similar code is also in ejsnet.cpp JSBool newStreamObject(JSContext* cx, JSObject* obj, std::streambuf* stream, jsval* rval) { // todo: this is quite ugly // create javascript Stream object and set stream pointer // the difficulty is that we do not have any native reference // => we must use the interpreter to indirectly create a native Stream // wrapper object and set the private data accordingly // this is only safe if we know that the created javascript object // is of the correct class (stream_class) otherwise this would be dangerous jsval streamval; if (!ejs_evalExpression(cx,obj,"new (ejs.ModuleLoader.get(\"Stream\").Stream)()",&streamval)) return JS_FALSE; // todo: is this enough to root this object? *rval=streamval; if (!JSVAL_IS_OBJECT(streamval)) EJS_THROW_ERROR(cx,obj,"failed to create Stream object"); JSObject* jsstream=JSVAL_TO_OBJECT(streamval); // make sure this object has a private slot and it is NULL JSClass* oclass; if ((!(oclass=JS_GET_CLASS(cx,jsstream))) || (!(oclass->flags & JSCLASS_HAS_PRIVATE)) || (JS_GetPrivate(cx,jsstream)) || (std::string("Stream")!=oclass->name)) EJS_THROW_ERROR(cx,obj,"you have messed with the Stream object"); if (!JS_SetPrivate(cx,jsstream,(void *)stream)) return JS_FALSE; // tell the stream object wether to delete this streambuf JS_SetReservedSlot(cx,jsstream,0,JSVAL_TRUE); return JS_TRUE; }
int JavaObject::getObjectId(JSContext* ctx, JSObject* obj) { jsval val; const JSClass* jsClass = JS_GET_CLASS(ctx, obj); if (jsClass != &JavaObjectClass) { Debug::log(Debug::Error) << "JavaObject::getObjectId called on non-JavaObject: " << jsClass->name << Debug::flush; return -1; } if (JSCLASS_RESERVED_SLOTS(jsClass) < 1) { Debug::log(Debug::Error) << "JavaObject::getObjectId -- " << static_cast<void*>(obj) << " has only " << (JSCLASS_RESERVED_SLOTS(jsClass)) << " reserved slots, no objectId present" << Debug::flush; return -1; } #if GECKO_VERSION >= 13000 val = JS_GetReservedSlot(obj, 0); #else if (!JS_GetReservedSlot(ctx, obj, 0, &val)) { Debug::log(Debug::Error) << "Error getting reserved slot" << Debug::flush; return -1; } #endif // TODO: assert JSVAL_IS_INT(val) return JSVAL_TO_INT(val); }
static void js_json_emit_jsval(JSContext *cx, jsval value, htsbuf_queue_t *out) { char buf[100]; if(JSVAL_IS_BOOLEAN(value)) { if(JSVAL_TO_BOOLEAN(value)) htsbuf_append(out, "true", 4); else htsbuf_append(out, "false", 5); } else if(JSVAL_IS_INT(value)) { snprintf(buf, sizeof(buf), "%d", JSVAL_TO_INT(value)); htsbuf_append(out, buf, strlen(buf)); } else if(JSVAL_IS_DOUBLE(value)) { double dbl; if(JS_ValueToNumber(cx, value, &dbl) && !my_double2str(buf, sizeof(buf), dbl)) htsbuf_append(out, buf, strlen(buf)); else htsbuf_append(out, "null", 4); } else if(JSVAL_IS_NULL(value)) { htsbuf_append(out, "null", 4); } else if(JSVAL_IS_STRING(value)) { js_json_emit_str(cx, value, out); } else if(JSVAL_IS_OBJECT(value)) { JSObject *obj = JSVAL_TO_OBJECT(value); JSClass *c = JS_GET_CLASS(cx, obj); if(!strcmp(c->name, "XML")) // Treat some classes special js_json_emit_str(cx, value, out); else { if(js_json_encode_from_object(cx, obj, out)) htsbuf_append(out, "null", 4); } } }
JSObject* gjs_construct_object_dynamic(JSContext *context, JSObject *proto, uintN argc, jsval *argv) { RuntimeData *rd; JSClass *proto_class; JSContext *load_context; JSObject *result; JS_BeginRequest(context); /* We replace the passed-in context and global object with our * runtime-global permanent load context. Otherwise, JS_ConstructObject * can't find the constructor in whatever random global object is set * on the passed-in context. */ load_context = gjs_runtime_get_load_context(JS_GetRuntime(context)); JS_BeginRequest(load_context); proto_class = JS_GET_CLASS(load_context, proto); rd = get_data_from_context(load_context); /* Check that it's safe to cast to DynamicJSClass */ if (g_hash_table_lookup(rd->dynamic_classes, proto_class) == NULL) { gjs_throw(load_context, "Prototype is not for a dynamically-registered class"); goto error; } gjs_debug_lifecycle(GJS_DEBUG_GREPO, "Constructing instance of dynamic class %s %p from proto %p", proto_class->name, proto_class, proto); if (argc > 0) result = JS_ConstructObjectWithArguments(load_context, proto_class, proto, NULL, argc, argv); else result = JS_ConstructObject(load_context, proto_class, proto, NULL); if (!result) goto error; JS_EndRequest(load_context); JS_EndRequest(context); return result; error: /* Move the exception to the calling context from load context. */ if (!gjs_move_exception(load_context, context)) { /* set an exception since none was set */ gjs_throw(context, "No exception was set, but object construction failed somehow"); } JS_EndRequest(load_context); JS_EndRequest(context); return NULL; }
JSObject* gjs_boxed_from_c_struct(JSContext *context, GIStructInfo *info, void *gboxed, GjsBoxedCreationFlags flags) { JSObject *obj; JSObject *proto; Boxed *priv; Boxed *proto_priv; if (gboxed == NULL) return NULL; gjs_debug_marshal(GJS_DEBUG_GBOXED, "Wrapping struct %s %p with JSObject", g_base_info_get_name((GIBaseInfo *)info), gboxed); proto = gjs_lookup_boxed_prototype(context, info); proto_priv = priv_from_js(context, proto); obj = JS_NewObjectWithGivenProto(context, JS_GET_CLASS(context, proto), proto, gjs_get_import_global (context)); GJS_INC_COUNTER(boxed); priv = g_slice_new0(Boxed); *priv = *proto_priv; g_base_info_ref( (GIBaseInfo*) priv->info); JS_SetPrivate(context, obj, priv); if ((flags & GJS_BOXED_CREATION_NO_COPY) != 0) { /* we need to create a JS Boxed which references the * original C struct, not a copy of it. Used for * G_SIGNAL_TYPE_STATIC_SCOPE */ priv->gboxed = gboxed; priv->not_owning_gboxed = TRUE; } else { if (priv->gtype != G_TYPE_NONE && g_type_is_a (priv->gtype, G_TYPE_BOXED)) { priv->gboxed = g_boxed_copy(priv->gtype, gboxed); } else if (priv->gtype == G_TYPE_VARIANT) { priv->gboxed = g_variant_ref_sink (gboxed); } else if (priv->can_allocate_directly) { boxed_new_direct(priv); memcpy(priv->gboxed, gboxed, g_struct_info_get_size (priv->info)); } else { gjs_throw(context, "Can't create a Javascript object for %s; no way to copy", g_base_info_get_name( (GIBaseInfo*) priv->info)); } } return obj; }
bool IsFunctionTemplate(Handle<Value> v) { if (v.IsEmpty()) return false; Handle<Object> o = v->ToObject(); if (o.IsEmpty()) return false; JSObject *obj = **o; return &gFunctionTemplateClass == JS_GET_CLASS(cx(), obj); }
static JSBool get_nested_interface_object (JSContext *context, JSObject *parent_obj, Boxed *parent_priv, GIFieldInfo *field_info, GITypeInfo *type_info, GIBaseInfo *interface_info, jsval *value) { JSObject *obj; JSObject *proto; int offset; Boxed *priv; Boxed *proto_priv; if (!struct_is_simple ((GIStructInfo *)interface_info)) { gjs_throw(context, "Reading field %s.%s is not supported", g_base_info_get_name ((GIBaseInfo *)parent_priv->info), g_base_info_get_name ((GIBaseInfo *)field_info)); return JS_FALSE; } proto = gjs_lookup_boxed_prototype(context, (GIBoxedInfo*) interface_info); proto_priv = priv_from_js(context, proto); offset = g_field_info_get_offset (field_info); obj = JS_NewObjectWithGivenProto(context, JS_GET_CLASS(context, proto), proto, gjs_get_import_global (context)); if (obj == NULL) return JS_FALSE; GJS_INC_COUNTER(boxed); priv = g_slice_new0(Boxed); JS_SetPrivate(context, obj, priv); priv->info = (GIBoxedInfo*) interface_info; g_base_info_ref( (GIBaseInfo*) priv->info); priv->gtype = g_registered_type_info_get_g_type ((GIRegisteredTypeInfo*) interface_info); priv->can_allocate_directly = proto_priv->can_allocate_directly; /* A structure nested inside a parent object; doesn't have an independent allocation */ priv->gboxed = ((char *)parent_priv->gboxed) + offset; priv->not_owning_gboxed = TRUE; /* We never actually read the reserved slot, but we put the parent object * into it to hold onto the parent object. */ JS_SetReservedSlot(context, obj, 0, OBJECT_TO_JSVAL (parent_obj)); *value = OBJECT_TO_JSVAL(obj); return JS_TRUE; }
JSClass* gjs_lookup_boxed_class(JSContext *context, GIBoxedInfo *info) { JSObject *prototype; prototype = gjs_lookup_boxed_prototype(context, info); return JS_GET_CLASS(context, prototype); }
bool js_value_is_proxy(JohnsonRuntime* MAYBE_UNUSED(runtime), jsval maybe_proxy) { JSClass* klass = JS_GET_CLASS( johnson_get_current_context(runtime), JSVAL_TO_OBJECT(maybe_proxy)); return &JSLandProxyClass == klass || &JSLandClassProxyClass == klass || &JSLandCallableProxyClass == klass; }
JSClass* gjs_lookup_error_class(JSContext *context, GIEnumInfo *info) { JSObject *prototype; prototype = gjs_lookup_error_prototype(context, info); return JS_GET_CLASS(context, prototype); }
static JSBool enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op, jsval *statep, jsid *idp) { JSObject *iterator; switch (enum_op) { case JSENUMERATE_INIT: if (resolverHasMethod(cx, obj, "enumerate")) { if (!delegateToResolver(cx, obj, "enumerate", 0, NULL, statep)) return JS_FALSE; if (!JSVAL_IS_OBJECT(*statep)) { JS_ReportError(cx, "Expected enumerate() to return an iterator."); return JS_FALSE; } *idp = JSVAL_ZERO; JS_AddRoot(cx, statep); return JS_TRUE; } // TODO: Default behavior? JS_ReportError(cx, "Enumeration is not implemented on this object."); return JS_FALSE; case JSENUMERATE_NEXT: jsval rval; iterator = JSVAL_TO_OBJECT(*statep); if (!JS_CallFunctionName(cx, iterator, "next", 0, NULL, &rval)) { if (JS_IsExceptionPending(cx)) { jsval exception; if (!JS_GetPendingException(cx, &exception)) return JS_FALSE; if (!JSVAL_IS_OBJECT(exception)) return JS_FALSE; JSClass *clasp = JS_GET_CLASS(cx, JSVAL_TO_OBJECT(exception)); if (clasp && JSCLASS_CACHED_PROTO_KEY(clasp) == JSProto_StopIteration) { JS_ClearPendingException(cx); *statep = JSVAL_NULL; JS_RemoveRoot(cx, statep); return JS_TRUE; } } return JS_FALSE; } if (!JS_ValueToId(cx, rval, idp)) return JS_FALSE; return JS_TRUE; case JSENUMERATE_DESTROY: JS_RemoveRoot(cx, statep); return JS_TRUE; default: JS_ReportError(cx, "Unknown enum_op"); return JS_FALSE; } }
void FFSessionHandler::getStringObjectClass(JSContext* ctx) { jsval str = JS_GetEmptyStringValue(ctx); JSObject* obj = 0; if (!JS_ValueToObject(ctx, str, &obj)) { return; } if (!obj) { return; } stringObjectClass = JS_GET_CLASS(ctx, obj); }
VALUE unwrap_js_land_proxy(JohnsonRuntime* runtime, jsval proxy) { VALUE value; JSObject *proxy_object = JSVAL_TO_OBJECT(proxy); JSContext * context = johnson_get_current_context(runtime); value = (VALUE)JS_GetInstancePrivate(context, proxy_object, JS_GET_CLASS(context, proxy_object), NULL); return value; }
JSObject* gjs_error_from_gerror(JSContext *context, GError *gerror, gboolean add_stack) { JSObject *obj; JSObject *proto; Error *priv; Error *proto_priv; GIEnumInfo *info; if (gerror == NULL) return NULL; info = find_error_domain_info(gerror->domain); if (!info) { /* We don't have error domain metadata */ /* Marshal the error as a plain GError */ GIBaseInfo *glib_boxed; JSObject *retval; glib_boxed = g_irepository_find_by_name(NULL, "GLib", "Error"); retval = gjs_boxed_from_c_struct(context, glib_boxed, gerror, 0); g_base_info_unref(glib_boxed); return retval; } gjs_debug_marshal(GJS_DEBUG_GBOXED, "Wrapping struct %s %p with JSObject", g_base_info_get_name((GIBaseInfo *)info), gboxed); proto = gjs_lookup_error_prototype(context, info); proto_priv = priv_from_js(context, proto); obj = JS_NewObjectWithGivenProto(context, JS_GET_CLASS(context, proto), proto, gjs_get_import_global (context)); GJS_INC_COUNTER(gerror); priv = g_slice_new0(Error); JS_SetPrivate(context, obj, priv); priv->info = info; priv->domain = proto_priv->domain; g_base_info_ref( (GIBaseInfo*) priv->info); priv->gerror = g_error_copy(gerror); if (add_stack) define_error_properties(context, obj); return obj; }
void ClearPrivateSlot(JSContext* aCx, JSObject* aObj, bool aSaveEventHandlers) { JSClass* clasp = JS_GET_CLASS(aCx, aObj); JS_ASSERT(clasp == Worker::Class() || clasp == ChromeWorker::Class()); if (clasp == ChromeWorker::Class()) { ChromeWorker::ClearPrivateSlot(aCx, aObj, aSaveEventHandlers); } else { Worker::ClearPrivateSlot(aCx, aObj, aSaveEventHandlers); } }
/* * "Steal" calls to netscape.security.PrivilegeManager.enablePrivilege, * et. al. so that code that worked with 4.0 can still work. */ NS_IMETHODIMP nsSecurityNameSet::InitializeNameSet(nsIScriptContext* aScriptContext) { JSContext *cx = (JSContext *) aScriptContext->GetNativeContext(); JSObject *global = JS_GetGlobalObject(cx); /* * Find Object.prototype's class by walking up the global object's * prototype chain. */ JSObject *obj = global; JSObject *proto; JSAutoRequest ar(cx); while ((proto = JS_GetPrototype(cx, obj)) != nsnull) obj = proto; JSClass *objectClass = JS_GET_CLASS(cx, obj); jsval v; if (!JS_GetProperty(cx, global, "netscape", &v)) return NS_ERROR_FAILURE; JSObject *securityObj; if (JSVAL_IS_OBJECT(v)) { /* * "netscape" property of window object exists; get the * "security" property. */ obj = JSVAL_TO_OBJECT(v); if (!JS_GetProperty(cx, obj, "security", &v) || !JSVAL_IS_OBJECT(v)) return NS_ERROR_FAILURE; securityObj = JSVAL_TO_OBJECT(v); } else { /* define netscape.security object */ obj = JS_DefineObject(cx, global, "netscape", objectClass, nsnull, 0); if (obj == nsnull) return NS_ERROR_FAILURE; securityObj = JS_DefineObject(cx, obj, "security", objectClass, nsnull, 0); if (securityObj == nsnull) return NS_ERROR_FAILURE; } /* Define PrivilegeManager object with the necessary "static" methods. */ obj = JS_DefineObject(cx, securityObj, "PrivilegeManager", objectClass, nsnull, 0); if (obj == nsnull) return NS_ERROR_FAILURE; return JS_DefineFunctions(cx, obj, PrivilegeManager_static_methods) ? NS_OK : NS_ERROR_FAILURE; }
static JSBool to_array(JSContext* js_context, JSObject* obj, uintN UNUSED(argc), jsval* UNUSED(argv), jsval* retval) { VALUE ruby_context = (VALUE)JS_GetContextPrivate(js_context); JohnsonContext* context; JohnsonRuntime* runtime; Data_Get_Struct(ruby_context, JohnsonContext, context); VALUE ruby_runtime = (VALUE)JS_GetRuntimePrivate(JS_GetRuntime(js_context)); Data_Get_Struct(ruby_runtime, JohnsonRuntime, runtime); PREPARE_JROOTS(js_context, 0); VALUE self = (VALUE)JS_GetInstancePrivate(context->js, obj, JS_GET_CLASS(context->js, obj), NULL); JCHECK(call_ruby_from_js(runtime, retval, self, rb_intern("to_a"), 0)); JRETURN; }
/* * Log a given jsval with a prefix. * cx - JSContext for the JS execution context to use * val - jsval to print * prefix - string to print before the value, defaults to empty string * * TODO(jat): this whole printf-style logging needs to be replaced, but we * run into library version issues if we use C++ iostreams so we would need * to implement our own equivalent. Given that this code is all likely to * be rewritten for out-of-process hosted mode, it seems unlikely to be worth * the effort until that is completed. */ void PrintJSValue(JSContext* cx, jsval val, char* prefix="") { JSType type = JS_TypeOfValue(cx, val); const char* typeString=JS_GetTypeName(cx, type); static const int BUF_SIZE = 256; char buf[BUF_SIZE]; const char *bufEnd = buf + BUF_SIZE; char* p = buf; p += append_sprintf(p, bufEnd, "%s%s", prefix, typeString); switch(type) { case JSTYPE_VOID: break; case JSTYPE_BOOLEAN: p += append_sprintf(p, bufEnd, ": %s", JSVAL_TO_BOOLEAN(val) ? "true" : "false"); break; case JSTYPE_NUMBER: if (JSVAL_IS_INT(val)) { p += append_sprintf(p, bufEnd, ": %d", JSVAL_TO_INT(val)); } else { p += append_sprintf(p, bufEnd, ": %lf", (double)*JSVAL_TO_DOUBLE(val)); } break; case JSTYPE_OBJECT: { JSObject* obj = JSVAL_TO_OBJECT(val); if (!JSVAL_IS_OBJECT(val)) break; JSClass* clazz = obj ? JS_GET_CLASS(cx, obj) : 0; p += append_sprintf(p, bufEnd, " @ %08x, class %s", (unsigned)obj, clazz ? clazz->name : "<null>"); break; } case JSTYPE_FUNCTION: case JSTYPE_LIMIT: break; case JSTYPE_STRING: { /* * TODO(jat): support JS strings with international characters */ JsStringWrap str(cx, JSVAL_TO_STRING(val)); p += append_sprintf(p, bufEnd, ": %.*s", str.length(), str.bytes()); break; } } Tracer::log("%s", buf); }
void* gjs_get_instance_private_dynamic(JSContext *context, JSObject *obj, JSClass *static_clasp, jsval *argv) { RuntimeData *rd; JSClass *obj_class; void *instance; if (static_clasp->name != NULL) { g_warning("Dynamic class should not have a name in the JSClass struct"); return NULL; } JS_BeginRequest(context); obj_class = JS_GET_CLASS(context, obj); g_assert(obj_class != NULL); rd = get_data_from_context(context); g_assert(rd != NULL); /* Check that it's safe to cast to DynamicJSClass */ if (g_hash_table_lookup(rd->dynamic_classes, obj_class) == NULL) { gjs_throw(context, "Object %p proto %p doesn't have a dynamically-registered class, it has %s", obj, JS_GetPrototype(context, obj), obj_class->name); JS_EndRequest(context); return NULL; } if (static_clasp != ((DynamicJSClass*) obj_class)->static_class) { gjs_throw(context, "Object is not a dynamically-registered class based on expected static class pointer"); JS_EndRequest(context); return NULL; } instance = JS_GetInstancePrivate(context, obj, obj_class, argv); JS_EndRequest(context); return instance; }
static void node_finalize(JSContext* cx, JSObject* obj) { assert(JS_GET_CLASS(cx, obj) == &node_class); dom::Node* node=(dom::Node *)JS_GetPrivate(cx,obj); if (!node) return; // reverse lookup in wrappers (could be improved by bimap) Wrappers::iterator it=wrappers.begin(); while (it!=wrappers.end()) { if (it->second == obj) { wrappers.erase(it); return; } ++it; } EJS_INFO("not in map"); }
static void passport_finalize( JSContext *cx, JSObject *passport ) { dTHX; SV *box = (SV *)JS_GetPrivate(cx, passport); if(box && SvOK(box) && SvROK(box)) { AV *avbox = (AV *)SvRV(box); #ifdef PJSDEBUG JSObject *parent = JS_GetParent(cx, passport); #endif PJS_DEBUG3("About to free a %s rc:%d,%d\n", JS_GET_CLASS(cx, parent)->name, SvREFCNT(box), SvREFCNT(avbox)); if(PL_dirty) return; av_store(avbox, 0, &PL_sv_undef); sv_free(box); } else croak("PJS_Assert: Bad finalize for passport\n"); /* Assertion */ }
static bool respond_to_p(JSContext* js_context, JSObject* obj, char* name) { VALUE ruby_context = (VALUE)JS_GetContextPrivate(js_context); JohnsonContext* context; Data_Get_Struct(ruby_context, JohnsonContext, context); VALUE self = (VALUE)JS_GetInstancePrivate( context->js, obj, JS_GET_CLASS(context->js, obj), NULL); if (!self) return false; return autovivified_p(ruby_context, self, name) || const_p(self, name) || global_p(name) || attribute_p(self, name) || method_p(self, name) || has_key_p(self, name); }
const char* gjs_value_debug_string(JSContext *context, jsval value) { JSString *str; const char *bytes; JS_BeginRequest(context); str = JS_ValueToString(context, value); if (str == NULL) { if (JSVAL_IS_OBJECT(value)) { /* Specifically the Call object (see jsfun.c in spidermonkey) * does not have a toString; there may be others also. */ JSClass *klass; klass = JS_GET_CLASS(context, JSVAL_TO_OBJECT(value)); if (klass != NULL) { str = JS_NewStringCopyZ(context, klass->name); JS_ClearPendingException(context); if (str == NULL) { return "[out of memory copying class name]"; } } else { gjs_log_exception(context, NULL); return "[unknown object]"; } } else { return "[unknown non-object]"; } } g_assert(str != NULL); bytes = JS_GetStringBytes(str); JS_EndRequest(context); return bytes; }
static gpsee_realm_t *getRealm(JSContext *cx) { JSObject *global = JS_GetGlobalObject(cx); gpsee_runtime_t *grt; gpsee_realm_t *realm = NULL; if ((realm = gpsee_getModuleScopeRealm(cx, NULL))) return realm; grt = JS_GetRuntimePrivate(JS_GetRuntime(cx)); gpsee_enterAutoMonitor(cx, &grt->monitors.realms); if (grt && grt->realmsByContext) realm = gpsee_ds_get(grt->realmsByContext, cx); gpsee_leaveAutoMonitor(grt->monitors.realms); if (global && JS_GET_CLASS(cx, global) == gpsee_getGlobalClass()) GPSEE_ASSERT(realm); return realm; }
static JSBool resolverHasMethod(JSContext *cx, JSObject *obj, const char *name) { // If we're the prototype of some other object, then obj won't be of // the JSClass we need it to be, so just deny that our membrane has // the method we're looking for. JSClass *klass = JS_GET_CLASS(cx, obj); if (klass != &sFlexibleWrapper_JSClass.base) return JS_FALSE; jsval resolver; if (!JS_GetReservedSlot(cx, obj, SLOT_RESOLVER, &resolver)) return JS_FALSE; JSObject *resolverObj = JSVAL_TO_OBJECT(resolver); JSBool hasProperty; if (!JS_HasProperty(cx, resolverObj, name, &hasProperty)) return JS_FALSE; return hasProperty; // TODO: Check to make sure the property is a function? }
void* gjs_get_instance_private_dynamic_with_typecheck(JSContext *context, JSObject *obj, JSClass *static_clasp, jsval *argv) { RuntimeData *rd; JSClass *obj_class; void *instance; if (static_clasp->name != NULL) { g_warning("Dynamic class should not have a name in the JSClass struct"); return NULL; } JS_BeginRequest(context); obj_class = JS_GET_CLASS(context, obj); g_assert(obj_class != NULL); rd = get_data_from_context(context); g_assert(rd != NULL); /* Check that it's safe to cast to DynamicJSClass */ if (g_hash_table_lookup(rd->dynamic_classes, obj_class) == NULL) { JS_EndRequest(context); return NULL; } if (static_clasp != ((DynamicJSClass*) obj_class)->static_class) { JS_EndRequest(context); return NULL; } instance = JS_GetInstancePrivate(context, obj, obj_class, argv); JS_EndRequest(context); return instance; }
static void finalize(JSContext* js_context, JSObject* obj) { VALUE ruby_context = (VALUE)JS_GetContextPrivate(js_context); if (ruby_context) { JohnsonContext* context; JohnsonRuntime* runtime; Data_Get_Struct(ruby_context, JohnsonContext, context); VALUE ruby_runtime = (VALUE)JS_GetRuntimePrivate(JS_GetRuntime(js_context)); Data_Get_Struct(ruby_runtime, JohnsonRuntime, runtime); VALUE self = (VALUE)JS_GetInstancePrivate(context->js, obj, JS_GET_CLASS(context->js, obj), NULL); // remove the proxy OID from the id map JS_HashTableRemove(runtime->rbids, (void *)self); // free up the ruby value for GC rb_funcall(ruby_runtime, rb_intern("remove_gcthing"), 1, rb_obj_id(self)); } }
static JSBool constructHook(JSContext *cx, uintN argc, jsval *vp) { // Check that arguments were passed properly from JS_New. JSObject *callee = JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)); JSObject *obj = JS_NewObjectForConstructor(cx, vp); if (!obj) { JS_ReportError(cx, "test failed, could not construct object"); return false; } if (strcmp(JS_GET_CLASS(cx, obj)->name, "Object") != 0) { JS_ReportError(cx, "test failed, wrong class for 'this'"); return false; } if (argc != 3) { JS_ReportError(cx, "test failed, argc == %d", argc); return false; } if (!JSVAL_IS_INT(argv[2]) || JSVAL_TO_INT(argv[2]) != 2) { JS_ReportError(cx, "test failed, wrong value in argv[2]"); return false; } if (!JS_IsConstructing(cx, vp)) { JS_ReportError(cx, "test failed, not constructing"); return false; } // Perform a side-effect to indicate that this hook was actually called. if (!JS_SetElement(cx, callee, 0, &argv[0])) return false; *vp = OBJECT_TO_JSVAL(obj); argv[0] = argv[1] = argv[2] = JSVAL_VOID; // trash the argv, perversely return true; }
jsval gjs_date_from_time_t (JSContext *context, time_t time) { JSObject *date; JSClass *date_class; JSObject *date_constructor; jsval date_prototype; jsval args[1]; jsval result; JS_BeginRequest(context); if (!JS_EnterLocalRootScope(context)) return JSVAL_VOID; if (!JS_GetClassObject(context, JS_GetGlobalObject(context), JSProto_Date, &date_constructor)) gjs_fatal("Failed to lookup Date prototype"); if (!JS_GetProperty(context, date_constructor, "prototype", &date_prototype)) gjs_fatal("Failed to get prototype from Date constructor"); date_class = JS_GET_CLASS(context, JSVAL_TO_OBJECT (date_prototype)); if (!JS_NewNumberValue(context, ((double) time) * 1000, &(args[0]))) gjs_fatal("Failed to convert time_t to number"); date = JS_ConstructObjectWithArguments(context, date_class, NULL, NULL, 1, args); result = OBJECT_TO_JSVAL(date); JS_LeaveLocalRootScope(context); JS_EndRequest(context); return result; }
bool Library::IsLibrary(JSContext* cx, JSObject* obj) { return JS_GET_CLASS(cx, obj) == &sLibraryClass; }