Example #1
0
JSObject*
gjs_param_from_g_param(JSContext    *context,
                       GParamSpec   *gparam)
{
    JSObject *obj;
    Param *priv;

    if (gparam == NULL)
        return NULL;

    gjs_debug(GJS_DEBUG_GPARAM,
              "Wrapping %s '%s' on %s with JSObject",
              g_type_name(G_TYPE_FROM_INSTANCE((GTypeInstance*) gparam)),
              gparam->name,
              g_type_name(gparam->owner_type));

    JS::RootedObject proto(context, gjs_lookup_param_prototype(context));

    obj = JS_NewObjectWithGivenProto(context, JS_GetClass(proto), proto);

    GJS_INC_COUNTER(param);
    priv = g_slice_new0(Param);
    JS_SetPrivate(obj, priv);
    priv->gparam = gparam;
    g_param_spec_ref (gparam);

    gjs_debug(GJS_DEBUG_GPARAM,
              "JSObject created with param instance %p type %s",
              priv->gparam, g_type_name(G_TYPE_FROM_INSTANCE((GTypeInstance*) priv->gparam)));

    return obj;
}
Example #2
0
/**
 * gjs_cairo_path_from_path:
 * @context: the context
 * @path: cairo_path_t to attach to the object
 *
 * Constructs a pattern wrapper given cairo pattern.
 * NOTE: This function takes ownership of the path.
 */
JSObject *
gjs_cairo_path_from_path(JSContext    *context,
                         cairo_path_t *path)
{
    GjsCairoPath *priv;

    g_return_val_if_fail(context != NULL, NULL);
    g_return_val_if_fail(path != NULL, NULL);

    JS::RootedObject proto(context, gjs_cairo_path_get_proto(context));
    JS::RootedObject object(context,
        JS_NewObjectWithGivenProto(context, &gjs_cairo_path_class, proto));
    if (!object) {
        gjs_throw(context, "failed to create path");
        return NULL;
    }

    priv = g_slice_new0(GjsCairoPath);

    g_assert(priv_from_js(context, object) == NULL);
    JS_SetPrivate(object, priv);

    priv->context = context;
    priv->object = object;
    priv->path = path;

    return object;
}
Example #3
0
JSBool 
js_createStore(JSContext *cx, JSObject *obj, uintN argc, 
	       jsval *argv, jsval *rval)
{
  const char *id;
  char spath[URL_MAX];
  JSBool per_user = 0;

  if(!JS_ConvertArguments(cx, argc, argv, "s/b", &id, &per_user))
    return JS_FALSE;
  js_plugin_t *jsp = JS_GetPrivate(cx, obj);
  snprintf(spath, sizeof(spath), "jsstore/%s-%s", jsp->jsp_id, id);

  js_setting_group_t *jsg = calloc(1, sizeof(js_setting_group_t));
  JSObject *robj;
  jsg->jsg_refcount = 1;
  jsg->jsg_frozen = 1;
  jsg->jsg_spath = strdup(spath);
  jsg->jsg_store = htsmsg_store_load(spath) ?: htsmsg_create_map();

  robj = JS_NewObjectWithGivenProto(cx, &setting_group_class, NULL, obj);
  *rval = OBJECT_TO_JSVAL(robj);
  JS_SetPrivate(cx, robj, jsg);
  jsg->jsg_frozen = 0;
  return JS_TRUE;
}
Example #4
0
JSBool 
js_createService(JSContext *cx, JSObject *obj, uintN argc, 
		 jsval *argv, jsval *rval)
{
  const char *title;
  const char *url;
  const char *type;
  const char *icon = NULL;
  JSObject *robj;
  JSBool enabled;

  if (!JS_ConvertArguments(cx, argc, argv, "sssb/s",
			   &title, &url, &type, &enabled, &icon))
    return JS_FALSE;

  js_plugin_t *jsp = JS_GetPrivate(cx, obj);

  js_service_t *jss = malloc(sizeof(js_service_t));
  jss->jss_ref = 2;
  jss->jss_s = service_create(title, url, type, icon, 0, enabled);
  LIST_INSERT_HEAD(&jsp->jsp_services, jss, jss_link);

  robj = JS_NewObjectWithGivenProto(cx, &service_class, NULL, NULL);
  *rval = OBJECT_TO_JSVAL(robj);

  JS_SetPrivate(cx, robj, jss);

  JS_DefineProperty(cx, robj, "enabled", BOOLEAN_TO_JSVAL(enabled),
		    NULL, setEnabled, JSPROP_PERMANENT);

  JS_DefineFunction(cx, robj, "destroy", destroy, 0, 0);
  return JS_TRUE;
}
JSBool
WrapObject(JSContext *cx, JSObject *parent, jsval v, jsval *vp)
{
  // Slim wrappers don't expect to be wrapped, so morph them to fat wrappers
  // if we're about to wrap one.
  JSObject *innerObj = JSVAL_TO_OBJECT(v);
  if (IS_SLIM_WRAPPER(innerObj) && !MorphSlimWrapper(cx, innerObj)) {
    return ThrowException(NS_ERROR_FAILURE, cx);
  }

  JSObject *wrapperObj =
    JS_NewObjectWithGivenProto(cx, js::Jsvalify(&SOWClass), NULL, parent);
  if (!wrapperObj) {
    return JS_FALSE;
  }

  *vp = OBJECT_TO_JSVAL(wrapperObj);
  js::AutoObjectRooter tvr(cx, wrapperObj);

  if (!JS_SetReservedSlot(cx, wrapperObj, sWrappedObjSlot, v) ||
      !JS_SetReservedSlot(cx, wrapperObj, sFlagsSlot, JSVAL_ZERO)) {
    return JS_FALSE;
  }

  return JS_TRUE;
}
Example #6
0
JSBool wrapObject(JSContext *cx, JSObject *obj, uintN argc,
                  jsval *argv, jsval *rval)
{
  JSObject *wrappee;
  JSObject *resolver;

  if (!JS_ConvertArguments(cx, argc, argv, "oo", &wrappee, &resolver))
    return JS_FALSE;

  JSObject *wrapper = JS_NewObjectWithGivenProto(
    cx,
    &sFlexibleWrapper_JSClass.base,
    NULL,
    wrappee
    );
  if (wrapper == NULL) {
    JS_ReportError(cx, "Creating new wrapper failed.");
    return JS_FALSE;
  }

  if (!JS_SetReservedSlot(cx, wrapper, SLOT_RESOLVER,
                          OBJECT_TO_JSVAL(resolver)) ||
      !JS_SetReservedSlot(cx, wrapper, SLOT_WRAPPEE,
                          OBJECT_TO_JSVAL(wrappee)))
    return JS_FALSE;

  *rval = OBJECT_TO_JSVAL(wrapper);
  return JS_TRUE;
}
JSBool
XPC_COW_WrapObject(JSContext *cx, JSObject *parent, jsval v, jsval *vp)
{
  JSObject *wrapperObj =
    JS_NewObjectWithGivenProto(cx, &sXPC_COW_JSClass.base, NULL, parent);
  if (!wrapperObj) {
    return JS_FALSE;
  }

  *vp = OBJECT_TO_JSVAL(wrapperObj);

  jsval exposedProps = JSVAL_VOID;
  JSAutoTempValueRooter tvr(cx, 1, &exposedProps);

  if (!GetExposedProperties(cx, JSVAL_TO_OBJECT(v), &exposedProps)) {
    return JS_FALSE;
  }

  if (!JS_SetReservedSlot(cx, wrapperObj, XPCWrapper::sWrappedObjSlot, v) ||
      !JS_SetReservedSlot(cx, wrapperObj, XPCWrapper::sFlagsSlot,
                          JSVAL_ZERO) ||
      !JS_SetReservedSlot(cx, wrapperObj, sExposedPropsSlot, exposedProps)) {
    return JS_FALSE;
  }

  return JS_TRUE;
}
// static
JSObject*
DOMProxyHandler::EnsureExpandoObject(JSContext* cx, JSObject* obj)
{
  NS_ASSERTION(IsDOMProxy(obj), "expected a DOM proxy object");
  JSObject* expando = GetExpandoObject(obj);
  if (!expando) {
    expando = JS_NewObjectWithGivenProto(cx, nullptr, nullptr,
                                         js::GetObjectParent(obj));
    if (!expando) {
      return NULL;
    }

    XPCWrappedNativeScope* scope = xpc::GetObjectScope(obj);
    if (!scope->RegisterDOMExpandoObject(obj)) {
      return NULL;
    }

    nsWrapperCache* cache;
    CallQueryInterface(UnwrapDOMObject<nsISupports>(obj), &cache);
    cache->SetPreservingWrapper(true);

    js::SetProxyExtra(obj, JSPROXYSLOT_EXPANDO, ObjectValue(*expando));
  }
  return expando;
}
Example #9
0
JSBool 
js_createSettings(JSContext *cx, JSObject *obj, uintN argc, 
		  jsval *argv, jsval *rval)
{
  const char *title;
  const char *icon = NULL;
  const char *desc = NULL;
  char spath[URL_MAX];

  if(!JS_ConvertArguments(cx, argc, argv, "s/ss", &title, &icon, &desc))
    return JS_FALSE;
  js_plugin_t *jsp = JS_GetPrivate(cx, obj);
  snprintf(spath, sizeof(spath), "plugins/%s", jsp->jsp_id);

  js_setting_group_t *jsg = calloc(1, sizeof(js_setting_group_t));
  JSObject *robj;
  jsg->jsg_refcount = 2;
  LIST_INSERT_HEAD(&jsp->jsp_setting_groups, jsg, jsg_link);

  jsg->jsg_frozen = 1;
  jsg->jsg_spath = strdup(spath);
  jsg->jsg_store = htsmsg_store_load(spath) ?: htsmsg_create_map();
  jsg->jsg_root = settings_add_dir(settings_apps, _p(title), NULL, icon,
				   desc ? _p(desc) : NULL);
  robj = JS_NewObjectWithGivenProto(cx, &setting_group_class, NULL, obj);
  jsg->jsg_val = *rval = OBJECT_TO_JSVAL(robj);
  JS_AddNamedRoot(cx, &jsg->jsg_val, "jsg");
  
  JS_SetPrivate(cx, robj, jsg);


  JS_DefineFunctions(cx, robj, setting_functions);
  jsg->jsg_frozen = 0;
  return JS_TRUE;
}
Example #10
0
/**
 * gjs_cairo_surface_from_surface:
 * @context: the context
 * @surface: cairo_surface to attach to the object
 *
 * Constructs a surface wrapper given cairo surface.
 * A reference to @surface will be taken.
 *
 */
