bug 313956: expand installer .exe contents to make complete mar. r=ted.
[gecko.git] / js / ipc / ObjectWrapperParent.cpp
blobf68156ea1149352393261b965d9d4700c2f8000b
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"
45 #include "nsJSUtils.h"
47 #include "jsobj.h"
48 #include "jsfun.h"
49 #include "jsutil.h"
51 using namespace mozilla::jsipc;
53 namespace {
55 // Only need one reserved slot because the ObjectWrapperParent* is
56 // stored in the private slot.
57 static const uintN sFlagsSlot = 0;
58 static const uintN sNumSlots = 1;
59 static const uintN CPOW_FLAG_RESOLVING = 1 << 0;
61 class AutoResolveFlag
63 JSContext* mContext;
64 JSObject* mObj;
65 uintN mOldFlags;
66 JS_DECL_USE_GUARD_OBJECT_NOTIFIER
68 static uintN GetFlags(JSContext* cx, JSObject* obj) {
69 jsval v;
70 #ifdef DEBUG
71 JSBool ok =
72 #endif
73 JS_GetReservedSlot(cx, obj, sFlagsSlot, &v);
74 NS_ASSERTION(ok, "Failed to get CPOW flags");
75 return JSVAL_TO_INT(v);
78 static uintN SetFlags(JSContext* cx, JSObject* obj, uintN flags) {
79 uintN oldFlags = GetFlags(cx, obj);
80 if (oldFlags != flags)
81 JS_SetReservedSlot(cx, obj, sFlagsSlot, INT_TO_JSVAL(flags));
82 return oldFlags;
85 public:
87 AutoResolveFlag(JSContext* cx,
88 JSObject* obj
89 JS_GUARD_OBJECT_NOTIFIER_PARAM)
90 : mContext(cx)
91 , mObj(obj)
92 , mOldFlags(SetFlags(cx, obj,
93 GetFlags(cx, obj) | CPOW_FLAG_RESOLVING))
95 JS_GUARD_OBJECT_NOTIFIER_INIT;
98 ~AutoResolveFlag() {
99 SetFlags(mContext, mObj, mOldFlags);
102 static JSBool IsSet(JSContext* cx, JSObject* obj) {
103 return GetFlags(cx, obj) & CPOW_FLAG_RESOLVING;
108 class StatusMemberOwner
110 OperationStatus mStatus;
111 public:
112 StatusMemberOwner() : mStatus(JS_FALSE) {}
113 OperationStatus* StatusPtr() {
114 return &mStatus;
118 typedef AutoCheckOperationBase<StatusMemberOwner> ACOBase;
120 class AutoCheckOperation : public ACOBase
122 JS_DECL_USE_GUARD_OBJECT_NOTIFIER
123 public:
124 AutoCheckOperation(JSContext* cx,
125 ObjectWrapperParent* owp
126 JS_GUARD_OBJECT_NOTIFIER_PARAM)
127 : ACOBase(cx, owp)
129 JS_GUARD_OBJECT_NOTIFIER_INIT;
135 void
136 ObjectWrapperParent::CheckOperation(JSContext* cx,
137 OperationStatus* status)
139 NS_PRECONDITION(status->type() != OperationStatus::T__None,
140 "Checking an uninitialized operation.");
142 switch (status->type()) {
143 case OperationStatus::TJSVariant:
145 jsval thrown;
146 if (jsval_from_JSVariant(cx, status->get_JSVariant(), &thrown))
147 JS_SetPendingException(cx, thrown);
148 *status = JS_FALSE;
150 break;
151 case OperationStatus::TJSBool:
152 if (!status->get_JSBool() && !JS_IsExceptionPending(cx)) {
153 NS_WARNING("CPOW operation failed without setting an exception.");
155 break;
156 default:
157 NS_NOTREACHED("Invalid or uninitialized OperationStatus type.");
158 break;
162 template <typename RType>
163 static RType
164 with_error(JSContext* cx,
165 RType rval,
166 const char* error = NULL)
168 if (!JS_IsExceptionPending(cx))
169 JS_ReportError(cx, error ? error : "Unspecified CPOW error");
170 return rval;
173 const js::Class ObjectWrapperParent::sCPOW_JSClass = {
174 "CrossProcessObjectWrapper",
175 JSCLASS_NEW_RESOLVE | JSCLASS_NEW_ENUMERATE |
176 JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(sNumSlots),
177 JS_VALUEIFY(js::PropertyOp, ObjectWrapperParent::CPOW_AddProperty),
178 JS_VALUEIFY(js::PropertyOp, ObjectWrapperParent::CPOW_DelProperty),
179 JS_VALUEIFY(js::PropertyOp, ObjectWrapperParent::CPOW_GetProperty),
180 JS_VALUEIFY(js::StrictPropertyOp, ObjectWrapperParent::CPOW_SetProperty),
181 (JSEnumerateOp) ObjectWrapperParent::CPOW_NewEnumerate,
182 (JSResolveOp) ObjectWrapperParent::CPOW_NewResolve,
183 JS_VALUEIFY(js::ConvertOp, ObjectWrapperParent::CPOW_Convert),
184 ObjectWrapperParent::CPOW_Finalize,
185 nsnull, // reserved1
186 nsnull, // checkAccess
187 JS_VALUEIFY(js::CallOp, ObjectWrapperParent::CPOW_Call),
188 JS_VALUEIFY(js::CallOp, ObjectWrapperParent::CPOW_Construct),
189 nsnull, // xdrObject
190 JS_VALUEIFY(js::HasInstanceOp, ObjectWrapperParent::CPOW_HasInstance),
191 nsnull, // mark
193 JS_VALUEIFY(js::EqualityOp, ObjectWrapperParent::CPOW_Equality),
194 nsnull, // outerObject
195 nsnull, // innerObject
196 nsnull, // iteratorObject
197 nsnull, // wrappedObject
201 void
202 ObjectWrapperParent::ActorDestroy(ActorDestroyReason)
204 if (mObj) {
205 mObj->setPrivate(NULL);
206 mObj = NULL;
210 ContextWrapperParent*
211 ObjectWrapperParent::Manager()
213 PContextWrapperParent* pcwp = PObjectWrapperParent::Manager();
214 return static_cast<ContextWrapperParent*>(pcwp);
217 JSObject*
218 ObjectWrapperParent::GetJSObject(JSContext* cx) const
220 js::Class *clasp = const_cast<js::Class *>(&ObjectWrapperParent::sCPOW_JSClass);
221 if (!mObj && (mObj = JS_NewObject(cx, js::Jsvalify(clasp), NULL, NULL))) {
222 JS_SetPrivate(cx, mObj, (void*)this);
223 JS_SetReservedSlot(cx, mObj, sFlagsSlot, JSVAL_ZERO);
225 return mObj;
228 static ObjectWrapperParent*
229 Unwrap(JSContext* cx, JSObject* obj)
231 while (obj->getClass() != &ObjectWrapperParent::sCPOW_JSClass)
232 if (!(obj = obj->getProto()))
233 return NULL;
235 ObjectWrapperParent* self =
236 static_cast<ObjectWrapperParent*>(JS_GetPrivate(cx, obj));
238 NS_ASSERTION(!self || self->GetJSObject(cx) == obj,
239 "Wrapper and wrapped object disagree?");
241 return self;
244 /*static*/ bool
245 ObjectWrapperParent::jsval_to_JSVariant(JSContext* cx, jsval from,
246 JSVariant* to)
248 switch (JS_TypeOfValue(cx, from)) {
249 case JSTYPE_VOID:
250 *to = void_t();
251 return true;
252 case JSTYPE_NULL:
253 if (from != JSVAL_NULL)
254 return false;
255 // fall through
256 case JSTYPE_FUNCTION:
257 // CPOWs can fool JS_TypeOfValue into returning JSTYPE_FUNCTION
258 // because they have a call hook, but CPOWs are really objects, so
259 // fall through to the JSTYPE_OBJECT case:
260 case JSTYPE_OBJECT:
262 PObjectWrapperParent* powp;
263 if (!JSObject_to_PObjectWrapperParent(cx, JSVAL_TO_OBJECT(from), &powp))
264 return with_error(cx, false, "Cannot pass parent-created object to child");
265 *to = powp;
267 return true;
268 case JSTYPE_STRING:
270 nsDependentJSString depStr;
271 if (!depStr.init(cx, from))
272 return false;
273 *to = depStr;
275 return true;
276 case JSTYPE_NUMBER:
277 if (JSVAL_IS_INT(from))
278 *to = JSVAL_TO_INT(from);
279 else if (JSVAL_IS_DOUBLE(from))
280 *to = JSVAL_TO_DOUBLE(from);
281 else return false;
282 return true;
283 case JSTYPE_BOOLEAN:
284 *to = !!JSVAL_TO_BOOLEAN(from);
285 return true;
286 case JSTYPE_XML:
287 return with_error(cx, false, "CPOWs currently cannot handle JSTYPE_XML");
288 default:
289 return with_error(cx, false, "Bad jsval type");
293 /*static*/ bool
294 ObjectWrapperParent::jsval_from_JSVariant(JSContext* cx, const JSVariant& from,
295 jsval* to)
297 switch (from.type()) {
298 case JSVariant::Tvoid_t:
299 *to = JSVAL_VOID;
300 return true;
301 case JSVariant::TPObjectWrapperParent:
302 return jsval_from_PObjectWrapperParent(cx, from.get_PObjectWrapperParent(), to);
303 case JSVariant::TnsString:
305 JSString* str = JS_NewUCStringCopyZ(cx, from.get_nsString().BeginReading());
306 if (!str)
307 return false;
308 *to = STRING_TO_JSVAL(str);
309 return true;
311 case JSVariant::Tint:
312 *to = INT_TO_JSVAL(from.get_int());
313 return true;
314 case JSVariant::Tdouble:
315 return !!JS_NewNumberValue(cx, from.get_double(), to);
316 case JSVariant::Tbool:
317 *to = BOOLEAN_TO_JSVAL(from.get_bool());
318 return true;
319 default:
320 return false;
324 /*static*/ bool
325 ObjectWrapperParent::
326 JSObject_to_PObjectWrapperParent(JSContext* cx, JSObject* from,
327 PObjectWrapperParent** to)
329 if (!from) {
330 *to = NULL;
331 return true;
333 ObjectWrapperParent* owp = Unwrap(cx, from);
334 if (!owp)
335 return false;
336 *to = owp;
337 return true;
340 /*static*/ bool
341 ObjectWrapperParent::
342 JSObject_from_PObjectWrapperParent(JSContext* cx,
343 const PObjectWrapperParent* from,
344 JSObject** to)
346 const ObjectWrapperParent* owp =
347 static_cast<const ObjectWrapperParent*>(from);
348 *to = owp
349 ? owp->GetJSObject(cx)
350 : JSVAL_TO_OBJECT(JSVAL_NULL);
351 return true;
354 /*static*/ bool
355 ObjectWrapperParent::
356 jsval_from_PObjectWrapperParent(JSContext* cx,
357 const PObjectWrapperParent* from,
358 jsval* to)
360 JSObject* obj;
361 if (!JSObject_from_PObjectWrapperParent(cx, from, &obj))
362 return false;
363 *to = OBJECT_TO_JSVAL(obj);
364 return true;
367 static bool
368 jsid_from_int(JSContext* cx, int from, jsid* to)
370 jsval v = INT_TO_JSVAL(from);
371 return JS_ValueToId(cx, v, to);
374 static bool
375 jsid_from_nsString(JSContext* cx, const nsString& from, jsid* to)
377 JSString* str = JS_NewUCStringCopyZ(cx, from.BeginReading());
378 if (!str)
379 return false;
380 return JS_ValueToId(cx, STRING_TO_JSVAL(str), to);
383 static bool
384 jsval_to_nsString(JSContext* cx, jsid from, nsString* to)
386 JSString* str;
387 const jschar* chars;
388 jsval idval;
389 if (JS_IdToValue(cx, from, &idval) &&
390 (str = JS_ValueToString(cx, idval)) &&
391 (chars = JS_GetStringCharsZ(cx, str))) {
392 *to = chars;
393 return true;
395 return false;
398 /*static*/ JSBool
399 ObjectWrapperParent::CPOW_AddProperty(JSContext *cx, JSObject *obj, jsid id,
400 jsval *vp)
402 CPOW_LOG(("Calling CPOW_AddProperty (%s)...",
403 JSVAL_TO_CSTR(cx, id)));
405 ObjectWrapperParent* self = Unwrap(cx, obj);
406 if (!self)
407 return with_error(cx, JS_FALSE, "Unwrapping failed in CPOW_AddProperty");
409 if (AutoResolveFlag::IsSet(cx, obj))
410 return JS_TRUE;
412 AutoCheckOperation aco(cx, self);
414 nsString in_id;
416 if (!jsval_to_nsString(cx, id, &in_id))
417 return JS_FALSE;
419 return (self->Manager()->RequestRunToCompletion() &&
420 self->CallAddProperty(in_id,
421 aco.StatusPtr()) &&
422 aco.Ok());
425 /*static*/ JSBool
426 ObjectWrapperParent::CPOW_GetProperty(JSContext *cx, JSObject *obj, jsid id,
427 jsval *vp)
429 CPOW_LOG(("Calling CPOW_GetProperty (%s)...",
430 JSVAL_TO_CSTR(cx, id)));
432 ObjectWrapperParent* self = Unwrap(cx, obj);
433 if (!self)
434 return with_error(cx, JS_FALSE, "Unwrapping failed in CPOW_GetProperty");
436 AutoCheckOperation aco(cx, self);
438 nsString in_id;
440 if (!jsval_to_nsString(cx, id, &in_id))
441 return JS_FALSE;
443 JSVariant out_v;
445 return (self->Manager()->RequestRunToCompletion() &&
446 self->CallGetProperty(in_id,
447 aco.StatusPtr(), &out_v) &&
448 aco.Ok() &&
449 self->jsval_from_JSVariant(cx, out_v, vp));
452 /*static*/ JSBool
453 ObjectWrapperParent::CPOW_SetProperty(JSContext *cx, JSObject *obj, jsid id,
454 JSBool strict, jsval *vp)
456 CPOW_LOG(("Calling CPOW_SetProperty (%s)...",
457 JSVAL_TO_CSTR(cx, id)));
459 ObjectWrapperParent* self = Unwrap(cx, obj);
460 if (!self)
461 return with_error(cx, JS_FALSE, "Unwrapping failed in CPOW_SetProperty");
463 AutoCheckOperation aco(cx, self);
465 nsString in_id;
466 JSVariant in_v;
468 if (!jsval_to_nsString(cx, id, &in_id) ||
469 !self->jsval_to_JSVariant(cx, *vp, &in_v))
470 return JS_FALSE;
472 JSVariant out_v;
474 return (self->Manager()->RequestRunToCompletion() &&
475 self->CallSetProperty(in_id, in_v,
476 aco.StatusPtr(), &out_v) &&
477 aco.Ok() &&
478 self->jsval_from_JSVariant(cx, out_v, vp));
481 /*static*/ JSBool
482 ObjectWrapperParent::CPOW_DelProperty(JSContext *cx, JSObject *obj, jsid id,
483 jsval *vp)
485 CPOW_LOG(("Calling CPOW_DelProperty (%s)...",
486 JSVAL_TO_CSTR(cx, id)));
488 ObjectWrapperParent* self = Unwrap(cx, obj);
489 if (!self)
490 return with_error(cx, JS_FALSE, "Unwrapping failed in CPOW_DelProperty");
492 AutoCheckOperation aco(cx, self);
494 nsString in_id;
496 if (!jsval_to_nsString(cx, id, &in_id))
497 return JS_FALSE;
499 JSVariant out_v;
501 return (self->Manager()->RequestRunToCompletion() &&
502 self->CallDelProperty(in_id,
503 aco.StatusPtr(), &out_v) &&
504 aco.Ok() &&
505 jsval_from_JSVariant(cx, out_v, vp));
508 JSBool
509 ObjectWrapperParent::NewEnumerateInit(JSContext* cx, jsval* statep, jsid* idp)
511 AutoCheckOperation aco(cx, this);
513 JSVariant out_state;
514 int out_id;
516 return (CallNewEnumerateInit(aco.StatusPtr(), &out_state, &out_id) &&
517 aco.Ok() &&
518 jsval_from_JSVariant(cx, out_state, statep) &&
519 (!idp || jsid_from_int(cx, out_id, idp)));
522 JSBool
523 ObjectWrapperParent::NewEnumerateNext(JSContext* cx, jsval* statep, jsid* idp)
525 AutoCheckOperation aco(cx, this);
527 JSVariant in_state;
529 if (!jsval_to_JSVariant(cx, *statep, &in_state))
530 return JS_FALSE;
532 JSVariant out_state;
533 nsString out_id;
535 if (CallNewEnumerateNext(in_state,
536 aco.StatusPtr(), &out_state, &out_id) &&
537 aco.Ok() &&
538 jsval_from_JSVariant(cx, out_state, statep) &&
539 jsid_from_nsString(cx, out_id, idp))
541 JSObject* obj = GetJSObject(cx);
542 AutoResolveFlag arf(cx, obj);
543 return JS_DefinePropertyById(cx, obj, *idp, JSVAL_VOID, NULL, NULL,
544 JSPROP_ENUMERATE);
546 return JS_FALSE;
549 JSBool
550 ObjectWrapperParent::NewEnumerateDestroy(JSContext* cx, jsval state)
552 AutoCheckOperation aco(cx, this);
554 JSVariant in_state;
556 if (!jsval_to_JSVariant(cx, state, &in_state))
557 return JS_FALSE;
559 return SendNewEnumerateDestroy(in_state);
562 /*static*/ JSBool
563 ObjectWrapperParent::CPOW_NewEnumerate(JSContext *cx, JSObject *obj,
564 JSIterateOp enum_op, jsval *statep,
565 jsid *idp)
567 CPOW_LOG(("Calling CPOW_NewEnumerate..."));
569 ObjectWrapperParent* self = Unwrap(cx, obj);
570 if (!self)
571 return with_error(cx, JS_FALSE, "Unwrapping failed in CPOW_NewEnumerate");
573 switch (enum_op) {
574 case JSENUMERATE_INIT:
575 case JSENUMERATE_INIT_ALL:
576 self->Manager()->RequestRunToCompletion();
577 return self->NewEnumerateInit(cx, statep, idp);
578 case JSENUMERATE_NEXT:
579 return self->NewEnumerateNext(cx, statep, idp);
580 case JSENUMERATE_DESTROY:
581 return self->NewEnumerateDestroy(cx, *statep);
584 NS_NOTREACHED("Unknown enum_op value in CPOW_NewEnumerate");
585 return JS_FALSE;
588 /*static*/ JSBool
589 ObjectWrapperParent::CPOW_NewResolve(JSContext *cx, JSObject *obj, jsid id,
590 uintN flags, JSObject **objp)
592 CPOW_LOG(("Calling CPOW_NewResolve (%s)...",
593 JSVAL_TO_CSTR(cx, id)));
595 ObjectWrapperParent* self = Unwrap(cx, obj);
596 if (!self)
597 return with_error(cx, JS_FALSE, "Unwrapping failed in CPOW_NewResolve");
599 AutoCheckOperation aco(cx, self);
601 nsString in_id;
603 if (!jsval_to_nsString(cx, id, &in_id))
604 return JS_FALSE;
606 PObjectWrapperParent* out_pobj;
608 if (!self->Manager()->RequestRunToCompletion() ||
609 !self->CallNewResolve(in_id, flags,
610 aco.StatusPtr(), &out_pobj) ||
611 !aco.Ok() ||
612 !JSObject_from_PObjectWrapperParent(cx, out_pobj, objp))
613 return JS_FALSE;
615 if (*objp) {
616 AutoResolveFlag arf(cx, *objp);
617 JS_DefinePropertyById(cx, *objp, id, JSVAL_VOID, NULL, NULL,
618 JSPROP_ENUMERATE);
620 return JS_TRUE;
623 /*static*/ JSBool
624 ObjectWrapperParent::CPOW_Convert(JSContext *cx, JSObject *obj, JSType type,
625 jsval *vp)
627 CPOW_LOG(("Calling CPOW_Convert (to %s)...",
628 JS_GetTypeName(cx, type)));
630 ObjectWrapperParent* self = Unwrap(cx, obj);
631 if (!self)
632 return with_error(cx, JS_FALSE, "Unwrapping failed in CPOW_Convert");
634 *vp = OBJECT_TO_JSVAL(obj);
636 return JS_TRUE;
639 /*static*/ void
640 ObjectWrapperParent::CPOW_Finalize(JSContext* cx, JSObject* obj)
642 CPOW_LOG(("Calling CPOW_Finalize..."));
644 ObjectWrapperParent* self = Unwrap(cx, obj);
645 if (self) {
646 self->mObj = NULL;
647 unused << ObjectWrapperParent::Send__delete__(self);
651 /*static*/ JSBool
652 ObjectWrapperParent::CPOW_Call(JSContext* cx, uintN argc, jsval* vp)
654 CPOW_LOG(("Calling CPOW_Call..."));
656 JSObject* thisobj = JS_THIS_OBJECT(cx, vp);
657 if (!thisobj)
658 return JS_FALSE;
660 ObjectWrapperParent* function =
661 Unwrap(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)));
662 if (!function)
663 return with_error(cx, JS_FALSE, "Could not unwrap CPOW function");
665 AutoCheckOperation aco(cx, function);
667 ObjectWrapperParent* receiver = Unwrap(cx, thisobj);
668 if (!receiver) {
669 // Substitute child global for parent global object.
670 // TODO First make sure we're really replacing the global object?
671 ContextWrapperParent* manager =
672 static_cast<ContextWrapperParent*>(function->Manager());
673 receiver = manager->GetGlobalObjectWrapper();
676 InfallibleTArray<JSVariant> in_argv(argc);
677 jsval* argv = JS_ARGV(cx, vp);
678 for (uintN i = 0; i < argc; i++)
679 if (!jsval_to_JSVariant(cx, argv[i], in_argv.AppendElement()))
680 return JS_FALSE;
682 JSVariant out_rval;
684 return (function->Manager()->RequestRunToCompletion() &&
685 function->CallCall(receiver, in_argv,
686 aco.StatusPtr(), &out_rval) &&
687 aco.Ok() &&
688 jsval_from_JSVariant(cx, out_rval, vp));
691 /*static*/ JSBool
692 ObjectWrapperParent::CPOW_Construct(JSContext* cx, uintN argc, jsval* vp)
694 CPOW_LOG(("Calling CPOW_Construct..."));
696 ObjectWrapperParent* constructor = Unwrap(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)));
697 if (!constructor)
698 return with_error(cx, JS_FALSE, "Could not unwrap CPOW constructor function");
700 AutoCheckOperation aco(cx, constructor);
702 InfallibleTArray<JSVariant> in_argv(argc);
703 jsval* argv = JS_ARGV(cx, vp);
704 for (uintN i = 0; i < argc; i++)
705 if (!jsval_to_JSVariant(cx, argv[i], in_argv.AppendElement()))
706 return JS_FALSE;
708 PObjectWrapperParent* out_powp;
710 return (constructor->Manager()->RequestRunToCompletion() &&
711 constructor->CallConstruct(in_argv, aco.StatusPtr(), &out_powp) &&
712 aco.Ok() &&
713 jsval_from_PObjectWrapperParent(cx, out_powp, vp));
716 /*static*/ JSBool
717 ObjectWrapperParent::CPOW_HasInstance(JSContext *cx, JSObject *obj, const jsval *v,
718 JSBool *bp)
720 CPOW_LOG(("Calling CPOW_HasInstance..."));
722 *bp = JS_FALSE;
724 ObjectWrapperParent* self = Unwrap(cx, obj);
725 if (!self)
726 return with_error(cx, JS_FALSE, "Unwrapping failed in CPOW_HasInstance");
728 AutoCheckOperation aco(cx, self);
730 JSVariant in_v;
732 if (!jsval_to_JSVariant(cx, *v, &in_v))
733 return JS_FALSE;
735 return (self->Manager()->RequestRunToCompletion() &&
736 self->CallHasInstance(in_v,
737 aco.StatusPtr(), bp) &&
738 aco.Ok());
741 /*static*/ JSBool
742 ObjectWrapperParent::CPOW_Equality(JSContext *cx, JSObject *obj, const jsval *v,
743 JSBool *bp)
745 CPOW_LOG(("Calling CPOW_Equality..."));
747 *bp = JS_FALSE;
749 ObjectWrapperParent* self = Unwrap(cx, obj);
750 if (!self)
751 return with_error(cx, JS_FALSE, "Unwrapping failed in CPOW_Equality");
753 if (JSVAL_IS_PRIMITIVE(*v))
754 return JS_TRUE;
756 ObjectWrapperParent* other = Unwrap(cx, JSVAL_TO_OBJECT(*v));
757 if (!other)
758 return JS_TRUE;
760 *bp = (self == other);
762 return JS_TRUE;