Bug 575870 - Enable the firefox button on xp themed, classic, and aero basic. r=dao...
[mozilla-central.git] / js / ipc / ObjectWrapperParent.cpp
blob0f63d58652377788fc7b54fd77d91a372a7af5ca
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: set ts=8 sw=4 et tw=80:
4 * ***** BEGIN LICENSE BLOCK *****
5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
15 * License.
17 * The Original Code is mozilla.org code.
19 * The Initial Developer of the Original Code is
20 * The Mozilla Foundation.
21 * Portions created by the Initial Developer are Copyright (C) 2010
22 * the Initial Developer. All Rights Reserved.
24 * Contributor(s):
25 * Ben Newman <b{enjam,newma}n@mozilla.com> (original author)
27 * Alternatively, the contents of this file may be used under the terms of
28 * either of the GNU General Public License Version 2 or later (the "GPL"),
29 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 * in which case the provisions of the GPL or the LGPL are applicable instead
31 * of those above. If you wish to allow use of your version of this file only
32 * under the terms of either the GPL or the LGPL, and not to allow others to
33 * use your version of this file under the terms of the MPL, indicate your
34 * decision by deleting the provisions above and replace them with the notice
35 * and other provisions required by the GPL or the LGPL. If you do not delete
36 * the provisions above, a recipient may use your version of this file under
37 * the terms of any one of the MPL, the GPL or the LGPL.
39 * ***** END LICENSE BLOCK ***** */
41 #include "mozilla/jsipc/ObjectWrapperParent.h"
42 #include "mozilla/jsipc/ContextWrapperParent.h"
43 #include "mozilla/jsipc/CPOWTypes.h"
44 #include "mozilla/unused.h"
46 #include "jsobj.h"
47 #include "jsfun.h"
48 #include "jsutil.h"
50 using namespace mozilla::jsipc;
52 namespace {
54 // Only need one reserved slot because the ObjectWrapperParent* is
55 // stored in the private slot.
56 static const uintN sFlagsSlot = 0;
57 static const uintN sNumSlots = 1;
58 static const uintN CPOW_FLAG_RESOLVING = 1 << 0;
60 class AutoResolveFlag
62 JSContext* mContext;
63 JSObject* mObj;
64 uintN mOldFlags;
65 JS_DECL_USE_GUARD_OBJECT_NOTIFIER;
67 static uintN GetFlags(JSContext* cx, JSObject* obj) {
68 jsval v;
69 #ifdef DEBUG
70 JSBool ok =
71 #endif
72 JS_GetReservedSlot(cx, obj, sFlagsSlot, &v);
73 NS_ASSERTION(ok, "Failed to get CPOW flags");
74 return JSVAL_TO_INT(v);
77 static uintN SetFlags(JSContext* cx, JSObject* obj, uintN flags) {
78 uintN oldFlags = GetFlags(cx, obj);
79 if (oldFlags != flags)
80 JS_SetReservedSlot(cx, obj, sFlagsSlot, INT_TO_JSVAL(flags));
81 return oldFlags;
84 public:
86 AutoResolveFlag(JSContext* cx,
87 JSObject* obj
88 JS_GUARD_OBJECT_NOTIFIER_PARAM)
89 : mContext(cx)
90 , mObj(obj)
91 , mOldFlags(SetFlags(cx, obj,
92 GetFlags(cx, obj) | CPOW_FLAG_RESOLVING))
94 JS_GUARD_OBJECT_NOTIFIER_INIT;
97 ~AutoResolveFlag() {
98 SetFlags(mContext, mObj, mOldFlags);
101 static JSBool IsSet(JSContext* cx, JSObject* obj) {
102 return GetFlags(cx, obj) & CPOW_FLAG_RESOLVING;
107 class StatusMemberOwner
109 OperationStatus mStatus;
110 public:
111 StatusMemberOwner() : mStatus(JS_FALSE) {}
112 OperationStatus* StatusPtr() {
113 return &mStatus;
117 typedef AutoCheckOperationBase<StatusMemberOwner> ACOBase;
119 class AutoCheckOperation : public ACOBase
121 JS_DECL_USE_GUARD_OBJECT_NOTIFIER;
122 public:
123 AutoCheckOperation(JSContext* cx,
124 ObjectWrapperParent* owp
125 JS_GUARD_OBJECT_NOTIFIER_PARAM)
126 : ACOBase(cx, owp)
128 JS_GUARD_OBJECT_NOTIFIER_INIT;
134 void
135 ObjectWrapperParent::CheckOperation(JSContext* cx,
136 OperationStatus* status)
138 NS_PRECONDITION(status->type() != OperationStatus::T__None,
139 "Checking an uninitialized operation.");
141 switch (status->type()) {
142 case OperationStatus::TJSVariant:
144 jsval thrown;
145 if (jsval_from_JSVariant(cx, status->get_JSVariant(), &thrown))
146 JS_SetPendingException(cx, thrown);
147 *status = JS_FALSE;
149 break;
150 case OperationStatus::TJSBool:
151 if (!status->get_JSBool() && !JS_IsExceptionPending(cx)) {
152 NS_WARNING("CPOW operation failed without setting an exception.");
154 break;
155 default:
156 NS_NOTREACHED("Invalid or uninitialized OperationStatus type.");
157 break;
161 template <typename RType>
162 static RType
163 with_error(JSContext* cx,
164 RType rval,
165 const char* error = NULL)
167 if (!JS_IsExceptionPending(cx))
168 JS_ReportError(cx, error ? error : "Unspecified CPOW error");
169 return rval;
172 const js::Class ObjectWrapperParent::sCPOW_JSClass = {
173 "CrossProcessObjectWrapper",
174 JSCLASS_NEW_RESOLVE | JSCLASS_NEW_ENUMERATE |
175 JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(sNumSlots),
176 js::Valueify(ObjectWrapperParent::CPOW_AddProperty),
177 js::Valueify(ObjectWrapperParent::CPOW_DelProperty),
178 js::Valueify(ObjectWrapperParent::CPOW_GetProperty),
179 js::Valueify(ObjectWrapperParent::CPOW_SetProperty),
180 (JSEnumerateOp) ObjectWrapperParent::CPOW_NewEnumerate,
181 (JSResolveOp) ObjectWrapperParent::CPOW_NewResolve,
182 js::Valueify(ObjectWrapperParent::CPOW_Convert),
183 ObjectWrapperParent::CPOW_Finalize,
184 nsnull, // reserved1
185 nsnull, // checkAccess
186 js::Valueify(ObjectWrapperParent::CPOW_Call),
187 js::Valueify(ObjectWrapperParent::CPOW_Construct),
188 nsnull, // xdrObject
189 js::Valueify(ObjectWrapperParent::CPOW_HasInstance),
190 nsnull, // mark
192 js::Valueify(ObjectWrapperParent::CPOW_Equality),
193 nsnull, // outerObject
194 nsnull, // innerObject
195 nsnull, // iteratorObject
196 nsnull, // wrappedObject
200 void
201 ObjectWrapperParent::ActorDestroy(ActorDestroyReason)
203 if (mObj) {
204 mObj->setPrivate(NULL);
205 mObj = NULL;
209 ContextWrapperParent*
210 ObjectWrapperParent::Manager()
212 PContextWrapperParent* pcwp = PObjectWrapperParent::Manager();
213 return static_cast<ContextWrapperParent*>(pcwp);
216 JSObject*
217 ObjectWrapperParent::GetJSObject(JSContext* cx) const
219 js::Class *clasp = const_cast<js::Class *>(&ObjectWrapperParent::sCPOW_JSClass);
220 if (!mObj && (mObj = JS_NewObject(cx, js::Jsvalify(clasp), NULL, NULL))) {
221 JS_SetPrivate(cx, mObj, (void*)this);
222 JS_SetReservedSlot(cx, mObj, sFlagsSlot, JSVAL_ZERO);
224 return mObj;
227 static ObjectWrapperParent*
228 Unwrap(JSContext* cx, JSObject* obj)
230 while (obj->getClass() != &ObjectWrapperParent::sCPOW_JSClass)
231 if (!(obj = obj->getProto()))
232 return NULL;
234 ObjectWrapperParent* self =
235 static_cast<ObjectWrapperParent*>(JS_GetPrivate(cx, obj));
237 NS_ASSERTION(!self || self->GetJSObject(cx) == obj,
238 "Wrapper and wrapped object disagree?");
240 return self;
243 /*static*/ bool
244 ObjectWrapperParent::jsval_to_JSVariant(JSContext* cx, jsval from,
245 JSVariant* to)
247 switch (JS_TypeOfValue(cx, from)) {
248 case JSTYPE_VOID:
249 *to = void_t();
250 return true;
251 case JSTYPE_NULL:
252 if (from != JSVAL_NULL)
253 return false;
254 // fall through
255 case JSTYPE_FUNCTION:
256 // CPOWs can fool JS_TypeOfValue into returning JSTYPE_FUNCTION
257 // because they have a call hook, but CPOWs are really objects, so
258 // fall through to the JSTYPE_OBJECT case:
259 case JSTYPE_OBJECT:
261 PObjectWrapperParent* powp;
262 if (!JSObject_to_PObjectWrapperParent(cx, JSVAL_TO_OBJECT(from), &powp))
263 return with_error(cx, false, "Cannot pass parent-created object to child");
264 *to = powp;
266 return true;
267 case JSTYPE_STRING:
268 *to = nsDependentString((PRUnichar*)JS_GetStringChars(JSVAL_TO_STRING(from)),
269 JS_GetStringLength(JSVAL_TO_STRING(from)));
270 return true;
271 case JSTYPE_NUMBER:
272 if (JSVAL_IS_INT(from))
273 *to = JSVAL_TO_INT(from);
274 else if (JSVAL_IS_DOUBLE(from))
275 *to = JSVAL_TO_DOUBLE(from);
276 else return false;
277 return true;
278 case JSTYPE_BOOLEAN:
279 *to = !!JSVAL_TO_BOOLEAN(from);
280 return true;
281 case JSTYPE_XML:
282 return with_error(cx, false, "CPOWs currently cannot handle JSTYPE_XML");
283 default:
284 return with_error(cx, false, "Bad jsval type");
288 /*static*/ bool
289 ObjectWrapperParent::jsval_from_JSVariant(JSContext* cx, const JSVariant& from,
290 jsval* to)
292 switch (from.type()) {
293 case JSVariant::Tvoid_t:
294 *to = JSVAL_VOID;
295 return true;
296 case JSVariant::TPObjectWrapperParent:
297 return jsval_from_PObjectWrapperParent(cx, from.get_PObjectWrapperParent(), to);
298 case JSVariant::TnsString:
300 JSString* str = JS_NewUCStringCopyZ(cx, from.get_nsString().BeginReading());
301 if (!str)
302 return false;
303 *to = STRING_TO_JSVAL(str);
304 return true;
306 case JSVariant::Tint:
307 *to = INT_TO_JSVAL(from.get_int());
308 return true;
309 case JSVariant::Tdouble:
310 return !!JS_NewNumberValue(cx, from.get_double(), to);
311 case JSVariant::Tbool:
312 *to = BOOLEAN_TO_JSVAL(from.get_bool());
313 return true;
314 default:
315 return false;
319 /*static*/ bool
320 ObjectWrapperParent::
321 JSObject_to_PObjectWrapperParent(JSContext* cx, JSObject* from,
322 PObjectWrapperParent** to)
324 if (!from) {
325 *to = NULL;
326 return true;
328 ObjectWrapperParent* owp = Unwrap(cx, from);
329 if (!owp)
330 return false;
331 *to = owp;
332 return true;
335 /*static*/ bool
336 ObjectWrapperParent::
337 JSObject_from_PObjectWrapperParent(JSContext* cx,
338 const PObjectWrapperParent* from,
339 JSObject** to)
341 const ObjectWrapperParent* owp =
342 static_cast<const ObjectWrapperParent*>(from);
343 *to = owp
344 ? owp->GetJSObject(cx)
345 : JSVAL_TO_OBJECT(JSVAL_NULL);
346 return true;
349 /*static*/ bool
350 ObjectWrapperParent::
351 jsval_from_PObjectWrapperParent(JSContext* cx,
352 const PObjectWrapperParent* from,
353 jsval* to)
355 JSObject* obj;
356 if (!JSObject_from_PObjectWrapperParent(cx, from, &obj))
357 return false;
358 *to = OBJECT_TO_JSVAL(obj);
359 return true;
362 static bool
363 jsid_from_int(JSContext* cx, int from, jsid* to)
365 jsval v = INT_TO_JSVAL(from);
366 return JS_ValueToId(cx, v, to);
369 static bool
370 jsid_from_nsString(JSContext* cx, const nsString& from, jsid* to)
372 JSString* str = JS_NewUCStringCopyZ(cx, from.BeginReading());
373 if (!str)
374 return false;
375 return JS_ValueToId(cx, STRING_TO_JSVAL(str), to);
378 static bool
379 jsval_to_nsString(JSContext* cx, jsid from, nsString* to)
381 JSString* str;
382 jsval idval;
383 if (JS_IdToValue(cx, from, &idval) &&
384 (str = JS_ValueToString(cx, idval))) {
385 *to = JS_GetStringChars(str);
386 return true;
388 return false;
391 /*static*/ JSBool
392 ObjectWrapperParent::CPOW_AddProperty(JSContext *cx, JSObject *obj, jsid id,
393 jsval *vp)
395 CPOW_LOG(("Calling CPOW_AddProperty (%s)...",
396 JSVAL_TO_CSTR(cx, id)));
398 ObjectWrapperParent* self = Unwrap(cx, obj);
399 if (!self)
400 return with_error(cx, JS_FALSE, "Unwrapping failed in CPOW_AddProperty");
402 if (AutoResolveFlag::IsSet(cx, obj))
403 return JS_TRUE;
405 AutoCheckOperation aco(cx, self);
407 nsString in_id;
409 if (!jsval_to_nsString(cx, id, &in_id))
410 return JS_FALSE;
412 return (self->Manager()->RequestRunToCompletion() &&
413 self->CallAddProperty(in_id,
414 aco.StatusPtr()) &&
415 aco.Ok());
418 /*static*/ JSBool
419 ObjectWrapperParent::CPOW_GetProperty(JSContext *cx, JSObject *obj, jsid id,
420 jsval *vp)
422 CPOW_LOG(("Calling CPOW_GetProperty (%s)...",
423 JSVAL_TO_CSTR(cx, id)));
425 ObjectWrapperParent* self = Unwrap(cx, obj);
426 if (!self)
427 return with_error(cx, JS_FALSE, "Unwrapping failed in CPOW_GetProperty");
429 AutoCheckOperation aco(cx, self);
431 nsString in_id;
433 if (!jsval_to_nsString(cx, id, &in_id))
434 return JS_FALSE;
436 JSVariant out_v;
438 return (self->Manager()->RequestRunToCompletion() &&
439 self->CallGetProperty(in_id,
440 aco.StatusPtr(), &out_v) &&
441 aco.Ok() &&
442 self->jsval_from_JSVariant(cx, out_v, vp));
445 /*static*/ JSBool
446 ObjectWrapperParent::CPOW_SetProperty(JSContext *cx, JSObject *obj, jsid id,
447 jsval *vp)
449 CPOW_LOG(("Calling CPOW_SetProperty (%s)...",
450 JSVAL_TO_CSTR(cx, id)));
452 ObjectWrapperParent* self = Unwrap(cx, obj);
453 if (!self)
454 return with_error(cx, JS_FALSE, "Unwrapping failed in CPOW_SetProperty");
456 AutoCheckOperation aco(cx, self);
458 nsString in_id;
459 JSVariant in_v;
461 if (!jsval_to_nsString(cx, id, &in_id) ||
462 !self->jsval_to_JSVariant(cx, *vp, &in_v))
463 return JS_FALSE;
465 JSVariant out_v;
467 return (self->Manager()->RequestRunToCompletion() &&
468 self->CallSetProperty(in_id, in_v,
469 aco.StatusPtr(), &out_v) &&
470 aco.Ok() &&
471 self->jsval_from_JSVariant(cx, out_v, vp));
474 /*static*/ JSBool
475 ObjectWrapperParent::CPOW_DelProperty(JSContext *cx, JSObject *obj, jsid id,
476 jsval *vp)
478 CPOW_LOG(("Calling CPOW_DelProperty (%s)...",
479 JSVAL_TO_CSTR(cx, id)));
481 ObjectWrapperParent* self = Unwrap(cx, obj);
482 if (!self)
483 return with_error(cx, JS_FALSE, "Unwrapping failed in CPOW_DelProperty");
485 AutoCheckOperation aco(cx, self);
487 nsString in_id;
489 if (!jsval_to_nsString(cx, id, &in_id))
490 return JS_FALSE;
492 JSVariant out_v;
494 return (self->Manager()->RequestRunToCompletion() &&
495 self->CallDelProperty(in_id,
496 aco.StatusPtr(), &out_v) &&
497 aco.Ok() &&
498 jsval_from_JSVariant(cx, out_v, vp));
501 JSBool
502 ObjectWrapperParent::NewEnumerateInit(JSContext* cx, jsval* statep, jsid* idp)
504 AutoCheckOperation aco(cx, this);
506 JSVariant out_state;
507 int out_id;
509 return (CallNewEnumerateInit(aco.StatusPtr(), &out_state, &out_id) &&
510 aco.Ok() &&
511 jsval_from_JSVariant(cx, out_state, statep) &&
512 (!idp || jsid_from_int(cx, out_id, idp)));
515 JSBool
516 ObjectWrapperParent::NewEnumerateNext(JSContext* cx, jsval* statep, jsid* idp)
518 AutoCheckOperation aco(cx, this);
520 JSVariant in_state;
522 if (!jsval_to_JSVariant(cx, *statep, &in_state))
523 return JS_FALSE;
525 JSVariant out_state;
526 nsString out_id;
528 if (CallNewEnumerateNext(in_state,
529 aco.StatusPtr(), &out_state, &out_id) &&
530 aco.Ok() &&
531 jsval_from_JSVariant(cx, out_state, statep) &&
532 jsid_from_nsString(cx, out_id, idp))
534 JSObject* obj = GetJSObject(cx);
535 AutoResolveFlag arf(cx, obj);
536 return JS_DefinePropertyById(cx, obj, *idp, JSVAL_VOID, NULL, NULL,
537 JSPROP_ENUMERATE);
539 return JS_FALSE;
542 JSBool
543 ObjectWrapperParent::NewEnumerateDestroy(JSContext* cx, jsval state)
545 AutoCheckOperation aco(cx, this);
547 JSVariant in_state;
549 if (!jsval_to_JSVariant(cx, state, &in_state))
550 return JS_FALSE;
552 return SendNewEnumerateDestroy(in_state);
555 /*static*/ JSBool
556 ObjectWrapperParent::CPOW_NewEnumerate(JSContext *cx, JSObject *obj,
557 JSIterateOp enum_op, jsval *statep,
558 jsid *idp)
560 CPOW_LOG(("Calling CPOW_NewEnumerate..."));
562 ObjectWrapperParent* self = Unwrap(cx, obj);
563 if (!self)
564 return with_error(cx, JS_FALSE, "Unwrapping failed in CPOW_NewEnumerate");
566 switch (enum_op) {
567 case JSENUMERATE_INIT:
568 case JSENUMERATE_INIT_ALL:
569 self->Manager()->RequestRunToCompletion();
570 return self->NewEnumerateInit(cx, statep, idp);
571 case JSENUMERATE_NEXT:
572 return self->NewEnumerateNext(cx, statep, idp);
573 case JSENUMERATE_DESTROY:
574 return self->NewEnumerateDestroy(cx, *statep);
577 NS_NOTREACHED("Unknown enum_op value in CPOW_NewEnumerate");
578 return JS_FALSE;
581 /*static*/ JSBool
582 ObjectWrapperParent::CPOW_NewResolve(JSContext *cx, JSObject *obj, jsid id,
583 uintN flags, JSObject **objp)
585 CPOW_LOG(("Calling CPOW_NewResolve (%s)...",
586 JSVAL_TO_CSTR(cx, id)));
588 ObjectWrapperParent* self = Unwrap(cx, obj);
589 if (!self)
590 return with_error(cx, JS_FALSE, "Unwrapping failed in CPOW_NewResolve");
592 AutoCheckOperation aco(cx, self);
594 nsString in_id;
596 if (!jsval_to_nsString(cx, id, &in_id))
597 return JS_FALSE;
599 PObjectWrapperParent* out_pobj;
601 if (!self->Manager()->RequestRunToCompletion() ||
602 !self->CallNewResolve(in_id, flags,
603 aco.StatusPtr(), &out_pobj) ||
604 !aco.Ok() ||
605 !JSObject_from_PObjectWrapperParent(cx, out_pobj, objp))
606 return JS_FALSE;
608 if (*objp) {
609 AutoResolveFlag arf(cx, *objp);
610 JS_DefinePropertyById(cx, *objp, id, JSVAL_VOID, NULL, NULL,
611 JSPROP_ENUMERATE);
613 return JS_TRUE;
616 /*static*/ JSBool
617 ObjectWrapperParent::CPOW_Convert(JSContext *cx, JSObject *obj, JSType type,
618 jsval *vp)
620 CPOW_LOG(("Calling CPOW_Convert (to %s)...",
621 JS_GetTypeName(cx, type)));
623 ObjectWrapperParent* self = Unwrap(cx, obj);
624 if (!self)
625 return with_error(cx, JS_FALSE, "Unwrapping failed in CPOW_Convert");
627 *vp = OBJECT_TO_JSVAL(obj);
629 return JS_TRUE;
632 /*static*/ void
633 ObjectWrapperParent::CPOW_Finalize(JSContext* cx, JSObject* obj)
635 CPOW_LOG(("Calling CPOW_Finalize..."));
637 ObjectWrapperParent* self = Unwrap(cx, obj);
638 if (self) {
639 self->mObj = NULL;
640 unused << ObjectWrapperParent::Send__delete__(self);
644 /*static*/ JSBool
645 ObjectWrapperParent::CPOW_Call(JSContext* cx, JSObject* obj, uintN argc,
646 jsval* argv, jsval* rval)
648 CPOW_LOG(("Calling CPOW_Call..."));
650 ObjectWrapperParent* function =
651 Unwrap(cx, JSVAL_TO_OBJECT(JS_ARGV_CALLEE(argv)));
652 if (!function)
653 return with_error(cx, JS_FALSE, "Could not unwrap CPOW function");
655 AutoCheckOperation aco(cx, function);
657 ObjectWrapperParent* receiver = Unwrap(cx, obj);
658 if (!receiver) {
659 // Substitute child global for parent global object.
660 // TODO First make sure we're really replacing the global object?
661 ContextWrapperParent* manager =
662 static_cast<ContextWrapperParent*>(function->Manager());
663 receiver = manager->GetGlobalObjectWrapper();
666 nsTArray<JSVariant> in_argv(argc);
667 for (uintN i = 0; i < argc; i++)
668 if (!jsval_to_JSVariant(cx, argv[i], in_argv.AppendElement()))
669 return JS_FALSE;
671 JSVariant out_rval;
673 return (function->Manager()->RequestRunToCompletion() &&
674 function->CallCall(receiver, in_argv,
675 aco.StatusPtr(), &out_rval) &&
676 aco.Ok() &&
677 jsval_from_JSVariant(cx, out_rval, rval));
680 /*static*/ JSBool
681 ObjectWrapperParent::CPOW_Construct(JSContext *cx, JSObject *obj, uintN argc,
682 jsval *argv, jsval *rval)
684 CPOW_LOG(("Calling CPOW_Construct..."));
686 ObjectWrapperParent* constructor =
687 Unwrap(cx, JSVAL_TO_OBJECT(JS_ARGV_CALLEE(argv)));
688 if (!constructor)
689 return with_error(cx, JS_FALSE, "Could not unwrap CPOW constructor function");
691 AutoCheckOperation aco(cx, constructor);
693 nsTArray<JSVariant> in_argv(argc);
694 for (uintN i = 0; i < argc; i++)
695 if (!jsval_to_JSVariant(cx, argv[i], in_argv.AppendElement()))
696 return JS_FALSE;
698 PObjectWrapperParent* out_powp;
700 return (constructor->Manager()->RequestRunToCompletion() &&
701 constructor->CallConstruct(in_argv,
702 aco.StatusPtr(), &out_powp) &&
703 aco.Ok() &&
704 jsval_from_PObjectWrapperParent(cx, out_powp, rval));
707 /*static*/ JSBool
708 ObjectWrapperParent::CPOW_HasInstance(JSContext *cx, JSObject *obj, const jsval *v,
709 JSBool *bp)
711 CPOW_LOG(("Calling CPOW_HasInstance..."));
713 *bp = JS_FALSE;
715 ObjectWrapperParent* self = Unwrap(cx, obj);
716 if (!self)
717 return with_error(cx, JS_FALSE, "Unwrapping failed in CPOW_HasInstance");
719 AutoCheckOperation aco(cx, self);
721 JSVariant in_v;
723 if (!jsval_to_JSVariant(cx, *v, &in_v))
724 return JS_FALSE;
726 return (self->Manager()->RequestRunToCompletion() &&
727 self->CallHasInstance(in_v,
728 aco.StatusPtr(), bp) &&
729 aco.Ok());
732 /*static*/ JSBool
733 ObjectWrapperParent::CPOW_Equality(JSContext *cx, JSObject *obj, const jsval *v,
734 JSBool *bp)
736 CPOW_LOG(("Calling CPOW_Equality..."));
738 *bp = JS_FALSE;
740 ObjectWrapperParent* self = Unwrap(cx, obj);
741 if (!self)
742 return with_error(cx, JS_FALSE, "Unwrapping failed in CPOW_Equality");
744 if (JSVAL_IS_PRIMITIVE(*v))
745 return JS_TRUE;
747 ObjectWrapperParent* other = Unwrap(cx, JSVAL_TO_OBJECT(*v));
748 if (!other)
749 return JS_TRUE;
751 *bp = (self == other);
753 return JS_TRUE;