JSObject *
gjs_cairo_surface_from_surface(JSContext       *context,
                               cairo_surface_t *surface)
{
    g_return_val_if_fail(context != NULL, NULL);
    g_return_val_if_fail(surface != NULL, NULL);

    cairo_surface_type_t type = cairo_surface_get_type(surface);
    if (type == CAIRO_SURFACE_TYPE_IMAGE)
        return gjs_cairo_image_surface_from_surface(context, surface);
    if (type == CAIRO_SURFACE_TYPE_PDF)
        return gjs_cairo_pdf_surface_from_surface(context, surface);
    if (type == CAIRO_SURFACE_TYPE_PS)
        return gjs_cairo_ps_surface_from_surface(context, surface);
    if (type == CAIRO_SURFACE_TYPE_SVG)
        return gjs_cairo_svg_surface_from_surface(context, surface);

    JS::RootedObject proto(context, gjs_cairo_surface_get_proto(context));
    JS::RootedObject object(context,
        JS_NewObjectWithGivenProto(context, &gjs_cairo_surface_class, proto));
    if (!object) {
        gjs_throw(context, "failed to create surface");
        return NULL;
    }

    gjs_cairo_surface_construct(context, object, surface);

    return object;
}
Example #11
0
JSObject *
js_object_from_prop(JSContext *cx, prop_t *p)
{
  JSObject *obj = JS_NewObjectWithGivenProto(cx, &prop_bridge_class,
					     NULL, NULL);
  JS_SetPrivate(cx, obj, prop_ref_inc(p));
  return obj;
}
Example #12
0
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;
}
Example #13
0
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;
}
Example #14
0
JSObject* ScriptInterface::CreateCustomObject(const std::string& typeName) const
{
	std::map<std::string, CustomType>::const_iterator it = m_CustomObjectTypes.find(typeName);

	if (it == m_CustomObjectTypes.end())
		throw PSERROR_Scripting_TypeDoesNotExist();

	JS::RootedObject prototype(m->m_cx, it->second.m_Prototype.get());
	return JS_NewObjectWithGivenProto(m->m_cx, it->second.m_Class, prototype);
}
Example #15
0
static JSBool 
js_appendItem0(JSContext *cx, js_model_t *model, prop_t *parent,
	       const char *url, const char *type, JSObject *metaobj,
	       jsval *data, jsval *rval, int enabled,
	       const char *metabind)
{
  prop_t *item = prop_create_root(NULL);

  if(url != NULL)
    prop_set_string(prop_create(item, "url"), url);

  if(data != NULL)
    js_prop_set_from_jsval(cx, prop_create(item, "data"), *data);

  *rval = JSVAL_VOID;

  if(metabind != NULL)
    metadb_bind_url_to_prop(NULL, metabind, item);

  if(type != NULL) {
    prop_set_string(prop_create(item, "type"), type);

    if(metaobj)
      js_prop_from_object(cx, metaobj, prop_create(item, "metadata"));

  } else if(url != NULL) {

    if(backend_resolve_item(url, item)) {
      prop_destroy(item);
      return JS_TRUE;
    }
  }

  prop_set_int(prop_create(item, "enabled"), enabled);

  prop_t *p = prop_ref_inc(item);

  if(prop_set_parent(item, parent)) {
    prop_destroy(item);
    prop_ref_dec(p);
  } else {
    JSObject *robj =
      JS_NewObjectWithGivenProto(cx, &item_class,
				 JSVAL_TO_OBJECT(model->jm_item_proto), NULL);

    *rval =  OBJECT_TO_JSVAL(robj);
    js_item_t *ji = calloc(1, sizeof(js_item_t));
    ji->ji_model = model;
    ji->ji_root =  p;
    LIST_INSERT_HEAD(&model->jm_items, ji, ji_link);
    JS_SetPrivate(cx, robj, ji);
    ji->ji_enable_set_property = 1; 
  }
  return JS_TRUE;
}
Example #16
0
static JSBool
AfxGlobal_newAfxGlImage(JSContext *cx, unsigned argc, JS::Value *vp)
{
	JSObject *obj = JS_NewObjectWithGivenProto(cx, &AfxGlImage_class, NULL, JS_GetGlobalForScopeChain(cx));
    
	JS_DefineFunctions(cx, obj, AfxGlImage_functions);

	JS_SetPrivate(obj, new AfxGlImage());

	JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj));
    return JS_TRUE;
}
Example #17
0
File: gerror.c Project: Cobinja/cjs
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;
}
Example #18
0
static void
js_txn_deadlock(JSContext *cx, js_db_t *jd)
{
    if(JS_IsExceptionPending(cx))
        return;

    if(jd->jd_debug)
        TRACE(TRACE_DEBUG, "JS", "Raising deadlock exception");

    JSObject *obj = JS_NewObjectWithGivenProto(cx, &db_deadlock_exn, NULL, NULL);
    JS_SetPendingException(cx, OBJECT_TO_JSVAL(obj));
}
// Because of the drastically different ways that same- and cross-origin XOWs
// work, we have to call JS_ClearScope when a XOW changes from being same-
// origin to cross-origin. Normally, there are defined places in Gecko where
// this happens and they notify us. However, UniversalXPConnect causes the
// same transition without any notifications. We could try to detect when this
// happens, but doing so would require calling JS_ClearScope from random
// hooks, which is bad.
//
// The compromise is the UXPCObject. When resolving a property on a XOW as
// same-origin because of UniversalXPConnect, we actually resolve it on the
// UXPCObject (which is just a XOW for the same object). This causes the JS
// engine to do all of its work on another object, not polluting the main
// object. However, if the get results in calling a setter, the engine still
// uses the regular object as 'this', ensuring that the UXPCObject doesn't
// leak to script.
static JSObject *
GetUXPCObject(JSContext *cx, JSObject *obj)
{
  NS_ASSERTION(STOBJ_GET_CLASS(obj) == &sXPC_XOW_JSClass.base, "wrong object");

  jsval v;
  if (!JS_GetReservedSlot(cx, obj, XPCWrapper::sFlagsSlot, &v)) {
    return nsnull;
  }

  if (HAS_FLAGS(v, FLAG_IS_UXPC_OBJECT)) {
    return obj;
  }

  if (!JS_GetReservedSlot(cx, obj, sUXPCObjectSlot, &v)) {
    return nsnull;
  }

  if (JSVAL_IS_OBJECT(v)) {
    return JSVAL_TO_OBJECT(v);
  }

  JSObject *uxpco =
    JS_NewObjectWithGivenProto(cx, &sXPC_XOW_JSClass.base, nsnull,
                               STOBJ_GET_PARENT(obj));
  if (!uxpco) {
    return nsnull;
  }

  JSAutoTempValueRooter tvr(cx, uxpco);

  jsval wrappedObj, parentScope;
  if (!JS_GetReservedSlot(cx, obj, XPCWrapper::sWrappedObjSlot, &wrappedObj) ||
      !JS_GetReservedSlot(cx, obj, XPC_XOW_ScopeSlot, &parentScope)) {
    return nsnull;
  }

  if (!JS_SetReservedSlot(cx, uxpco, XPCWrapper::sWrappedObjSlot, wrappedObj) ||
      !JS_SetReservedSlot(cx, uxpco, XPCWrapper::sFlagsSlot,
                          INT_TO_JSVAL(FLAG_IS_UXPC_OBJECT)) ||
      !JS_SetReservedSlot(cx, uxpco, XPC_XOW_ScopeSlot, parentScope)) {
    return nsnull;
  }

  if (!JS_SetReservedSlot(cx, obj, sUXPCObjectSlot, OBJECT_TO_JSVAL(uxpco))) {
    return nsnull;
  }

  return uxpco;
}
Example #20
0
static JSBool
AfxGlobal_testObject(JSContext *cx, unsigned argc, JS::Value *vp)
{
	JS::RootedObject thisobj(cx, JS_THIS_OBJECT(cx, vp));
    if (!thisobj)
        return false;

	JSObject *obj = JS_NewObjectWithGivenProto(cx, &JsTestObject_class, NULL, JS_GetGlobalForScopeChain(cx));
    
	JS_DefineProperties(cx, obj, JsTestObject_properties);

	JS_SetPrivate(obj, new JsTestObject());

	JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj));
    return JS_TRUE;
}
Example #21
0
static JSBool
js_db_step(JSContext *cx, JSObject *obj, uintN argc,
           jsval *argv, jsval *rval)
{
    js_db_t *jd = JS_GetPrivate(cx, obj);

    if(js_db_check(cx, jd))
        return JS_FALSE;

    if(jd->jd_stmt == NULL) {
        *rval = JSVAL_NULL;
    } else if(jd->jd_step_rc == SQLITE_ROW) {
        int cols = sqlite3_data_count(jd->jd_stmt);
        int i;

        JSObject *r = JS_NewObjectWithGivenProto(cx, NULL, NULL, obj);
        *rval = OBJECT_TO_JSVAL(r);

        if(!JS_EnterLocalRootScope(cx))
            return JS_FALSE;

        for(i = 0; i < cols; i++) {

            const char *cn = sqlite3_column_name(jd->jd_stmt, i);

            switch(sqlite3_column_type(jd->jd_stmt, i)) {
            case SQLITE_INTEGER:
                js_set_prop_int(cx, r, cn, sqlite3_column_int(jd->jd_stmt, i));
                break;
            case SQLITE_TEXT:
                js_set_prop_str(cx, r, cn,
                                (const char *)sqlite3_column_text(jd->jd_stmt, i));
                break;
            case SQLITE_FLOAT:
                js_set_prop_dbl(cx, r, cn, sqlite3_column_double(jd->jd_stmt, i));
                break;
            }
        }
        JS_LeaveLocalRootScope(cx);

        return js_stmt_step(cx, jd, rval);
    }
    *rval = JSVAL_FALSE;
    return JS_TRUE;
}
// static
JSObject*
DOMProxyHandler::EnsureExpandoObject(JSContext* cx, JS::Handle<JSObject*> obj)
{
    NS_ASSERTION(IsDOMProxy(obj), "expected a DOM proxy object");
    JS::Value v = js::GetProxyExtra(obj, JSPROXYSLOT_EXPANDO);
    if (v.isObject()) {
        return &v.toObject();
    }

    js::ExpandoAndGeneration* expandoAndGeneration;
    if (!v.isUndefined()) {
        expandoAndGeneration = static_cast<js::ExpandoAndGeneration*>(v.toPrivate());
        if (expandoAndGeneration->expando.isObject()) {
            return &expandoAndGeneration->expando.toObject();
        }
    } else {
        expandoAndGeneration = nullptr;
    }

    JS::Rooted<JSObject*> expando(cx,
                                  JS_NewObjectWithGivenProto(cx, nullptr, nullptr, js::GetObjectParent(obj)));
    if (!expando) {
        return nullptr;
    }

    nsISupports* native = UnwrapDOMObject<nsISupports>(obj);
    nsWrapperCache* cache;
    CallQueryInterface(native, &cache);
    if (expandoAndGeneration) {
        cache->PreserveWrapper(native);
        expandoAndGeneration->expando.setObject(*expando);

        return expando;
    }

    XPCWrappedNativeScope* scope = xpc::GetObjectScope(obj);
    if (!scope->RegisterDOMExpandoObject(obj)) {
        return nullptr;
    }

    cache->SetPreservingWrapper(true);
    js::SetProxyExtra(obj, JSPROXYSLOT_EXPANDO, ObjectValue(*expando));

    return expando;
}
Example #23
0
JSBool
js_db_open(JSContext *cx, JSObject *obj, uintN argc,
           jsval *argv, jsval *rval)
{
    const char *name;
    char path[URL_MAX];
    char errbuf[512];
    if(!JS_ConvertArguments(cx, argc, argv, "s", &name))
        return JS_FALSE;

    js_plugin_t *jsp = JS_GetPrivate(cx, obj);

    snprintf(path, sizeof(path), "file://%s/plugins/%s/databases",
             gconf.persistent_path, jsp->jsp_id);

    if(fa_makedirs(path, errbuf, sizeof(errbuf))) {
        JS_ReportError(cx, errbuf);
        return JS_FALSE;
    }

    snprintf(path, sizeof(path), "%s/plugins/%s/databases/%s",
             gconf.persistent_path, jsp->jsp_id, name);

    sqlite3 *db = db_open(path, 0);
    if(db == NULL) {
        JS_ReportError(cx, "Unable to open database -- check logs");
        return JS_FALSE;
    }

    JSObject *robj = JS_NewObjectWithGivenProto(cx, &db_class, NULL, obj);
    *rval = OBJECT_TO_JSVAL(robj);

    js_db_t *jd = calloc(1, sizeof(js_db_t));
    jd->jd_db = db;

    snprintf(path, sizeof(path), "%s:%s", jsp->jsp_id, name);
    jd->jd_name = strdup(path);

    jd->jd_self = hts_thread_current();

    JS_SetPrivate(cx, robj, jd);
    JS_DefineFunctions(cx, robj, db_functions);
    return JS_TRUE;
}
Example #24
0
// static
JSObject* DOMProxyHandler::EnsureExpandoObject(JSContext* cx,
                                               JS::Handle<JSObject*> obj) {
  CheckDOMProxy(obj);

  JS::Value v = js::GetProxyPrivate(obj);
  if (v.isObject()) {
    CheckExpandoObject(obj, v);
    return &v.toObject();
  }

  js::ExpandoAndGeneration* expandoAndGeneration;
  if (!v.isUndefined()) {
    expandoAndGeneration =
        static_cast<js::ExpandoAndGeneration*>(v.toPrivate());
    CheckExpandoAndGeneration(obj, expandoAndGeneration);
    if (expandoAndGeneration->expando.isObject()) {
      return &expandoAndGeneration->expando.toObject();
    }
  } else {
    expandoAndGeneration = nullptr;
  }

  JS::Rooted<JSObject*> expando(
      cx, JS_NewObjectWithGivenProto(cx, nullptr, nullptr));
  if (!expando) {
    return nullptr;
  }

  nsISupports* native = UnwrapDOMObject<nsISupports>(obj);
  nsWrapperCache* cache;
  CallQueryInterface(native, &cache);
  cache->PreserveWrapper(native);

  if (expandoAndGeneration) {
    expandoAndGeneration->expando.setObject(*expando);
    return expando;
  }

  js::SetProxyPrivate(obj, ObjectValue(*expando));

  return expando;
}
Example #25
0
JSObject*
gjs_object_from_g_fundamental(JSContext    *context,
                              GIObjectInfo *info,
                              void         *gfundamental)
{
    JSObject *proto;
    JSObject *object;

    if (gfundamental == NULL)
        return NULL;

    object = _fundamental_lookup_object(gfundamental);
    if (object)
        return object;

    gjs_debug_marshal(GJS_DEBUG_GFUNDAMENTAL,
                      "Wrapping fundamental %s.%s %p with JSObject",
                      g_base_info_get_namespace((GIBaseInfo *) info),
                      g_base_info_get_name((GIBaseInfo *) info),
                      gfundamental);

    proto = gjs_lookup_fundamental_prototype_from_gtype(context,
                                                        G_TYPE_FROM_INSTANCE(gfundamental));

    object = JS_NewObjectWithGivenProto(context,
                                        JS_GetClass(proto), proto,
                                        gjs_get_import_global(context));

    if (object == NULL)
        goto out;

    init_fundamental_instance(context, object);

    associate_js_instance_to_fundamental(context, object, gfundamental, FALSE);

 out:
    return object;
}
Example #26
0
jsval CStdDeserializer::ReadScriptVal(const char* UNUSED(name), JS::HandleObject appendParent)
{
	JSContext* cx = m_ScriptInterface.GetContext();
	JSAutoRequest rq(cx);

	uint8_t type;
	NumberU8_Unbounded("type", type);
	switch (type)
	{
	case SCRIPT_TYPE_VOID:
		return JS::UndefinedValue();

	case SCRIPT_TYPE_NULL:
		return JS::NullValue();

	case SCRIPT_TYPE_ARRAY:
	case SCRIPT_TYPE_OBJECT:
	case SCRIPT_TYPE_OBJECT_PROTOTYPE:
	{
		JS::RootedObject obj(cx);
		if (appendParent)
		{
			obj.set(appendParent);
		}
		else if (type == SCRIPT_TYPE_ARRAY)
		{
			u32 length;
			NumberU32_Unbounded("array length", length);
			obj.set(JS_NewArrayObject(cx, length));
		}
		else if (type == SCRIPT_TYPE_OBJECT)
		{
			obj.set(JS_NewPlainObject(cx));
		}
		else // SCRIPT_TYPE_OBJECT_PROTOTYPE
		{
			std::wstring prototypeName;
			String("proto name", prototypeName, 0, 256);

			// Get constructor object
			JS::RootedObject proto(cx);
			GetSerializablePrototype(prototypeName, &proto);
			if (!proto)
				throw PSERROR_Deserialize_ScriptError("Failed to find serializable prototype for object");

			JS::RootedObject parent(cx, JS_GetParent(proto));
			if (!proto || !parent)
				throw PSERROR_Deserialize_ScriptError();

			// TODO: Remove support for parent since this is dropped upstream SpiderMonkey
			obj.set(JS_NewObjectWithGivenProto(cx, nullptr, proto, parent));
			if (!obj)
				throw PSERROR_Deserialize_ScriptError("JS_NewObject failed");

			// Does it have custom Deserialize function?
			// if so, we let it handle the deserialized data, rather than adding properties directly
			bool hasCustomDeserialize, hasCustomSerialize;
			if (!JS_HasProperty(cx, obj, "Serialize", &hasCustomSerialize) || !JS_HasProperty(cx, obj, "Deserialize", &hasCustomDeserialize))
				throw PSERROR_Serialize_ScriptError("JS_HasProperty failed");

			if (hasCustomDeserialize)
			{
				AddScriptBackref(obj);

				JS::RootedValue serialize(cx);
				if (!JS_GetProperty(cx, obj, "Serialize", &serialize))
					throw PSERROR_Serialize_ScriptError("JS_GetProperty failed");
				bool hasNullSerialize = hasCustomSerialize && serialize.isNull();

				// If Serialize is null, we'll still call Deserialize but with undefined argument
				JS::RootedValue data(cx);
				if (!hasNullSerialize)
					ScriptVal("data", &data);

				JS::RootedValue objVal(cx, JS::ObjectValue(*obj));
				m_ScriptInterface.CallFunctionVoid(objVal, "Deserialize", data);

				return JS::ObjectValue(*obj);
			}
		}

		if (!obj)
			throw PSERROR_Deserialize_ScriptError("Deserializer failed to create new object");

		AddScriptBackref(obj);

		uint32_t numProps;
		NumberU32_Unbounded("num props", numProps);
		bool isLatin1;
		for (uint32_t i = 0; i < numProps; ++i)
		{
			Bool("isLatin1", isLatin1);
			if (isLatin1)
			{
				std::vector<JS::Latin1Char> propname;
				ReadStringLatin1("prop name", propname);
				JS::RootedValue propval(cx, ReadScriptVal("prop value", JS::NullPtr()));

				utf16string prp(propname.begin(), propname.end());;
// TODO: Should ask upstream about getting a variant of JS_SetProperty with a length param.
				if (!JS_SetUCProperty(cx, obj, (const char16_t*)prp.data(), prp.length(), propval))
					throw PSERROR_Deserialize_ScriptError();
			}
			else
			{
				utf16string propname;
				ReadStringUTF16("prop name", propname);
				JS::RootedValue propval(cx, ReadScriptVal("prop value", JS::NullPtr()));

				if (!JS_SetUCProperty(cx, obj, (const char16_t*)propname.data(), propname.length(), propval))
					throw PSERROR_Deserialize_ScriptError();
			}
		}

		return JS::ObjectValue(*obj);
	}
	case SCRIPT_TYPE_STRING:
	{
		JS::RootedString str(cx);
		ScriptString("string", &str);
		return JS::StringValue(str);
	}
	case SCRIPT_TYPE_INT:
	{
		int32_t value;
		NumberI32("value", value, JSVAL_INT_MIN, JSVAL_INT_MAX);
		return JS::NumberValue(value);
	}
	case SCRIPT_TYPE_DOUBLE:
	{
		double value;
		NumberDouble_Unbounded("value", value);
		JS::RootedValue rval(cx, JS::NumberValue(value));
		if (rval.isNull())
			throw PSERROR_Deserialize_ScriptError("JS_NewNumberValue failed");
		return rval;
	}
	case SCRIPT_TYPE_BOOLEAN:
	{
		uint8_t value;
		NumberU8("value", value, 0, 1);
		return JS::BooleanValue(value ? true : false);
	}
	case SCRIPT_TYPE_BACKREF:
	{
		u32 tag;
		NumberU32_Unbounded("tag", tag);
		JS::RootedObject obj(cx);
		GetScriptBackref(tag, &obj);
		if (!obj)
			throw PSERROR_Deserialize_ScriptError("Invalid backref tag");
		return JS::ObjectValue(*obj);
	}
	case SCRIPT_TYPE_OBJECT_NUMBER:
	{
		double value;
		NumberDouble_Unbounded("value", value);
		JS::RootedValue val(cx, JS::NumberValue(value));

		JS::RootedObject ctorobj(cx);
		if (!JS_GetClassObject(cx, JSProto_Number, &ctorobj))
			throw PSERROR_Deserialize_ScriptError("JS_GetClassObject failed");

		JS::RootedObject obj(cx, JS_New(cx, ctorobj, JS::HandleValueArray(val)));
		if (!obj)
			throw PSERROR_Deserialize_ScriptError("JS_New failed");
		AddScriptBackref(obj);
		return JS::ObjectValue(*obj);
	}
	case SCRIPT_TYPE_OBJECT_STRING:
	{
		JS::RootedString str(cx);
		ScriptString("value", &str);
		if (!str)
			throw PSERROR_Deserialize_ScriptError();
		JS::RootedValue val(cx, JS::StringValue(str));

		JS::RootedObject ctorobj(cx);
		if (!JS_GetClassObject(cx, JSProto_String, &ctorobj))
			throw PSERROR_Deserialize_ScriptError("JS_GetClassObject failed");

		JS::RootedObject obj(cx, JS_New(cx, ctorobj, JS::HandleValueArray(val)));
		if (!obj)
			throw PSERROR_Deserialize_ScriptError("JS_New failed");
		AddScriptBackref(obj);
		return JS::ObjectValue(*obj);
	}
	case SCRIPT_TYPE_OBJECT_BOOLEAN:
	{
		bool value;
		Bool("value", value);
		JS::RootedValue val(cx, JS::BooleanValue(value));

		JS::RootedObject ctorobj(cx);
		if (!JS_GetClassObject(cx, JSProto_Boolean, &ctorobj))
			throw PSERROR_Deserialize_ScriptError("JS_GetClassObject failed");

		JS::RootedObject obj(cx, JS_New(cx, ctorobj, JS::HandleValueArray(val)));
		if (!obj)
			throw PSERROR_Deserialize_ScriptError("JS_New failed");
		AddScriptBackref(obj);
		return JS::ObjectValue(*obj);
	}
	case SCRIPT_TYPE_TYPED_ARRAY:
	{
		u8 arrayType;
		u32 byteOffset, length;
		NumberU8_Unbounded("array type", arrayType);
		NumberU32_Unbounded("byte offset", byteOffset);
		NumberU32_Unbounded("length", length);

		// To match the serializer order, we reserve the typed array's backref tag here
		JS::RootedObject arrayObj(cx);
		AddScriptBackref(arrayObj);

		// Get buffer object
		JS::RootedValue bufferVal(cx, ReadScriptVal("buffer", JS::NullPtr()));

		if (!bufferVal.isObject())
			throw PSERROR_Deserialize_ScriptError();

		JS::RootedObject bufferObj(cx, &bufferVal.toObject());
		if (!JS_IsArrayBufferObject(bufferObj))
			throw PSERROR_Deserialize_ScriptError("js_IsArrayBuffer failed");

		switch(arrayType)
		{
		case SCRIPT_TYPED_ARRAY_INT8:
			arrayObj = JS_NewInt8ArrayWithBuffer(cx, bufferObj, byteOffset, length);
			break;
		case SCRIPT_TYPED_ARRAY_UINT8:
			arrayObj = JS_NewUint8ArrayWithBuffer(cx, bufferObj, byteOffset, length);
			break;
		case SCRIPT_TYPED_ARRAY_INT16:
			arrayObj = JS_NewInt16ArrayWithBuffer(cx, bufferObj, byteOffset, length);
			break;
		case SCRIPT_TYPED_ARRAY_UINT16:
			arrayObj = JS_NewUint16ArrayWithBuffer(cx, bufferObj, byteOffset, length);
			break;
		case SCRIPT_TYPED_ARRAY_INT32:
			arrayObj = JS_NewInt32ArrayWithBuffer(cx, bufferObj, byteOffset, length);
			break;
		case SCRIPT_TYPED_ARRAY_UINT32:
			arrayObj = JS_NewUint32ArrayWithBuffer(cx, bufferObj, byteOffset, length);
			break;
		case SCRIPT_TYPED_ARRAY_FLOAT32:
			arrayObj = JS_NewFloat32ArrayWithBuffer(cx, bufferObj, byteOffset, length);
			break;
		case SCRIPT_TYPED_ARRAY_FLOAT64:
			arrayObj = JS_NewFloat64ArrayWithBuffer(cx, bufferObj, byteOffset, length);
			break;
		case SCRIPT_TYPED_ARRAY_UINT8_CLAMPED:
			arrayObj = JS_NewUint8ClampedArrayWithBuffer(cx, bufferObj, byteOffset, length);
			break;
		default:
			throw PSERROR_Deserialize_ScriptError("Failed to deserialize unrecognized typed array view");
		}
		if (!arrayObj)
			throw PSERROR_Deserialize_ScriptError("js_CreateTypedArrayWithBuffer failed");

		return JS::ObjectValue(*arrayObj);
	}
	case SCRIPT_TYPE_ARRAY_BUFFER:
	{
		u32 length;
		NumberU32_Unbounded("buffer length", length);

#if BYTE_ORDER != LITTLE_ENDIAN
#error TODO: need to convert JS ArrayBuffer data from little-endian
#endif
		void* contents = malloc(length);
		ENSURE(contents);
		RawBytes("buffer data", (u8*)contents, length);
		JS::RootedObject bufferObj(cx, JS_NewArrayBufferWithContents(cx, length, contents));
		AddScriptBackref(bufferObj);

		return JS::ObjectValue(*bufferObj);
	}
	case SCRIPT_TYPE_OBJECT_MAP:
	{
		JS::RootedObject obj(cx, JS::NewMapObject(cx));
		AddScriptBackref(obj);

		u32 mapSize;
		NumberU32_Unbounded("map size", mapSize);

		for (u32 i=0; i<mapSize; ++i)
		{
			JS::RootedValue key(cx, ReadScriptVal("map key", JS::NullPtr()));
			JS::RootedValue value(cx, ReadScriptVal("map value", JS::NullPtr()));
			JS::MapSet(cx, obj, key, value);
		}

		return JS::ObjectValue(*obj);
	}
	case SCRIPT_TYPE_OBJECT_SET:
	{
		JS::RootedValue setVal(cx);
		m_ScriptInterface.Eval("(new Set())", &setVal);

		JS::RootedObject setObj(cx, &setVal.toObject());
		AddScriptBackref(setObj);

		u32 setSize;
		NumberU32_Unbounded("set size", setSize);

		for (u32 i=0; i<setSize; ++i)
		{
			JS::RootedValue value(cx, ReadScriptVal("set value", JS::NullPtr()));
			m_ScriptInterface.CallFunctionVoid(setVal, "add", value);
		}

		return setVal;
	}
	default:
		throw PSERROR_Deserialize_OutOfBounds();
	}
}
JSBool
XPC_XOW_WrapObject(JSContext *cx, JSObject *parent, jsval *vp,
                   XPCWrappedNative* wn)
{
  NS_ASSERTION(XPCPerThreadData::IsMainThread(cx),
               "Can't do this off the main thread!");

  // Our argument should be a wrapped native object, but the caller may have
  // passed it in as an optimization.
  JSObject *wrappedObj;
  if (!JSVAL_IS_OBJECT(*vp) ||
      !(wrappedObj = JSVAL_TO_OBJECT(*vp)) ||
      STOBJ_GET_CLASS(wrappedObj) == &sXPC_XOW_JSClass.base) {
    return JS_TRUE;
  }

  if (!wn &&
      !(wn = XPCWrappedNative::GetAndMorphWrappedNativeOfJSObject(cx, wrappedObj))) {
    return JS_TRUE;
  }

  XPCJSRuntime *rt = nsXPConnect::GetRuntimeInstance();

  // The parent must be the inner global object for its scope.
  parent = JS_GetGlobalForObject(cx, parent);

  JSClass *clasp = STOBJ_GET_CLASS(parent);
  if (clasp->flags & JSCLASS_IS_EXTENDED) {
    JSExtendedClass *xclasp = reinterpret_cast<JSExtendedClass *>(clasp);
    if (xclasp->innerObject) {
      parent = xclasp->innerObject(cx, parent);
      if (!parent) {
        return JS_FALSE;
      }
    }
  }

  XPCWrappedNativeScope *parentScope =
    XPCWrappedNativeScope::FindInJSObjectScope(cx, parent, nsnull, rt);

#ifdef DEBUG_mrbkap_off
  printf("Wrapping object at %p (%s) [%p]\n",
         (void *)wrappedObj, STOBJ_GET_CLASS(wrappedObj)->name,
         (void *)parentScope);
#endif

  JSObject *outerObj = nsnull;
  WrappedNative2WrapperMap *map = parentScope->GetWrapperMap();

  outerObj = map->Find(wrappedObj);
  if (outerObj) {
    NS_ASSERTION(STOBJ_GET_CLASS(outerObj) == &sXPC_XOW_JSClass.base,
                              "What crazy object are we getting here?");
#ifdef DEBUG_mrbkap_off
    printf("But found a wrapper in the map %p!\n", (void *)outerObj);
#endif
    *vp = OBJECT_TO_JSVAL(outerObj);
    return JS_TRUE;
  }

  outerObj = JS_NewObjectWithGivenProto(cx, &sXPC_XOW_JSClass.base, nsnull,
                                        parent);
  if (!outerObj) {
    return JS_FALSE;
  }

  if (!JS_SetReservedSlot(cx, outerObj, XPCWrapper::sWrappedObjSlot, *vp) ||
      !JS_SetReservedSlot(cx, outerObj, XPCWrapper::sFlagsSlot,
                          JSVAL_ZERO) ||
      !JS_SetReservedSlot(cx, outerObj, XPC_XOW_ScopeSlot,
                          PRIVATE_TO_JSVAL(parentScope))) {
    return JS_FALSE;
  }

  *vp = OBJECT_TO_JSVAL(outerObj);

  map->Add(wn->GetScope()->GetWrapperMap(), wrappedObj, outerObj);

  return JS_TRUE;
}
JSBool
WrapObject(JSContext *cx, JSObject *scope, jsval v, jsval *vp)
{
  // This might be redundant if called from XPC_SJOW_Construct, but it should
  // be cheap in that case.
  JSObject *objToWrap = UnsafeUnwrapSecurityWrapper(cx, JSVAL_TO_OBJECT(v));
  if (!objToWrap ||
      JS_TypeOfValue(cx, OBJECT_TO_JSVAL(objToWrap)) == JSTYPE_XML) {
    return ThrowException(NS_ERROR_INVALID_ARG, cx);
  }

  // Prevent script created Script objects from ever being wrapped
  // with XPCSafeJSObjectWrapper, and never let the eval function
  // object be directly wrapped.

  if (objToWrap->getClass() == &js_ScriptClass ||
      (JS_ObjectIsFunction(cx, objToWrap) &&
       JS_GetFunctionFastNative(cx, JS_ValueToFunction(cx, v)) ==
       XPCWrapper::sEvalNative)) {
    return ThrowException(NS_ERROR_INVALID_ARG, cx);
  }

  XPCWrappedNativeScope *xpcscope =
    XPCWrappedNativeScope::FindInJSObjectScope(cx, scope);
  NS_ASSERTION(xpcscope, "what crazy scope are we in?");

  XPCWrappedNative *wrappedNative;
  WrapperType type = xpcscope->GetWrapperFor(cx, objToWrap, SJOW,
                                             &wrappedNative);

  // NB: We allow XOW here because we're as restrictive as it is (and we know
  // we're same origin here).
  if (type != NONE && type != XOW && !(type & SJOW)) {
    return ThrowException(NS_ERROR_INVALID_ARG, cx);
  }

  SLIM_LOG_WILL_MORPH(cx, objToWrap);
  if (IS_SLIM_WRAPPER(objToWrap) && !MorphSlimWrapper(cx, objToWrap)) {
    return ThrowException(NS_ERROR_FAILURE, cx);
  }

  XPCWrappedNative *wn =
    XPCWrappedNative::GetWrappedNativeOfJSObject(cx, objToWrap);
  if (wn) {
    CheckWindow(wn);
  }

  JSObject *wrapperObj =
    JS_NewObjectWithGivenProto(cx, js::Jsvalify(&SJOWClass), nsnull, scope);

  if (!wrapperObj) {
    // JS_NewObjectWithGivenProto already threw.
    return JS_FALSE;
  }

  *vp = OBJECT_TO_JSVAL(wrapperObj);
  if (!JS_SetReservedSlot(cx, wrapperObj, XPCWrapper::sWrappedObjSlot,
                          OBJECT_TO_JSVAL(objToWrap)) ||
      !JS_SetReservedSlot(cx, wrapperObj, XPCWrapper::sFlagsSlot, JSVAL_ZERO)) {
    return JS_FALSE;
  }

  return JS_TRUE;
}
Example #29
0
static JSBool 
js_appendItem0(JSContext *cx, js_model_t *model, prop_t *parent,
	       const char *url, const char *type, JSObject *metaobj,
	       jsval *data, jsval *rval, int enabled,
	       const char *metabind)
{
  install_nodesub(model);

  prop_t *item = prop_create_root(NULL);

  rstr_t *rurl = url ? rstr_alloc(url) : NULL;

  if(url != NULL)
    prop_set(item, "url", PROP_SET_RSTRING, rurl);

  if(data != NULL)
    js_prop_set_from_jsval(cx, prop_create(item, "data"), *data);

  *rval = JSVAL_VOID;

  if(metabind != NULL)
    playinfo_bind_url_to_prop(metabind, item);

  if(type != NULL) {
    prop_set_string(prop_create(item, "type"), type);

    if(metaobj)
      js_prop_from_object(cx, metaobj, prop_create(item, "metadata"));

  } else if(url != NULL) {

    if(backend_resolve_item(url, item)) {
      prop_destroy(item);
      rstr_release(rurl);
      return JS_TRUE;
    }
  }

  prop_set_int(prop_create(item, "enabled"), enabled);

  prop_t *p = prop_ref_inc(item);

  if(prop_set_parent(item, parent)) {
    prop_destroy(item);
    prop_ref_dec(p);
  } else {
    JSObject *robj =
      JS_NewObjectWithGivenProto(cx, &item_class,
				 JSVAL_TO_OBJECT(model->jm_item_proto), NULL);

    *rval =  OBJECT_TO_JSVAL(robj);
    js_item_t *ji = calloc(1, sizeof(js_item_t));
    atomic_add(&model->jm_refcount, 1);
    ji->ji_url = rstr_dup(rurl);
    ji->ji_model = model;
    ji->ji_root =  p;
    TAILQ_INSERT_TAIL(&model->jm_items, ji, ji_link);
    JS_SetPrivate(cx, robj, ji);
    ji->ji_enable_set_property = 1; 

    ji->ji_eventsub = 
      prop_subscribe(PROP_SUB_TRACK_DESTROY,
		     PROP_TAG_CALLBACK, js_item_eventsub, ji,
		     PROP_TAG_ROOT, ji->ji_root,
		     PROP_TAG_COURIER, model->jm_pc,
		     NULL);
    model->jm_subs++;
    ji->ji_this = OBJECT_TO_JSVAL(robj);
    JS_AddNamedRoot(cx, &ji->ji_this, "item_this");
    prop_tag_set(ji->ji_root, model, ji);
  }
  rstr_release(rurl);
  return JS_TRUE;
}
JSBool
WrapObject(JSContext *cx, JSObject *parent, jsval *vp, XPCWrappedNative* wn)
{
  NS_ASSERTION(XPCPerThreadData::IsMainThread(cx),
               "Can't do this off the main thread!");

  // Our argument should be a wrapped native object, but the caller may have
  // passed it in as an optimization.
  JSObject *wrappedObj;
  if (JSVAL_IS_PRIMITIVE(*vp) ||
      !(wrappedObj = JSVAL_TO_OBJECT(*vp)) ||
      wrappedObj->getClass() == &XOWClass) {
    return JS_TRUE;
  }

  if (!wn &&
      !(wn = XPCWrappedNative::GetAndMorphWrappedNativeOfJSObject(cx, wrappedObj))) {
    return JS_TRUE;
  }

  CheckWindow(wn);

  // The parent must be the inner global object for its scope.
  parent = JS_GetGlobalForObject(cx, parent);
  OBJ_TO_INNER_OBJECT(cx, parent);
  if (!parent) {
    return JS_FALSE;
  }

  XPCWrappedNativeWithXOW *wnxow = nsnull;
  if (wn->NeedsXOW()) {
    JSObject *innerWrappedObj = wrappedObj;
    OBJ_TO_INNER_OBJECT(cx, innerWrappedObj);
    if (!innerWrappedObj) {
      return JS_FALSE;
    }

    if (innerWrappedObj == parent) {
      wnxow = static_cast<XPCWrappedNativeWithXOW *>(wn);
      JSObject *xow = wnxow->GetXOW();
      if (xow) {
        *vp = OBJECT_TO_JSVAL(xow);
        return JS_TRUE;
      }
    }
  }

  XPCWrappedNative *parentwn =
    XPCWrappedNative::GetWrappedNativeOfJSObject(cx, parent);
  XPCWrappedNativeScope *parentScope;
  if (NS_LIKELY(parentwn)) {
    parentScope = parentwn->GetScope();
  } else {
    parentScope = XPCWrappedNativeScope::FindInJSObjectScope(cx, parent);
  }

  JSObject *outerObj = nsnull;
  WrappedNative2WrapperMap *map = parentScope->GetWrapperMap();

  outerObj = map->Find(wrappedObj);
  if (outerObj) {
    NS_ASSERTION(outerObj->getClass() == &XOWClass,
                 "What crazy object are we getting here?");
    *vp = OBJECT_TO_JSVAL(outerObj);

    if (wnxow) {
      // NB: wnxow->GetXOW() must have returned false.
      SetFlags(cx, outerObj, AddFlags(GetFlags(cx, outerObj), FLAG_IS_CACHED));
      wnxow->SetXOW(outerObj);
    }

    return JS_TRUE;
  }

  outerObj = JS_NewObjectWithGivenProto(cx, js::Jsvalify(&XOWClass), nsnull,
                                        parent);
  if (!outerObj) {
    return JS_FALSE;
  }

  jsval flags = INT_TO_JSVAL(wnxow ? FLAG_IS_CACHED : 0);
  if (!JS_SetReservedSlot(cx, outerObj, sWrappedObjSlot, *vp) ||
      !JS_SetReservedSlot(cx, outerObj, sFlagsSlot, flags) ||
      !JS_SetReservedSlot(cx, outerObj, XPC_XOW_ScopeSlot,
                          PRIVATE_TO_JSVAL(parentScope))) {
    return JS_FALSE;
  }

  *vp = OBJECT_TO_JSVAL(outerObj);

  map->Add(wn->GetScope()->GetWrapperMap(), wrappedObj, outerObj);
  if(wnxow) {
    wnxow->SetXOW(outerObj);
  }

  return JS_TRUE;
}