2013-07-03 00:24:32 -07:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
|
|
* vim: set ts=4 sw=4 et tw=80:
|
|
|
|
*
|
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
|
|
|
#include "JavaScriptParent.h"
|
|
|
|
#include "mozilla/dom/ContentParent.h"
|
|
|
|
#include "nsJSUtils.h"
|
|
|
|
#include "jsfriendapi.h"
|
|
|
|
#include "jsproxy.h"
|
2013-08-17 15:50:18 -07:00
|
|
|
#include "jswrapper.h"
|
2013-07-03 00:24:32 -07:00
|
|
|
#include "HeapAPI.h"
|
|
|
|
#include "xpcprivate.h"
|
|
|
|
#include "mozilla/Casting.h"
|
|
|
|
|
|
|
|
using namespace js;
|
|
|
|
using namespace JS;
|
|
|
|
using namespace mozilla;
|
|
|
|
using namespace mozilla::jsipc;
|
2013-06-03 03:14:37 -07:00
|
|
|
using namespace mozilla::dom;
|
2013-07-03 00:24:32 -07:00
|
|
|
|
|
|
|
JavaScriptParent::JavaScriptParent()
|
2014-05-16 16:40:36 -07:00
|
|
|
: refcount_(1)
|
2013-07-03 00:24:32 -07:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2013-07-11 08:23:34 -07:00
|
|
|
void
|
|
|
|
JavaScriptParent::drop(JSObject *obj)
|
|
|
|
{
|
|
|
|
ObjectId objId = idOf(obj);
|
|
|
|
|
2014-05-16 16:40:36 -07:00
|
|
|
cpows_.remove(objId);
|
2014-05-16 16:40:36 -07:00
|
|
|
if (active() && !SendDropObject(objId))
|
2013-07-10 15:05:39 -07:00
|
|
|
(void)0;
|
2013-07-11 08:23:34 -07:00
|
|
|
decref();
|
|
|
|
}
|
|
|
|
|
2013-07-03 00:24:32 -07:00
|
|
|
bool
|
|
|
|
JavaScriptParent::init()
|
|
|
|
{
|
2014-05-16 16:40:36 -07:00
|
|
|
if (!WrapperOwner::init())
|
2013-07-03 00:24:32 -07:00
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2014-05-16 16:40:35 -07:00
|
|
|
JavaScriptParent::toId(JSContext *cx, JSObject *obj, ObjectId *idp)
|
2013-07-03 00:24:32 -07:00
|
|
|
{
|
2013-08-01 16:45:17 -07:00
|
|
|
obj = js::CheckedUnwrap(obj, false);
|
2014-05-16 16:40:36 -07:00
|
|
|
if (!obj || !IsCPOW(obj)) {
|
2013-07-03 00:24:32 -07:00
|
|
|
JS_ReportError(cx, "cannot ipc non-cpow object");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
*idp = idOf(obj);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
JSObject *
|
2014-05-16 16:40:35 -07:00
|
|
|
JavaScriptParent::fromId(JSContext *cx, ObjectId objId)
|
2013-07-03 00:24:32 -07:00
|
|
|
{
|
2014-05-16 16:40:35 -07:00
|
|
|
RootedObject obj(cx, findCPOWById(objId));
|
2013-08-23 15:53:46 -07:00
|
|
|
if (obj) {
|
2013-10-15 17:02:23 -07:00
|
|
|
if (!JS_WrapObject(cx, &obj))
|
2013-09-19 12:24:53 -07:00
|
|
|
return nullptr;
|
2013-07-03 00:24:32 -07:00
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (objId > MAX_CPOW_IDS) {
|
|
|
|
JS_ReportError(cx, "unusable CPOW id");
|
2013-09-19 12:24:53 -07:00
|
|
|
return nullptr;
|
2013-07-03 00:24:32 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
bool callable = !!(objId & OBJECT_IS_CALLABLE);
|
|
|
|
|
2013-07-29 17:51:16 -07:00
|
|
|
RootedObject global(cx, JS::CurrentGlobalOrNull(cx));
|
2013-07-25 11:50:00 -07:00
|
|
|
|
2013-07-03 00:24:32 -07:00
|
|
|
RootedValue v(cx, UndefinedValue());
|
2013-10-04 04:29:35 -07:00
|
|
|
ProxyOptions options;
|
2014-01-29 17:20:16 -08:00
|
|
|
options.selectDefaultClass(callable);
|
2013-08-23 15:53:46 -07:00
|
|
|
obj = NewProxyObject(cx,
|
2014-05-16 16:40:36 -07:00
|
|
|
ProxyHandler(),
|
2013-08-23 15:53:46 -07:00
|
|
|
v,
|
2013-09-19 12:24:53 -07:00
|
|
|
nullptr,
|
2013-08-23 15:53:46 -07:00
|
|
|
global,
|
2013-10-04 04:29:35 -07:00
|
|
|
options);
|
2013-07-03 00:24:32 -07:00
|
|
|
if (!obj)
|
2013-09-19 12:24:53 -07:00
|
|
|
return nullptr;
|
2013-07-03 00:24:32 -07:00
|
|
|
|
2014-05-16 16:40:36 -07:00
|
|
|
if (!cpows_.add(objId, obj))
|
2013-09-19 12:24:53 -07:00
|
|
|
return nullptr;
|
2013-07-03 00:24:32 -07:00
|
|
|
|
|
|
|
// Incref once we know the decref will be called.
|
|
|
|
incref();
|
|
|
|
|
|
|
|
SetProxyExtra(obj, 0, PrivateValue(this));
|
|
|
|
SetProxyExtra(obj, 1, DoubleValue(BitwiseCast<double>(objId)));
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
JavaScriptParent::decref()
|
|
|
|
{
|
|
|
|
refcount_--;
|
|
|
|
if (!refcount_)
|
|
|
|
delete this;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
JavaScriptParent::incref()
|
|
|
|
{
|
|
|
|
refcount_++;
|
|
|
|
}
|
|
|
|
|
2013-06-03 03:14:37 -07:00
|
|
|
mozilla::ipc::IProtocol*
|
|
|
|
JavaScriptParent::CloneProtocol(Channel* aChannel, ProtocolCloneContext* aCtx)
|
|
|
|
{
|
|
|
|
ContentParent *contentParent = aCtx->GetContentParent();
|
|
|
|
nsAutoPtr<PJavaScriptParent> actor(contentParent->AllocPJavaScriptParent());
|
|
|
|
if (!actor || !contentParent->RecvPJavaScriptConstructor(actor)) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
return actor.forget();
|
|
|
|
}
|