зеркало из https://github.com/mozilla/gecko-dev.git
Merge inbound to m-c
This commit is contained in:
Коммит
7091eb5722
|
@ -735,6 +735,12 @@ var Input = {
|
||||||
case 'swipeleft1':
|
case 'swipeleft1':
|
||||||
this.moveCursor('movePrevious', 'Simple', 'gesture');
|
this.moveCursor('movePrevious', 'Simple', 'gesture');
|
||||||
break;
|
break;
|
||||||
|
case 'swipeup1':
|
||||||
|
this.contextAction('backward');
|
||||||
|
break;
|
||||||
|
case 'swipedown1':
|
||||||
|
this.contextAction('forward');
|
||||||
|
break;
|
||||||
case 'exploreend1':
|
case 'exploreend1':
|
||||||
this.activateCurrent(null, true);
|
this.activateCurrent(null, true);
|
||||||
break;
|
break;
|
||||||
|
@ -859,6 +865,12 @@ var Input = {
|
||||||
origin: 'top', inputType: aInputType});
|
origin: 'top', inputType: aInputType});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
contextAction: function contextAction(aDirection) {
|
||||||
|
// XXX: For now, the only supported context action is adjusting a range.
|
||||||
|
let mm = Utils.getMessageManager(Utils.CurrentBrowser);
|
||||||
|
mm.sendAsyncMessage('AccessFu:AdjustRange', {direction: aDirection});
|
||||||
|
},
|
||||||
|
|
||||||
moveByGranularity: function moveByGranularity(aDetails) {
|
moveByGranularity: function moveByGranularity(aDetails) {
|
||||||
const MOVEMENT_GRANULARITY_PARAGRAPH = 8;
|
const MOVEMENT_GRANULARITY_PARAGRAPH = 8;
|
||||||
|
|
||||||
|
|
|
@ -331,6 +331,23 @@ function scroll(aMessage) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function adjustRange(aMessage) {
|
||||||
|
function sendUpDownKey(aAccessible) {
|
||||||
|
let evt = content.document.createEvent('KeyboardEvent');
|
||||||
|
let keycode = aMessage.json.direction == 'forward' ?
|
||||||
|
content.KeyEvent.DOM_VK_DOWN : content.KeyEvent.DOM_VK_UP;
|
||||||
|
evt.initKeyEvent(
|
||||||
|
"keypress", false, true, null, false, false, false, false, keycode, 0);
|
||||||
|
if (aAccessible.DOMNode) {
|
||||||
|
aAccessible.DOMNode.dispatchEvent(evt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let position = Utils.getVirtualCursor(content.document).position;
|
||||||
|
if (!forwardToChild(aMessage, adjustRange, position)) {
|
||||||
|
sendUpDownKey(position);
|
||||||
|
}
|
||||||
|
}
|
||||||
addMessageListener(
|
addMessageListener(
|
||||||
'AccessFu:Start',
|
'AccessFu:Start',
|
||||||
function(m) {
|
function(m) {
|
||||||
|
@ -344,6 +361,7 @@ addMessageListener(
|
||||||
addMessageListener('AccessFu:Activate', activateCurrent);
|
addMessageListener('AccessFu:Activate', activateCurrent);
|
||||||
addMessageListener('AccessFu:ContextMenu', activateContextMenu);
|
addMessageListener('AccessFu:ContextMenu', activateContextMenu);
|
||||||
addMessageListener('AccessFu:Scroll', scroll);
|
addMessageListener('AccessFu:Scroll', scroll);
|
||||||
|
addMessageListener('AccessFu:AdjustRange', adjustRange);
|
||||||
addMessageListener('AccessFu:MoveCaret', moveCaret);
|
addMessageListener('AccessFu:MoveCaret', moveCaret);
|
||||||
addMessageListener('AccessFu:MoveByGranularity', moveByGranularity);
|
addMessageListener('AccessFu:MoveByGranularity', moveByGranularity);
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ interface nsIDOMDOMStringList;
|
||||||
interface nsIDOMWindow;
|
interface nsIDOMWindow;
|
||||||
interface nsIDocShell;
|
interface nsIDocShell;
|
||||||
interface nsIContent;
|
interface nsIContent;
|
||||||
|
interface nsIPrincipal;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Message managers provide a way for chrome-privileged JS code to
|
* Message managers provide a way for chrome-privileged JS code to
|
||||||
|
@ -156,14 +157,15 @@ interface nsIMessageListener : nsISupports
|
||||||
* receiveMessage is called with one parameter, which has the following
|
* receiveMessage is called with one parameter, which has the following
|
||||||
* properties:
|
* properties:
|
||||||
* {
|
* {
|
||||||
* target: %the target of the message. Either an element owning
|
* target: %the target of the message. Either an element owning
|
||||||
* the message manager, or message manager itself if no
|
* the message manager, or message manager itself if no
|
||||||
* element owns it%
|
* element owns it%
|
||||||
* name: %message name%,
|
* name: %message name%,
|
||||||
* sync: %true or false%.
|
* sync: %true or false%.
|
||||||
* data: %structured clone of the sent message data%,
|
* data: %structured clone of the sent message data%,
|
||||||
* json: %same as .data, deprecated%,
|
* json: %same as .data, deprecated%,
|
||||||
* objects: %named table of jsvals/objects, or null%
|
* objects: %named table of jsvals/objects, or null%
|
||||||
|
* principal: %principal for the window app
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* Each listener is invoked with its own copy of the message
|
* Each listener is invoked with its own copy of the message
|
||||||
|
@ -231,7 +233,7 @@ interface nsIMessageListenerManager : nsISupports
|
||||||
* messages that are only delivered to its one parent-process message
|
* messages that are only delivered to its one parent-process message
|
||||||
* manager.
|
* manager.
|
||||||
*/
|
*/
|
||||||
[scriptable, builtinclass, uuid(7f23767d-0f39-40c1-a22d-d3ab8a481f9d)]
|
[scriptable, builtinclass, uuid(d6b0d851-43e6-426d-9f13-054bc0198175)]
|
||||||
interface nsIMessageSender : nsIMessageListenerManager
|
interface nsIMessageSender : nsIMessageListenerManager
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
@ -252,7 +254,8 @@ interface nsIMessageSender : nsIMessageListenerManager
|
||||||
[implicit_jscontext, optional_argc]
|
[implicit_jscontext, optional_argc]
|
||||||
void sendAsyncMessage([optional] in AString messageName,
|
void sendAsyncMessage([optional] in AString messageName,
|
||||||
[optional] in jsval obj,
|
[optional] in jsval obj,
|
||||||
[optional] in jsval objects);
|
[optional] in jsval objects,
|
||||||
|
[optional] in nsIPrincipal principal);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -289,7 +292,7 @@ interface nsIMessageBroadcaster : nsIMessageListenerManager
|
||||||
nsIMessageListenerManager getChildAt(in unsigned long aIndex);
|
nsIMessageListenerManager getChildAt(in unsigned long aIndex);
|
||||||
};
|
};
|
||||||
|
|
||||||
[scriptable, builtinclass, uuid(79eeb70f-58e3-4d32-b46f-106f42ada12b)]
|
[scriptable, builtinclass, uuid(7fda0941-9dcc-448b-bd39-16373c5b4003)]
|
||||||
interface nsISyncMessageSender : nsIMessageSender
|
interface nsISyncMessageSender : nsIMessageSender
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
@ -300,7 +303,8 @@ interface nsISyncMessageSender : nsIMessageSender
|
||||||
[implicit_jscontext, optional_argc]
|
[implicit_jscontext, optional_argc]
|
||||||
jsval sendSyncMessage([optional] in AString messageName,
|
jsval sendSyncMessage([optional] in AString messageName,
|
||||||
[optional] in jsval obj,
|
[optional] in jsval obj,
|
||||||
[optional] in jsval objects);
|
[optional] in jsval objects,
|
||||||
|
[optional] in nsIPrincipal principal);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Like |sendSyncMessage()|, except re-entrant. New RPC messages may be
|
* Like |sendSyncMessage()|, except re-entrant. New RPC messages may be
|
||||||
|
@ -314,7 +318,8 @@ interface nsISyncMessageSender : nsIMessageSender
|
||||||
[implicit_jscontext, optional_argc]
|
[implicit_jscontext, optional_argc]
|
||||||
jsval sendRpcMessage([optional] in AString messageName,
|
jsval sendRpcMessage([optional] in AString messageName,
|
||||||
[optional] in jsval obj,
|
[optional] in jsval obj,
|
||||||
[optional] in jsval objects);
|
[optional] in jsval objects,
|
||||||
|
[optional] in nsIPrincipal principal);
|
||||||
};
|
};
|
||||||
|
|
||||||
[scriptable, builtinclass, uuid(894ff2d4-39a3-4df8-9d76-8ee329975488)]
|
[scriptable, builtinclass, uuid(894ff2d4-39a3-4df8-9d76-8ee329975488)]
|
||||||
|
|
|
@ -2215,8 +2215,10 @@ public:
|
||||||
nsFrameLoader* aFrameLoader,
|
nsFrameLoader* aFrameLoader,
|
||||||
const nsAString& aMessage,
|
const nsAString& aMessage,
|
||||||
const StructuredCloneData& aData,
|
const StructuredCloneData& aData,
|
||||||
JS::Handle<JSObject *> aCpows)
|
JS::Handle<JSObject *> aCpows,
|
||||||
: mRuntime(js::GetRuntime(aCx)), mFrameLoader(aFrameLoader), mMessage(aMessage), mCpows(aCpows)
|
nsIPrincipal* aPrincipal)
|
||||||
|
: mRuntime(js::GetRuntime(aCx)), mFrameLoader(aFrameLoader)
|
||||||
|
, mMessage(aMessage), mCpows(aCpows), mPrincipal(aPrincipal)
|
||||||
{
|
{
|
||||||
if (aData.mDataLength && !mData.copy(aData.mData, aData.mDataLength)) {
|
if (aData.mDataLength && !mData.copy(aData.mData, aData.mDataLength)) {
|
||||||
NS_RUNTIMEABORT("OOM");
|
NS_RUNTIMEABORT("OOM");
|
||||||
|
@ -2249,7 +2251,7 @@ public:
|
||||||
|
|
||||||
nsRefPtr<nsFrameMessageManager> mm = tabChild->GetInnerManager();
|
nsRefPtr<nsFrameMessageManager> mm = tabChild->GetInnerManager();
|
||||||
mm->ReceiveMessage(static_cast<EventTarget*>(tabChild), mMessage,
|
mm->ReceiveMessage(static_cast<EventTarget*>(tabChild), mMessage,
|
||||||
false, &data, &cpows, nullptr);
|
false, &data, &cpows, mPrincipal, nullptr);
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -2259,13 +2261,15 @@ public:
|
||||||
JSAutoStructuredCloneBuffer mData;
|
JSAutoStructuredCloneBuffer mData;
|
||||||
StructuredCloneClosure mClosure;
|
StructuredCloneClosure mClosure;
|
||||||
JSObject* mCpows;
|
JSObject* mCpows;
|
||||||
|
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool
|
bool
|
||||||
nsFrameLoader::DoSendAsyncMessage(JSContext* aCx,
|
nsFrameLoader::DoSendAsyncMessage(JSContext* aCx,
|
||||||
const nsAString& aMessage,
|
const nsAString& aMessage,
|
||||||
const StructuredCloneData& aData,
|
const StructuredCloneData& aData,
|
||||||
JS::Handle<JSObject *> aCpows)
|
JS::Handle<JSObject *> aCpows,
|
||||||
|
nsIPrincipal* aPrincipal)
|
||||||
{
|
{
|
||||||
TabParent* tabParent = mRemoteBrowser;
|
TabParent* tabParent = mRemoteBrowser;
|
||||||
if (tabParent) {
|
if (tabParent) {
|
||||||
|
@ -2278,11 +2282,14 @@ nsFrameLoader::DoSendAsyncMessage(JSContext* aCx,
|
||||||
if (aCpows && !cp->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
|
if (aCpows && !cp->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return tabParent->SendAsyncMessage(nsString(aMessage), data, cpows);
|
return tabParent->SendAsyncMessage(nsString(aMessage), data, cpows,
|
||||||
|
aPrincipal);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mChildMessageManager) {
|
if (mChildMessageManager) {
|
||||||
nsRefPtr<nsIRunnable> ev = new nsAsyncMessageToChild(aCx, this, aMessage, aData, aCpows);
|
nsRefPtr<nsIRunnable> ev = new nsAsyncMessageToChild(aCx, this, aMessage,
|
||||||
|
aData, aCpows,
|
||||||
|
aPrincipal);
|
||||||
NS_DispatchToCurrentThread(ev);
|
NS_DispatchToCurrentThread(ev);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -184,7 +184,8 @@ public:
|
||||||
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||||
const nsAString& aMessage,
|
const nsAString& aMessage,
|
||||||
const mozilla::dom::StructuredCloneData& aData,
|
const mozilla::dom::StructuredCloneData& aData,
|
||||||
JS::Handle<JSObject *> aCpows);
|
JS::Handle<JSObject *> aCpows,
|
||||||
|
nsIPrincipal* aPrincipal) MOZ_OVERRIDE;
|
||||||
virtual bool CheckPermission(const nsAString& aPermission) MOZ_OVERRIDE;
|
virtual bool CheckPermission(const nsAString& aPermission) MOZ_OVERRIDE;
|
||||||
virtual bool CheckManifestURL(const nsAString& aManifestURL) MOZ_OVERRIDE;
|
virtual bool CheckManifestURL(const nsAString& aManifestURL) MOZ_OVERRIDE;
|
||||||
virtual bool CheckAppHasPermission(const nsAString& aPermission) MOZ_OVERRIDE;
|
virtual bool CheckAppHasPermission(const nsAString& aPermission) MOZ_OVERRIDE;
|
||||||
|
|
|
@ -500,28 +500,33 @@ NS_IMETHODIMP
|
||||||
nsFrameMessageManager::SendSyncMessage(const nsAString& aMessageName,
|
nsFrameMessageManager::SendSyncMessage(const nsAString& aMessageName,
|
||||||
const JS::Value& aJSON,
|
const JS::Value& aJSON,
|
||||||
const JS::Value& aObjects,
|
const JS::Value& aObjects,
|
||||||
|
nsIPrincipal* aPrincipal,
|
||||||
JSContext* aCx,
|
JSContext* aCx,
|
||||||
uint8_t aArgc,
|
uint8_t aArgc,
|
||||||
JS::Value* aRetval)
|
JS::Value* aRetval)
|
||||||
{
|
{
|
||||||
return SendMessage(aMessageName, aJSON, aObjects, aCx, aArgc, aRetval, true);
|
return SendMessage(aMessageName, aJSON, aObjects, aPrincipal, aCx, aArgc,
|
||||||
|
aRetval, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsFrameMessageManager::SendRpcMessage(const nsAString& aMessageName,
|
nsFrameMessageManager::SendRpcMessage(const nsAString& aMessageName,
|
||||||
const JS::Value& aJSON,
|
const JS::Value& aJSON,
|
||||||
const JS::Value& aObjects,
|
const JS::Value& aObjects,
|
||||||
|
nsIPrincipal* aPrincipal,
|
||||||
JSContext* aCx,
|
JSContext* aCx,
|
||||||
uint8_t aArgc,
|
uint8_t aArgc,
|
||||||
JS::Value* aRetval)
|
JS::Value* aRetval)
|
||||||
{
|
{
|
||||||
return SendMessage(aMessageName, aJSON, aObjects, aCx, aArgc, aRetval, false);
|
return SendMessage(aMessageName, aJSON, aObjects, aPrincipal, aCx, aArgc,
|
||||||
|
aRetval, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsFrameMessageManager::SendMessage(const nsAString& aMessageName,
|
nsFrameMessageManager::SendMessage(const nsAString& aMessageName,
|
||||||
const JS::Value& aJSON,
|
const JS::Value& aJSON,
|
||||||
const JS::Value& aObjects,
|
const JS::Value& aObjects,
|
||||||
|
nsIPrincipal* aPrincipal,
|
||||||
JSContext* aCx,
|
JSContext* aCx,
|
||||||
uint8_t aArgc,
|
uint8_t aArgc,
|
||||||
JS::Value* aRetval,
|
JS::Value* aRetval,
|
||||||
|
@ -556,7 +561,8 @@ nsFrameMessageManager::SendMessage(const nsAString& aMessageName,
|
||||||
InfallibleTArray<nsString> retval;
|
InfallibleTArray<nsString> retval;
|
||||||
|
|
||||||
sSendingSyncMessage |= aIsSync;
|
sSendingSyncMessage |= aIsSync;
|
||||||
bool rv = mCallback->DoSendBlockingMessage(aCx, aMessageName, data, objects, &retval, aIsSync);
|
bool rv = mCallback->DoSendBlockingMessage(aCx, aMessageName, data, objects,
|
||||||
|
aPrincipal, &retval, aIsSync);
|
||||||
if (aIsSync) {
|
if (aIsSync) {
|
||||||
sSendingSyncMessage = false;
|
sSendingSyncMessage = false;
|
||||||
}
|
}
|
||||||
|
@ -591,19 +597,20 @@ nsresult
|
||||||
nsFrameMessageManager::DispatchAsyncMessageInternal(JSContext* aCx,
|
nsFrameMessageManager::DispatchAsyncMessageInternal(JSContext* aCx,
|
||||||
const nsAString& aMessage,
|
const nsAString& aMessage,
|
||||||
const StructuredCloneData& aData,
|
const StructuredCloneData& aData,
|
||||||
JS::Handle<JSObject *> aCpows)
|
JS::Handle<JSObject *> aCpows,
|
||||||
|
nsIPrincipal* aPrincipal)
|
||||||
{
|
{
|
||||||
if (mIsBroadcaster) {
|
if (mIsBroadcaster) {
|
||||||
int32_t len = mChildManagers.Count();
|
int32_t len = mChildManagers.Count();
|
||||||
for (int32_t i = 0; i < len; ++i) {
|
for (int32_t i = 0; i < len; ++i) {
|
||||||
static_cast<nsFrameMessageManager*>(mChildManagers[i])->
|
static_cast<nsFrameMessageManager*>(mChildManagers[i])->
|
||||||
DispatchAsyncMessageInternal(aCx, aMessage, aData, aCpows);
|
DispatchAsyncMessageInternal(aCx, aMessage, aData, aCpows, aPrincipal);
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_ENSURE_TRUE(mCallback, NS_ERROR_NOT_INITIALIZED);
|
NS_ENSURE_TRUE(mCallback, NS_ERROR_NOT_INITIALIZED);
|
||||||
if (!mCallback->DoSendAsyncMessage(aCx, aMessage, aData, aCpows)) {
|
if (!mCallback->DoSendAsyncMessage(aCx, aMessage, aData, aCpows, aPrincipal)) {
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -613,6 +620,7 @@ nsresult
|
||||||
nsFrameMessageManager::DispatchAsyncMessage(const nsAString& aMessageName,
|
nsFrameMessageManager::DispatchAsyncMessage(const nsAString& aMessageName,
|
||||||
const JS::Value& aJSON,
|
const JS::Value& aJSON,
|
||||||
const JS::Value& aObjects,
|
const JS::Value& aObjects,
|
||||||
|
nsIPrincipal* aPrincipal,
|
||||||
JSContext* aCx,
|
JSContext* aCx,
|
||||||
uint8_t aArgc)
|
uint8_t aArgc)
|
||||||
{
|
{
|
||||||
|
@ -632,7 +640,8 @@ nsFrameMessageManager::DispatchAsyncMessage(const nsAString& aMessageName,
|
||||||
data.mData = buffer.data();
|
data.mData = buffer.data();
|
||||||
data.mDataLength = buffer.nbytes();
|
data.mDataLength = buffer.nbytes();
|
||||||
|
|
||||||
return DispatchAsyncMessageInternal(aCx, aMessageName, data, objects);
|
return DispatchAsyncMessageInternal(aCx, aMessageName, data, objects,
|
||||||
|
aPrincipal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -642,10 +651,12 @@ NS_IMETHODIMP
|
||||||
nsFrameMessageManager::SendAsyncMessage(const nsAString& aMessageName,
|
nsFrameMessageManager::SendAsyncMessage(const nsAString& aMessageName,
|
||||||
const JS::Value& aJSON,
|
const JS::Value& aJSON,
|
||||||
const JS::Value& aObjects,
|
const JS::Value& aObjects,
|
||||||
|
nsIPrincipal* aPrincipal,
|
||||||
JSContext* aCx,
|
JSContext* aCx,
|
||||||
uint8_t aArgc)
|
uint8_t aArgc)
|
||||||
{
|
{
|
||||||
return DispatchAsyncMessage(aMessageName, aJSON, aObjects, aCx, aArgc);
|
return DispatchAsyncMessage(aMessageName, aJSON, aObjects, aPrincipal, aCx,
|
||||||
|
aArgc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -658,7 +669,8 @@ nsFrameMessageManager::BroadcastAsyncMessage(const nsAString& aMessageName,
|
||||||
JSContext* aCx,
|
JSContext* aCx,
|
||||||
uint8_t aArgc)
|
uint8_t aArgc)
|
||||||
{
|
{
|
||||||
return DispatchAsyncMessage(aMessageName, aJSON, aObjects, aCx, aArgc);
|
return DispatchAsyncMessage(aMessageName, aJSON, aObjects, nullptr, aCx,
|
||||||
|
aArgc);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -841,6 +853,7 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
|
||||||
bool aIsSync,
|
bool aIsSync,
|
||||||
const StructuredCloneData* aCloneData,
|
const StructuredCloneData* aCloneData,
|
||||||
CpowHolder* aCpows,
|
CpowHolder* aCpows,
|
||||||
|
nsIPrincipal* aPrincipal,
|
||||||
InfallibleTArray<nsString>* aJSONRetVal)
|
InfallibleTArray<nsString>* aJSONRetVal)
|
||||||
{
|
{
|
||||||
AutoSafeJSContext ctx;
|
AutoSafeJSContext ctx;
|
||||||
|
@ -926,6 +939,42 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
|
||||||
JS_DefineProperty(ctx, param, "data", json, nullptr, nullptr, JSPROP_ENUMERATE);
|
JS_DefineProperty(ctx, param, "data", json, nullptr, nullptr, JSPROP_ENUMERATE);
|
||||||
JS_DefineProperty(ctx, param, "objects", cpowsv, nullptr, nullptr, JSPROP_ENUMERATE);
|
JS_DefineProperty(ctx, param, "objects", cpowsv, nullptr, nullptr, JSPROP_ENUMERATE);
|
||||||
|
|
||||||
|
// message.principal == null
|
||||||
|
if (!aPrincipal) {
|
||||||
|
JS::Rooted<JS::Value> nullValue(ctx);
|
||||||
|
JS_DefineProperty(ctx, param, "principal", nullValue, nullptr, nullptr, JSPROP_ENUMERATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// message.principal = { appId: <id>, origin: <origin>, isInBrowserElement: <something> }
|
||||||
|
else {
|
||||||
|
JS::Rooted<JSObject*> principalObj(ctx,
|
||||||
|
JS_NewObject(ctx, nullptr, nullptr, nullptr));
|
||||||
|
|
||||||
|
uint32_t appId;
|
||||||
|
nsresult rv = aPrincipal->GetAppId(&appId);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
JS::Rooted<JS::Value> appIdValue(ctx, INT_TO_JSVAL(appId));
|
||||||
|
JS_DefineProperty(ctx, principalObj, "appId", appIdValue, nullptr, nullptr, JSPROP_ENUMERATE);
|
||||||
|
|
||||||
|
nsCString origin;
|
||||||
|
rv = aPrincipal->GetOrigin(getter_Copies(origin));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
JS::Rooted<JSString*> originValue(ctx, JS_InternString(ctx, origin.get()));
|
||||||
|
JS_DefineProperty(ctx, principalObj, "origin", STRING_TO_JSVAL(originValue), nullptr, nullptr, JSPROP_ENUMERATE);
|
||||||
|
|
||||||
|
bool browser;
|
||||||
|
rv = aPrincipal->GetIsInBrowserElement(&browser);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
JS::Rooted<JS::Value> browserValue(ctx, BOOLEAN_TO_JSVAL(browser));
|
||||||
|
JS_DefineProperty(ctx, principalObj, "isInBrowserElement", browserValue, nullptr, nullptr, JSPROP_ENUMERATE);
|
||||||
|
|
||||||
|
JS::RootedValue principalValue(ctx, JS::ObjectValue(*principalObj));
|
||||||
|
JS_DefineProperty(ctx, param, "principal", principalValue, nullptr, nullptr, JSPROP_ENUMERATE);
|
||||||
|
}
|
||||||
|
|
||||||
JS::Rooted<JS::Value> thisValue(ctx, JS::UndefinedValue());
|
JS::Rooted<JS::Value> thisValue(ctx, JS::UndefinedValue());
|
||||||
|
|
||||||
JS::Rooted<JS::Value> funval(ctx);
|
JS::Rooted<JS::Value> funval(ctx);
|
||||||
|
@ -981,7 +1030,7 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
|
||||||
nsRefPtr<nsFrameMessageManager> kungfuDeathGrip = mParentManager;
|
nsRefPtr<nsFrameMessageManager> kungfuDeathGrip = mParentManager;
|
||||||
return mParentManager ? mParentManager->ReceiveMessage(aTarget, aMessage,
|
return mParentManager ? mParentManager->ReceiveMessage(aTarget, aMessage,
|
||||||
aIsSync, aCloneData,
|
aIsSync, aCloneData,
|
||||||
aCpows,
|
aCpows, aPrincipal,
|
||||||
aJSONRetVal) : NS_OK;
|
aJSONRetVal) : NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1452,10 +1501,12 @@ public:
|
||||||
nsAsyncMessageToSameProcessChild(JSContext* aCx,
|
nsAsyncMessageToSameProcessChild(JSContext* aCx,
|
||||||
const nsAString& aMessage,
|
const nsAString& aMessage,
|
||||||
const StructuredCloneData& aData,
|
const StructuredCloneData& aData,
|
||||||
JS::Handle<JSObject *> aCpows)
|
JS::Handle<JSObject *> aCpows,
|
||||||
|
nsIPrincipal* aPrincipal)
|
||||||
: mRuntime(js::GetRuntime(aCx)),
|
: mRuntime(js::GetRuntime(aCx)),
|
||||||
mMessage(aMessage),
|
mMessage(aMessage),
|
||||||
mCpows(aCpows)
|
mCpows(aCpows),
|
||||||
|
mPrincipal(aPrincipal)
|
||||||
{
|
{
|
||||||
if (aData.mDataLength && !mData.copy(aData.mData, aData.mDataLength)) {
|
if (aData.mDataLength && !mData.copy(aData.mData, aData.mDataLength)) {
|
||||||
NS_RUNTIMEABORT("OOM");
|
NS_RUNTIMEABORT("OOM");
|
||||||
|
@ -1485,7 +1536,7 @@ public:
|
||||||
|
|
||||||
nsRefPtr<nsFrameMessageManager> ppm = nsFrameMessageManager::sChildProcessManager;
|
nsRefPtr<nsFrameMessageManager> ppm = nsFrameMessageManager::sChildProcessManager;
|
||||||
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()), mMessage,
|
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()), mMessage,
|
||||||
false, &data, &cpows, nullptr);
|
false, &data, &cpows, mPrincipal, nullptr);
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -1494,6 +1545,7 @@ public:
|
||||||
JSAutoStructuredCloneBuffer mData;
|
JSAutoStructuredCloneBuffer mData;
|
||||||
StructuredCloneClosure mClosure;
|
StructuredCloneClosure mClosure;
|
||||||
JSObject* mCpows;
|
JSObject* mCpows;
|
||||||
|
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1515,10 +1567,12 @@ public:
|
||||||
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||||
const nsAString& aMessage,
|
const nsAString& aMessage,
|
||||||
const StructuredCloneData& aData,
|
const StructuredCloneData& aData,
|
||||||
JS::Handle<JSObject *> aCpows)
|
JS::Handle<JSObject *> aCpows,
|
||||||
|
nsIPrincipal* aPrincipal)
|
||||||
{
|
{
|
||||||
nsRefPtr<nsIRunnable> ev =
|
nsRefPtr<nsIRunnable> ev =
|
||||||
new nsAsyncMessageToSameProcessChild(aCx, aMessage, aData, aCpows);
|
new nsAsyncMessageToSameProcessChild(aCx, aMessage, aData, aCpows,
|
||||||
|
aPrincipal);
|
||||||
NS_DispatchToCurrentThread(ev);
|
NS_DispatchToCurrentThread(ev);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1562,6 +1616,7 @@ public:
|
||||||
const nsAString& aMessage,
|
const nsAString& aMessage,
|
||||||
const mozilla::dom::StructuredCloneData& aData,
|
const mozilla::dom::StructuredCloneData& aData,
|
||||||
JS::Handle<JSObject *> aCpows,
|
JS::Handle<JSObject *> aCpows,
|
||||||
|
nsIPrincipal* aPrincipal,
|
||||||
InfallibleTArray<nsString>* aJSONRetVal,
|
InfallibleTArray<nsString>* aJSONRetVal,
|
||||||
bool aIsSync) MOZ_OVERRIDE
|
bool aIsSync) MOZ_OVERRIDE
|
||||||
{
|
{
|
||||||
|
@ -1579,15 +1634,18 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (aIsSync) {
|
if (aIsSync) {
|
||||||
return cc->SendSyncMessage(nsString(aMessage), data, cpows, aJSONRetVal);
|
return cc->SendSyncMessage(nsString(aMessage), data, cpows, aPrincipal,
|
||||||
|
aJSONRetVal);
|
||||||
}
|
}
|
||||||
return cc->CallRpcMessage(nsString(aMessage), data, cpows, aJSONRetVal);
|
return cc->CallRpcMessage(nsString(aMessage), data, cpows, aPrincipal,
|
||||||
|
aJSONRetVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||||
const nsAString& aMessage,
|
const nsAString& aMessage,
|
||||||
const mozilla::dom::StructuredCloneData& aData,
|
const mozilla::dom::StructuredCloneData& aData,
|
||||||
JS::Handle<JSObject *> aCpows) MOZ_OVERRIDE
|
JS::Handle<JSObject *> aCpows,
|
||||||
|
nsIPrincipal* aPrincipal) MOZ_OVERRIDE
|
||||||
{
|
{
|
||||||
mozilla::dom::ContentChild* cc =
|
mozilla::dom::ContentChild* cc =
|
||||||
mozilla::dom::ContentChild::GetSingleton();
|
mozilla::dom::ContentChild::GetSingleton();
|
||||||
|
@ -1602,7 +1660,7 @@ public:
|
||||||
if (!cc->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
|
if (!cc->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return cc->SendAsyncMessage(nsString(aMessage), data, cpows);
|
return cc->SendAsyncMessage(nsString(aMessage), data, cpows, aPrincipal);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -1614,10 +1672,12 @@ public:
|
||||||
nsAsyncMessageToSameProcessParent(JSContext* aCx,
|
nsAsyncMessageToSameProcessParent(JSContext* aCx,
|
||||||
const nsAString& aMessage,
|
const nsAString& aMessage,
|
||||||
const StructuredCloneData& aData,
|
const StructuredCloneData& aData,
|
||||||
JS::Handle<JSObject *> aCpows)
|
JS::Handle<JSObject *> aCpows,
|
||||||
|
nsIPrincipal* aPrincipal)
|
||||||
: mRuntime(js::GetRuntime(aCx)),
|
: mRuntime(js::GetRuntime(aCx)),
|
||||||
mMessage(aMessage),
|
mMessage(aMessage),
|
||||||
mCpows(aCpows)
|
mCpows(aCpows),
|
||||||
|
mPrincipal(aPrincipal)
|
||||||
{
|
{
|
||||||
if (aData.mDataLength && !mData.copy(aData.mData, aData.mDataLength)) {
|
if (aData.mDataLength && !mData.copy(aData.mData, aData.mDataLength)) {
|
||||||
NS_RUNTIMEABORT("OOM");
|
NS_RUNTIMEABORT("OOM");
|
||||||
|
@ -1651,7 +1711,7 @@ public:
|
||||||
nsRefPtr<nsFrameMessageManager> ppm =
|
nsRefPtr<nsFrameMessageManager> ppm =
|
||||||
nsFrameMessageManager::sSameProcessParentManager;
|
nsFrameMessageManager::sSameProcessParentManager;
|
||||||
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
|
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
|
||||||
mMessage, false, &data, &cpows, nullptr);
|
mMessage, false, &data, &cpows, mPrincipal, nullptr);
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -1660,6 +1720,7 @@ public:
|
||||||
JSAutoStructuredCloneBuffer mData;
|
JSAutoStructuredCloneBuffer mData;
|
||||||
StructuredCloneClosure mClosure;
|
StructuredCloneClosure mClosure;
|
||||||
JSObject* mCpows;
|
JSObject* mCpows;
|
||||||
|
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1681,6 +1742,7 @@ public:
|
||||||
const nsAString& aMessage,
|
const nsAString& aMessage,
|
||||||
const mozilla::dom::StructuredCloneData& aData,
|
const mozilla::dom::StructuredCloneData& aData,
|
||||||
JS::Handle<JSObject *> aCpows,
|
JS::Handle<JSObject *> aCpows,
|
||||||
|
nsIPrincipal* aPrincipal,
|
||||||
InfallibleTArray<nsString>* aJSONRetVal,
|
InfallibleTArray<nsString>* aJSONRetVal,
|
||||||
bool aIsSync) MOZ_OVERRIDE
|
bool aIsSync) MOZ_OVERRIDE
|
||||||
{
|
{
|
||||||
|
@ -1697,7 +1759,7 @@ public:
|
||||||
SameProcessCpowHolder cpows(js::GetRuntime(aCx), aCpows);
|
SameProcessCpowHolder cpows(js::GetRuntime(aCx), aCpows);
|
||||||
nsRefPtr<nsFrameMessageManager> ppm = nsFrameMessageManager::sSameProcessParentManager;
|
nsRefPtr<nsFrameMessageManager> ppm = nsFrameMessageManager::sSameProcessParentManager;
|
||||||
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()), aMessage,
|
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()), aMessage,
|
||||||
true, &aData, &cpows, aJSONRetVal);
|
true, &aData, &cpows, aPrincipal, aJSONRetVal);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1705,13 +1767,14 @@ public:
|
||||||
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||||
const nsAString& aMessage,
|
const nsAString& aMessage,
|
||||||
const mozilla::dom::StructuredCloneData& aData,
|
const mozilla::dom::StructuredCloneData& aData,
|
||||||
JS::Handle<JSObject *> aCpows)
|
JS::Handle<JSObject *> aCpows,
|
||||||
|
nsIPrincipal* aPrincipal)
|
||||||
{
|
{
|
||||||
if (!nsFrameMessageManager::sPendingSameProcessAsyncMessages) {
|
if (!nsFrameMessageManager::sPendingSameProcessAsyncMessages) {
|
||||||
nsFrameMessageManager::sPendingSameProcessAsyncMessages = new nsTArray<nsCOMPtr<nsIRunnable> >;
|
nsFrameMessageManager::sPendingSameProcessAsyncMessages = new nsTArray<nsCOMPtr<nsIRunnable> >;
|
||||||
}
|
}
|
||||||
nsCOMPtr<nsIRunnable> ev =
|
nsCOMPtr<nsIRunnable> ev =
|
||||||
new nsAsyncMessageToSameProcessParent(aCx, aMessage, aData, aCpows);
|
new nsAsyncMessageToSameProcessParent(aCx, aMessage, aData, aCpows, aPrincipal);
|
||||||
nsFrameMessageManager::sPendingSameProcessAsyncMessages->AppendElement(ev);
|
nsFrameMessageManager::sPendingSameProcessAsyncMessages->AppendElement(ev);
|
||||||
NS_DispatchToCurrentThread(ev);
|
NS_DispatchToCurrentThread(ev);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -61,6 +61,7 @@ public:
|
||||||
const nsAString& aMessage,
|
const nsAString& aMessage,
|
||||||
const mozilla::dom::StructuredCloneData& aData,
|
const mozilla::dom::StructuredCloneData& aData,
|
||||||
JS::Handle<JSObject *> aCpows,
|
JS::Handle<JSObject *> aCpows,
|
||||||
|
nsIPrincipal* aPrincipal,
|
||||||
InfallibleTArray<nsString>* aJSONRetVal,
|
InfallibleTArray<nsString>* aJSONRetVal,
|
||||||
bool aIsSync)
|
bool aIsSync)
|
||||||
{
|
{
|
||||||
|
@ -70,7 +71,8 @@ public:
|
||||||
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||||
const nsAString& aMessage,
|
const nsAString& aMessage,
|
||||||
const mozilla::dom::StructuredCloneData& aData,
|
const mozilla::dom::StructuredCloneData& aData,
|
||||||
JS::Handle<JSObject *> aCpows)
|
JS::Handle<JSObject *> aCpows,
|
||||||
|
nsIPrincipal* aPrincipal)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -218,7 +220,7 @@ public:
|
||||||
|
|
||||||
nsresult ReceiveMessage(nsISupports* aTarget, const nsAString& aMessage,
|
nsresult ReceiveMessage(nsISupports* aTarget, const nsAString& aMessage,
|
||||||
bool aIsSync, const StructuredCloneData* aCloneData,
|
bool aIsSync, const StructuredCloneData* aCloneData,
|
||||||
CpowHolder* aCpows,
|
CpowHolder* aCpows, nsIPrincipal* aPrincipal,
|
||||||
InfallibleTArray<nsString>* aJSONRetVal);
|
InfallibleTArray<nsString>* aJSONRetVal);
|
||||||
|
|
||||||
void AddChildManager(nsFrameMessageManager* aManager,
|
void AddChildManager(nsFrameMessageManager* aManager,
|
||||||
|
@ -239,12 +241,14 @@ public:
|
||||||
nsresult DispatchAsyncMessage(const nsAString& aMessageName,
|
nsresult DispatchAsyncMessage(const nsAString& aMessageName,
|
||||||
const JS::Value& aJSON,
|
const JS::Value& aJSON,
|
||||||
const JS::Value& aObjects,
|
const JS::Value& aObjects,
|
||||||
|
nsIPrincipal* aPrincipal,
|
||||||
JSContext* aCx,
|
JSContext* aCx,
|
||||||
uint8_t aArgc);
|
uint8_t aArgc);
|
||||||
nsresult DispatchAsyncMessageInternal(JSContext* aCx,
|
nsresult DispatchAsyncMessageInternal(JSContext* aCx,
|
||||||
const nsAString& aMessage,
|
const nsAString& aMessage,
|
||||||
const StructuredCloneData& aData,
|
const StructuredCloneData& aData,
|
||||||
JS::Handle<JSObject *> aCpows);
|
JS::Handle<JSObject *> aCpows,
|
||||||
|
nsIPrincipal* aPrincipal);
|
||||||
void RemoveFromParent();
|
void RemoveFromParent();
|
||||||
nsFrameMessageManager* GetParentManager() { return mParentManager; }
|
nsFrameMessageManager* GetParentManager() { return mParentManager; }
|
||||||
void SetParentManager(nsFrameMessageManager* aParent)
|
void SetParentManager(nsFrameMessageManager* aParent)
|
||||||
|
@ -268,6 +272,7 @@ private:
|
||||||
nsresult SendMessage(const nsAString& aMessageName,
|
nsresult SendMessage(const nsAString& aMessageName,
|
||||||
const JS::Value& aJSON,
|
const JS::Value& aJSON,
|
||||||
const JS::Value& aObjects,
|
const JS::Value& aObjects,
|
||||||
|
nsIPrincipal* aPrincipal,
|
||||||
JSContext* aCx,
|
JSContext* aCx,
|
||||||
uint8_t aArgc,
|
uint8_t aArgc,
|
||||||
JS::Value* aRetval,
|
JS::Value* aRetval,
|
||||||
|
|
|
@ -30,6 +30,7 @@ nsInProcessTabChildGlobal::DoSendBlockingMessage(JSContext* aCx,
|
||||||
const nsAString& aMessage,
|
const nsAString& aMessage,
|
||||||
const mozilla::dom::StructuredCloneData& aData,
|
const mozilla::dom::StructuredCloneData& aData,
|
||||||
JS::Handle<JSObject *> aCpows,
|
JS::Handle<JSObject *> aCpows,
|
||||||
|
nsIPrincipal* aPrincipal,
|
||||||
InfallibleTArray<nsString>* aJSONRetVal,
|
InfallibleTArray<nsString>* aJSONRetVal,
|
||||||
bool aIsSync)
|
bool aIsSync)
|
||||||
{
|
{
|
||||||
|
@ -43,7 +44,8 @@ nsInProcessTabChildGlobal::DoSendBlockingMessage(JSContext* aCx,
|
||||||
if (mChromeMessageManager) {
|
if (mChromeMessageManager) {
|
||||||
SameProcessCpowHolder cpows(js::GetRuntime(aCx), aCpows);
|
SameProcessCpowHolder cpows(js::GetRuntime(aCx), aCpows);
|
||||||
nsRefPtr<nsFrameMessageManager> mm = mChromeMessageManager;
|
nsRefPtr<nsFrameMessageManager> mm = mChromeMessageManager;
|
||||||
mm->ReceiveMessage(mOwner, aMessage, true, &aData, &cpows, aJSONRetVal);
|
mm->ReceiveMessage(mOwner, aMessage, true, &aData, &cpows, aPrincipal,
|
||||||
|
aJSONRetVal);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -55,11 +57,13 @@ public:
|
||||||
nsInProcessTabChildGlobal* aTabChild,
|
nsInProcessTabChildGlobal* aTabChild,
|
||||||
const nsAString& aMessage,
|
const nsAString& aMessage,
|
||||||
const StructuredCloneData& aData,
|
const StructuredCloneData& aData,
|
||||||
JS::Handle<JSObject *> aCpows)
|
JS::Handle<JSObject *> aCpows,
|
||||||
|
nsIPrincipal* aPrincipal)
|
||||||
: mRuntime(js::GetRuntime(aCx)),
|
: mRuntime(js::GetRuntime(aCx)),
|
||||||
mTabChild(aTabChild),
|
mTabChild(aTabChild),
|
||||||
mMessage(aMessage),
|
mMessage(aMessage),
|
||||||
mCpows(aCpows),
|
mCpows(aCpows),
|
||||||
|
mPrincipal(aPrincipal),
|
||||||
mRun(false)
|
mRun(false)
|
||||||
{
|
{
|
||||||
if (aData.mDataLength && !mData.copy(aData.mData, aData.mDataLength)) {
|
if (aData.mDataLength && !mData.copy(aData.mData, aData.mDataLength)) {
|
||||||
|
@ -95,7 +99,8 @@ public:
|
||||||
SameProcessCpowHolder cpows(mRuntime, JS::Handle<JSObject *>::fromMarkedLocation(&mCpows));
|
SameProcessCpowHolder cpows(mRuntime, JS::Handle<JSObject *>::fromMarkedLocation(&mCpows));
|
||||||
|
|
||||||
nsRefPtr<nsFrameMessageManager> mm = mTabChild->mChromeMessageManager;
|
nsRefPtr<nsFrameMessageManager> mm = mTabChild->mChromeMessageManager;
|
||||||
mm->ReceiveMessage(mTabChild->mOwner, mMessage, false, &data, &cpows, nullptr);
|
mm->ReceiveMessage(mTabChild->mOwner, mMessage, false, &data, &cpows,
|
||||||
|
mPrincipal, nullptr);
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -105,6 +110,7 @@ public:
|
||||||
JSAutoStructuredCloneBuffer mData;
|
JSAutoStructuredCloneBuffer mData;
|
||||||
StructuredCloneClosure mClosure;
|
StructuredCloneClosure mClosure;
|
||||||
JSObject* mCpows;
|
JSObject* mCpows;
|
||||||
|
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||||
// True if this runnable has already been called. This can happen if DoSendSyncMessage
|
// True if this runnable has already been called. This can happen if DoSendSyncMessage
|
||||||
// is called while waiting for an asynchronous message send.
|
// is called while waiting for an asynchronous message send.
|
||||||
bool mRun;
|
bool mRun;
|
||||||
|
@ -114,10 +120,11 @@ bool
|
||||||
nsInProcessTabChildGlobal::DoSendAsyncMessage(JSContext* aCx,
|
nsInProcessTabChildGlobal::DoSendAsyncMessage(JSContext* aCx,
|
||||||
const nsAString& aMessage,
|
const nsAString& aMessage,
|
||||||
const StructuredCloneData& aData,
|
const StructuredCloneData& aData,
|
||||||
JS::Handle<JSObject *> aCpows)
|
JS::Handle<JSObject *> aCpows,
|
||||||
|
nsIPrincipal* aPrincipal)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIRunnable> ev =
|
nsCOMPtr<nsIRunnable> ev =
|
||||||
new nsAsyncMessageToParent(aCx, this, aMessage, aData, aCpows);
|
new nsAsyncMessageToParent(aCx, this, aMessage, aData, aCpows, aPrincipal);
|
||||||
mASyncMessages.AppendElement(ev);
|
mASyncMessages.AppendElement(ev);
|
||||||
NS_DispatchToCurrentThread(ev);
|
NS_DispatchToCurrentThread(ev);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -43,23 +43,27 @@ public:
|
||||||
NS_IMETHOD SendSyncMessage(const nsAString& aMessageName,
|
NS_IMETHOD SendSyncMessage(const nsAString& aMessageName,
|
||||||
const JS::Value& aObject,
|
const JS::Value& aObject,
|
||||||
const JS::Value& aRemote,
|
const JS::Value& aRemote,
|
||||||
|
nsIPrincipal* aPrincipal,
|
||||||
JSContext* aCx,
|
JSContext* aCx,
|
||||||
uint8_t aArgc,
|
uint8_t aArgc,
|
||||||
JS::Value* aRetval)
|
JS::Value* aRetval)
|
||||||
{
|
{
|
||||||
return mMessageManager
|
return mMessageManager
|
||||||
? mMessageManager->SendSyncMessage(aMessageName, aObject, aRemote, aCx, aArgc, aRetval)
|
? mMessageManager->SendSyncMessage(aMessageName, aObject, aRemote,
|
||||||
|
aPrincipal, aCx, aArgc, aRetval)
|
||||||
: NS_ERROR_NULL_POINTER;
|
: NS_ERROR_NULL_POINTER;
|
||||||
}
|
}
|
||||||
NS_IMETHOD SendRpcMessage(const nsAString& aMessageName,
|
NS_IMETHOD SendRpcMessage(const nsAString& aMessageName,
|
||||||
const JS::Value& aObject,
|
const JS::Value& aObject,
|
||||||
const JS::Value& aRemote,
|
const JS::Value& aRemote,
|
||||||
|
nsIPrincipal* aPrincipal,
|
||||||
JSContext* aCx,
|
JSContext* aCx,
|
||||||
uint8_t aArgc,
|
uint8_t aArgc,
|
||||||
JS::Value* aRetval)
|
JS::Value* aRetval)
|
||||||
{
|
{
|
||||||
return mMessageManager
|
return mMessageManager
|
||||||
? mMessageManager->SendRpcMessage(aMessageName, aObject, aRemote, aCx, aArgc, aRetval)
|
? mMessageManager->SendRpcMessage(aMessageName, aObject, aRemote,
|
||||||
|
aPrincipal, aCx, aArgc, aRetval)
|
||||||
: NS_ERROR_NULL_POINTER;
|
: NS_ERROR_NULL_POINTER;
|
||||||
}
|
}
|
||||||
NS_IMETHOD GetContent(nsIDOMWindow** aContent) MOZ_OVERRIDE;
|
NS_IMETHOD GetContent(nsIDOMWindow** aContent) MOZ_OVERRIDE;
|
||||||
|
@ -83,12 +87,14 @@ public:
|
||||||
const nsAString& aMessage,
|
const nsAString& aMessage,
|
||||||
const mozilla::dom::StructuredCloneData& aData,
|
const mozilla::dom::StructuredCloneData& aData,
|
||||||
JS::Handle<JSObject *> aCpows,
|
JS::Handle<JSObject *> aCpows,
|
||||||
|
nsIPrincipal* aPrincipal,
|
||||||
InfallibleTArray<nsString>* aJSONRetVal,
|
InfallibleTArray<nsString>* aJSONRetVal,
|
||||||
bool aIsSync) MOZ_OVERRIDE;
|
bool aIsSync) MOZ_OVERRIDE;
|
||||||
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||||
const nsAString& aMessage,
|
const nsAString& aMessage,
|
||||||
const mozilla::dom::StructuredCloneData& aData,
|
const mozilla::dom::StructuredCloneData& aData,
|
||||||
JS::Handle<JSObject *> aCpows);
|
JS::Handle<JSObject *> aCpows,
|
||||||
|
nsIPrincipal* aPrincipal) MOZ_OVERRIDE;
|
||||||
|
|
||||||
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor) MOZ_OVERRIDE;
|
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor) MOZ_OVERRIDE;
|
||||||
NS_IMETHOD AddEventListener(const nsAString& aType,
|
NS_IMETHOD AddEventListener(const nsAString& aType,
|
||||||
|
|
|
@ -2,3 +2,4 @@
|
||||||
|
|
||||||
[test_bug357450.js]
|
[test_bug357450.js]
|
||||||
[test_copypaste.xul]
|
[test_copypaste.xul]
|
||||||
|
[test_messagemanager_principal.html]
|
||||||
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Test for Principal in MessageManager</title>
|
||||||
|
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<script type="application/javascript;version=1.7">
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const Ci = Components.interfaces;
|
||||||
|
const Cc = Components.classes;
|
||||||
|
const Cu = Components.utils;
|
||||||
|
|
||||||
|
var permManager = Cc["@mozilla.org/permissionmanager;1"]
|
||||||
|
.getService(Ci.nsIPermissionManager);
|
||||||
|
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
|
||||||
|
const childFrameURL =
|
||||||
|
"data:text/html,<!DOCTYPE HTML><html><body></body></html>";
|
||||||
|
|
||||||
|
function childFrameScript() {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
addMessageListener("test:ipcMessage", function(message) {
|
||||||
|
sendAsyncMessage(message.name, "principal: " + (message.principal ? "OK" : "KO"));
|
||||||
|
|
||||||
|
sendAsyncMessage(message.name, "principal.appId: " +
|
||||||
|
("appId" in message.principal ? "OK" : "KO"));
|
||||||
|
|
||||||
|
sendAsyncMessage(message.name, "principal.origin: " +
|
||||||
|
("origin" in message.principal ? "OK" : "KO"));
|
||||||
|
|
||||||
|
sendAsyncMessage(message.name, "principal.isInBrowserElement: " +
|
||||||
|
("isInBrowserElement" in message.principal ? "OK" : "KO"));
|
||||||
|
|
||||||
|
sendAsyncMessage(message.name, "DONE");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function runTests() {
|
||||||
|
ok("Browser prefs set.");
|
||||||
|
|
||||||
|
let iframe = document.createElement("iframe");
|
||||||
|
SpecialPowers.wrap(iframe).mozbrowser = true;
|
||||||
|
iframe.id = "iframe";
|
||||||
|
iframe.src = childFrameURL;
|
||||||
|
|
||||||
|
iframe.addEventListener("mozbrowserloadend", function() {
|
||||||
|
ok(true, "Got iframe load event.");
|
||||||
|
|
||||||
|
let mm = SpecialPowers.getBrowserFrameMessageManager(iframe);
|
||||||
|
mm.addMessageListener("test:ipcMessage", function(message) {
|
||||||
|
// We need to wrap to access message.json, and unwrap to do the
|
||||||
|
// identity check.
|
||||||
|
var msg = SpecialPowers.unwrap(SpecialPowers.wrap(message).json);
|
||||||
|
if (/OK$/.exec(msg)) {
|
||||||
|
ok(true, msg);
|
||||||
|
} else if(/KO$/.exec(msg)) {
|
||||||
|
ok(true, false);
|
||||||
|
} else if (/DONE/.exec(msg)) {
|
||||||
|
permManager.removeFromPrincipal(window.document.nodePrincipal, "browser",
|
||||||
|
Ci.nsIPermissionManager.ALLOW_ACTION);
|
||||||
|
SimpleTest.finish();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
mm.loadFrameScript("data:,(" + childFrameScript.toString() + ")();",
|
||||||
|
false);
|
||||||
|
|
||||||
|
mm.sendAsyncMessage("test:ipcMessage", 42, null, window.document.nodePrincipal);
|
||||||
|
});
|
||||||
|
|
||||||
|
document.body.appendChild(iframe);
|
||||||
|
}
|
||||||
|
|
||||||
|
addEventListener("load", function() {
|
||||||
|
info("Got load event.");
|
||||||
|
|
||||||
|
permManager.addFromPrincipal(window.document.nodePrincipal, "browser",
|
||||||
|
Ci.nsIPermissionManager.ALLOW_ACTION);
|
||||||
|
|
||||||
|
SpecialPowers.pushPrefEnv({
|
||||||
|
"set": [
|
||||||
|
["dom.mozBrowserFramesEnabled", true],
|
||||||
|
["browser.pagethumbnails.capturing_disabled", true]
|
||||||
|
]
|
||||||
|
}, runTests);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -211,7 +211,8 @@ HTMLOptionElement::BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
|
|
||||||
int32_t index = Index();
|
int32_t index = Index();
|
||||||
uint32_t mask = HTMLSelectElement::SET_DISABLED;
|
uint32_t mask = HTMLSelectElement::SET_DISABLED;
|
||||||
if (aValue) {
|
bool defaultSelected = aValue;
|
||||||
|
if (defaultSelected) {
|
||||||
mask |= HTMLSelectElement::IS_SELECTED;
|
mask |= HTMLSelectElement::IS_SELECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,8 +228,10 @@ HTMLOptionElement::BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
// Now reset our members; when we finish the attr set we'll end up with the
|
// Now reset our members; when we finish the attr set we'll end up with the
|
||||||
// rigt selected state.
|
// rigt selected state.
|
||||||
mIsInSetDefaultSelected = inSetDefaultSelected;
|
mIsInSetDefaultSelected = inSetDefaultSelected;
|
||||||
mSelectedChanged = false;
|
// mIsSelected has already been set by SetOptionsSelectedByIndex.
|
||||||
// mIsSelected doesn't matter while mSelectedChanged is false
|
// Possibly more than once; make sure our mSelectedChanged state is
|
||||||
|
// set correctly.
|
||||||
|
mSelectedChanged = mIsSelected != defaultSelected;
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -402,6 +402,7 @@ support-files =
|
||||||
[test_object_attributes_reflection.html]
|
[test_object_attributes_reflection.html]
|
||||||
[test_object_plugin_nav.html]
|
[test_object_plugin_nav.html]
|
||||||
[test_ol_attributes_reflection.html]
|
[test_ol_attributes_reflection.html]
|
||||||
|
[test_option_defaultSelected.html]
|
||||||
[test_param_attributes_reflection.html]
|
[test_param_attributes_reflection.html]
|
||||||
[test_q_attributes_reflection.html]
|
[test_q_attributes_reflection.html]
|
||||||
[test_restore_from_parser_fragment.html]
|
[test_restore_from_parser_fragment.html]
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<!--
|
||||||
|
https://bugzilla.mozilla.org/show_bug.cgi?id=927796
|
||||||
|
-->
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Test for Bug 927796</title>
|
||||||
|
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=927796">Mozilla Bug 927796</a>
|
||||||
|
<p id="display">
|
||||||
|
<select id="s1">
|
||||||
|
<option selected>one</option>
|
||||||
|
<option>two</option>
|
||||||
|
</select>
|
||||||
|
<select id="s2" size="5">
|
||||||
|
<option selected>one</option>
|
||||||
|
<option>two</option>
|
||||||
|
</select>
|
||||||
|
</p>
|
||||||
|
<div id="content" style="display: none">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<pre id="test">
|
||||||
|
</pre>
|
||||||
|
<script type="application/javascript">
|
||||||
|
|
||||||
|
/** Test for Bug 927796 **/
|
||||||
|
var s1 = $("s1");
|
||||||
|
s1.options[0].defaultSelected = false;
|
||||||
|
is(s1.options[0].selected, true,
|
||||||
|
"First option in combobox should still be selected");
|
||||||
|
is(s1.options[1].selected, false,
|
||||||
|
"Second option in combobox should not be selected");
|
||||||
|
|
||||||
|
var s2 = $("s2");
|
||||||
|
s2.options[0].defaultSelected = false;
|
||||||
|
is(s2.options[0].selected, false,
|
||||||
|
"First option in listbox should not be selected");
|
||||||
|
is(s2.options[1].selected, false,
|
||||||
|
"Second option in listbox should not be selected");
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -3651,6 +3651,14 @@ NS_IMETHODIMP
|
||||||
nsWindowSH::Finalize(nsIXPConnectWrappedNative *wrapper, JSFreeOp *fop,
|
nsWindowSH::Finalize(nsIXPConnectWrappedNative *wrapper, JSFreeOp *fop,
|
||||||
JSObject *obj)
|
JSObject *obj)
|
||||||
{
|
{
|
||||||
|
// Since this call is virtual, the exact rooting hazard static analysis is
|
||||||
|
// not able to determine that it happens during finalization and should be
|
||||||
|
// ignored. Moreover, the analysis cannot discover and validate the
|
||||||
|
// potential targets of the virtual call to OnFinalize below because of the
|
||||||
|
// indirection through nsCOMMPtr. Thus, we annotate the analysis here so
|
||||||
|
// that it does not report OnFinalize as GCing with |obj| on stack.
|
||||||
|
JS::AutoAssertNoGC nogc;
|
||||||
|
|
||||||
nsCOMPtr<nsIScriptGlobalObject> sgo(do_QueryWrappedNative(wrapper));
|
nsCOMPtr<nsIScriptGlobalObject> sgo(do_QueryWrappedNative(wrapper));
|
||||||
NS_ENSURE_TRUE(sgo, NS_ERROR_UNEXPECTED);
|
NS_ENSURE_TRUE(sgo, NS_ERROR_UNEXPECTED);
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,12 @@ using namespace mozilla::dom;
|
||||||
using namespace mozilla::hal_sandbox;
|
using namespace mozilla::hal_sandbox;
|
||||||
using namespace mozilla::services;
|
using namespace mozilla::services;
|
||||||
#else
|
#else
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
class PContentParent;
|
class PContentParent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class nsIPrincipal;
|
class nsIPrincipal;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -280,16 +285,16 @@ AssertAppProcess(mozilla::hal_sandbox::PHalParent* aActor,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
AssertAppPrincipal(PContentParent* aActor,
|
AssertAppPrincipal(mozilla::dom::PContentParent* aActor,
|
||||||
nsIPrincipal* aPrincipal)
|
nsIPrincipal* aPrincipal)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
CheckPermission(PContentParent*,
|
CheckPermission(mozilla::dom::PContentParent* aActor,
|
||||||
nsIPrincipal*,
|
nsIPrincipal* aPrincipal,
|
||||||
const char*)
|
const char* aPermission)
|
||||||
{
|
{
|
||||||
return nsIPermissionManager::ALLOW_ACTION;
|
return nsIPermissionManager::ALLOW_ACTION;
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,6 +72,8 @@
|
||||||
#include "nsPermissionManager.h"
|
#include "nsPermissionManager.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "PermissionMessageUtils.h"
|
||||||
|
|
||||||
#if defined(MOZ_WIDGET_ANDROID)
|
#if defined(MOZ_WIDGET_ANDROID)
|
||||||
#include "APKOpen.h"
|
#include "APKOpen.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -1172,14 +1174,15 @@ ContentChild::RecvNotifyVisited(const URIParams& aURI)
|
||||||
bool
|
bool
|
||||||
ContentChild::RecvAsyncMessage(const nsString& aMsg,
|
ContentChild::RecvAsyncMessage(const nsString& aMsg,
|
||||||
const ClonedMessageData& aData,
|
const ClonedMessageData& aData,
|
||||||
const InfallibleTArray<CpowEntry>& aCpows)
|
const InfallibleTArray<CpowEntry>& aCpows,
|
||||||
|
const IPC::Principal& aPrincipal)
|
||||||
{
|
{
|
||||||
nsRefPtr<nsFrameMessageManager> cpm = nsFrameMessageManager::sChildProcessManager;
|
nsRefPtr<nsFrameMessageManager> cpm = nsFrameMessageManager::sChildProcessManager;
|
||||||
if (cpm) {
|
if (cpm) {
|
||||||
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForChild(aData);
|
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForChild(aData);
|
||||||
CpowIdHolder cpows(GetCPOWManager(), aCpows);
|
CpowIdHolder cpows(GetCPOWManager(), aCpows);
|
||||||
cpm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(cpm.get()),
|
cpm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(cpm.get()),
|
||||||
aMsg, false, &cloneData, &cpows, nullptr);
|
aMsg, false, &cloneData, &cpows, aPrincipal, nullptr);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -188,7 +188,8 @@ public:
|
||||||
|
|
||||||
virtual bool RecvAsyncMessage(const nsString& aMsg,
|
virtual bool RecvAsyncMessage(const nsString& aMsg,
|
||||||
const ClonedMessageData& aData,
|
const ClonedMessageData& aData,
|
||||||
const InfallibleTArray<CpowEntry>& aCpows);
|
const InfallibleTArray<CpowEntry>& aCpows,
|
||||||
|
const IPC::Principal& aPrincipal);
|
||||||
|
|
||||||
virtual bool RecvGeolocationUpdate(const GeoPosition& somewhere);
|
virtual bool RecvGeolocationUpdate(const GeoPosition& somewhere);
|
||||||
|
|
||||||
|
|
|
@ -1139,7 +1139,7 @@ ContentParent::ActorDestroy(ActorDestroyReason why)
|
||||||
if (ppm) {
|
if (ppm) {
|
||||||
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
|
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
|
||||||
CHILD_PROCESS_SHUTDOWN_MESSAGE, false,
|
CHILD_PROCESS_SHUTDOWN_MESSAGE, false,
|
||||||
nullptr, nullptr, nullptr);
|
nullptr, nullptr, nullptr, nullptr);
|
||||||
}
|
}
|
||||||
nsCOMPtr<nsIThreadObserver>
|
nsCOMPtr<nsIThreadObserver>
|
||||||
kungFuDeathGrip(static_cast<nsIThreadObserver*>(this));
|
kungFuDeathGrip(static_cast<nsIThreadObserver*>(this));
|
||||||
|
@ -2865,14 +2865,21 @@ bool
|
||||||
ContentParent::RecvSyncMessage(const nsString& aMsg,
|
ContentParent::RecvSyncMessage(const nsString& aMsg,
|
||||||
const ClonedMessageData& aData,
|
const ClonedMessageData& aData,
|
||||||
const InfallibleTArray<CpowEntry>& aCpows,
|
const InfallibleTArray<CpowEntry>& aCpows,
|
||||||
|
const IPC::Principal& aPrincipal,
|
||||||
InfallibleTArray<nsString>* aRetvals)
|
InfallibleTArray<nsString>* aRetvals)
|
||||||
{
|
{
|
||||||
|
nsIPrincipal* principal = aPrincipal;
|
||||||
|
if (principal && !AssertAppPrincipal(this, principal)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
nsRefPtr<nsFrameMessageManager> ppm = mMessageManager;
|
nsRefPtr<nsFrameMessageManager> ppm = mMessageManager;
|
||||||
if (ppm) {
|
if (ppm) {
|
||||||
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
|
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
|
||||||
CpowIdHolder cpows(GetCPOWManager(), aCpows);
|
CpowIdHolder cpows(GetCPOWManager(), aCpows);
|
||||||
|
|
||||||
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
|
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
|
||||||
aMsg, true, &cloneData, &cpows, aRetvals);
|
aMsg, true, &cloneData, &cpows, aPrincipal, aRetvals);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -2881,14 +2888,20 @@ bool
|
||||||
ContentParent::AnswerRpcMessage(const nsString& aMsg,
|
ContentParent::AnswerRpcMessage(const nsString& aMsg,
|
||||||
const ClonedMessageData& aData,
|
const ClonedMessageData& aData,
|
||||||
const InfallibleTArray<CpowEntry>& aCpows,
|
const InfallibleTArray<CpowEntry>& aCpows,
|
||||||
|
const IPC::Principal& aPrincipal,
|
||||||
InfallibleTArray<nsString>* aRetvals)
|
InfallibleTArray<nsString>* aRetvals)
|
||||||
{
|
{
|
||||||
|
nsIPrincipal* principal = aPrincipal;
|
||||||
|
if (principal && !AssertAppPrincipal(this, principal)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
nsRefPtr<nsFrameMessageManager> ppm = mMessageManager;
|
nsRefPtr<nsFrameMessageManager> ppm = mMessageManager;
|
||||||
if (ppm) {
|
if (ppm) {
|
||||||
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
|
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
|
||||||
CpowIdHolder cpows(GetCPOWManager(), aCpows);
|
CpowIdHolder cpows(GetCPOWManager(), aCpows);
|
||||||
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
|
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
|
||||||
aMsg, true, &cloneData, &cpows, aRetvals);
|
aMsg, true, &cloneData, &cpows, aPrincipal, aRetvals);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -2896,14 +2909,20 @@ ContentParent::AnswerRpcMessage(const nsString& aMsg,
|
||||||
bool
|
bool
|
||||||
ContentParent::RecvAsyncMessage(const nsString& aMsg,
|
ContentParent::RecvAsyncMessage(const nsString& aMsg,
|
||||||
const ClonedMessageData& aData,
|
const ClonedMessageData& aData,
|
||||||
const InfallibleTArray<CpowEntry>& aCpows)
|
const InfallibleTArray<CpowEntry>& aCpows,
|
||||||
|
const IPC::Principal& aPrincipal)
|
||||||
{
|
{
|
||||||
|
nsIPrincipal* principal = aPrincipal;
|
||||||
|
if (principal && !AssertAppPrincipal(this, principal)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
nsRefPtr<nsFrameMessageManager> ppm = mMessageManager;
|
nsRefPtr<nsFrameMessageManager> ppm = mMessageManager;
|
||||||
if (ppm) {
|
if (ppm) {
|
||||||
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
|
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
|
||||||
CpowIdHolder cpows(GetCPOWManager(), aCpows);
|
CpowIdHolder cpows(GetCPOWManager(), aCpows);
|
||||||
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
|
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
|
||||||
aMsg, false, &cloneData, &cpows, nullptr);
|
aMsg, false, &cloneData, &cpows, aPrincipal, nullptr);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -3110,7 +3129,8 @@ bool
|
||||||
ContentParent::DoSendAsyncMessage(JSContext* aCx,
|
ContentParent::DoSendAsyncMessage(JSContext* aCx,
|
||||||
const nsAString& aMessage,
|
const nsAString& aMessage,
|
||||||
const mozilla::dom::StructuredCloneData& aData,
|
const mozilla::dom::StructuredCloneData& aData,
|
||||||
JS::Handle<JSObject *> aCpows)
|
JS::Handle<JSObject *> aCpows,
|
||||||
|
nsIPrincipal* aPrincipal)
|
||||||
{
|
{
|
||||||
ClonedMessageData data;
|
ClonedMessageData data;
|
||||||
if (!BuildClonedMessageDataForParent(this, aData, data)) {
|
if (!BuildClonedMessageDataForParent(this, aData, data)) {
|
||||||
|
@ -3120,7 +3140,7 @@ ContentParent::DoSendAsyncMessage(JSContext* aCx,
|
||||||
if (!GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
|
if (!GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return SendAsyncMessage(nsString(aMessage), data, cpows);
|
return SendAsyncMessage(nsString(aMessage), data, cpows, aPrincipal);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -117,7 +117,8 @@ public:
|
||||||
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||||
const nsAString& aMessage,
|
const nsAString& aMessage,
|
||||||
const mozilla::dom::StructuredCloneData& aData,
|
const mozilla::dom::StructuredCloneData& aData,
|
||||||
JS::Handle<JSObject *> aCpows) MOZ_OVERRIDE;
|
JS::Handle<JSObject *> aCpows,
|
||||||
|
nsIPrincipal* aPrincipal) MOZ_OVERRIDE;
|
||||||
virtual bool CheckPermission(const nsAString& aPermission) MOZ_OVERRIDE;
|
virtual bool CheckPermission(const nsAString& aPermission) MOZ_OVERRIDE;
|
||||||
virtual bool CheckManifestURL(const nsAString& aManifestURL) MOZ_OVERRIDE;
|
virtual bool CheckManifestURL(const nsAString& aManifestURL) MOZ_OVERRIDE;
|
||||||
virtual bool CheckAppHasPermission(const nsAString& aPermission) MOZ_OVERRIDE;
|
virtual bool CheckAppHasPermission(const nsAString& aPermission) MOZ_OVERRIDE;
|
||||||
|
@ -420,14 +421,17 @@ private:
|
||||||
virtual bool RecvSyncMessage(const nsString& aMsg,
|
virtual bool RecvSyncMessage(const nsString& aMsg,
|
||||||
const ClonedMessageData& aData,
|
const ClonedMessageData& aData,
|
||||||
const InfallibleTArray<CpowEntry>& aCpows,
|
const InfallibleTArray<CpowEntry>& aCpows,
|
||||||
|
const IPC::Principal& aPrincipal,
|
||||||
InfallibleTArray<nsString>* aRetvals);
|
InfallibleTArray<nsString>* aRetvals);
|
||||||
virtual bool AnswerRpcMessage(const nsString& aMsg,
|
virtual bool AnswerRpcMessage(const nsString& aMsg,
|
||||||
const ClonedMessageData& aData,
|
const ClonedMessageData& aData,
|
||||||
const InfallibleTArray<CpowEntry>& aCpows,
|
const InfallibleTArray<CpowEntry>& aCpows,
|
||||||
|
const IPC::Principal& aPrincipal,
|
||||||
InfallibleTArray<nsString>* aRetvals);
|
InfallibleTArray<nsString>* aRetvals);
|
||||||
virtual bool RecvAsyncMessage(const nsString& aMsg,
|
virtual bool RecvAsyncMessage(const nsString& aMsg,
|
||||||
const ClonedMessageData& aData,
|
const ClonedMessageData& aData,
|
||||||
const InfallibleTArray<CpowEntry>& aCpows);
|
const InfallibleTArray<CpowEntry>& aCpows,
|
||||||
|
const IPC::Principal& aPrincipal);
|
||||||
|
|
||||||
virtual bool RecvFilePathUpdateNotify(const nsString& aType,
|
virtual bool RecvFilePathUpdateNotify(const nsString& aType,
|
||||||
const nsString& aStorageName,
|
const nsString& aStorageName,
|
||||||
|
|
|
@ -61,7 +61,8 @@ intr protocol PBrowser
|
||||||
manages PIndexedDB;
|
manages PIndexedDB;
|
||||||
|
|
||||||
both:
|
both:
|
||||||
AsyncMessage(nsString aMessage, ClonedMessageData aData, CpowEntry[] aCpows);
|
AsyncMessage(nsString aMessage, ClonedMessageData aData, CpowEntry[] aCpows,
|
||||||
|
Principal aPrincipal);
|
||||||
|
|
||||||
parent:
|
parent:
|
||||||
/**
|
/**
|
||||||
|
@ -74,10 +75,12 @@ parent:
|
||||||
|
|
||||||
intr CreateWindow() returns (PBrowser window);
|
intr CreateWindow() returns (PBrowser window);
|
||||||
|
|
||||||
sync SyncMessage(nsString aMessage, ClonedMessageData aData, CpowEntry[] aCpows)
|
sync SyncMessage(nsString aMessage, ClonedMessageData aData,
|
||||||
|
CpowEntry[] aCpows, Principal aPrincipal)
|
||||||
returns (nsString[] retval);
|
returns (nsString[] retval);
|
||||||
|
|
||||||
rpc RpcMessage(nsString aMessage, ClonedMessageData aData, CpowEntry[] aCpows)
|
rpc RpcMessage(nsString aMessage, ClonedMessageData aData,
|
||||||
|
CpowEntry[] aCpows, Principal aPrincipal)
|
||||||
returns (nsString[] retval);
|
returns (nsString[] retval);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -375,10 +375,12 @@ parent:
|
||||||
|
|
||||||
sync ReadFontList() returns (FontListEntry[] retValue);
|
sync ReadFontList() returns (FontListEntry[] retValue);
|
||||||
|
|
||||||
sync SyncMessage(nsString aMessage, ClonedMessageData aData, CpowEntry[] aCpows)
|
sync SyncMessage(nsString aMessage, ClonedMessageData aData,
|
||||||
|
CpowEntry[] aCpows, Principal aPrincipal)
|
||||||
returns (nsString[] retval);
|
returns (nsString[] retval);
|
||||||
|
|
||||||
rpc RpcMessage(nsString aMessage, ClonedMessageData aData, CpowEntry[] aCpows)
|
rpc RpcMessage(nsString aMessage, ClonedMessageData aData,
|
||||||
|
CpowEntry[] aCpows, Principal aPrincipal)
|
||||||
returns (nsString[] retval);
|
returns (nsString[] retval);
|
||||||
|
|
||||||
ShowAlertNotification(nsString imageUrl,
|
ShowAlertNotification(nsString imageUrl,
|
||||||
|
@ -469,7 +471,8 @@ parent:
|
||||||
returns (OptionalInputStreamParams postData, OptionalURIParams uri);
|
returns (OptionalInputStreamParams postData, OptionalURIParams uri);
|
||||||
|
|
||||||
both:
|
both:
|
||||||
AsyncMessage(nsString aMessage, ClonedMessageData aData, CpowEntry[] aCpows);
|
AsyncMessage(nsString aMessage, ClonedMessageData aData,
|
||||||
|
CpowEntry[] aCpows, Principal aPrincipal);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,7 @@
|
||||||
#include "nsPrintfCString.h"
|
#include "nsPrintfCString.h"
|
||||||
#include "nsThreadUtils.h"
|
#include "nsThreadUtils.h"
|
||||||
#include "nsWeakReference.h"
|
#include "nsWeakReference.h"
|
||||||
|
#include "PermissionMessageUtils.h"
|
||||||
#include "PCOMContentPermissionRequestChild.h"
|
#include "PCOMContentPermissionRequestChild.h"
|
||||||
#include "PuppetWidget.h"
|
#include "PuppetWidget.h"
|
||||||
#include "StructuredCloneUtils.h"
|
#include "StructuredCloneUtils.h"
|
||||||
|
@ -1506,7 +1507,7 @@ TabChild::DispatchMessageManagerMessage(const nsAString& aMessageName,
|
||||||
nsRefPtr<nsFrameMessageManager> mm =
|
nsRefPtr<nsFrameMessageManager> mm =
|
||||||
static_cast<nsFrameMessageManager*>(mTabChildGlobal->mMessageManager.get());
|
static_cast<nsFrameMessageManager*>(mTabChildGlobal->mMessageManager.get());
|
||||||
mm->ReceiveMessage(static_cast<EventTarget*>(mTabChildGlobal),
|
mm->ReceiveMessage(static_cast<EventTarget*>(mTabChildGlobal),
|
||||||
aMessageName, false, &cloneData, nullptr, nullptr);
|
aMessageName, false, &cloneData, nullptr, nullptr, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -2071,7 +2072,8 @@ TabChild::RecvLoadRemoteScript(const nsString& aURL)
|
||||||
bool
|
bool
|
||||||
TabChild::RecvAsyncMessage(const nsString& aMessage,
|
TabChild::RecvAsyncMessage(const nsString& aMessage,
|
||||||
const ClonedMessageData& aData,
|
const ClonedMessageData& aData,
|
||||||
const InfallibleTArray<CpowEntry>& aCpows)
|
const InfallibleTArray<CpowEntry>& aCpows,
|
||||||
|
const IPC::Principal& aPrincipal)
|
||||||
{
|
{
|
||||||
if (mTabChildGlobal) {
|
if (mTabChildGlobal) {
|
||||||
nsCOMPtr<nsIXPConnectJSObjectHolder> kungFuDeathGrip(GetGlobal());
|
nsCOMPtr<nsIXPConnectJSObjectHolder> kungFuDeathGrip(GetGlobal());
|
||||||
|
@ -2080,7 +2082,7 @@ TabChild::RecvAsyncMessage(const nsString& aMessage,
|
||||||
static_cast<nsFrameMessageManager*>(mTabChildGlobal->mMessageManager.get());
|
static_cast<nsFrameMessageManager*>(mTabChildGlobal->mMessageManager.get());
|
||||||
CpowIdHolder cpows(static_cast<ContentChild*>(Manager())->GetCPOWManager(), aCpows);
|
CpowIdHolder cpows(static_cast<ContentChild*>(Manager())->GetCPOWManager(), aCpows);
|
||||||
mm->ReceiveMessage(static_cast<EventTarget*>(mTabChildGlobal),
|
mm->ReceiveMessage(static_cast<EventTarget*>(mTabChildGlobal),
|
||||||
aMessage, false, &cloneData, &cpows, nullptr);
|
aMessage, false, &cloneData, &cpows, aPrincipal, nullptr);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -2404,6 +2406,7 @@ TabChild::DoSendBlockingMessage(JSContext* aCx,
|
||||||
const nsAString& aMessage,
|
const nsAString& aMessage,
|
||||||
const StructuredCloneData& aData,
|
const StructuredCloneData& aData,
|
||||||
JS::Handle<JSObject *> aCpows,
|
JS::Handle<JSObject *> aCpows,
|
||||||
|
nsIPrincipal* aPrincipal,
|
||||||
InfallibleTArray<nsString>* aJSONRetVal,
|
InfallibleTArray<nsString>* aJSONRetVal,
|
||||||
bool aIsSync)
|
bool aIsSync)
|
||||||
{
|
{
|
||||||
|
@ -2418,16 +2421,21 @@ TabChild::DoSendBlockingMessage(JSContext* aCx,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (aIsSync)
|
if (aIsSync) {
|
||||||
return SendSyncMessage(nsString(aMessage), data, cpows, aJSONRetVal);
|
return SendSyncMessage(nsString(aMessage), data, cpows, aPrincipal,
|
||||||
return CallRpcMessage(nsString(aMessage), data, cpows, aJSONRetVal);
|
aJSONRetVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
return CallRpcMessage(nsString(aMessage), data, cpows, aPrincipal,
|
||||||
|
aJSONRetVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TabChild::DoSendAsyncMessage(JSContext* aCx,
|
TabChild::DoSendAsyncMessage(JSContext* aCx,
|
||||||
const nsAString& aMessage,
|
const nsAString& aMessage,
|
||||||
const StructuredCloneData& aData,
|
const StructuredCloneData& aData,
|
||||||
JS::Handle<JSObject *> aCpows)
|
JS::Handle<JSObject *> aCpows,
|
||||||
|
nsIPrincipal* aPrincipal)
|
||||||
{
|
{
|
||||||
ContentChild* cc = Manager();
|
ContentChild* cc = Manager();
|
||||||
ClonedMessageData data;
|
ClonedMessageData data;
|
||||||
|
@ -2440,7 +2448,8 @@ TabChild::DoSendAsyncMessage(JSContext* aCx,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return SendAsyncMessage(nsString(aMessage), data, cpows);
|
return SendAsyncMessage(nsString(aMessage), data, cpows,
|
||||||
|
aPrincipal);
|
||||||
}
|
}
|
||||||
|
|
||||||
TabChild*
|
TabChild*
|
||||||
|
|
|
@ -63,23 +63,27 @@ public:
|
||||||
NS_IMETHOD SendSyncMessage(const nsAString& aMessageName,
|
NS_IMETHOD SendSyncMessage(const nsAString& aMessageName,
|
||||||
const JS::Value& aObject,
|
const JS::Value& aObject,
|
||||||
const JS::Value& aRemote,
|
const JS::Value& aRemote,
|
||||||
|
nsIPrincipal* aPrincipal,
|
||||||
JSContext* aCx,
|
JSContext* aCx,
|
||||||
uint8_t aArgc,
|
uint8_t aArgc,
|
||||||
JS::Value* aRetval)
|
JS::Value* aRetval)
|
||||||
{
|
{
|
||||||
return mMessageManager
|
return mMessageManager
|
||||||
? mMessageManager->SendSyncMessage(aMessageName, aObject, aRemote, aCx, aArgc, aRetval)
|
? mMessageManager->SendSyncMessage(aMessageName, aObject, aRemote,
|
||||||
|
aPrincipal, aCx, aArgc, aRetval)
|
||||||
: NS_ERROR_NULL_POINTER;
|
: NS_ERROR_NULL_POINTER;
|
||||||
}
|
}
|
||||||
NS_IMETHOD SendRpcMessage(const nsAString& aMessageName,
|
NS_IMETHOD SendRpcMessage(const nsAString& aMessageName,
|
||||||
const JS::Value& aObject,
|
const JS::Value& aObject,
|
||||||
const JS::Value& aRemote,
|
const JS::Value& aRemote,
|
||||||
|
nsIPrincipal* aPrincipal,
|
||||||
JSContext* aCx,
|
JSContext* aCx,
|
||||||
uint8_t aArgc,
|
uint8_t aArgc,
|
||||||
JS::Value* aRetval)
|
JS::Value* aRetval)
|
||||||
{
|
{
|
||||||
return mMessageManager
|
return mMessageManager
|
||||||
? mMessageManager->SendRpcMessage(aMessageName, aObject, aRemote, aCx, aArgc, aRetval)
|
? mMessageManager->SendRpcMessage(aMessageName, aObject, aRemote,
|
||||||
|
aPrincipal, aCx, aArgc, aRetval)
|
||||||
: NS_ERROR_NULL_POINTER;
|
: NS_ERROR_NULL_POINTER;
|
||||||
}
|
}
|
||||||
NS_IMETHOD GetContent(nsIDOMWindow** aContent) MOZ_OVERRIDE;
|
NS_IMETHOD GetContent(nsIDOMWindow** aContent) MOZ_OVERRIDE;
|
||||||
|
@ -194,12 +198,14 @@ public:
|
||||||
const nsAString& aMessage,
|
const nsAString& aMessage,
|
||||||
const mozilla::dom::StructuredCloneData& aData,
|
const mozilla::dom::StructuredCloneData& aData,
|
||||||
JS::Handle<JSObject *> aCpows,
|
JS::Handle<JSObject *> aCpows,
|
||||||
|
nsIPrincipal* aPrincipal,
|
||||||
InfallibleTArray<nsString>* aJSONRetVal,
|
InfallibleTArray<nsString>* aJSONRetVal,
|
||||||
bool aIsSync) MOZ_OVERRIDE;
|
bool aIsSync) MOZ_OVERRIDE;
|
||||||
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||||
const nsAString& aMessage,
|
const nsAString& aMessage,
|
||||||
const mozilla::dom::StructuredCloneData& aData,
|
const mozilla::dom::StructuredCloneData& aData,
|
||||||
JS::Handle<JSObject *> aCpows) MOZ_OVERRIDE;
|
JS::Handle<JSObject *> aCpows,
|
||||||
|
nsIPrincipal* aPrincipal) MOZ_OVERRIDE;
|
||||||
|
|
||||||
virtual bool RecvLoadURL(const nsCString& uri);
|
virtual bool RecvLoadURL(const nsCString& uri);
|
||||||
virtual bool RecvCacheFileDescriptor(const nsString& aPath,
|
virtual bool RecvCacheFileDescriptor(const nsString& aPath,
|
||||||
|
@ -237,7 +243,8 @@ public:
|
||||||
virtual bool RecvLoadRemoteScript(const nsString& aURL);
|
virtual bool RecvLoadRemoteScript(const nsString& aURL);
|
||||||
virtual bool RecvAsyncMessage(const nsString& aMessage,
|
virtual bool RecvAsyncMessage(const nsString& aMessage,
|
||||||
const ClonedMessageData& aData,
|
const ClonedMessageData& aData,
|
||||||
const InfallibleTArray<CpowEntry>& aCpows);
|
const InfallibleTArray<CpowEntry>& aCpows,
|
||||||
|
const IPC::Principal& aPrincipal) MOZ_OVERRIDE;
|
||||||
|
|
||||||
virtual PDocumentRendererChild*
|
virtual PDocumentRendererChild*
|
||||||
AllocPDocumentRendererChild(const nsRect& documentRect, const gfxMatrix& transform,
|
AllocPDocumentRendererChild(const nsRect& documentRect, const gfxMatrix& transform,
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include "TabParent.h"
|
#include "TabParent.h"
|
||||||
|
|
||||||
|
#include "AppProcessChecker.h"
|
||||||
#include "IDBFactory.h"
|
#include "IDBFactory.h"
|
||||||
#include "IndexedDBParent.h"
|
#include "IndexedDBParent.h"
|
||||||
#include "mozIApplication.h"
|
#include "mozIApplication.h"
|
||||||
|
@ -52,6 +53,7 @@
|
||||||
#include "nsServiceManagerUtils.h"
|
#include "nsServiceManagerUtils.h"
|
||||||
#include "nsThreadUtils.h"
|
#include "nsThreadUtils.h"
|
||||||
#include "private/pprio.h"
|
#include "private/pprio.h"
|
||||||
|
#include "PermissionMessageUtils.h"
|
||||||
#include "StructuredCloneUtils.h"
|
#include "StructuredCloneUtils.h"
|
||||||
#include "JavaScriptParent.h"
|
#include "JavaScriptParent.h"
|
||||||
#include "TabChild.h"
|
#include "TabChild.h"
|
||||||
|
@ -299,7 +301,8 @@ TabParent::ActorDestroy(ActorDestroyReason why)
|
||||||
if (frameLoader) {
|
if (frameLoader) {
|
||||||
fmm = frameLoader->GetFrameMessageManager();
|
fmm = frameLoader->GetFrameMessageManager();
|
||||||
nsCOMPtr<Element> frameElement(mFrameElement);
|
nsCOMPtr<Element> frameElement(mFrameElement);
|
||||||
ReceiveMessage(CHILD_PROCESS_SHUTDOWN_MESSAGE, false, nullptr, nullptr);
|
ReceiveMessage(CHILD_PROCESS_SHUTDOWN_MESSAGE, false, nullptr, nullptr,
|
||||||
|
nullptr);
|
||||||
frameLoader->DestroyChild();
|
frameLoader->DestroyChild();
|
||||||
|
|
||||||
if (why == AbnormalShutdown && os) {
|
if (why == AbnormalShutdown && os) {
|
||||||
|
@ -765,32 +768,53 @@ bool
|
||||||
TabParent::RecvSyncMessage(const nsString& aMessage,
|
TabParent::RecvSyncMessage(const nsString& aMessage,
|
||||||
const ClonedMessageData& aData,
|
const ClonedMessageData& aData,
|
||||||
const InfallibleTArray<CpowEntry>& aCpows,
|
const InfallibleTArray<CpowEntry>& aCpows,
|
||||||
|
const IPC::Principal& aPrincipal,
|
||||||
InfallibleTArray<nsString>* aJSONRetVal)
|
InfallibleTArray<nsString>* aJSONRetVal)
|
||||||
{
|
{
|
||||||
|
nsIPrincipal* principal = aPrincipal;
|
||||||
|
ContentParent* parent = static_cast<ContentParent*>(Manager());
|
||||||
|
if (principal && !AssertAppPrincipal(parent, principal)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
|
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
|
||||||
CpowIdHolder cpows(static_cast<ContentParent*>(Manager())->GetCPOWManager(), aCpows);
|
CpowIdHolder cpows(parent->GetCPOWManager(), aCpows);
|
||||||
return ReceiveMessage(aMessage, true, &cloneData, &cpows, aJSONRetVal);
|
return ReceiveMessage(aMessage, true, &cloneData, &cpows, aPrincipal, aJSONRetVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TabParent::AnswerRpcMessage(const nsString& aMessage,
|
TabParent::AnswerRpcMessage(const nsString& aMessage,
|
||||||
const ClonedMessageData& aData,
|
const ClonedMessageData& aData,
|
||||||
const InfallibleTArray<CpowEntry>& aCpows,
|
const InfallibleTArray<CpowEntry>& aCpows,
|
||||||
|
const IPC::Principal& aPrincipal,
|
||||||
InfallibleTArray<nsString>* aJSONRetVal)
|
InfallibleTArray<nsString>* aJSONRetVal)
|
||||||
{
|
{
|
||||||
|
nsIPrincipal* principal = aPrincipal;
|
||||||
|
ContentParent* parent = static_cast<ContentParent*>(Manager());
|
||||||
|
if (principal && !AssertAppPrincipal(parent, principal)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
|
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
|
||||||
CpowIdHolder cpows(static_cast<ContentParent*>(Manager())->GetCPOWManager(), aCpows);
|
CpowIdHolder cpows(parent->GetCPOWManager(), aCpows);
|
||||||
return ReceiveMessage(aMessage, true, &cloneData, &cpows, aJSONRetVal);
|
return ReceiveMessage(aMessage, true, &cloneData, &cpows, aPrincipal, aJSONRetVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TabParent::RecvAsyncMessage(const nsString& aMessage,
|
TabParent::RecvAsyncMessage(const nsString& aMessage,
|
||||||
const ClonedMessageData& aData,
|
const ClonedMessageData& aData,
|
||||||
const InfallibleTArray<CpowEntry>& aCpows)
|
const InfallibleTArray<CpowEntry>& aCpows,
|
||||||
|
const IPC::Principal& aPrincipal)
|
||||||
{
|
{
|
||||||
|
nsIPrincipal* principal = aPrincipal;
|
||||||
|
ContentParent* parent = static_cast<ContentParent*>(Manager());
|
||||||
|
if (principal && !AssertAppPrincipal(parent, principal)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
|
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
|
||||||
CpowIdHolder cpows(static_cast<ContentParent*>(Manager())->GetCPOWManager(), aCpows);
|
CpowIdHolder cpows(parent->GetCPOWManager(), aCpows);
|
||||||
return ReceiveMessage(aMessage, false, &cloneData, &cpows, nullptr);
|
return ReceiveMessage(aMessage, false, &cloneData, &cpows, aPrincipal, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -1214,6 +1238,7 @@ TabParent::ReceiveMessage(const nsString& aMessage,
|
||||||
bool aSync,
|
bool aSync,
|
||||||
const StructuredCloneData* aCloneData,
|
const StructuredCloneData* aCloneData,
|
||||||
CpowHolder* aCpows,
|
CpowHolder* aCpows,
|
||||||
|
nsIPrincipal* aPrincipal,
|
||||||
InfallibleTArray<nsString>* aJSONRetVal)
|
InfallibleTArray<nsString>* aJSONRetVal)
|
||||||
{
|
{
|
||||||
nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
|
nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
|
||||||
|
@ -1226,6 +1251,7 @@ TabParent::ReceiveMessage(const nsString& aMessage,
|
||||||
aSync,
|
aSync,
|
||||||
aCloneData,
|
aCloneData,
|
||||||
aCpows,
|
aCpows,
|
||||||
|
aPrincipal,
|
||||||
aJSONRetVal);
|
aJSONRetVal);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
struct gfxMatrix;
|
struct gfxMatrix;
|
||||||
class nsFrameLoader;
|
class nsFrameLoader;
|
||||||
class nsIContent;
|
class nsIContent;
|
||||||
|
class nsIPrincipal;
|
||||||
class nsIURI;
|
class nsIURI;
|
||||||
class nsIWidget;
|
class nsIWidget;
|
||||||
class CpowHolder;
|
class CpowHolder;
|
||||||
|
@ -121,14 +122,17 @@ public:
|
||||||
virtual bool RecvSyncMessage(const nsString& aMessage,
|
virtual bool RecvSyncMessage(const nsString& aMessage,
|
||||||
const ClonedMessageData& aData,
|
const ClonedMessageData& aData,
|
||||||
const InfallibleTArray<CpowEntry>& aCpows,
|
const InfallibleTArray<CpowEntry>& aCpows,
|
||||||
|
const IPC::Principal& aPrincipal,
|
||||||
InfallibleTArray<nsString>* aJSONRetVal);
|
InfallibleTArray<nsString>* aJSONRetVal);
|
||||||
virtual bool AnswerRpcMessage(const nsString& aMessage,
|
virtual bool AnswerRpcMessage(const nsString& aMessage,
|
||||||
const ClonedMessageData& aData,
|
const ClonedMessageData& aData,
|
||||||
const InfallibleTArray<CpowEntry>& aCpows,
|
const InfallibleTArray<CpowEntry>& aCpows,
|
||||||
|
const IPC::Principal& aPrincipal,
|
||||||
InfallibleTArray<nsString>* aJSONRetVal);
|
InfallibleTArray<nsString>* aJSONRetVal);
|
||||||
virtual bool RecvAsyncMessage(const nsString& aMessage,
|
virtual bool RecvAsyncMessage(const nsString& aMessage,
|
||||||
const ClonedMessageData& aData,
|
const ClonedMessageData& aData,
|
||||||
const InfallibleTArray<CpowEntry>& aCpows);
|
const InfallibleTArray<CpowEntry>& aCpows,
|
||||||
|
const IPC::Principal& aPrincipal);
|
||||||
virtual bool RecvNotifyIMEFocus(const bool& aFocus,
|
virtual bool RecvNotifyIMEFocus(const bool& aFocus,
|
||||||
nsIMEUpdatePreference* aPreference,
|
nsIMEUpdatePreference* aPreference,
|
||||||
uint32_t* aSeqno);
|
uint32_t* aSeqno);
|
||||||
|
@ -254,6 +258,7 @@ protected:
|
||||||
bool aSync,
|
bool aSync,
|
||||||
const StructuredCloneData* aCloneData,
|
const StructuredCloneData* aCloneData,
|
||||||
CpowHolder* aCpows,
|
CpowHolder* aCpows,
|
||||||
|
nsIPrincipal* aPrincipal,
|
||||||
InfallibleTArray<nsString>* aJSONRetVal = nullptr);
|
InfallibleTArray<nsString>* aJSONRetVal = nullptr);
|
||||||
|
|
||||||
virtual bool Recv__delete__() MOZ_OVERRIDE;
|
virtual bool Recv__delete__() MOZ_OVERRIDE;
|
||||||
|
|
|
@ -1662,6 +1662,7 @@ NS_IMETHODIMP nsWebBrowser::EnsureDocShellTreeOwner()
|
||||||
static void DrawThebesLayer(ThebesLayer* aLayer,
|
static void DrawThebesLayer(ThebesLayer* aLayer,
|
||||||
gfxContext* aContext,
|
gfxContext* aContext,
|
||||||
const nsIntRegion& aRegionToDraw,
|
const nsIntRegion& aRegionToDraw,
|
||||||
|
DrawRegionClip aClip,
|
||||||
const nsIntRegion& aRegionToInvalidate,
|
const nsIntRegion& aRegionToInvalidate,
|
||||||
void* aCallbackData)
|
void* aCallbackData)
|
||||||
{
|
{
|
||||||
|
|
|
@ -265,6 +265,7 @@ public:
|
||||||
typedef void (* DrawThebesLayerCallback)(ThebesLayer* aLayer,
|
typedef void (* DrawThebesLayerCallback)(ThebesLayer* aLayer,
|
||||||
gfxContext* aContext,
|
gfxContext* aContext,
|
||||||
const nsIntRegion& aRegionToDraw,
|
const nsIntRegion& aRegionToDraw,
|
||||||
|
DrawRegionClip aClip,
|
||||||
const nsIntRegion& aRegionToInvalidate,
|
const nsIntRegion& aRegionToInvalidate,
|
||||||
void* aCallbackData);
|
void* aCallbackData);
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,12 @@ enum BufferMode {
|
||||||
BUFFER_BUFFERED
|
BUFFER_BUFFERED
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum DrawRegionClip {
|
||||||
|
CLIP_DRAW,
|
||||||
|
CLIP_DRAW_SNAPPED,
|
||||||
|
CLIP_NONE,
|
||||||
|
};
|
||||||
|
|
||||||
// LayerRenderState for Composer2D
|
// LayerRenderState for Composer2D
|
||||||
// We currently only support Composer2D using gralloc. If we want to be backed
|
// We currently only support Composer2D using gralloc. If we want to be backed
|
||||||
// by other surfaces we will need a more generic LayerRenderState.
|
// by other surfaces we will need a more generic LayerRenderState.
|
||||||
|
|
|
@ -856,6 +856,7 @@ ThebesLayerBuffer::BeginPaint(ThebesLayer* aLayer, ContentType aContentType,
|
||||||
|
|
||||||
nsIntPoint topLeft;
|
nsIntPoint topLeft;
|
||||||
result.mContext = GetContextForQuadrantUpdate(drawBounds, BUFFER_BOTH, &topLeft);
|
result.mContext = GetContextForQuadrantUpdate(drawBounds, BUFFER_BOTH, &topLeft);
|
||||||
|
result.mClip = CLIP_DRAW_SNAPPED;
|
||||||
|
|
||||||
if (mode == Layer::SURFACE_COMPONENT_ALPHA) {
|
if (mode == Layer::SURFACE_COMPONENT_ALPHA) {
|
||||||
if (IsAzureBuffer()) {
|
if (IsAzureBuffer()) {
|
||||||
|
@ -873,7 +874,6 @@ ThebesLayerBuffer::BeginPaint(ThebesLayer* aLayer, ContentType aContentType,
|
||||||
FillSurface(mBuffer, result.mRegionToDraw, topLeft, gfxRGBA(0.0, 0.0, 0.0, 1.0));
|
FillSurface(mBuffer, result.mRegionToDraw, topLeft, gfxRGBA(0.0, 0.0, 0.0, 1.0));
|
||||||
FillSurface(mBufferOnWhite, result.mRegionToDraw, topLeft, gfxRGBA(1.0, 1.0, 1.0, 1.0));
|
FillSurface(mBufferOnWhite, result.mRegionToDraw, topLeft, gfxRGBA(1.0, 1.0, 1.0, 1.0));
|
||||||
}
|
}
|
||||||
gfxUtils::ClipToRegionSnapped(result.mContext, result.mRegionToDraw);
|
|
||||||
} else if (contentType == GFX_CONTENT_COLOR_ALPHA && !isClear) {
|
} else if (contentType == GFX_CONTENT_COLOR_ALPHA && !isClear) {
|
||||||
if (IsAzureBuffer()) {
|
if (IsAzureBuffer()) {
|
||||||
nsIntRegionRectIterator iter(result.mRegionToDraw);
|
nsIntRegionRectIterator iter(result.mRegionToDraw);
|
||||||
|
@ -883,16 +883,14 @@ ThebesLayerBuffer::BeginPaint(ThebesLayer* aLayer, ContentType aContentType,
|
||||||
}
|
}
|
||||||
// Clear will do something expensive with a complex clip pushed, so clip
|
// Clear will do something expensive with a complex clip pushed, so clip
|
||||||
// here.
|
// here.
|
||||||
gfxUtils::ClipToRegionSnapped(result.mContext, result.mRegionToDraw);
|
|
||||||
} else {
|
} else {
|
||||||
MOZ_ASSERT(result.mContext->IsCairo());
|
MOZ_ASSERT(result.mContext->IsCairo());
|
||||||
|
result.mContext->Save();
|
||||||
gfxUtils::ClipToRegionSnapped(result.mContext, result.mRegionToDraw);
|
gfxUtils::ClipToRegionSnapped(result.mContext, result.mRegionToDraw);
|
||||||
result.mContext->SetOperator(gfxContext::OPERATOR_CLEAR);
|
result.mContext->SetOperator(gfxContext::OPERATOR_CLEAR);
|
||||||
result.mContext->Paint();
|
result.mContext->Paint();
|
||||||
result.mContext->SetOperator(gfxContext::OPERATOR_OVER);
|
result.mContext->Restore();
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
gfxUtils::ClipToRegionSnapped(result.mContext, result.mRegionToDraw);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "nsRect.h" // for nsIntRect
|
#include "nsRect.h" // for nsIntRect
|
||||||
#include "nsRegion.h" // for nsIntRegion
|
#include "nsRegion.h" // for nsIntRegion
|
||||||
#include "nsTraceRefcnt.h" // for MOZ_COUNT_CTOR, etc
|
#include "nsTraceRefcnt.h" // for MOZ_COUNT_CTOR, etc
|
||||||
|
#include "LayersTypes.h"
|
||||||
|
|
||||||
struct gfxMatrix;
|
struct gfxMatrix;
|
||||||
struct nsIntSize;
|
struct nsIntSize;
|
||||||
|
@ -218,6 +219,7 @@ public:
|
||||||
nsIntRegion mRegionToDraw;
|
nsIntRegion mRegionToDraw;
|
||||||
nsIntRegion mRegionToInvalidate;
|
nsIntRegion mRegionToInvalidate;
|
||||||
bool mDidSelfCopy;
|
bool mDidSelfCopy;
|
||||||
|
DrawRegionClip mClip;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
|
|
@ -115,10 +115,10 @@ protected:
|
||||||
{
|
{
|
||||||
EnsureSurface();
|
EnsureSurface();
|
||||||
if (!mSurface) {
|
if (!mSurface) {
|
||||||
mSurface = mCompositor->GetDrawTarget()->CreateSourceSurfaceFromData(mThebesImage->Data(),
|
mSurface = Factory::CreateWrappingDataSourceSurface(mThebesImage->Data(),
|
||||||
mSize,
|
mThebesImage->Stride(),
|
||||||
mThebesImage->Stride(),
|
mSize,
|
||||||
mFormat);
|
mFormat);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,7 +131,7 @@ BasicThebesLayer::PaintThebes(gfxContext* aContext,
|
||||||
groupContext = aContext;
|
groupContext = aContext;
|
||||||
}
|
}
|
||||||
SetAntialiasingFlags(this, groupContext);
|
SetAntialiasingFlags(this, groupContext);
|
||||||
aCallback(this, groupContext, toDraw, nsIntRegion(), aCallbackData);
|
aCallback(this, groupContext, toDraw, CLIP_NONE, nsIntRegion(), aCallbackData);
|
||||||
if (needsGroup) {
|
if (needsGroup) {
|
||||||
BasicManager()->PopGroupToSourceWithCachedSurface(aContext, groupContext);
|
BasicManager()->PopGroupToSourceWithCachedSurface(aContext, groupContext);
|
||||||
if (needsClipToVisibleRegion) {
|
if (needsClipToVisibleRegion) {
|
||||||
|
@ -236,6 +236,7 @@ BasicThebesLayer::Validate(LayerManager::DrawThebesLayerCallback aCallback,
|
||||||
PaintBuffer(state.mContext,
|
PaintBuffer(state.mContext,
|
||||||
state.mRegionToDraw, extendedDrawRegion, state.mRegionToInvalidate,
|
state.mRegionToDraw, extendedDrawRegion, state.mRegionToInvalidate,
|
||||||
state.mDidSelfCopy,
|
state.mDidSelfCopy,
|
||||||
|
state.mClip,
|
||||||
aCallback, aCallbackData);
|
aCallback, aCallbackData);
|
||||||
MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) PaintThebes", this));
|
MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) PaintThebes", this));
|
||||||
Mutated();
|
Mutated();
|
||||||
|
|
|
@ -103,6 +103,7 @@ protected:
|
||||||
const nsIntRegion& aExtendedRegionToDraw,
|
const nsIntRegion& aExtendedRegionToDraw,
|
||||||
const nsIntRegion& aRegionToInvalidate,
|
const nsIntRegion& aRegionToInvalidate,
|
||||||
bool aDidSelfCopy,
|
bool aDidSelfCopy,
|
||||||
|
DrawRegionClip aClip,
|
||||||
LayerManager::DrawThebesLayerCallback aCallback,
|
LayerManager::DrawThebesLayerCallback aCallback,
|
||||||
void* aCallbackData)
|
void* aCallbackData)
|
||||||
{
|
{
|
||||||
|
@ -110,8 +111,8 @@ protected:
|
||||||
BasicManager()->SetTransactionIncomplete();
|
BasicManager()->SetTransactionIncomplete();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
aCallback(this, aContext, aExtendedRegionToDraw, aRegionToInvalidate,
|
aCallback(this, aContext, aExtendedRegionToDraw, aClip,
|
||||||
aCallbackData);
|
aRegionToInvalidate, aCallbackData);
|
||||||
// Everything that's visible has been validated. Do this instead of just
|
// Everything that's visible has been validated. Do this instead of just
|
||||||
// OR-ing with aRegionToDraw, since that can lead to a very complex region
|
// OR-ing with aRegionToDraw, since that can lead to a very complex region
|
||||||
// here (OR doesn't automatically simplify to the simplest possible
|
// here (OR doesn't automatically simplify to the simplest possible
|
||||||
|
|
|
@ -106,7 +106,7 @@ ClientThebesLayer::PaintThebes()
|
||||||
|
|
||||||
PaintBuffer(state.mContext,
|
PaintBuffer(state.mContext,
|
||||||
state.mRegionToDraw, extendedDrawRegion, state.mRegionToInvalidate,
|
state.mRegionToDraw, extendedDrawRegion, state.mRegionToInvalidate,
|
||||||
state.mDidSelfCopy);
|
state.mDidSelfCopy, state.mClip);
|
||||||
MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) PaintThebes", this));
|
MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) PaintThebes", this));
|
||||||
Mutated();
|
Mutated();
|
||||||
} else {
|
} else {
|
||||||
|
@ -146,7 +146,7 @@ ClientThebesLayer::PaintBuffer(gfxContext* aContext,
|
||||||
const nsIntRegion& aRegionToDraw,
|
const nsIntRegion& aRegionToDraw,
|
||||||
const nsIntRegion& aExtendedRegionToDraw,
|
const nsIntRegion& aExtendedRegionToDraw,
|
||||||
const nsIntRegion& aRegionToInvalidate,
|
const nsIntRegion& aRegionToInvalidate,
|
||||||
bool aDidSelfCopy)
|
bool aDidSelfCopy, DrawRegionClip aClip)
|
||||||
{
|
{
|
||||||
ContentClientRemote* contentClientRemote = static_cast<ContentClientRemote*>(mContentClient.get());
|
ContentClientRemote* contentClientRemote = static_cast<ContentClientRemote*>(mContentClient.get());
|
||||||
MOZ_ASSERT(contentClientRemote->GetIPDLActor());
|
MOZ_ASSERT(contentClientRemote->GetIPDLActor());
|
||||||
|
@ -161,7 +161,8 @@ ClientThebesLayer::PaintBuffer(gfxContext* aContext,
|
||||||
}
|
}
|
||||||
ClientManager()->GetThebesLayerCallback()(this,
|
ClientManager()->GetThebesLayerCallback()(this,
|
||||||
aContext,
|
aContext,
|
||||||
aExtendedRegionToDraw,
|
aExtendedRegionToDraw,
|
||||||
|
aClip,
|
||||||
aRegionToInvalidate,
|
aRegionToInvalidate,
|
||||||
ClientManager()->GetThebesLayerCallbackData());
|
ClientManager()->GetThebesLayerCallbackData());
|
||||||
|
|
||||||
|
|
|
@ -105,7 +105,8 @@ protected:
|
||||||
const nsIntRegion& aRegionToDraw,
|
const nsIntRegion& aRegionToDraw,
|
||||||
const nsIntRegion& aExtendedRegionToDraw,
|
const nsIntRegion& aExtendedRegionToDraw,
|
||||||
const nsIntRegion& aRegionToInvalidate,
|
const nsIntRegion& aRegionToInvalidate,
|
||||||
bool aDidSelfCopy);
|
bool aDidSelfCopy,
|
||||||
|
DrawRegionClip aClip);
|
||||||
|
|
||||||
void PaintThebes();
|
void PaintThebes();
|
||||||
|
|
||||||
|
|
|
@ -69,18 +69,6 @@ private:
|
||||||
return static_cast<ClientLayerManager*>(mManager);
|
return static_cast<ClientLayerManager*>(mManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
// BasicImplData
|
|
||||||
virtual void
|
|
||||||
PaintBuffer(gfxContext* aContext,
|
|
||||||
const nsIntRegion& aRegionToDraw,
|
|
||||||
const nsIntRegion& aExtendedRegionToDraw,
|
|
||||||
const nsIntRegion& aRegionToInvalidate,
|
|
||||||
bool aDidSelfCopy,
|
|
||||||
LayerManager::DrawThebesLayerCallback aCallback,
|
|
||||||
void* aCallbackData)
|
|
||||||
{ NS_RUNTIMEABORT("Not reached."); }
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For the initial PaintThebes of a transaction, calculates all the data
|
* For the initial PaintThebes of a transaction, calculates all the data
|
||||||
* needed for that paint and any repeated transactions.
|
* needed for that paint and any repeated transactions.
|
||||||
|
|
|
@ -894,12 +894,14 @@ ContentClientIncremental::BeginPaintBuffer(ThebesLayer* aLayer,
|
||||||
// although they never cover it. This leads to two draw rects, the narow strip and the actually
|
// although they never cover it. This leads to two draw rects, the narow strip and the actually
|
||||||
// newly exposed area. It would be wise to fix this glitch in any way to have simpler
|
// newly exposed area. It would be wise to fix this glitch in any way to have simpler
|
||||||
// clip and draw regions.
|
// clip and draw regions.
|
||||||
gfxUtils::ClipToRegion(result.mContext, result.mRegionToDraw);
|
result.mClip = CLIP_DRAW;
|
||||||
|
|
||||||
if (mContentType == GFX_CONTENT_COLOR_ALPHA) {
|
if (mContentType == GFX_CONTENT_COLOR_ALPHA) {
|
||||||
|
result.mContext->Save();
|
||||||
|
gfxUtils::ClipToRegion(result.mContext, result.mRegionToDraw);
|
||||||
result.mContext->SetOperator(gfxContext::OPERATOR_CLEAR);
|
result.mContext->SetOperator(gfxContext::OPERATOR_CLEAR);
|
||||||
result.mContext->Paint();
|
result.mContext->Paint();
|
||||||
result.mContext->SetOperator(gfxContext::OPERATOR_OVER);
|
result.mContext->Restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -274,7 +274,7 @@ BasicTiledLayerBuffer::PaintThebes(const nsIntRegion& aNewValidRegion,
|
||||||
#endif
|
#endif
|
||||||
PROFILER_LABEL("BasicTiledLayerBuffer", "PaintThebesSingleBufferDraw");
|
PROFILER_LABEL("BasicTiledLayerBuffer", "PaintThebesSingleBufferDraw");
|
||||||
|
|
||||||
mCallback(mThebesLayer, ctxt, aPaintRegion, nsIntRegion(), mCallbackData);
|
mCallback(mThebesLayer, ctxt, aPaintRegion, CLIP_NONE, nsIntRegion(), mCallbackData);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef GFX_TILEDLAYER_PREF_WARNINGS
|
#ifdef GFX_TILEDLAYER_PREF_WARNINGS
|
||||||
|
@ -383,6 +383,7 @@ BasicTiledLayerBuffer::ValidateTileInternal(BasicTiledLayerTile aTile,
|
||||||
mCallback(mThebesLayer, ctxt,
|
mCallback(mThebesLayer, ctxt,
|
||||||
nsIntRegion(nsIntRect(a, nsIntSize(GetScaledTileLength(),
|
nsIntRegion(nsIntRect(a, nsIntSize(GetScaledTileLength(),
|
||||||
GetScaledTileLength()))),
|
GetScaledTileLength()))),
|
||||||
|
CLIP_NONE,
|
||||||
nsIntRegion(), mCallbackData);
|
nsIntRegion(), mCallbackData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -392,7 +392,6 @@ APZCTreeManager::ProcessEvent(const WidgetInputEvent& aEvent,
|
||||||
gfx3DMatrix transformToApzc;
|
gfx3DMatrix transformToApzc;
|
||||||
gfx3DMatrix transformToGecko;
|
gfx3DMatrix transformToGecko;
|
||||||
GetInputTransforms(apzc, transformToApzc, transformToGecko);
|
GetInputTransforms(apzc, transformToApzc, transformToGecko);
|
||||||
ApplyTransform(&(aOutEvent->refPoint), transformToApzc);
|
|
||||||
gfx3DMatrix outTransform = transformToApzc * transformToGecko;
|
gfx3DMatrix outTransform = transformToApzc * transformToGecko;
|
||||||
ApplyTransform(&(aOutEvent->refPoint), outTransform);
|
ApplyTransform(&(aOutEvent->refPoint), outTransform);
|
||||||
return nsEventStatus_eIgnore;
|
return nsEventStatus_eIgnore;
|
||||||
|
|
|
@ -158,20 +158,6 @@ public:
|
||||||
void* GetThebesLayerCallbackData() const
|
void* GetThebesLayerCallbackData() const
|
||||||
{ return mThebesLayerCallbackData; }
|
{ return mThebesLayerCallbackData; }
|
||||||
|
|
||||||
/*
|
|
||||||
* Helper functions for our layers
|
|
||||||
*/
|
|
||||||
void CallThebesLayerDrawCallback(ThebesLayer* aLayer,
|
|
||||||
gfxContext* aContext,
|
|
||||||
const nsIntRegion& aRegionToDraw)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(mThebesLayerCallback,
|
|
||||||
"CallThebesLayerDrawCallback without callback!");
|
|
||||||
mThebesLayerCallback(aLayer, aContext,
|
|
||||||
aRegionToDraw, nsIntRegion(),
|
|
||||||
mThebesLayerCallbackData);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef MOZ_LAYERS_HAVE_LOG
|
#ifdef MOZ_LAYERS_HAVE_LOG
|
||||||
virtual const char* Name() const MOZ_OVERRIDE { return ""; }
|
virtual const char* Name() const MOZ_OVERRIDE { return ""; }
|
||||||
#endif // MOZ_LAYERS_HAVE_LOG
|
#endif // MOZ_LAYERS_HAVE_LOG
|
||||||
|
|
|
@ -414,40 +414,22 @@ ThebesLayerD3D10::DrawRegion(nsIntRegion &aRegion, SurfaceMode aMode)
|
||||||
destinationSurface = mD2DSurface;
|
destinationSurface = mD2DSurface;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<gfxContext> context;
|
MOZ_ASSERT(mDrawTarget);
|
||||||
|
nsRefPtr<gfxContext> context = new gfxContext(mDrawTarget);
|
||||||
|
|
||||||
if (mDrawTarget) {
|
|
||||||
context = new gfxContext(mDrawTarget);
|
|
||||||
} else {
|
|
||||||
context = new gfxContext(destinationSurface);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsIntRegionRectIterator iter(aRegion);
|
|
||||||
context->Translate(gfxPoint(-visibleRect.x, -visibleRect.y));
|
context->Translate(gfxPoint(-visibleRect.x, -visibleRect.y));
|
||||||
context->NewPath();
|
if (aMode == SURFACE_SINGLE_CHANNEL_ALPHA) {
|
||||||
const nsIntRect *iterRect;
|
nsIntRegionRectIterator iter(aRegion);
|
||||||
while ((iterRect = iter.Next())) {
|
const nsIntRect *iterRect;
|
||||||
context->Rectangle(gfxRect(iterRect->x, iterRect->y, iterRect->width, iterRect->height));
|
while ((iterRect = iter.Next())) {
|
||||||
if (mDrawTarget && aMode == SURFACE_SINGLE_CHANNEL_ALPHA) {
|
|
||||||
mDrawTarget->ClearRect(Rect(iterRect->x, iterRect->y, iterRect->width, iterRect->height));
|
mDrawTarget->ClearRect(Rect(iterRect->x, iterRect->y, iterRect->width, iterRect->height));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
context->Clip();
|
|
||||||
|
|
||||||
if (!mDrawTarget && aMode == SURFACE_SINGLE_CHANNEL_ALPHA) {
|
mDrawTarget->SetPermitSubpixelAA(!(mContentFlags & CONTENT_COMPONENT_ALPHA));
|
||||||
context->SetOperator(gfxContext::OPERATOR_CLEAR);
|
|
||||||
context->Paint();
|
|
||||||
context->SetOperator(gfxContext::OPERATOR_OVER);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mD2DSurface) {
|
|
||||||
mD2DSurface->SetSubpixelAntialiasingEnabled(!(mContentFlags & CONTENT_COMPONENT_ALPHA));
|
|
||||||
} else if (mDrawTarget) {
|
|
||||||
mDrawTarget->SetPermitSubpixelAA(!(mContentFlags & CONTENT_COMPONENT_ALPHA));
|
|
||||||
}
|
|
||||||
|
|
||||||
LayerManagerD3D10::CallbackInfo cbInfo = mD3DManager->GetCallbackInfo();
|
LayerManagerD3D10::CallbackInfo cbInfo = mD3DManager->GetCallbackInfo();
|
||||||
cbInfo.Callback(this, context, aRegion, nsIntRegion(), cbInfo.CallbackData);
|
cbInfo.Callback(this, context, aRegion, CLIP_DRAW, nsIntRegion(), cbInfo.CallbackData);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -493,7 +493,7 @@ ThebesLayerD3D9::DrawRegion(nsIntRegion &aRegion, SurfaceMode aMode,
|
||||||
|
|
||||||
context->Translate(gfxPoint(-bounds.x, -bounds.y));
|
context->Translate(gfxPoint(-bounds.x, -bounds.y));
|
||||||
LayerManagerD3D9::CallbackInfo cbInfo = mD3DManager->GetCallbackInfo();
|
LayerManagerD3D9::CallbackInfo cbInfo = mD3DManager->GetCallbackInfo();
|
||||||
cbInfo.Callback(this, context, aRegion, nsIntRegion(), cbInfo.CallbackData);
|
cbInfo.Callback(this, context, aRegion, CLIP_NONE, nsIntRegion(), cbInfo.CallbackData);
|
||||||
|
|
||||||
for (uint32_t i = 0; i < aReadbackUpdates.Length(); ++i) {
|
for (uint32_t i = 0; i < aReadbackUpdates.Length(); ++i) {
|
||||||
NS_ASSERTION(aMode == SURFACE_OPAQUE,
|
NS_ASSERTION(aMode == SURFACE_OPAQUE,
|
||||||
|
|
|
@ -200,21 +200,6 @@ public:
|
||||||
void* GetThebesLayerCallbackData() const
|
void* GetThebesLayerCallbackData() const
|
||||||
{ return mThebesLayerCallbackData; }
|
{ return mThebesLayerCallbackData; }
|
||||||
|
|
||||||
/*
|
|
||||||
* Helper functions for our layers
|
|
||||||
*/
|
|
||||||
void CallThebesLayerDrawCallback(ThebesLayer* aLayer,
|
|
||||||
gfxContext* aContext,
|
|
||||||
const nsIntRegion& aRegionToDraw)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(mThebesLayerCallback,
|
|
||||||
"CallThebesLayerDrawCallback without callback!");
|
|
||||||
mThebesLayerCallback(aLayer, aContext,
|
|
||||||
aRegionToDraw, nsIntRegion(),
|
|
||||||
mThebesLayerCallbackData);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
GLenum FBOTextureTarget() { return mFBOTextureTarget; }
|
GLenum FBOTextureTarget() { return mFBOTextureTarget; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -828,12 +828,14 @@ BasicBufferOGL::BeginPaint(ContentType aContentType,
|
||||||
// although they never cover it. This leads to two draw rects, the narow strip and the actually
|
// although they never cover it. This leads to two draw rects, the narow strip and the actually
|
||||||
// newly exposed area. It would be wise to fix this glitch in any way to have simpler
|
// newly exposed area. It would be wise to fix this glitch in any way to have simpler
|
||||||
// clip and draw regions.
|
// clip and draw regions.
|
||||||
gfxUtils::ClipToRegion(result.mContext, result.mRegionToDraw);
|
result.mClip = CLIP_DRAW;
|
||||||
|
|
||||||
if (mTexImage->GetContentType() == GFX_CONTENT_COLOR_ALPHA) {
|
if (mTexImage->GetContentType() == GFX_CONTENT_COLOR_ALPHA) {
|
||||||
|
result.mContext->Save();
|
||||||
|
gfxUtils::ClipToRegion(result.mContext, result.mRegionToDraw);
|
||||||
result.mContext->SetOperator(gfxContext::OPERATOR_CLEAR);
|
result.mContext->SetOperator(gfxContext::OPERATOR_CLEAR);
|
||||||
result.mContext->Paint();
|
result.mContext->Paint();
|
||||||
result.mContext->SetOperator(gfxContext::OPERATOR_OVER);
|
result.mContext->Restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -931,7 +933,7 @@ ThebesLayerOGL::RenderLayer(int aPreviousFrameBuffer,
|
||||||
} else {
|
} else {
|
||||||
void* callbackData = mOGLManager->GetThebesLayerCallbackData();
|
void* callbackData = mOGLManager->GetThebesLayerCallbackData();
|
||||||
SetAntialiasingFlags(this, state.mContext);
|
SetAntialiasingFlags(this, state.mContext);
|
||||||
callback(this, state.mContext, state.mRegionToDraw,
|
callback(this, state.mContext, state.mRegionToDraw, state.mClip,
|
||||||
state.mRegionToInvalidate, callbackData);
|
state.mRegionToInvalidate, callbackData);
|
||||||
// Everything that's visible has been validated. Do this instead of just
|
// Everything that's visible has been validated. Do this instead of just
|
||||||
// OR-ing with aRegionToDraw, since that can lead to a very complex region
|
// OR-ing with aRegionToDraw, since that can lead to a very complex region
|
||||||
|
|
|
@ -213,13 +213,18 @@ WasIncrementalGC(JSRuntime *rt);
|
||||||
extern JS_FRIEND_API(size_t)
|
extern JS_FRIEND_API(size_t)
|
||||||
GetGCNumber();
|
GetGCNumber();
|
||||||
|
|
||||||
class AutoAssertNoGC {
|
class JS_PUBLIC_API(AutoAssertNoGC)
|
||||||
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
size_t gcNumber;
|
size_t gcNumber;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AutoAssertNoGC();
|
AutoAssertNoGC();
|
||||||
~AutoAssertNoGC();
|
~AutoAssertNoGC();
|
||||||
|
#else
|
||||||
|
public:
|
||||||
|
/* Prevent unreferenced local warnings in opt builds. */
|
||||||
|
AutoAssertNoGC() {}
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -311,6 +316,31 @@ ExposeObjectToActiveJS(JSObject *obj)
|
||||||
ExposeGCThingToActiveJS(obj, JSTRACE_OBJECT);
|
ExposeGCThingToActiveJS(obj, JSTRACE_OBJECT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If a GC is currently marking, mark the object black.
|
||||||
|
*/
|
||||||
|
static JS_ALWAYS_INLINE void
|
||||||
|
MarkGCThingAsLive(JSRuntime *rt_, void *thing, JSGCTraceKind kind)
|
||||||
|
{
|
||||||
|
shadow::Runtime *rt = shadow::Runtime::asShadowRuntime(rt_);
|
||||||
|
#ifdef JSGC_GENERATIONAL
|
||||||
|
/*
|
||||||
|
* Any object in the nursery will not be freed during any GC running at that time.
|
||||||
|
*/
|
||||||
|
if (js::gc::IsInsideNursery(rt, thing))
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
if (IsIncrementalBarrierNeededOnGCThing(rt, thing, kind))
|
||||||
|
IncrementalReferenceBarrier(thing, kind);
|
||||||
|
}
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE void
|
||||||
|
MarkStringAsLive(Zone *zone, JSString *string)
|
||||||
|
{
|
||||||
|
JSRuntime *rt = JS::shadow::Zone::asShadowZone(zone)->runtimeFromMainThread();
|
||||||
|
MarkGCThingAsLive(rt, string, JSTRACE_STRING);
|
||||||
|
}
|
||||||
|
|
||||||
} /* namespace JS */
|
} /* namespace JS */
|
||||||
|
|
||||||
#endif /* js_GCAPI_h */
|
#endif /* js_GCAPI_h */
|
||||||
|
|
|
@ -1249,6 +1249,8 @@ js_InitTypedObjectClass(JSContext *cx, HandleObject obj)
|
||||||
|
|
||||||
RootedObject module(cx, NewObjectWithClassProto(cx, &JSObject::class_,
|
RootedObject module(cx, NewObjectWithClassProto(cx, &JSObject::class_,
|
||||||
objProto, global));
|
objProto, global));
|
||||||
|
if (!module)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
// Define TypedObject global.
|
// Define TypedObject global.
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
|
|
||||||
#include "frontend/ParseMaps-inl.h"
|
#include "frontend/ParseMaps-inl.h"
|
||||||
#include "frontend/ParseNode-inl.h"
|
#include "frontend/ParseNode-inl.h"
|
||||||
|
#include "vm/ScopeObject-inl.h"
|
||||||
|
|
||||||
using namespace js;
|
using namespace js;
|
||||||
using namespace js::gc;
|
using namespace js::gc;
|
||||||
|
@ -1165,9 +1166,9 @@ TryConvertFreeName(BytecodeEmitter *bce, ParseNode *pn)
|
||||||
if (bce->script->directlyInsideEval)
|
if (bce->script->directlyInsideEval)
|
||||||
return false;
|
return false;
|
||||||
RootedObject outerScope(bce->sc->context, bce->script->enclosingStaticScope());
|
RootedObject outerScope(bce->sc->context, bce->script->enclosingStaticScope());
|
||||||
for (StaticScopeIter ssi(bce->sc->context, outerScope); !ssi.done(); ssi++) {
|
for (StaticScopeIter<CanGC> ssi(bce->sc->context, outerScope); !ssi.done(); ssi++) {
|
||||||
if (ssi.type() != StaticScopeIter::FUNCTION) {
|
if (ssi.type() != StaticScopeIter<CanGC>::FUNCTION) {
|
||||||
if (ssi.type() == StaticScopeIter::BLOCK) {
|
if (ssi.type() == StaticScopeIter<CanGC>::BLOCK) {
|
||||||
// Use generic ops if a catch block is encountered.
|
// Use generic ops if a catch block is encountered.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -6446,6 +6447,11 @@ frontend::EmitTree(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||||
: EmitVariables(cx, bce, pn, InitializeVars);
|
: EmitVariables(cx, bce, pn, InitializeVars);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PNK_IMPORT:
|
||||||
|
// TODO: Implement emitter support for modules
|
||||||
|
bce->reportError(nullptr, JSMSG_MODULES_NOT_IMPLEMENTED);
|
||||||
|
return false;
|
||||||
|
|
||||||
case PNK_ARRAYPUSH: {
|
case PNK_ARRAYPUSH: {
|
||||||
int slot;
|
int slot;
|
||||||
|
|
||||||
|
|
|
@ -295,6 +295,16 @@ class FullParseHandler
|
||||||
return new_<UnaryNode>(PNK_SEMI, JSOP_NOP, pos, (ParseNode *) nullptr);
|
return new_<UnaryNode>(PNK_SEMI, JSOP_NOP, pos, (ParseNode *) nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ParseNode *newImportDeclaration(ParseNode *importSpecSet,
|
||||||
|
ParseNode *moduleSpec, const TokenPos &pos)
|
||||||
|
{
|
||||||
|
ParseNode *pn = new_<BinaryNode>(PNK_IMPORT, JSOP_NOP, pos,
|
||||||
|
importSpecSet, moduleSpec);
|
||||||
|
if (!pn)
|
||||||
|
return null();
|
||||||
|
return pn;
|
||||||
|
}
|
||||||
|
|
||||||
ParseNode *newExprStatement(ParseNode *expr, uint32_t end) {
|
ParseNode *newExprStatement(ParseNode *expr, uint32_t end) {
|
||||||
JS_ASSERT(expr->pn_pos.end <= end);
|
JS_ASSERT(expr->pn_pos.end <= end);
|
||||||
return new_<UnaryNode>(PNK_SEMI, JSOP_NOP, TokenPos(expr->pn_pos.begin, end), expr);
|
return new_<UnaryNode>(PNK_SEMI, JSOP_NOP, TokenPos(expr->pn_pos.begin, end), expr);
|
||||||
|
|
|
@ -128,6 +128,9 @@ class UpvarCookie
|
||||||
F(ARRAYPUSH) \
|
F(ARRAYPUSH) \
|
||||||
F(LEXICALSCOPE) \
|
F(LEXICALSCOPE) \
|
||||||
F(LET) \
|
F(LET) \
|
||||||
|
F(IMPORT) \
|
||||||
|
F(IMPORT_SPEC_LIST) \
|
||||||
|
F(IMPORT_SPEC) \
|
||||||
F(SEQ) \
|
F(SEQ) \
|
||||||
F(FORIN) \
|
F(FORIN) \
|
||||||
F(FOROF) \
|
F(FOROF) \
|
||||||
|
|
|
@ -3628,6 +3628,134 @@ Parser<SyntaxParseHandler>::letStatement()
|
||||||
return SyntaxParseHandler::NodeFailure;
|
return SyntaxParseHandler::NodeFailure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename ParseHandler>
|
||||||
|
typename ParseHandler::Node
|
||||||
|
Parser<ParseHandler>::importDeclaration()
|
||||||
|
{
|
||||||
|
JS_ASSERT(tokenStream.currentToken().type == TOK_IMPORT);
|
||||||
|
|
||||||
|
if (pc->sc->isFunctionBox() || !pc->atBodyLevel()) {
|
||||||
|
report(ParseError, false, null(), JSMSG_IMPORT_DECL_AT_TOP_LEVEL);
|
||||||
|
return null();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t begin = pos().begin;
|
||||||
|
TokenKind tt = tokenStream.getToken();
|
||||||
|
|
||||||
|
Node importSpecSet = handler.newList(PNK_IMPORT_SPEC_LIST);
|
||||||
|
if (!importSpecSet)
|
||||||
|
return null();
|
||||||
|
|
||||||
|
if (tt == TOK_NAME || tt == TOK_LC) {
|
||||||
|
if (tt == TOK_NAME) {
|
||||||
|
// Handle the form |import a from 'b'|, by adding a single import
|
||||||
|
// specifier to the list, with 'default' as the import name and
|
||||||
|
// 'a' as the binding name. This is equivalent to
|
||||||
|
// |import { default as a } from 'b'|.
|
||||||
|
Node importName = newName(context->names().default_);
|
||||||
|
if (!importName)
|
||||||
|
return null();
|
||||||
|
|
||||||
|
Node bindingName = newName(tokenStream.currentName());
|
||||||
|
if (!bindingName)
|
||||||
|
return null();
|
||||||
|
|
||||||
|
Node importSpec = handler.newBinary(PNK_IMPORT_SPEC, importName, bindingName);
|
||||||
|
if (!importSpec)
|
||||||
|
return null();
|
||||||
|
|
||||||
|
handler.addList(importSpecSet, importSpec);
|
||||||
|
} else {
|
||||||
|
do {
|
||||||
|
// Handle the forms |import {} from 'a'| and
|
||||||
|
// |import { ..., } from 'a'| (where ... is non empty), by
|
||||||
|
// escaping the loop early if the next token is }.
|
||||||
|
tt = tokenStream.peekToken(TokenStream::KeywordIsName);
|
||||||
|
if (tt == TOK_ERROR)
|
||||||
|
return null();
|
||||||
|
if (tt == TOK_RC)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// If the next token is a keyword, the previous call to
|
||||||
|
// peekToken matched it as a TOK_NAME, and put it in the
|
||||||
|
// lookahead buffer, so this call will match keywords as well.
|
||||||
|
MUST_MATCH_TOKEN(TOK_NAME, JSMSG_NO_IMPORT_NAME);
|
||||||
|
Node importName = newName(tokenStream.currentName());
|
||||||
|
if (!importName)
|
||||||
|
return null();
|
||||||
|
|
||||||
|
if (tokenStream.getToken() == TOK_NAME &&
|
||||||
|
tokenStream.currentName() == context->names().as)
|
||||||
|
{
|
||||||
|
if (tokenStream.getToken() != TOK_NAME) {
|
||||||
|
report(ParseError, false, null(), JSMSG_NO_BINDING_NAME);
|
||||||
|
return null();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Keywords cannot be bound to themselves, so an import name
|
||||||
|
// that is a keyword is a syntax error if it is not followed
|
||||||
|
// by the keyword 'as'.
|
||||||
|
if (IsKeyword(importName->name())) {
|
||||||
|
JSAutoByteString bytes;
|
||||||
|
if (!AtomToPrintableString(context, importName->name(), &bytes))
|
||||||
|
return null();
|
||||||
|
report(ParseError, false, null(), JSMSG_AS_AFTER_RESERVED_WORD, bytes.ptr());
|
||||||
|
return null();
|
||||||
|
}
|
||||||
|
tokenStream.ungetToken();
|
||||||
|
}
|
||||||
|
Node bindingName = newName(tokenStream.currentName());
|
||||||
|
if (!bindingName)
|
||||||
|
return null();
|
||||||
|
|
||||||
|
Node importSpec = handler.newBinary(PNK_IMPORT_SPEC, importName, bindingName);
|
||||||
|
if (!importSpec)
|
||||||
|
return null();
|
||||||
|
|
||||||
|
handler.addList(importSpecSet, importSpec);
|
||||||
|
} while (tokenStream.matchToken(TOK_COMMA));
|
||||||
|
|
||||||
|
MUST_MATCH_TOKEN(TOK_RC, JSMSG_RC_AFTER_IMPORT_SPEC_LIST);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tokenStream.getToken() != TOK_NAME ||
|
||||||
|
tokenStream.currentName() != context->names().from)
|
||||||
|
{
|
||||||
|
report(ParseError, false, null(), JSMSG_FROM_AFTER_IMPORT_SPEC_SET);
|
||||||
|
return null();
|
||||||
|
}
|
||||||
|
|
||||||
|
MUST_MATCH_TOKEN(TOK_STRING, JSMSG_MODULE_SPEC_AFTER_FROM);
|
||||||
|
} else {
|
||||||
|
if (tt != TOK_STRING) {
|
||||||
|
report(ParseError, false, null(), JSMSG_DECLARATION_AFTER_IMPORT);
|
||||||
|
return null();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle the form |import 'a'| by leaving the list empty. This is
|
||||||
|
// equivalent to |import {} from 'a'|.
|
||||||
|
importSpecSet->pn_pos.end = importSpecSet->pn_pos.begin;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node moduleSpec = stringLiteral();
|
||||||
|
if (!moduleSpec)
|
||||||
|
return null();
|
||||||
|
|
||||||
|
if (!MatchOrInsertSemicolon(tokenStream))
|
||||||
|
return null();
|
||||||
|
|
||||||
|
return handler.newImportDeclaration(importSpecSet, moduleSpec,
|
||||||
|
TokenPos(begin, pos().end));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
SyntaxParseHandler::Node
|
||||||
|
Parser<SyntaxParseHandler>::importDeclaration()
|
||||||
|
{
|
||||||
|
JS_ALWAYS_FALSE(abortIfSyntaxParser());
|
||||||
|
return SyntaxParseHandler::NodeFailure;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename ParseHandler>
|
template <typename ParseHandler>
|
||||||
typename ParseHandler::Node
|
typename ParseHandler::Node
|
||||||
Parser<ParseHandler>::expressionStatement()
|
Parser<ParseHandler>::expressionStatement()
|
||||||
|
@ -4907,6 +5035,8 @@ Parser<ParseHandler>::statement(bool canHaveDirectives)
|
||||||
|
|
||||||
case TOK_LET:
|
case TOK_LET:
|
||||||
return letStatement();
|
return letStatement();
|
||||||
|
case TOK_IMPORT:
|
||||||
|
return importDeclaration();
|
||||||
case TOK_SEMI:
|
case TOK_SEMI:
|
||||||
return handler.newEmptyStatement(pos());
|
return handler.newEmptyStatement(pos());
|
||||||
case TOK_IF:
|
case TOK_IF:
|
||||||
|
|
|
@ -512,6 +512,7 @@ class Parser : private AutoGCRooter, public StrictModeGetter
|
||||||
Node debuggerStatement();
|
Node debuggerStatement();
|
||||||
|
|
||||||
Node letStatement();
|
Node letStatement();
|
||||||
|
Node importDeclaration();
|
||||||
Node expressionStatement();
|
Node expressionStatement();
|
||||||
Node variables(ParseNodeKind kind, bool *psimple = nullptr,
|
Node variables(ParseNodeKind kind, bool *psimple = nullptr,
|
||||||
StaticBlockObject *blockObj = nullptr,
|
StaticBlockObject *blockObj = nullptr,
|
||||||
|
|
|
@ -297,7 +297,7 @@ gc::GetPageFaultCount()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(XP_UNIX) || defined(XP_MACOSX) || defined(DARWIN)
|
#elif defined(XP_UNIX)
|
||||||
|
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
|
|
|
@ -39,6 +39,7 @@ JS::Zone::Zone(JSRuntime *rt)
|
||||||
maybeAlive(true),
|
maybeAlive(true),
|
||||||
gcMallocBytes(0),
|
gcMallocBytes(0),
|
||||||
gcGrayRoots(),
|
gcGrayRoots(),
|
||||||
|
data(nullptr),
|
||||||
types(this)
|
types(this)
|
||||||
{
|
{
|
||||||
/* Ensure that there are no vtables to mess us up here. */
|
/* Ensure that there are no vtables to mess us up here. */
|
||||||
|
|
|
@ -255,6 +255,9 @@ struct Zone : public JS::shadow::Zone,
|
||||||
/* This compartment's gray roots. */
|
/* This compartment's gray roots. */
|
||||||
js::Vector<js::GrayRoot, 0, js::SystemAllocPolicy> gcGrayRoots;
|
js::Vector<js::GrayRoot, 0, js::SystemAllocPolicy> gcGrayRoots;
|
||||||
|
|
||||||
|
/* Per-zone data for use by an embedder. */
|
||||||
|
void *data;
|
||||||
|
|
||||||
Zone(JSRuntime *rt);
|
Zone(JSRuntime *rt);
|
||||||
~Zone();
|
~Zone();
|
||||||
bool init(JSContext *cx);
|
bool init(JSContext *cx);
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
loadRelativeToScript("../../tests/js1_8_5/extensions/shell.js");
|
|
@ -0,0 +1,13 @@
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
function loop(a) {
|
||||||
|
a = arguments.length;
|
||||||
|
var result = 0;
|
||||||
|
for (var i = 0; i < 5000; i++) {
|
||||||
|
result += a;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEq(loop(11), 5000);
|
|
@ -0,0 +1,13 @@
|
||||||
|
if (typeof dis === "function") {
|
||||||
|
(function() {
|
||||||
|
function foo() {}
|
||||||
|
|
||||||
|
dis(function bar(e) {
|
||||||
|
try {
|
||||||
|
(function() { e; });
|
||||||
|
} catch (e) {
|
||||||
|
foo();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}());
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
load(libdir + "asserts.js");
|
||||||
|
assertThrowsInstanceOf(
|
||||||
|
function() {
|
||||||
|
function foo() {}
|
||||||
|
foo = null;
|
||||||
|
(function bar(e) {
|
||||||
|
try {
|
||||||
|
(function() { e; });
|
||||||
|
throw 1;
|
||||||
|
} catch (e) {
|
||||||
|
foo();
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
},
|
||||||
|
TypeError);
|
|
@ -0,0 +1,186 @@
|
||||||
|
load(libdir + "match.js");
|
||||||
|
load(libdir + "asserts.js");
|
||||||
|
|
||||||
|
var { Pattern, MatchError } = Match;
|
||||||
|
|
||||||
|
program = (elts) => Pattern({
|
||||||
|
type: "Program",
|
||||||
|
body: elts
|
||||||
|
})
|
||||||
|
importDeclaration = (specifiers, source) => Pattern({
|
||||||
|
type: "ImportDeclaration",
|
||||||
|
specifiers: specifiers,
|
||||||
|
source: source
|
||||||
|
});
|
||||||
|
importSpecifier = (id, name) => Pattern({
|
||||||
|
type: "ImportSpecifier",
|
||||||
|
id: id,
|
||||||
|
name: name
|
||||||
|
});
|
||||||
|
ident = (name) => Pattern({
|
||||||
|
type: "Identifier",
|
||||||
|
name: name
|
||||||
|
})
|
||||||
|
lit = (val) => Pattern({
|
||||||
|
type: "Literal",
|
||||||
|
value: val
|
||||||
|
})
|
||||||
|
|
||||||
|
program([
|
||||||
|
importDeclaration(
|
||||||
|
[
|
||||||
|
importSpecifier(
|
||||||
|
ident("default"),
|
||||||
|
ident("a")
|
||||||
|
)
|
||||||
|
],
|
||||||
|
lit("b")
|
||||||
|
)
|
||||||
|
]).assert(Reflect.parse("import a from 'b'"));
|
||||||
|
|
||||||
|
program([
|
||||||
|
importDeclaration(
|
||||||
|
[],
|
||||||
|
lit("a")
|
||||||
|
)
|
||||||
|
]).assert(Reflect.parse("import {} from 'a'"));
|
||||||
|
|
||||||
|
program([
|
||||||
|
importDeclaration(
|
||||||
|
[
|
||||||
|
importSpecifier(
|
||||||
|
ident("a"),
|
||||||
|
ident("a")
|
||||||
|
)
|
||||||
|
],
|
||||||
|
lit("b")
|
||||||
|
)
|
||||||
|
]).assert(Reflect.parse("import { a } from 'b'"));
|
||||||
|
|
||||||
|
program([
|
||||||
|
importDeclaration(
|
||||||
|
[
|
||||||
|
importSpecifier(
|
||||||
|
ident("a"),
|
||||||
|
ident("a")
|
||||||
|
)
|
||||||
|
],
|
||||||
|
lit("b")
|
||||||
|
)
|
||||||
|
]).assert(Reflect.parse("import { a, } from 'b'"));
|
||||||
|
|
||||||
|
program([
|
||||||
|
importDeclaration(
|
||||||
|
[
|
||||||
|
importSpecifier(
|
||||||
|
ident("a"),
|
||||||
|
ident("b")
|
||||||
|
)
|
||||||
|
],
|
||||||
|
lit("c")
|
||||||
|
)
|
||||||
|
]).assert(Reflect.parse("import { a as b } from 'c'"));
|
||||||
|
|
||||||
|
program([
|
||||||
|
importDeclaration(
|
||||||
|
[
|
||||||
|
importSpecifier(
|
||||||
|
ident("as"),
|
||||||
|
ident("as")
|
||||||
|
)
|
||||||
|
],
|
||||||
|
lit("a")
|
||||||
|
)
|
||||||
|
]).assert(Reflect.parse("import { as as as } from 'a'"));
|
||||||
|
|
||||||
|
program([
|
||||||
|
importDeclaration(
|
||||||
|
[
|
||||||
|
importSpecifier(
|
||||||
|
ident("true"),
|
||||||
|
ident("a")
|
||||||
|
)
|
||||||
|
],
|
||||||
|
lit("b")
|
||||||
|
)
|
||||||
|
]).assert(Reflect.parse("import { true as a } from 'b'"));
|
||||||
|
|
||||||
|
program([
|
||||||
|
importDeclaration(
|
||||||
|
[
|
||||||
|
importSpecifier(
|
||||||
|
ident("a"),
|
||||||
|
ident("a")
|
||||||
|
),
|
||||||
|
importSpecifier(
|
||||||
|
ident("b"),
|
||||||
|
ident("b")
|
||||||
|
),
|
||||||
|
],
|
||||||
|
lit("c")
|
||||||
|
)
|
||||||
|
]).assert(Reflect.parse("import { a, b } from 'c'"));
|
||||||
|
|
||||||
|
program([
|
||||||
|
importDeclaration(
|
||||||
|
[
|
||||||
|
importSpecifier(
|
||||||
|
ident("a"),
|
||||||
|
ident("b")
|
||||||
|
),
|
||||||
|
importSpecifier(
|
||||||
|
ident("c"),
|
||||||
|
ident("d")
|
||||||
|
),
|
||||||
|
],
|
||||||
|
lit("e")
|
||||||
|
)
|
||||||
|
]).assert(Reflect.parse("import { a as b, c as d } from 'e'"));
|
||||||
|
|
||||||
|
program([
|
||||||
|
importDeclaration(
|
||||||
|
[],
|
||||||
|
lit("a")
|
||||||
|
)
|
||||||
|
]).assert(Reflect.parse("import 'a'"));
|
||||||
|
|
||||||
|
var loc = Reflect.parse("import { a as b } from 'c'", {
|
||||||
|
loc: true
|
||||||
|
}).body[0].loc;
|
||||||
|
|
||||||
|
assertEq(loc.start.line, 1);
|
||||||
|
assertEq(loc.start.column, 0);
|
||||||
|
assertEq(loc.start.line, 1);
|
||||||
|
assertEq(loc.end.column, 26);
|
||||||
|
|
||||||
|
assertThrowsInstanceOf(function () {
|
||||||
|
Reflect.parse("function f() { import a from 'b' }");
|
||||||
|
}, SyntaxError);
|
||||||
|
|
||||||
|
assertThrowsInstanceOf(function () {
|
||||||
|
Reflect.parse("if (true) import a from 'b'");
|
||||||
|
}, SyntaxError);
|
||||||
|
|
||||||
|
assertThrowsInstanceOf(function() {
|
||||||
|
Reflect.parse("import {");
|
||||||
|
}, SyntaxError);
|
||||||
|
|
||||||
|
assertThrowsInstanceOf(function() {
|
||||||
|
Reflect.parse("import {}");
|
||||||
|
}, SyntaxError);
|
||||||
|
|
||||||
|
assertThrowsInstanceOf(function() {
|
||||||
|
Reflect.parse("import {} from");
|
||||||
|
}, SyntaxError);
|
||||||
|
|
||||||
|
assertThrowsInstanceOf(function() {
|
||||||
|
Reflect.parse("import {,} from 'a'");
|
||||||
|
}, SyntaxError);
|
||||||
|
|
||||||
|
assertThrowsInstanceOf(function() {
|
||||||
|
Reflect.parse("import { a as true } from 'b'");
|
||||||
|
}, SyntaxError);
|
||||||
|
|
||||||
|
assertThrowsInstanceOf(function() {
|
||||||
|
Reflect.parse("import { true } from 'a'");
|
||||||
|
}, SyntaxError);
|
|
@ -1231,6 +1231,7 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||||
|
|
||||||
char * errorString_;
|
char * errorString_;
|
||||||
uint32_t errorOffset_;
|
uint32_t errorOffset_;
|
||||||
|
bool errorOverRecursed_;
|
||||||
|
|
||||||
int64_t usecBefore_;
|
int64_t usecBefore_;
|
||||||
SlowFunctionVector slowFunctions_;
|
SlowFunctionVector slowFunctions_;
|
||||||
|
@ -1260,6 +1261,7 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||||
globalAccesses_(cx),
|
globalAccesses_(cx),
|
||||||
errorString_(nullptr),
|
errorString_(nullptr),
|
||||||
errorOffset_(UINT32_MAX),
|
errorOffset_(UINT32_MAX),
|
||||||
|
errorOverRecursed_(false),
|
||||||
usecBefore_(PRMJ_Now()),
|
usecBefore_(PRMJ_Now()),
|
||||||
slowFunctions_(cx),
|
slowFunctions_(cx),
|
||||||
finishedFunctionBodies_(false)
|
finishedFunctionBodies_(false)
|
||||||
|
@ -1275,6 +1277,8 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||||
errorString_);
|
errorString_);
|
||||||
js_free(errorString_);
|
js_free(errorString_);
|
||||||
}
|
}
|
||||||
|
if (errorOverRecursed_)
|
||||||
|
js_ReportOverRecursed(cx_);
|
||||||
|
|
||||||
// Avoid spurious Label assertions on compilation failure.
|
// Avoid spurious Label assertions on compilation failure.
|
||||||
if (!stackOverflowLabel_.bound())
|
if (!stackOverflowLabel_.bound())
|
||||||
|
@ -1324,7 +1328,15 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fail(ParseNode *pn, const char *str) {
|
bool fail(ParseNode *pn, const char *str) {
|
||||||
return failOffset(pn ? pn->pn_pos.begin : parser_.tokenStream.peekTokenPos().begin, str);
|
if (pn)
|
||||||
|
return failOffset(pn->pn_pos.begin, str);
|
||||||
|
|
||||||
|
// The exact rooting static analysis does not perform dataflow analysis, so it believes
|
||||||
|
// that unrooted things on the stack during compilation may still be accessed after this.
|
||||||
|
// Since pn is typically only null under OOM, this suppression simply forces any GC to be
|
||||||
|
// delayed until the compilation is off the stack and more memory can be freed.
|
||||||
|
gc::AutoSuppressGC nogc(cx_);
|
||||||
|
return failOffset(parser_.tokenStream.peekTokenPos().begin, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool failfVA(ParseNode *pn, const char *fmt, va_list ap) {
|
bool failfVA(ParseNode *pn, const char *fmt, va_list ap) {
|
||||||
|
@ -1353,6 +1365,11 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool failOverRecursed() {
|
||||||
|
errorOverRecursed_ = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static const unsigned SLOW_FUNCTION_THRESHOLD_MS = 250;
|
static const unsigned SLOW_FUNCTION_THRESHOLD_MS = 250;
|
||||||
|
|
||||||
bool maybeReportCompileTime(const Func &func) {
|
bool maybeReportCompileTime(const Func &func) {
|
||||||
|
@ -3813,7 +3830,7 @@ CheckMathBuiltinCall(FunctionCompiler &f, ParseNode *callNode, AsmJSMathBuiltin
|
||||||
static bool
|
static bool
|
||||||
CheckCall(FunctionCompiler &f, ParseNode *call, RetType retType, MDefinition **def, Type *type)
|
CheckCall(FunctionCompiler &f, ParseNode *call, RetType retType, MDefinition **def, Type *type)
|
||||||
{
|
{
|
||||||
JS_CHECK_RECURSION(f.cx(), return false);
|
JS_CHECK_RECURSION_DONT_REPORT(f.cx(), return f.m().failOverRecursed());
|
||||||
|
|
||||||
ParseNode *callee = CallCallee(call);
|
ParseNode *callee = CallCallee(call);
|
||||||
|
|
||||||
|
@ -4104,7 +4121,7 @@ static bool
|
||||||
CheckAddOrSub(FunctionCompiler &f, ParseNode *expr, MDefinition **def, Type *type,
|
CheckAddOrSub(FunctionCompiler &f, ParseNode *expr, MDefinition **def, Type *type,
|
||||||
unsigned *numAddOrSubOut = nullptr)
|
unsigned *numAddOrSubOut = nullptr)
|
||||||
{
|
{
|
||||||
JS_CHECK_RECURSION(f.cx(), return false);
|
JS_CHECK_RECURSION_DONT_REPORT(f.cx(), return f.m().failOverRecursed());
|
||||||
|
|
||||||
JS_ASSERT(expr->isKind(PNK_ADD) || expr->isKind(PNK_SUB));
|
JS_ASSERT(expr->isKind(PNK_ADD) || expr->isKind(PNK_SUB));
|
||||||
ParseNode *lhs = BinaryLeft(expr);
|
ParseNode *lhs = BinaryLeft(expr);
|
||||||
|
@ -4308,7 +4325,7 @@ CheckBitwise(FunctionCompiler &f, ParseNode *bitwise, MDefinition **def, Type *t
|
||||||
static bool
|
static bool
|
||||||
CheckExpr(FunctionCompiler &f, ParseNode *expr, MDefinition **def, Type *type)
|
CheckExpr(FunctionCompiler &f, ParseNode *expr, MDefinition **def, Type *type)
|
||||||
{
|
{
|
||||||
JS_CHECK_RECURSION(f.cx(), return false);
|
JS_CHECK_RECURSION_DONT_REPORT(f.cx(), return f.m().failOverRecursed());
|
||||||
|
|
||||||
if (!f.mirGen().ensureBallast())
|
if (!f.mirGen().ensureBallast())
|
||||||
return false;
|
return false;
|
||||||
|
@ -4781,7 +4798,7 @@ CheckStatementList(FunctionCompiler &f, ParseNode *stmtList)
|
||||||
static bool
|
static bool
|
||||||
CheckStatement(FunctionCompiler &f, ParseNode *stmt, LabelVector *maybeLabels)
|
CheckStatement(FunctionCompiler &f, ParseNode *stmt, LabelVector *maybeLabels)
|
||||||
{
|
{
|
||||||
JS_CHECK_RECURSION(f.cx(), return false);
|
JS_CHECK_RECURSION_DONT_REPORT(f.cx(), return f.m().failOverRecursed());
|
||||||
|
|
||||||
if (!f.mirGen().ensureBallast())
|
if (!f.mirGen().ensureBallast())
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -1907,7 +1907,7 @@ Address
|
||||||
BaselineCompiler::getScopeCoordinateAddressFromObject(Register objReg, Register reg)
|
BaselineCompiler::getScopeCoordinateAddressFromObject(Register objReg, Register reg)
|
||||||
{
|
{
|
||||||
ScopeCoordinate sc(pc);
|
ScopeCoordinate sc(pc);
|
||||||
Shape *shape = ScopeCoordinateToStaticScopeShape(cx, script, pc);
|
Shape *shape = ScopeCoordinateToStaticScopeShape(script, pc);
|
||||||
|
|
||||||
Address addr;
|
Address addr;
|
||||||
if (shape->numFixedSlots() <= sc.slot) {
|
if (shape->numFixedSlots() <= sc.slot) {
|
||||||
|
@ -1950,7 +1950,7 @@ BaselineCompiler::emit_JSOP_CALLALIASEDVAR()
|
||||||
bool
|
bool
|
||||||
BaselineCompiler::emit_JSOP_SETALIASEDVAR()
|
BaselineCompiler::emit_JSOP_SETALIASEDVAR()
|
||||||
{
|
{
|
||||||
JSScript *outerScript = ScopeCoordinateFunctionScript(cx, script, pc);
|
JSScript *outerScript = ScopeCoordinateFunctionScript(script, pc);
|
||||||
if (outerScript && outerScript->treatAsRunOnce) {
|
if (outerScript && outerScript->treatAsRunOnce) {
|
||||||
// Type updates for this operation might need to be tracked, so treat
|
// Type updates for this operation might need to be tracked, so treat
|
||||||
// this as a SETPROP.
|
// this as a SETPROP.
|
||||||
|
|
|
@ -1460,7 +1460,7 @@ DoTypeUpdateFallback(JSContext *cx, BaselineFrame *frame, ICUpdatedStub *stub, H
|
||||||
JS_ASSERT(obj->isNative());
|
JS_ASSERT(obj->isNative());
|
||||||
jsbytecode *pc = stub->getChainFallback()->icEntry()->pc(script);
|
jsbytecode *pc = stub->getChainFallback()->icEntry()->pc(script);
|
||||||
if (*pc == JSOP_SETALIASEDVAR)
|
if (*pc == JSOP_SETALIASEDVAR)
|
||||||
id = NameToId(ScopeCoordinateName(cx, script, pc));
|
id = NameToId(ScopeCoordinateName(script, pc));
|
||||||
else
|
else
|
||||||
id = NameToId(script->getName(pc));
|
id = NameToId(script->getName(pc));
|
||||||
types::AddTypePropertyId(cx, obj, id, value);
|
types::AddTypePropertyId(cx, obj, id, value);
|
||||||
|
@ -6843,7 +6843,7 @@ DoSetPropFallback(JSContext *cx, BaselineFrame *frame, ICSetProp_Fallback *stub,
|
||||||
|
|
||||||
RootedPropertyName name(cx);
|
RootedPropertyName name(cx);
|
||||||
if (op == JSOP_SETALIASEDVAR)
|
if (op == JSOP_SETALIASEDVAR)
|
||||||
name = ScopeCoordinateName(cx, script, pc);
|
name = ScopeCoordinateName(script, pc);
|
||||||
else
|
else
|
||||||
name = script->getName(pc);
|
name = script->getName(pc);
|
||||||
RootedId id(cx, NameToId(name));
|
RootedId id(cx, NameToId(name));
|
||||||
|
|
|
@ -46,6 +46,7 @@ IonBuilder::IonBuilder(JSContext *cx, TempAllocator *temp, MIRGraph *graph,
|
||||||
cx(cx),
|
cx(cx),
|
||||||
baselineFrame_(baselineFrame),
|
baselineFrame_(baselineFrame),
|
||||||
abortReason_(AbortReason_Disable),
|
abortReason_(AbortReason_Disable),
|
||||||
|
reprSetHash_(nullptr),
|
||||||
constraints_(constraints),
|
constraints_(constraints),
|
||||||
analysis_(info->script()),
|
analysis_(info->script()),
|
||||||
thisTypes(nullptr),
|
thisTypes(nullptr),
|
||||||
|
@ -5696,7 +5697,11 @@ IonBuilder::newOsrPreheader(MBasicBlock *predecessor, jsbytecode *loopEntry)
|
||||||
for (uint32_t i = 0; i < info().nargs(); i++) {
|
for (uint32_t i = 0; i < info().nargs(); i++) {
|
||||||
uint32_t slot = needsArgsObj ? info().argSlotUnchecked(i) : info().argSlot(i);
|
uint32_t slot = needsArgsObj ? info().argSlotUnchecked(i) : info().argSlot(i);
|
||||||
|
|
||||||
if (needsArgsObj) {
|
// Only grab arguments from the arguments object if the arguments object
|
||||||
|
// aliases formals. If the argsobj does not alias formals, then the
|
||||||
|
// formals may have been assigned to during interpretation, and that change
|
||||||
|
// will not be reflected in the argsobj.
|
||||||
|
if (needsArgsObj && info().argsObjAliasesFormals()) {
|
||||||
JS_ASSERT(argsObj && argsObj->isOsrArgumentsObject());
|
JS_ASSERT(argsObj && argsObj->isOsrArgumentsObject());
|
||||||
// If this is an aliased formal, then the arguments object
|
// If this is an aliased formal, then the arguments object
|
||||||
// contains a hole at this index. Any references to this
|
// contains a hole at this index. Any references to this
|
||||||
|
@ -7678,8 +7683,9 @@ IonBuilder::testCommonGetterSetter(types::TemporaryTypeSet *types, PropertyName
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
IonBuilder::annotateGetPropertyCache(JSContext *cx, MDefinition *obj, MGetPropertyCache *getPropCache,
|
IonBuilder::annotateGetPropertyCache(MDefinition *obj, MGetPropertyCache *getPropCache,
|
||||||
types::TemporaryTypeSet *objTypes, types::TemporaryTypeSet *pushedTypes)
|
types::TemporaryTypeSet *objTypes,
|
||||||
|
types::TemporaryTypeSet *pushedTypes)
|
||||||
{
|
{
|
||||||
PropertyName *name = getPropCache->name();
|
PropertyName *name = getPropCache->name();
|
||||||
|
|
||||||
|
@ -8240,7 +8246,7 @@ IonBuilder::getPropTryInlineAccess(bool *emitted, PropertyName *name,
|
||||||
Shape *objShape = shapes[0];
|
Shape *objShape = shapes[0];
|
||||||
obj = addShapeGuard(obj, objShape, Bailout_ShapeGuard);
|
obj = addShapeGuard(obj, objShape, Bailout_ShapeGuard);
|
||||||
|
|
||||||
Shape *shape = objShape->search(cx, NameToId(name));
|
Shape *shape = objShape->searchLinear(NameToId(name));
|
||||||
JS_ASSERT(shape);
|
JS_ASSERT(shape);
|
||||||
|
|
||||||
if (!loadSlot(obj, shape, rvalType, barrier, types))
|
if (!loadSlot(obj, shape, rvalType, barrier, types))
|
||||||
|
@ -8255,7 +8261,7 @@ IonBuilder::getPropTryInlineAccess(bool *emitted, PropertyName *name,
|
||||||
|
|
||||||
for (size_t i = 0; i < shapes.length(); i++) {
|
for (size_t i = 0; i < shapes.length(); i++) {
|
||||||
Shape *objShape = shapes[i];
|
Shape *objShape = shapes[i];
|
||||||
Shape *shape = objShape->search(cx, NameToId(name));
|
Shape *shape = objShape->searchLinear(NameToId(name));
|
||||||
JS_ASSERT(shape);
|
JS_ASSERT(shape);
|
||||||
if (!load->addShape(objShape, shape))
|
if (!load->addShape(objShape, shape))
|
||||||
return false;
|
return false;
|
||||||
|
@ -8307,7 +8313,7 @@ IonBuilder::getPropTryCache(bool *emitted, PropertyName *name,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (JSOp(*pc) == JSOP_CALLPROP) {
|
if (JSOp(*pc) == JSOP_CALLPROP) {
|
||||||
if (!annotateGetPropertyCache(cx, obj, load, obj->resultTypeSet(), types))
|
if (!annotateGetPropertyCache(obj, load, obj->resultTypeSet(), types))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8642,7 +8648,7 @@ IonBuilder::setPropTryInlineAccess(bool *emitted, MDefinition *obj,
|
||||||
Shape *objShape = shapes[0];
|
Shape *objShape = shapes[0];
|
||||||
obj = addShapeGuard(obj, objShape, Bailout_ShapeGuard);
|
obj = addShapeGuard(obj, objShape, Bailout_ShapeGuard);
|
||||||
|
|
||||||
Shape *shape = objShape->search(cx, NameToId(name));
|
Shape *shape = objShape->searchLinear(NameToId(name));
|
||||||
JS_ASSERT(shape);
|
JS_ASSERT(shape);
|
||||||
|
|
||||||
bool needsBarrier = objTypes->propertyNeedsBarrier(constraints(), NameToId(name));
|
bool needsBarrier = objTypes->propertyNeedsBarrier(constraints(), NameToId(name));
|
||||||
|
@ -8658,7 +8664,7 @@ IonBuilder::setPropTryInlineAccess(bool *emitted, MDefinition *obj,
|
||||||
|
|
||||||
for (size_t i = 0; i < shapes.length(); i++) {
|
for (size_t i = 0; i < shapes.length(); i++) {
|
||||||
Shape *objShape = shapes[i];
|
Shape *objShape = shapes[i];
|
||||||
Shape *shape = objShape->search(cx, NameToId(name));
|
Shape *shape = objShape->searchLinear(NameToId(name));
|
||||||
JS_ASSERT(shape);
|
JS_ASSERT(shape);
|
||||||
if (!ins->addShape(objShape, shape))
|
if (!ins->addShape(objShape, shape))
|
||||||
return false;
|
return false;
|
||||||
|
@ -8727,9 +8733,8 @@ IonBuilder::jsop_delelem()
|
||||||
bool
|
bool
|
||||||
IonBuilder::jsop_regexp(RegExpObject *reobj)
|
IonBuilder::jsop_regexp(RegExpObject *reobj)
|
||||||
{
|
{
|
||||||
JSObject *prototype = script()->global().getOrCreateRegExpPrototype(cx);
|
JSObject *prototype = reobj->getProto();
|
||||||
if (!prototype)
|
JS_ASSERT(prototype == script()->global().maybeGetRegExpPrototype());
|
||||||
return false;
|
|
||||||
|
|
||||||
JS_ASSERT(&reobj->JSObject::global() == &script()->global());
|
JS_ASSERT(&reobj->JSObject::global() == &script()->global());
|
||||||
|
|
||||||
|
@ -9057,7 +9062,7 @@ IonBuilder::walkScopeChain(unsigned hops)
|
||||||
bool
|
bool
|
||||||
IonBuilder::hasStaticScopeObject(ScopeCoordinate sc, JSObject **pcall)
|
IonBuilder::hasStaticScopeObject(ScopeCoordinate sc, JSObject **pcall)
|
||||||
{
|
{
|
||||||
JSScript *outerScript = ScopeCoordinateFunctionScript(cx, script(), pc);
|
JSScript *outerScript = ScopeCoordinateFunctionScript(script(), pc);
|
||||||
if (!outerScript || !outerScript->treatAsRunOnce)
|
if (!outerScript || !outerScript->treatAsRunOnce)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -9114,7 +9119,7 @@ IonBuilder::jsop_getaliasedvar(ScopeCoordinate sc)
|
||||||
{
|
{
|
||||||
JSObject *call = nullptr;
|
JSObject *call = nullptr;
|
||||||
if (hasStaticScopeObject(sc, &call) && call) {
|
if (hasStaticScopeObject(sc, &call) && call) {
|
||||||
PropertyName *name = ScopeCoordinateName(cx, script(), pc);
|
PropertyName *name = ScopeCoordinateName(script(), pc);
|
||||||
bool succeeded;
|
bool succeeded;
|
||||||
if (!getStaticName(call, name, &succeeded))
|
if (!getStaticName(call, name, &succeeded))
|
||||||
return false;
|
return false;
|
||||||
|
@ -9124,7 +9129,7 @@ IonBuilder::jsop_getaliasedvar(ScopeCoordinate sc)
|
||||||
|
|
||||||
MDefinition *obj = walkScopeChain(sc.hops);
|
MDefinition *obj = walkScopeChain(sc.hops);
|
||||||
|
|
||||||
Shape *shape = ScopeCoordinateToStaticScopeShape(cx, script(), pc);
|
Shape *shape = ScopeCoordinateToStaticScopeShape(script(), pc);
|
||||||
|
|
||||||
MInstruction *load;
|
MInstruction *load;
|
||||||
if (shape->numFixedSlots() <= sc.slot) {
|
if (shape->numFixedSlots() <= sc.slot) {
|
||||||
|
@ -9154,7 +9159,7 @@ IonBuilder::jsop_setaliasedvar(ScopeCoordinate sc)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
MDefinition *value = current->pop();
|
MDefinition *value = current->pop();
|
||||||
PropertyName *name = ScopeCoordinateName(cx, script(), pc);
|
PropertyName *name = ScopeCoordinateName(script(), pc);
|
||||||
|
|
||||||
if (call) {
|
if (call) {
|
||||||
// Push the object on the stack to match the bound object expected in
|
// Push the object on the stack to match the bound object expected in
|
||||||
|
@ -9177,7 +9182,7 @@ IonBuilder::jsop_setaliasedvar(ScopeCoordinate sc)
|
||||||
MDefinition *rval = current->peek(-1);
|
MDefinition *rval = current->peek(-1);
|
||||||
MDefinition *obj = walkScopeChain(sc.hops);
|
MDefinition *obj = walkScopeChain(sc.hops);
|
||||||
|
|
||||||
Shape *shape = ScopeCoordinateToStaticScopeShape(cx, script(), pc);
|
Shape *shape = ScopeCoordinateToStaticScopeShape(script(), pc);
|
||||||
|
|
||||||
if (NeedsPostBarrier(info(), rval))
|
if (NeedsPostBarrier(info(), rval))
|
||||||
current->add(MPostWriteBarrier::New(obj, rval));
|
current->add(MPostWriteBarrier::New(obj, rval));
|
||||||
|
@ -9333,16 +9338,14 @@ TypeRepresentationSetHash *
|
||||||
IonBuilder::getOrCreateReprSetHash()
|
IonBuilder::getOrCreateReprSetHash()
|
||||||
{
|
{
|
||||||
if (!reprSetHash_) {
|
if (!reprSetHash_) {
|
||||||
TypeRepresentationSetHash* hash =
|
TypeRepresentationSetHash *hash =
|
||||||
cx->new_<TypeRepresentationSetHash>();
|
temp_->lifoAlloc()->new_<TypeRepresentationSetHash>();
|
||||||
if (!hash || !hash->init()) {
|
if (!hash || !hash->init())
|
||||||
js_delete(hash);
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
|
||||||
|
|
||||||
reprSetHash_ = hash;
|
reprSetHash_ = hash;
|
||||||
}
|
}
|
||||||
return reprSetHash_.get();
|
return reprSetHash_;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -636,8 +636,9 @@ class IonBuilder : public MIRGenerator
|
||||||
bool testShouldDOMCall(types::TypeSet *inTypes,
|
bool testShouldDOMCall(types::TypeSet *inTypes,
|
||||||
JSFunction *func, JSJitInfo::OpType opType);
|
JSFunction *func, JSJitInfo::OpType opType);
|
||||||
|
|
||||||
bool annotateGetPropertyCache(JSContext *cx, MDefinition *obj, MGetPropertyCache *getPropCache,
|
bool annotateGetPropertyCache(MDefinition *obj, MGetPropertyCache *getPropCache,
|
||||||
types::TemporaryTypeSet *objTypes, types::TemporaryTypeSet *pushedTypes);
|
types::TemporaryTypeSet *objTypes,
|
||||||
|
types::TemporaryTypeSet *pushedTypes);
|
||||||
|
|
||||||
MGetPropertyCache *getInlineableGetPropertyCache(CallInfo &callInfo);
|
MGetPropertyCache *getInlineableGetPropertyCache(CallInfo &callInfo);
|
||||||
|
|
||||||
|
@ -712,7 +713,7 @@ class IonBuilder : public MIRGenerator
|
||||||
JSContext *cx;
|
JSContext *cx;
|
||||||
BaselineFrame *baselineFrame_;
|
BaselineFrame *baselineFrame_;
|
||||||
AbortReason abortReason_;
|
AbortReason abortReason_;
|
||||||
ScopedJSDeletePtr<TypeRepresentationSetHash> reprSetHash_;
|
TypeRepresentationSetHash *reprSetHash_;
|
||||||
|
|
||||||
// Constraints for recording dependencies on type information.
|
// Constraints for recording dependencies on type information.
|
||||||
types::CompilerConstraintList *constraints_;
|
types::CompilerConstraintList *constraints_;
|
||||||
|
|
|
@ -417,3 +417,13 @@ MSG_DEF(JSMSG_TYPEDOBJECT_NO_SUCH_PROP, 363, 1, JSEXN_TYPEERR, "No such property
|
||||||
MSG_DEF(JSMSG_TYPEDOBJECT_HANDLE_BAD_ARGS, 364, 2, JSEXN_TYPEERR, "argument {0} invalid: expected {1}")
|
MSG_DEF(JSMSG_TYPEDOBJECT_HANDLE_BAD_ARGS, 364, 2, JSEXN_TYPEERR, "argument {0} invalid: expected {1}")
|
||||||
MSG_DEF(JSMSG_TYPEDOBJECT_HANDLE_UNATTACHED, 365, 0, JSEXN_TYPEERR, "handle unattached")
|
MSG_DEF(JSMSG_TYPEDOBJECT_HANDLE_UNATTACHED, 365, 0, JSEXN_TYPEERR, "handle unattached")
|
||||||
MSG_DEF(JSMSG_TYPEDOBJECT_HANDLE_BAD_TYPE, 366, 0, JSEXN_TYPEERR, "handle moved to destination of incorrect type")
|
MSG_DEF(JSMSG_TYPEDOBJECT_HANDLE_BAD_TYPE, 366, 0, JSEXN_TYPEERR, "handle moved to destination of incorrect type")
|
||||||
|
|
||||||
|
MSG_DEF(JSMSG_IMPORT_DECL_AT_TOP_LEVEL, 367, 0, JSEXN_SYNTAXERR, "import declarations may only appear at top level")
|
||||||
|
MSG_DEF(JSMSG_NO_IMPORT_NAME, 368, 0, JSEXN_SYNTAXERR, "missing import name")
|
||||||
|
MSG_DEF(JSMSG_AS_AFTER_RESERVED_WORD, 369, 1, JSEXN_SYNTAXERR, "missing keyword 'as' after reserved word '{0}'")
|
||||||
|
MSG_DEF(JSMSG_NO_BINDING_NAME, 370, 0, JSEXN_SYNTAXERR, "missing binding name")
|
||||||
|
MSG_DEF(JSMSG_RC_AFTER_IMPORT_SPEC_LIST, 371, 0, JSEXN_SYNTAXERR, "missing '}' after module specifier list")
|
||||||
|
MSG_DEF(JSMSG_FROM_AFTER_IMPORT_SPEC_SET, 372, 0, JSEXN_SYNTAXERR, "missing keyword 'from' after import specifier set")
|
||||||
|
MSG_DEF(JSMSG_DECLARATION_AFTER_IMPORT, 373, 0, JSEXN_SYNTAXERR, "missing declaration after 'import' keyword")
|
||||||
|
MSG_DEF(JSMSG_MODULE_SPEC_AFTER_FROM, 374, 0, JSEXN_SYNTAXERR, "missing module specifier after 'from' keyword")
|
||||||
|
MSG_DEF(JSMSG_MODULES_NOT_IMPLEMENTED, 375, 0, JSEXN_SYNTAXERR, "modules are not implemented yet")
|
||||||
|
|
|
@ -908,6 +908,18 @@ JS_SetDestroyCompartmentCallback(JSRuntime *rt, JSDestroyCompartmentCallback cal
|
||||||
rt->destroyCompartmentCallback = callback;
|
rt->destroyCompartmentCallback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JS_PUBLIC_API(void)
|
||||||
|
JS_SetDestroyZoneCallback(JSRuntime *rt, JSZoneCallback callback)
|
||||||
|
{
|
||||||
|
rt->destroyZoneCallback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
JS_PUBLIC_API(void)
|
||||||
|
JS_SetSweepZoneCallback(JSRuntime *rt, JSZoneCallback callback)
|
||||||
|
{
|
||||||
|
rt->sweepZoneCallback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
JS_PUBLIC_API(void)
|
JS_PUBLIC_API(void)
|
||||||
JS_SetCompartmentNameCallback(JSRuntime *rt, JSCompartmentNameCallback callback)
|
JS_SetCompartmentNameCallback(JSRuntime *rt, JSCompartmentNameCallback callback)
|
||||||
{
|
{
|
||||||
|
@ -988,6 +1000,18 @@ JS_GetCompartmentPrivate(JSCompartment *compartment)
|
||||||
return compartment->data;
|
return compartment->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JS_PUBLIC_API(void)
|
||||||
|
JS_SetZoneUserData(JS::Zone *zone, void *data)
|
||||||
|
{
|
||||||
|
zone->data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
JS_PUBLIC_API(void *)
|
||||||
|
JS_GetZoneUserData(JS::Zone *zone)
|
||||||
|
{
|
||||||
|
return zone->data;
|
||||||
|
}
|
||||||
|
|
||||||
JS_PUBLIC_API(bool)
|
JS_PUBLIC_API(bool)
|
||||||
JS_WrapObject(JSContext *cx, MutableHandleObject objp)
|
JS_WrapObject(JSContext *cx, MutableHandleObject objp)
|
||||||
{
|
{
|
||||||
|
|
|
@ -841,6 +841,9 @@ typedef JSObject *
|
||||||
typedef void
|
typedef void
|
||||||
(* JSDestroyCompartmentCallback)(JSFreeOp *fop, JSCompartment *compartment);
|
(* JSDestroyCompartmentCallback)(JSFreeOp *fop, JSCompartment *compartment);
|
||||||
|
|
||||||
|
typedef void
|
||||||
|
(* JSZoneCallback)(JS::Zone *zone);
|
||||||
|
|
||||||
typedef void
|
typedef void
|
||||||
(* JSCompartmentNameCallback)(JSRuntime *rt, JSCompartment *compartment,
|
(* JSCompartmentNameCallback)(JSRuntime *rt, JSCompartment *compartment,
|
||||||
char *buf, size_t bufsize);
|
char *buf, size_t bufsize);
|
||||||
|
@ -1623,6 +1626,12 @@ JS_GetImplementationVersion(void);
|
||||||
extern JS_PUBLIC_API(void)
|
extern JS_PUBLIC_API(void)
|
||||||
JS_SetDestroyCompartmentCallback(JSRuntime *rt, JSDestroyCompartmentCallback callback);
|
JS_SetDestroyCompartmentCallback(JSRuntime *rt, JSDestroyCompartmentCallback callback);
|
||||||
|
|
||||||
|
extern JS_PUBLIC_API(void)
|
||||||
|
JS_SetDestroyZoneCallback(JSRuntime *rt, JSZoneCallback callback);
|
||||||
|
|
||||||
|
extern JS_PUBLIC_API(void)
|
||||||
|
JS_SetSweepZoneCallback(JSRuntime *rt, JSZoneCallback callback);
|
||||||
|
|
||||||
extern JS_PUBLIC_API(void)
|
extern JS_PUBLIC_API(void)
|
||||||
JS_SetCompartmentNameCallback(JSRuntime *rt, JSCompartmentNameCallback callback);
|
JS_SetCompartmentNameCallback(JSRuntime *rt, JSCompartmentNameCallback callback);
|
||||||
|
|
||||||
|
@ -1638,6 +1647,12 @@ JS_SetCompartmentPrivate(JSCompartment *compartment, void *data);
|
||||||
extern JS_PUBLIC_API(void *)
|
extern JS_PUBLIC_API(void *)
|
||||||
JS_GetCompartmentPrivate(JSCompartment *compartment);
|
JS_GetCompartmentPrivate(JSCompartment *compartment);
|
||||||
|
|
||||||
|
extern JS_PUBLIC_API(void)
|
||||||
|
JS_SetZoneUserData(JS::Zone *zone, void *data);
|
||||||
|
|
||||||
|
extern JS_PUBLIC_API(void *)
|
||||||
|
JS_GetZoneUserData(JS::Zone *zone);
|
||||||
|
|
||||||
extern JS_PUBLIC_API(bool)
|
extern JS_PUBLIC_API(bool)
|
||||||
JS_WrapObject(JSContext *cx, JS::MutableHandleObject objp);
|
JS_WrapObject(JSContext *cx, JS::MutableHandleObject objp);
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,8 @@ ASTDEF(AST_TRY_STMT, "TryStatement", "tryStatemen
|
||||||
ASTDEF(AST_THROW_STMT, "ThrowStatement", "throwStatement")
|
ASTDEF(AST_THROW_STMT, "ThrowStatement", "throwStatement")
|
||||||
ASTDEF(AST_DEBUGGER_STMT, "DebuggerStatement", "debuggerStatement")
|
ASTDEF(AST_DEBUGGER_STMT, "DebuggerStatement", "debuggerStatement")
|
||||||
ASTDEF(AST_LET_STMT, "LetStatement", "letStatement")
|
ASTDEF(AST_LET_STMT, "LetStatement", "letStatement")
|
||||||
|
ASTDEF(AST_IMPORT_DECL, "ImportDeclaration", "importDeclaration")
|
||||||
|
ASTDEF(AST_IMPORT_SPEC, "ImportSpecifier", "importSpecifier")
|
||||||
|
|
||||||
ASTDEF(AST_CASE, "SwitchCase", "switchCase")
|
ASTDEF(AST_CASE, "SwitchCase", "switchCase")
|
||||||
ASTDEF(AST_CATCH, "CatchClause", "catchClause")
|
ASTDEF(AST_CATCH, "CatchClause", "catchClause")
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
|
|
||||||
#include "jsobjinlines.h"
|
#include "jsobjinlines.h"
|
||||||
|
|
||||||
|
#include "vm/ScopeObject-inl.h"
|
||||||
|
|
||||||
using namespace js;
|
using namespace js;
|
||||||
using namespace JS;
|
using namespace JS;
|
||||||
|
|
||||||
|
@ -453,8 +455,8 @@ js::GetOutermostEnclosingFunctionOfScriptedCaller(JSContext *cx)
|
||||||
|
|
||||||
RootedFunction scriptedCaller(cx, iter.callee());
|
RootedFunction scriptedCaller(cx, iter.callee());
|
||||||
RootedScript outermost(cx, scriptedCaller->nonLazyScript());
|
RootedScript outermost(cx, scriptedCaller->nonLazyScript());
|
||||||
for (StaticScopeIter i(cx, scriptedCaller); !i.done(); i++) {
|
for (StaticScopeIter<NoGC> i(scriptedCaller); !i.done(); i++) {
|
||||||
if (i.type() == StaticScopeIter::FUNCTION)
|
if (i.type() == StaticScopeIter<NoGC>::FUNCTION)
|
||||||
outermost = i.funScript();
|
outermost = i.funScript();
|
||||||
}
|
}
|
||||||
return outermost;
|
return outermost;
|
||||||
|
|
|
@ -665,7 +665,7 @@ GetNativeStackLimit(JSContext *cx)
|
||||||
* extra space so that we can ensure that crucial code is able to run.
|
* extra space so that we can ensure that crucial code is able to run.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define JS_CHECK_RECURSION(cx, onerror) \
|
#define JS_CHECK_RECURSION(cx, onerror) \
|
||||||
JS_BEGIN_MACRO \
|
JS_BEGIN_MACRO \
|
||||||
int stackDummy_; \
|
int stackDummy_; \
|
||||||
if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(cx), &stackDummy_)) { \
|
if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(cx), &stackDummy_)) { \
|
||||||
|
@ -674,6 +674,14 @@ GetNativeStackLimit(JSContext *cx)
|
||||||
} \
|
} \
|
||||||
JS_END_MACRO
|
JS_END_MACRO
|
||||||
|
|
||||||
|
#define JS_CHECK_RECURSION_DONT_REPORT(cx, onerror) \
|
||||||
|
JS_BEGIN_MACRO \
|
||||||
|
int stackDummy_; \
|
||||||
|
if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(cx), &stackDummy_)) { \
|
||||||
|
onerror; \
|
||||||
|
} \
|
||||||
|
JS_END_MACRO
|
||||||
|
|
||||||
#define JS_CHECK_RECURSION_WITH_SP_DONT_REPORT(cx, sp, onerror) \
|
#define JS_CHECK_RECURSION_WITH_SP_DONT_REPORT(cx, sp, onerror) \
|
||||||
JS_BEGIN_MACRO \
|
JS_BEGIN_MACRO \
|
||||||
if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(cx), sp)) { \
|
if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(cx), sp)) { \
|
||||||
|
|
|
@ -2614,6 +2614,7 @@ static void
|
||||||
SweepZones(FreeOp *fop, bool lastGC)
|
SweepZones(FreeOp *fop, bool lastGC)
|
||||||
{
|
{
|
||||||
JSRuntime *rt = fop->runtime();
|
JSRuntime *rt = fop->runtime();
|
||||||
|
JSZoneCallback callback = rt->destroyZoneCallback;
|
||||||
|
|
||||||
/* Skip the atomsCompartment zone. */
|
/* Skip the atomsCompartment zone. */
|
||||||
Zone **read = rt->zones.begin() + 1;
|
Zone **read = rt->zones.begin() + 1;
|
||||||
|
@ -2628,6 +2629,8 @@ SweepZones(FreeOp *fop, bool lastGC)
|
||||||
if (!zone->hold && zone->wasGCStarted()) {
|
if (!zone->hold && zone->wasGCStarted()) {
|
||||||
if (zone->allocator.arenas.arenaListsAreEmpty() || lastGC) {
|
if (zone->allocator.arenas.arenaListsAreEmpty() || lastGC) {
|
||||||
zone->allocator.arenas.checkEmptyFreeLists();
|
zone->allocator.arenas.checkEmptyFreeLists();
|
||||||
|
if (callback)
|
||||||
|
callback(zone);
|
||||||
SweepCompartments(fop, zone, false, lastGC);
|
SweepCompartments(fop, zone, false, lastGC);
|
||||||
JS_ASSERT(zone->compartments.empty());
|
JS_ASSERT(zone->compartments.empty());
|
||||||
fop->delete_(zone);
|
fop->delete_(zone);
|
||||||
|
@ -3714,6 +3717,9 @@ BeginSweepingZoneGroup(JSRuntime *rt)
|
||||||
|
|
||||||
if (rt->isAtomsZone(zone))
|
if (rt->isAtomsZone(zone))
|
||||||
sweepingAtoms = true;
|
sweepingAtoms = true;
|
||||||
|
|
||||||
|
if (rt->sweepZoneCallback)
|
||||||
|
rt->sweepZoneCallback(zone);
|
||||||
}
|
}
|
||||||
|
|
||||||
ValidateIncrementalMarking(rt);
|
ValidateIncrementalMarking(rt);
|
||||||
|
|
|
@ -389,7 +389,7 @@ class BytecodeParser
|
||||||
|
|
||||||
JSContext *cx_;
|
JSContext *cx_;
|
||||||
LifoAllocScope allocScope_;
|
LifoAllocScope allocScope_;
|
||||||
JSScript *script_;
|
RootedScript script_;
|
||||||
|
|
||||||
Bytecode **codeArray_;
|
Bytecode **codeArray_;
|
||||||
|
|
||||||
|
@ -397,7 +397,7 @@ class BytecodeParser
|
||||||
BytecodeParser(JSContext *cx, JSScript *script)
|
BytecodeParser(JSContext *cx, JSScript *script)
|
||||||
: cx_(cx),
|
: cx_(cx),
|
||||||
allocScope_(&cx->tempLifoAlloc()),
|
allocScope_(&cx->tempLifoAlloc()),
|
||||||
script_(script),
|
script_(cx, script),
|
||||||
codeArray_(nullptr) { }
|
codeArray_(nullptr) { }
|
||||||
|
|
||||||
bool parse();
|
bool parse();
|
||||||
|
@ -949,7 +949,7 @@ js_Disassemble1(JSContext *cx, HandleScript script, jsbytecode *pc,
|
||||||
}
|
}
|
||||||
|
|
||||||
case JOF_SCOPECOORD: {
|
case JOF_SCOPECOORD: {
|
||||||
Value v = StringValue(ScopeCoordinateName(cx, script, pc));
|
Value v = StringValue(ScopeCoordinateName(script, pc));
|
||||||
JSAutoByteString bytes;
|
JSAutoByteString bytes;
|
||||||
if (!ToDisassemblySource(cx, v, &bytes))
|
if (!ToDisassemblySource(cx, v, &bytes))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1590,7 +1590,7 @@ ExpressionDecompiler::decompilePC(jsbytecode *pc)
|
||||||
}
|
}
|
||||||
case JSOP_CALLALIASEDVAR:
|
case JSOP_CALLALIASEDVAR:
|
||||||
case JSOP_GETALIASEDVAR: {
|
case JSOP_GETALIASEDVAR: {
|
||||||
JSAtom *atom = ScopeCoordinateName(cx, script, pc);
|
JSAtom *atom = ScopeCoordinateName(script, pc);
|
||||||
JS_ASSERT(atom);
|
JS_ASSERT(atom);
|
||||||
return write(atom);
|
return write(atom);
|
||||||
}
|
}
|
||||||
|
|
|
@ -562,6 +562,10 @@ class NodeBuilder
|
||||||
|
|
||||||
bool letStatement(NodeVector &head, HandleValue stmt, TokenPos *pos, MutableHandleValue dst);
|
bool letStatement(NodeVector &head, HandleValue stmt, TokenPos *pos, MutableHandleValue dst);
|
||||||
|
|
||||||
|
bool importDeclaration(NodeVector &elts, HandleValue moduleSpec, TokenPos *pos, MutableHandleValue dst);
|
||||||
|
|
||||||
|
bool importSpecifier(HandleValue importName, HandleValue bindingName, TokenPos *pos, MutableHandleValue dst);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* expressions
|
* expressions
|
||||||
*/
|
*/
|
||||||
|
@ -1353,6 +1357,38 @@ NodeBuilder::letStatement(NodeVector &head, HandleValue stmt, TokenPos *pos, Mut
|
||||||
dst);
|
dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
NodeBuilder::importDeclaration(NodeVector &elts, HandleValue moduleSpec, TokenPos *pos,
|
||||||
|
MutableHandleValue dst)
|
||||||
|
{
|
||||||
|
RootedValue array(cx);
|
||||||
|
if (!newArray(elts, &array))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
RootedValue cb(cx, callbacks[AST_IMPORT_DECL]);
|
||||||
|
if (!cb.isNull())
|
||||||
|
return callback(cb, array, moduleSpec, pos, dst);
|
||||||
|
|
||||||
|
return newNode(AST_IMPORT_DECL, pos,
|
||||||
|
"specifiers", array,
|
||||||
|
"source", moduleSpec,
|
||||||
|
dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
NodeBuilder::importSpecifier(HandleValue importName, HandleValue bindingName, TokenPos *pos,
|
||||||
|
MutableHandleValue dst)
|
||||||
|
{
|
||||||
|
RootedValue cb(cx, callbacks[AST_IMPORT_SPEC]);
|
||||||
|
if (!cb.isNull())
|
||||||
|
return callback(cb, importName, bindingName, pos, dst);
|
||||||
|
|
||||||
|
return newNode(AST_IMPORT_SPEC, pos,
|
||||||
|
"id", importName,
|
||||||
|
"name", bindingName,
|
||||||
|
dst);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
NodeBuilder::variableDeclaration(NodeVector &elts, VarDeclKind kind, TokenPos *pos,
|
NodeBuilder::variableDeclaration(NodeVector &elts, VarDeclKind kind, TokenPos *pos,
|
||||||
MutableHandleValue dst)
|
MutableHandleValue dst)
|
||||||
|
@ -1520,6 +1556,8 @@ class ASTSerializer
|
||||||
bool variableDeclaration(ParseNode *pn, bool let, MutableHandleValue dst);
|
bool variableDeclaration(ParseNode *pn, bool let, MutableHandleValue dst);
|
||||||
bool variableDeclarator(ParseNode *pn, VarDeclKind *pkind, MutableHandleValue dst);
|
bool variableDeclarator(ParseNode *pn, VarDeclKind *pkind, MutableHandleValue dst);
|
||||||
bool let(ParseNode *pn, bool expr, MutableHandleValue dst);
|
bool let(ParseNode *pn, bool expr, MutableHandleValue dst);
|
||||||
|
bool importDeclaration(ParseNode *pn, MutableHandleValue dst);
|
||||||
|
bool importSpecifier(ParseNode *pn, MutableHandleValue dst);
|
||||||
|
|
||||||
bool optStatement(ParseNode *pn, MutableHandleValue dst) {
|
bool optStatement(ParseNode *pn, MutableHandleValue dst) {
|
||||||
if (!pn) {
|
if (!pn) {
|
||||||
|
@ -1883,6 +1921,41 @@ ASTSerializer::let(ParseNode *pn, bool expr, MutableHandleValue dst)
|
||||||
builder.letStatement(dtors, v, &pn->pn_pos, dst);
|
builder.letStatement(dtors, v, &pn->pn_pos, dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ASTSerializer::importDeclaration(ParseNode *pn, MutableHandleValue dst)
|
||||||
|
{
|
||||||
|
JS_ASSERT(pn->isKind(PNK_IMPORT));
|
||||||
|
JS_ASSERT(pn->pn_left->isKind(PNK_IMPORT_SPEC_LIST));
|
||||||
|
JS_ASSERT(pn->pn_right->isKind(PNK_STRING));
|
||||||
|
|
||||||
|
NodeVector elts(cx);
|
||||||
|
if (!elts.reserve(pn->pn_count))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (ParseNode *next = pn->pn_left->pn_head; next; next = next->pn_next) {
|
||||||
|
RootedValue elt(cx);
|
||||||
|
if (!importSpecifier(next, &elt))
|
||||||
|
return false;
|
||||||
|
elts.infallibleAppend(elt);
|
||||||
|
}
|
||||||
|
|
||||||
|
RootedValue moduleSpec(cx);
|
||||||
|
return literal(pn->pn_right, &moduleSpec) &&
|
||||||
|
builder.importDeclaration(elts, moduleSpec, &pn->pn_pos, dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ASTSerializer::importSpecifier(ParseNode *pn, MutableHandleValue dst)
|
||||||
|
{
|
||||||
|
JS_ASSERT(pn->isKind(PNK_IMPORT_SPEC));
|
||||||
|
|
||||||
|
RootedValue importName(cx);
|
||||||
|
RootedValue bindingName(cx);
|
||||||
|
return identifier(pn->pn_left, &importName) &&
|
||||||
|
identifier(pn->pn_right, &bindingName) &&
|
||||||
|
builder.importSpecifier(importName, bindingName, &pn->pn_pos, dst);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ASTSerializer::switchCase(ParseNode *pn, MutableHandleValue dst)
|
ASTSerializer::switchCase(ParseNode *pn, MutableHandleValue dst)
|
||||||
{
|
{
|
||||||
|
@ -2038,6 +2111,9 @@ ASTSerializer::statement(ParseNode *pn, MutableHandleValue dst)
|
||||||
? let(pn, false, dst)
|
? let(pn, false, dst)
|
||||||
: declaration(pn, dst);
|
: declaration(pn, dst);
|
||||||
|
|
||||||
|
case PNK_IMPORT:
|
||||||
|
return importDeclaration(pn, dst);
|
||||||
|
|
||||||
case PNK_NAME:
|
case PNK_NAME:
|
||||||
LOCAL_ASSERT(pn->isUsed());
|
LOCAL_ASSERT(pn->isUsed());
|
||||||
return statement(pn->pn_lexdef, dst);
|
return statement(pn->pn_lexdef, dst);
|
||||||
|
|
|
@ -687,8 +687,8 @@ js::XDRScript(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript enc
|
||||||
if (!innerScript)
|
if (!innerScript)
|
||||||
return false;
|
return false;
|
||||||
RootedObject staticScope(cx, innerScript->enclosingStaticScope());
|
RootedObject staticScope(cx, innerScript->enclosingStaticScope());
|
||||||
StaticScopeIter ssi(cx, staticScope);
|
StaticScopeIter<NoGC> ssi(staticScope);
|
||||||
if (ssi.done() || ssi.type() == StaticScopeIter::FUNCTION) {
|
if (ssi.done() || ssi.type() == StaticScopeIter<NoGC>::FUNCTION) {
|
||||||
JS_ASSERT(ssi.done() == !fun);
|
JS_ASSERT(ssi.done() == !fun);
|
||||||
funEnclosingScopeIndex = UINT32_MAX;
|
funEnclosingScopeIndex = UINT32_MAX;
|
||||||
} else {
|
} else {
|
||||||
|
@ -2315,9 +2315,9 @@ js::CloneScript(JSContext *cx, HandleObject enclosingScope, HandleFunction fun,
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
RootedObject staticScope(cx, innerFun->nonLazyScript()->enclosingStaticScope());
|
RootedObject staticScope(cx, innerFun->nonLazyScript()->enclosingStaticScope());
|
||||||
StaticScopeIter ssi(cx, staticScope);
|
StaticScopeIter<CanGC> ssi(cx, staticScope);
|
||||||
RootedObject enclosingScope(cx);
|
RootedObject enclosingScope(cx);
|
||||||
if (!ssi.done() && ssi.type() == StaticScopeIter::BLOCK)
|
if (!ssi.done() && ssi.type() == StaticScopeIter<CanGC>::BLOCK)
|
||||||
enclosingScope = objects[FindBlockIndex(src, ssi.block())];
|
enclosingScope = objects[FindBlockIndex(src, ssi.block())];
|
||||||
else
|
else
|
||||||
enclosingScope = fun;
|
enclosingScope = fun;
|
||||||
|
@ -3001,8 +3001,8 @@ LazyScript::Create(ExclusiveContext *cx, HandleFunction fun,
|
||||||
uint32_t
|
uint32_t
|
||||||
LazyScript::staticLevel(JSContext *cx) const
|
LazyScript::staticLevel(JSContext *cx) const
|
||||||
{
|
{
|
||||||
for (StaticScopeIter ssi(cx, enclosingScope()); !ssi.done(); ssi++) {
|
for (StaticScopeIter<NoGC> ssi(enclosingScope()); !ssi.done(); ssi++) {
|
||||||
if (ssi.type() == StaticScopeIter::FUNCTION)
|
if (ssi.type() == StaticScopeIter<NoGC>::FUNCTION)
|
||||||
return ssi.funScript()->staticLevel + 1;
|
return ssi.funScript()->staticLevel + 1;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -4129,10 +4129,6 @@ static const JSFunctionSpecWithHelp shell_functions[] = {
|
||||||
"intern(str)",
|
"intern(str)",
|
||||||
" Internalize str in the atom table."),
|
" Internalize str in the atom table."),
|
||||||
|
|
||||||
JS_FN_HELP("clone", Clone, 1, 0,
|
|
||||||
"clone(fun[, scope])",
|
|
||||||
" Clone function object."),
|
|
||||||
|
|
||||||
JS_FN_HELP("getpda", GetPDA, 1, 0,
|
JS_FN_HELP("getpda", GetPDA, 1, 0,
|
||||||
"getpda(obj)",
|
"getpda(obj)",
|
||||||
" Get the property descriptors for obj."),
|
" Get the property descriptors for obj."),
|
||||||
|
@ -4277,6 +4273,10 @@ static const JSFunctionSpecWithHelp shell_functions[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const JSFunctionSpecWithHelp fuzzing_unsafe_functions[] = {
|
static const JSFunctionSpecWithHelp fuzzing_unsafe_functions[] = {
|
||||||
|
JS_FN_HELP("clone", Clone, 1, 0,
|
||||||
|
"clone(fun[, scope])",
|
||||||
|
" Clone function object."),
|
||||||
|
|
||||||
JS_FN_HELP("getSelfHostedValue", GetSelfHostedValue, 1, 0,
|
JS_FN_HELP("getSelfHostedValue", GetSelfHostedValue, 1, 0,
|
||||||
"getSelfHostedValue()",
|
"getSelfHostedValue()",
|
||||||
" Get a self-hosted value by its name. Note that these values don't get \n"
|
" Get a self-hosted value by its name. Note that these values don't get \n"
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
macro(anonymous, anonymous, "anonymous") \
|
macro(anonymous, anonymous, "anonymous") \
|
||||||
macro(apply, apply, "apply") \
|
macro(apply, apply, "apply") \
|
||||||
macro(arguments, arguments, "arguments") \
|
macro(arguments, arguments, "arguments") \
|
||||||
|
macro(as, as, "as") \
|
||||||
macro(ArrayType, ArrayType, "ArrayType") \
|
macro(ArrayType, ArrayType, "ArrayType") \
|
||||||
macro(buffer, buffer, "buffer") \
|
macro(buffer, buffer, "buffer") \
|
||||||
macro(builder, builder, "builder") \
|
macro(builder, builder, "builder") \
|
||||||
|
@ -43,6 +44,7 @@
|
||||||
macro(DateTimeFormatFormatGet, DateTimeFormatFormatGet, "Intl_DateTimeFormat_format_get") \
|
macro(DateTimeFormatFormatGet, DateTimeFormatFormatGet, "Intl_DateTimeFormat_format_get") \
|
||||||
macro(decodeURI, decodeURI, "decodeURI") \
|
macro(decodeURI, decodeURI, "decodeURI") \
|
||||||
macro(decodeURIComponent, decodeURIComponent, "decodeURIComponent") \
|
macro(decodeURIComponent, decodeURIComponent, "decodeURIComponent") \
|
||||||
|
macro(default_, default_, "default") \
|
||||||
macro(defineProperty, defineProperty, "defineProperty") \
|
macro(defineProperty, defineProperty, "defineProperty") \
|
||||||
macro(defineGetter, defineGetter, "__defineGetter__") \
|
macro(defineGetter, defineGetter, "__defineGetter__") \
|
||||||
macro(defineSetter, defineSetter, "__defineSetter__") \
|
macro(defineSetter, defineSetter, "__defineSetter__") \
|
||||||
|
@ -68,6 +70,7 @@
|
||||||
macro(float32, float32, "float32") \
|
macro(float32, float32, "float32") \
|
||||||
macro(float64, float64, "float64") \
|
macro(float64, float64, "float64") \
|
||||||
macro(format, format, "format") \
|
macro(format, format, "format") \
|
||||||
|
macro(from, from, "from") \
|
||||||
macro(get, get, "get") \
|
macro(get, get, "get") \
|
||||||
macro(getInternals, getInternals, "getInternals") \
|
macro(getInternals, getInternals, "getInternals") \
|
||||||
macro(getOwnPropertyDescriptor, getOwnPropertyDescriptor, "getOwnPropertyDescriptor") \
|
macro(getOwnPropertyDescriptor, getOwnPropertyDescriptor, "getOwnPropertyDescriptor") \
|
||||||
|
|
|
@ -390,6 +390,12 @@ class GlobalObject : public JSObject
|
||||||
return &self->getPrototype(JSProto_RegExp).toObject();
|
return &self->getPrototype(JSProto_RegExp).toObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JSObject *maybeGetRegExpPrototype() {
|
||||||
|
if (regexpClassInitialized())
|
||||||
|
return &getPrototype(JSProto_RegExp).toObject();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
JSObject *getOrCreateArrayBufferPrototype(JSContext *cx) {
|
JSObject *getOrCreateArrayBufferPrototype(JSContext *cx) {
|
||||||
if (arrayBufferClassInitialized())
|
if (arrayBufferClassInitialized())
|
||||||
return &getPrototype(JSProto_ArrayBuffer).toObject();
|
return &getPrototype(JSProto_ArrayBuffer).toObject();
|
||||||
|
@ -523,9 +529,10 @@ class GlobalObject : public JSObject
|
||||||
bool getIntrinsicValue(JSContext *cx, HandlePropertyName name, MutableHandleValue value) {
|
bool getIntrinsicValue(JSContext *cx, HandlePropertyName name, MutableHandleValue value) {
|
||||||
if (maybeGetIntrinsicValue(name, value.address()))
|
if (maybeGetIntrinsicValue(name, value.address()))
|
||||||
return true;
|
return true;
|
||||||
|
Rooted<GlobalObject*> self(cx, this);
|
||||||
if (!cx->runtime()->cloneSelfHostedValue(cx, name, value))
|
if (!cx->runtime()->cloneSelfHostedValue(cx, name, value))
|
||||||
return false;
|
return false;
|
||||||
RootedObject holder(cx, intrinsicsHolder());
|
RootedObject holder(cx, self->intrinsicsHolder());
|
||||||
RootedId id(cx, NameToId(name));
|
RootedId id(cx, NameToId(name));
|
||||||
return JS_DefinePropertyById(cx, holder, id, value, nullptr, nullptr, 0);
|
return JS_DefinePropertyById(cx, holder, id, value, nullptr, nullptr, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2787,7 +2787,7 @@ CASE(JSOP_SETALIASEDVAR)
|
||||||
|
|
||||||
// Avoid computing the name if no type updates are needed, as this may be
|
// Avoid computing the name if no type updates are needed, as this may be
|
||||||
// expensive on scopes with large numbers of variables.
|
// expensive on scopes with large numbers of variables.
|
||||||
PropertyName *name = obj.hasSingletonType() ? ScopeCoordinateName(cx, script, REGS.pc)
|
PropertyName *name = obj.hasSingletonType() ? ScopeCoordinateName(script, REGS.pc)
|
||||||
: nullptr;
|
: nullptr;
|
||||||
|
|
||||||
obj.setAliasedVar(cx, sc, name, REGS.sp[-1]);
|
obj.setAliasedVar(cx, sc, name, REGS.sp[-1]);
|
||||||
|
|
|
@ -41,12 +41,12 @@
|
||||||
macro(void, void_, TOK_VOID, JSVERSION_DEFAULT) \
|
macro(void, void_, TOK_VOID, JSVERSION_DEFAULT) \
|
||||||
macro(while, while_, TOK_WHILE, JSVERSION_DEFAULT) \
|
macro(while, while_, TOK_WHILE, JSVERSION_DEFAULT) \
|
||||||
macro(with, with, TOK_WITH, JSVERSION_DEFAULT) \
|
macro(with, with, TOK_WITH, JSVERSION_DEFAULT) \
|
||||||
|
macro(import, import, TOK_IMPORT, JSVERSION_DEFAULT) \
|
||||||
/* Reserved keywords. */ \
|
/* Reserved keywords. */ \
|
||||||
macro(class, class_, TOK_RESERVED, JSVERSION_DEFAULT) \
|
macro(class, class_, TOK_RESERVED, JSVERSION_DEFAULT) \
|
||||||
macro(enum, enum_, TOK_RESERVED, JSVERSION_DEFAULT) \
|
macro(enum, enum_, TOK_RESERVED, JSVERSION_DEFAULT) \
|
||||||
macro(export, export, TOK_RESERVED, JSVERSION_DEFAULT) \
|
macro(export, export, TOK_RESERVED, JSVERSION_DEFAULT) \
|
||||||
macro(extends, extends, TOK_RESERVED, JSVERSION_DEFAULT) \
|
macro(extends, extends, TOK_RESERVED, JSVERSION_DEFAULT) \
|
||||||
macro(import, import, TOK_RESERVED, JSVERSION_DEFAULT) \
|
|
||||||
macro(super, super, TOK_RESERVED, JSVERSION_DEFAULT) \
|
macro(super, super, TOK_RESERVED, JSVERSION_DEFAULT) \
|
||||||
/* Future reserved keywords, but only in strict mode. */ \
|
/* Future reserved keywords, but only in strict mode. */ \
|
||||||
macro(implements, implements, TOK_STRICT_RESERVED, JSVERSION_DEFAULT) \
|
macro(implements, implements, TOK_STRICT_RESERVED, JSVERSION_DEFAULT) \
|
||||||
|
|
|
@ -146,6 +146,8 @@ JSRuntime::JSRuntime(JSUseHelperThreads useHelperThreads)
|
||||||
nativeStackBase(0),
|
nativeStackBase(0),
|
||||||
cxCallback(nullptr),
|
cxCallback(nullptr),
|
||||||
destroyCompartmentCallback(nullptr),
|
destroyCompartmentCallback(nullptr),
|
||||||
|
destroyZoneCallback(nullptr),
|
||||||
|
sweepZoneCallback(nullptr),
|
||||||
compartmentNameCallback(nullptr),
|
compartmentNameCallback(nullptr),
|
||||||
activityCallback(nullptr),
|
activityCallback(nullptr),
|
||||||
activityCallbackArg(nullptr),
|
activityCallbackArg(nullptr),
|
||||||
|
|
|
@ -950,6 +950,12 @@ struct JSRuntime : public JS::shadow::Runtime,
|
||||||
/* Compartment destroy callback. */
|
/* Compartment destroy callback. */
|
||||||
JSDestroyCompartmentCallback destroyCompartmentCallback;
|
JSDestroyCompartmentCallback destroyCompartmentCallback;
|
||||||
|
|
||||||
|
/* Zone destroy callback. */
|
||||||
|
JSZoneCallback destroyZoneCallback;
|
||||||
|
|
||||||
|
/* Zone sweep callback. */
|
||||||
|
JSZoneCallback sweepZoneCallback;
|
||||||
|
|
||||||
/* Call this to get the name of a compartment. */
|
/* Call this to get the name of a compartment. */
|
||||||
JSCompartmentNameCallback compartmentNameCallback;
|
JSCompartmentNameCallback compartmentNameCallback;
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,74 @@ CallObject::setAliasedVar(JSContext *cx, AliasedFormalIter fi, PropertyName *nam
|
||||||
types::AddTypePropertyId(cx, this, NameToId(name), v);
|
types::AddTypePropertyId(cx, this, NameToId(name), v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <AllowGC allowGC>
|
||||||
|
inline bool
|
||||||
|
StaticScopeIter<allowGC>::done() const
|
||||||
|
{
|
||||||
|
return !obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <AllowGC allowGC>
|
||||||
|
inline void
|
||||||
|
StaticScopeIter<allowGC>::operator++(int)
|
||||||
|
{
|
||||||
|
if (obj->template is<StaticBlockObject>()) {
|
||||||
|
obj = obj->template as<StaticBlockObject>().enclosingStaticScope();
|
||||||
|
} else if (onNamedLambda || !obj->template as<JSFunction>().isNamedLambda()) {
|
||||||
|
onNamedLambda = false;
|
||||||
|
obj = obj->template as<JSFunction>().nonLazyScript()->enclosingStaticScope();
|
||||||
|
} else {
|
||||||
|
onNamedLambda = true;
|
||||||
|
}
|
||||||
|
JS_ASSERT_IF(obj, obj->template is<StaticBlockObject>() || obj->template is<JSFunction>());
|
||||||
|
JS_ASSERT_IF(onNamedLambda, obj->template is<JSFunction>());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <AllowGC allowGC>
|
||||||
|
inline bool
|
||||||
|
StaticScopeIter<allowGC>::hasDynamicScopeObject() const
|
||||||
|
{
|
||||||
|
return obj->template is<StaticBlockObject>()
|
||||||
|
? obj->template as<StaticBlockObject>().needsClone()
|
||||||
|
: obj->template as<JSFunction>().isHeavyweight();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <AllowGC allowGC>
|
||||||
|
inline Shape *
|
||||||
|
StaticScopeIter<allowGC>::scopeShape() const
|
||||||
|
{
|
||||||
|
JS_ASSERT(hasDynamicScopeObject());
|
||||||
|
JS_ASSERT(type() != NAMED_LAMBDA);
|
||||||
|
return type() == BLOCK
|
||||||
|
? block().lastProperty()
|
||||||
|
: funScript()->bindings.callObjShape();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <AllowGC allowGC>
|
||||||
|
inline typename StaticScopeIter<allowGC>::Type
|
||||||
|
StaticScopeIter<allowGC>::type() const
|
||||||
|
{
|
||||||
|
if (onNamedLambda)
|
||||||
|
return NAMED_LAMBDA;
|
||||||
|
return obj->template is<StaticBlockObject>() ? BLOCK : FUNCTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <AllowGC allowGC>
|
||||||
|
inline StaticBlockObject &
|
||||||
|
StaticScopeIter<allowGC>::block() const
|
||||||
|
{
|
||||||
|
JS_ASSERT(type() == BLOCK);
|
||||||
|
return obj->template as<StaticBlockObject>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <AllowGC allowGC>
|
||||||
|
inline JSScript *
|
||||||
|
StaticScopeIter<allowGC>::funScript() const
|
||||||
|
{
|
||||||
|
JS_ASSERT(type() == FUNCTION);
|
||||||
|
return obj->template as<JSFunction>().nonLazyScript();
|
||||||
|
}
|
||||||
|
|
||||||
} /* namespace js */
|
} /* namespace js */
|
||||||
|
|
||||||
#endif /* vm_ScopeObject_inl_h */
|
#endif /* vm_ScopeObject_inl_h */
|
||||||
|
|
|
@ -32,75 +32,6 @@ typedef Rooted<ArgumentsObject *> RootedArgumentsObject;
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
StaticScopeIter::StaticScopeIter(ExclusiveContext *cx, JSObject *objArg)
|
|
||||||
: obj(cx, objArg), onNamedLambda(false)
|
|
||||||
{
|
|
||||||
JS_ASSERT_IF(obj, obj->is<StaticBlockObject>() || obj->is<JSFunction>());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
StaticScopeIter::done() const
|
|
||||||
{
|
|
||||||
return !obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
StaticScopeIter::operator++(int)
|
|
||||||
{
|
|
||||||
if (obj->is<StaticBlockObject>()) {
|
|
||||||
obj = obj->as<StaticBlockObject>().enclosingStaticScope();
|
|
||||||
} else if (onNamedLambda || !obj->as<JSFunction>().isNamedLambda()) {
|
|
||||||
onNamedLambda = false;
|
|
||||||
obj = obj->as<JSFunction>().nonLazyScript()->enclosingStaticScope();
|
|
||||||
} else {
|
|
||||||
onNamedLambda = true;
|
|
||||||
}
|
|
||||||
JS_ASSERT_IF(obj, obj->is<StaticBlockObject>() || obj->is<JSFunction>());
|
|
||||||
JS_ASSERT_IF(onNamedLambda, obj->is<JSFunction>());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
StaticScopeIter::hasDynamicScopeObject() const
|
|
||||||
{
|
|
||||||
return obj->is<StaticBlockObject>()
|
|
||||||
? obj->as<StaticBlockObject>().needsClone()
|
|
||||||
: obj->as<JSFunction>().isHeavyweight();
|
|
||||||
}
|
|
||||||
|
|
||||||
Shape *
|
|
||||||
StaticScopeIter::scopeShape() const
|
|
||||||
{
|
|
||||||
JS_ASSERT(hasDynamicScopeObject());
|
|
||||||
JS_ASSERT(type() != NAMED_LAMBDA);
|
|
||||||
return type() == BLOCK
|
|
||||||
? block().lastProperty()
|
|
||||||
: funScript()->bindings.callObjShape();
|
|
||||||
}
|
|
||||||
|
|
||||||
StaticScopeIter::Type
|
|
||||||
StaticScopeIter::type() const
|
|
||||||
{
|
|
||||||
if (onNamedLambda)
|
|
||||||
return NAMED_LAMBDA;
|
|
||||||
return obj->is<StaticBlockObject>() ? BLOCK : FUNCTION;
|
|
||||||
}
|
|
||||||
|
|
||||||
StaticBlockObject &
|
|
||||||
StaticScopeIter::block() const
|
|
||||||
{
|
|
||||||
JS_ASSERT(type() == BLOCK);
|
|
||||||
return obj->as<StaticBlockObject>();
|
|
||||||
}
|
|
||||||
|
|
||||||
JSScript *
|
|
||||||
StaticScopeIter::funScript() const
|
|
||||||
{
|
|
||||||
JS_ASSERT(type() == FUNCTION);
|
|
||||||
return obj->as<JSFunction>().nonLazyScript();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
|
|
||||||
static JSObject *
|
static JSObject *
|
||||||
InnermostStaticScope(JSScript *script, jsbytecode *pc)
|
InnermostStaticScope(JSScript *script, jsbytecode *pc)
|
||||||
{
|
{
|
||||||
|
@ -115,9 +46,9 @@ InnermostStaticScope(JSScript *script, jsbytecode *pc)
|
||||||
}
|
}
|
||||||
|
|
||||||
Shape *
|
Shape *
|
||||||
js::ScopeCoordinateToStaticScopeShape(JSContext *cx, JSScript *script, jsbytecode *pc)
|
js::ScopeCoordinateToStaticScopeShape(JSScript *script, jsbytecode *pc)
|
||||||
{
|
{
|
||||||
StaticScopeIter ssi(cx, InnermostStaticScope(script, pc));
|
StaticScopeIter<NoGC> ssi(InnermostStaticScope(script, pc));
|
||||||
ScopeCoordinate sc(pc);
|
ScopeCoordinate sc(pc);
|
||||||
while (true) {
|
while (true) {
|
||||||
if (ssi.hasDynamicScopeObject()) {
|
if (ssi.hasDynamicScopeObject()) {
|
||||||
|
@ -131,9 +62,9 @@ js::ScopeCoordinateToStaticScopeShape(JSContext *cx, JSScript *script, jsbytecod
|
||||||
}
|
}
|
||||||
|
|
||||||
PropertyName *
|
PropertyName *
|
||||||
js::ScopeCoordinateName(JSContext *cx, JSScript *script, jsbytecode *pc)
|
js::ScopeCoordinateName(JSScript *script, jsbytecode *pc)
|
||||||
{
|
{
|
||||||
Shape::Range<NoGC> r(ScopeCoordinateToStaticScopeShape(cx, script, pc));
|
Shape::Range<NoGC> r(ScopeCoordinateToStaticScopeShape(script, pc));
|
||||||
ScopeCoordinate sc(pc);
|
ScopeCoordinate sc(pc);
|
||||||
while (r.front().slot() != sc.slot)
|
while (r.front().slot() != sc.slot)
|
||||||
r.popFront();
|
r.popFront();
|
||||||
|
@ -141,14 +72,14 @@ js::ScopeCoordinateName(JSContext *cx, JSScript *script, jsbytecode *pc)
|
||||||
|
|
||||||
/* Beware nameless destructuring formal. */
|
/* Beware nameless destructuring formal. */
|
||||||
if (!JSID_IS_ATOM(id))
|
if (!JSID_IS_ATOM(id))
|
||||||
return cx->runtime()->atomState.empty;
|
return script->runtimeFromAnyThread()->atomState.empty;
|
||||||
return JSID_TO_ATOM(id)->asPropertyName();
|
return JSID_TO_ATOM(id)->asPropertyName();
|
||||||
}
|
}
|
||||||
|
|
||||||
JSScript *
|
JSScript *
|
||||||
js::ScopeCoordinateFunctionScript(JSContext *cx, JSScript *script, jsbytecode *pc)
|
js::ScopeCoordinateFunctionScript(JSScript *script, jsbytecode *pc)
|
||||||
{
|
{
|
||||||
StaticScopeIter ssi(cx, InnermostStaticScope(script, pc));
|
StaticScopeIter<NoGC> ssi(InnermostStaticScope(script, pc));
|
||||||
ScopeCoordinate sc(pc);
|
ScopeCoordinate sc(pc);
|
||||||
while (true) {
|
while (true) {
|
||||||
if (ssi.hasDynamicScopeObject()) {
|
if (ssi.hasDynamicScopeObject()) {
|
||||||
|
@ -158,7 +89,7 @@ js::ScopeCoordinateFunctionScript(JSContext *cx, JSScript *script, jsbytecode *p
|
||||||
}
|
}
|
||||||
ssi++;
|
ssi++;
|
||||||
}
|
}
|
||||||
if (ssi.type() != StaticScopeIter::FUNCTION)
|
if (ssi.type() != StaticScopeIter<NoGC>::FUNCTION)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return ssi.funScript();
|
return ssi.funScript();
|
||||||
}
|
}
|
||||||
|
@ -2195,7 +2126,7 @@ RemoveReferencedNames(JSContext *cx, HandleScript script, PropertyNameSet &remai
|
||||||
case JSOP_GETALIASEDVAR:
|
case JSOP_GETALIASEDVAR:
|
||||||
case JSOP_CALLALIASEDVAR:
|
case JSOP_CALLALIASEDVAR:
|
||||||
case JSOP_SETALIASEDVAR:
|
case JSOP_SETALIASEDVAR:
|
||||||
name = ScopeCoordinateName(cx, script, pc);
|
name = ScopeCoordinateName(script, pc);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -54,13 +54,26 @@ namespace frontend { struct Definition; }
|
||||||
*
|
*
|
||||||
* (See also AssertDynamicScopeMatchesStaticScope.)
|
* (See also AssertDynamicScopeMatchesStaticScope.)
|
||||||
*/
|
*/
|
||||||
|
template <AllowGC allowGC>
|
||||||
class StaticScopeIter
|
class StaticScopeIter
|
||||||
{
|
{
|
||||||
RootedObject obj;
|
typename MaybeRooted<JSObject*, allowGC>::RootType obj;
|
||||||
bool onNamedLambda;
|
bool onNamedLambda;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit StaticScopeIter(ExclusiveContext *cx, JSObject *obj);
|
StaticScopeIter(ExclusiveContext *cx, JSObject *obj)
|
||||||
|
: obj(cx, obj), onNamedLambda(false)
|
||||||
|
{
|
||||||
|
JS_STATIC_ASSERT(allowGC == CanGC);
|
||||||
|
JS_ASSERT_IF(obj, obj->is<StaticBlockObject>() || obj->is<JSFunction>());
|
||||||
|
}
|
||||||
|
|
||||||
|
StaticScopeIter(JSObject *obj)
|
||||||
|
: obj((ExclusiveContext *) nullptr, obj), onNamedLambda(false)
|
||||||
|
{
|
||||||
|
JS_STATIC_ASSERT(allowGC == NoGC);
|
||||||
|
JS_ASSERT_IF(obj, obj->is<StaticBlockObject>() || obj->is<JSFunction>());
|
||||||
|
}
|
||||||
|
|
||||||
bool done() const;
|
bool done() const;
|
||||||
void operator++(int);
|
void operator++(int);
|
||||||
|
@ -106,15 +119,15 @@ struct ScopeCoordinate
|
||||||
* accessed by the ALIASEDVAR op at 'pc'.
|
* accessed by the ALIASEDVAR op at 'pc'.
|
||||||
*/
|
*/
|
||||||
extern Shape *
|
extern Shape *
|
||||||
ScopeCoordinateToStaticScopeShape(JSContext *cx, JSScript *script, jsbytecode *pc);
|
ScopeCoordinateToStaticScopeShape(JSScript *script, jsbytecode *pc);
|
||||||
|
|
||||||
/* Return the name being accessed by the given ALIASEDVAR op. */
|
/* Return the name being accessed by the given ALIASEDVAR op. */
|
||||||
extern PropertyName *
|
extern PropertyName *
|
||||||
ScopeCoordinateName(JSContext *cx, JSScript *script, jsbytecode *pc);
|
ScopeCoordinateName(JSScript *script, jsbytecode *pc);
|
||||||
|
|
||||||
/* Return the function script accessed by the given ALIASEDVAR op, or nullptr. */
|
/* Return the function script accessed by the given ALIASEDVAR op, or nullptr. */
|
||||||
extern JSScript *
|
extern JSScript *
|
||||||
ScopeCoordinateFunctionScript(JSContext *cx, JSScript *script, jsbytecode *pc);
|
ScopeCoordinateFunctionScript(JSScript *script, jsbytecode *pc);
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
|
@ -1295,6 +1295,7 @@ class Shape : public gc::BarrieredCell<Shape>
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Shape *search(ExclusiveContext *cx, jsid id);
|
inline Shape *search(ExclusiveContext *cx, jsid id);
|
||||||
|
inline Shape *searchLinear(jsid id);
|
||||||
|
|
||||||
/* For JIT usage */
|
/* For JIT usage */
|
||||||
static inline size_t offsetOfBase() { return offsetof(Shape, base_); }
|
static inline size_t offsetOfBase() { return offsetof(Shape, base_); }
|
||||||
|
@ -1582,6 +1583,25 @@ Shape::Shape(UnownedBaseShape *base, uint32_t nfixed)
|
||||||
kids.setNull();
|
kids.setNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline Shape *
|
||||||
|
Shape::searchLinear(jsid id)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Non-dictionary shapes can acquire a table at any point the main thread
|
||||||
|
* is operating on it, so other threads inspecting such shapes can't use
|
||||||
|
* their table without racing. This function can be called from any thread
|
||||||
|
* on any non-dictionary shape.
|
||||||
|
*/
|
||||||
|
JS_ASSERT(!inDictionary());
|
||||||
|
|
||||||
|
for (Shape *shape = this; shape; shape = shape->parent) {
|
||||||
|
if (shape->propidRef() == id)
|
||||||
|
return shape;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Keep this function in sync with search. It neither hashifies the start
|
* Keep this function in sync with search. It neither hashifies the start
|
||||||
* shape nor increments linear search count.
|
* shape nor increments linear search count.
|
||||||
|
@ -1598,12 +1618,7 @@ Shape::searchNoHashify(Shape *start, jsid id)
|
||||||
return SHAPE_FETCH(spp);
|
return SHAPE_FETCH(spp);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Shape *shape = start; shape; shape = shape->parent) {
|
return start->searchLinear(id);
|
||||||
if (shape->propidRef() == id)
|
|
||||||
return shape;
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "jit/IonFrameIterator-inl.h"
|
#include "jit/IonFrameIterator-inl.h"
|
||||||
#include "vm/Interpreter-inl.h"
|
#include "vm/Interpreter-inl.h"
|
||||||
#include "vm/Probes-inl.h"
|
#include "vm/Probes-inl.h"
|
||||||
|
#include "vm/ScopeObject-inl.h"
|
||||||
|
|
||||||
using namespace js;
|
using namespace js;
|
||||||
|
|
||||||
|
@ -204,7 +205,7 @@ AssertDynamicScopeMatchesStaticScope(JSContext *cx, JSScript *script, JSObject *
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
RootedObject enclosingScope(cx, script->enclosingStaticScope());
|
RootedObject enclosingScope(cx, script->enclosingStaticScope());
|
||||||
for (StaticScopeIter i(cx, enclosingScope); !i.done(); i++) {
|
for (StaticScopeIter<NoGC> i(enclosingScope); !i.done(); i++) {
|
||||||
if (i.hasDynamicScopeObject()) {
|
if (i.hasDynamicScopeObject()) {
|
||||||
/*
|
/*
|
||||||
* 'with' does not participate in the static scope of the script,
|
* 'with' does not participate in the static scope of the script,
|
||||||
|
@ -214,15 +215,15 @@ AssertDynamicScopeMatchesStaticScope(JSContext *cx, JSScript *script, JSObject *
|
||||||
scope = &scope->as<WithObject>().enclosingScope();
|
scope = &scope->as<WithObject>().enclosingScope();
|
||||||
|
|
||||||
switch (i.type()) {
|
switch (i.type()) {
|
||||||
case StaticScopeIter::BLOCK:
|
case StaticScopeIter<NoGC>::BLOCK:
|
||||||
JS_ASSERT(i.block() == scope->as<ClonedBlockObject>().staticBlock());
|
JS_ASSERT(i.block() == scope->as<ClonedBlockObject>().staticBlock());
|
||||||
scope = &scope->as<ClonedBlockObject>().enclosingScope();
|
scope = &scope->as<ClonedBlockObject>().enclosingScope();
|
||||||
break;
|
break;
|
||||||
case StaticScopeIter::FUNCTION:
|
case StaticScopeIter<NoGC>::FUNCTION:
|
||||||
JS_ASSERT(scope->as<CallObject>().callee().nonLazyScript() == i.funScript());
|
JS_ASSERT(scope->as<CallObject>().callee().nonLazyScript() == i.funScript());
|
||||||
scope = &scope->as<CallObject>().enclosingScope();
|
scope = &scope->as<CallObject>().enclosingScope();
|
||||||
break;
|
break;
|
||||||
case StaticScopeIter::NAMED_LAMBDA:
|
case StaticScopeIter<NoGC>::NAMED_LAMBDA:
|
||||||
scope = &scope->as<DeclEnvObject>().enclosingScope();
|
scope = &scope->as<DeclEnvObject>().enclosingScope();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -741,8 +741,6 @@ XPCJSRuntime::FinalizeCallback(JSFreeOp *fop, JSFinalizeStatus status, bool isCo
|
||||||
// Find dying scopes.
|
// Find dying scopes.
|
||||||
XPCWrappedNativeScope::StartFinalizationPhaseOfGC(fop, self);
|
XPCWrappedNativeScope::StartFinalizationPhaseOfGC(fop, self);
|
||||||
|
|
||||||
XPCStringConvert::ClearCache();
|
|
||||||
|
|
||||||
self->mDoingFinalization = true;
|
self->mDoingFinalization = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,24 +24,29 @@
|
||||||
#include "jsapi.h"
|
#include "jsapi.h"
|
||||||
#include "xpcpublic.h"
|
#include "xpcpublic.h"
|
||||||
|
|
||||||
// One-slot cache, because it turns out it's common for web pages to
|
|
||||||
// get the same string a few times in a row. We get about a 40% cache
|
|
||||||
// hit rate on this cache last it was measured. We'd get about 70%
|
|
||||||
// hit rate with a hashtable with removal on finalization, but that
|
|
||||||
// would take a lot more machinery.
|
|
||||||
nsStringBuffer* XPCStringConvert::sCachedBuffer = nullptr;
|
|
||||||
JSString* XPCStringConvert::sCachedString = nullptr;
|
|
||||||
|
|
||||||
// Called from GC finalize callback to make sure we don't hand out a pointer to
|
|
||||||
// a JSString that's about to be finalized by incremental sweeping.
|
|
||||||
// static
|
// static
|
||||||
void
|
void
|
||||||
XPCStringConvert::ClearCache()
|
XPCStringConvert::FreeZoneCache(JS::Zone *zone)
|
||||||
{
|
{
|
||||||
sCachedBuffer = nullptr;
|
// Put the zone user data into an AutoPtr (which will do the cleanup for us),
|
||||||
sCachedString = nullptr;
|
// and null out the user data (which may already be null).
|
||||||
|
nsAutoPtr<ZoneStringCache> cache(static_cast<ZoneStringCache*>(JS_GetZoneUserData(zone)));
|
||||||
|
JS_SetZoneUserData(zone, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void
|
||||||
|
XPCStringConvert::ClearZoneCache(JS::Zone *zone)
|
||||||
|
{
|
||||||
|
ZoneStringCache *cache = static_cast<ZoneStringCache*>(JS_GetZoneUserData(zone));
|
||||||
|
if (cache) {
|
||||||
|
cache->mBuffer = nullptr;
|
||||||
|
cache->mString = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
void
|
void
|
||||||
XPCStringConvert::FinalizeDOMString(const JSStringFinalizer *fin, jschar *chars)
|
XPCStringConvert::FinalizeDOMString(const JSStringFinalizer *fin, jschar *chars)
|
||||||
{
|
{
|
||||||
|
@ -83,26 +88,6 @@ XPCStringConvert::ReadableToJSVal(JSContext *cx,
|
||||||
}
|
}
|
||||||
|
|
||||||
// blech, have to copy.
|
// blech, have to copy.
|
||||||
|
str = JS_NewUCStringCopyN(cx, readable.BeginReading(), length);
|
||||||
jschar *chars = reinterpret_cast<jschar *>
|
return str ? JS::StringValue(str) : JS::NullValue();
|
||||||
(JS_malloc(cx, (length + 1) *
|
|
||||||
sizeof(jschar)));
|
|
||||||
if (!chars)
|
|
||||||
return JS::NullValue();
|
|
||||||
|
|
||||||
if (length && !CopyUnicodeTo(readable, 0,
|
|
||||||
reinterpret_cast<PRUnichar *>(chars),
|
|
||||||
length)) {
|
|
||||||
JS_free(cx, chars);
|
|
||||||
return JS::NullValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
chars[length] = 0;
|
|
||||||
|
|
||||||
str = JS_NewUCString(cx, chars, length);
|
|
||||||
if (!str) {
|
|
||||||
JS_free(cx, chars);
|
|
||||||
}
|
|
||||||
|
|
||||||
return str ? STRING_TO_JSVAL(str) : JSVAL_NULL;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -149,6 +149,17 @@ xpc_ActivateDebugMode();
|
||||||
// readable string conversions, static methods and members only
|
// readable string conversions, static methods and members only
|
||||||
class XPCStringConvert
|
class XPCStringConvert
|
||||||
{
|
{
|
||||||
|
// One-slot cache, because it turns out it's common for web pages to
|
||||||
|
// get the same string a few times in a row. We get about a 40% cache
|
||||||
|
// hit rate on this cache last it was measured. We'd get about 70%
|
||||||
|
// hit rate with a hashtable with removal on finalization, but that
|
||||||
|
// would take a lot more machinery.
|
||||||
|
struct ZoneStringCache
|
||||||
|
{
|
||||||
|
nsStringBuffer* mBuffer;
|
||||||
|
JSString* mString;
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// If the string shares the readable's buffer, that buffer will
|
// If the string shares the readable's buffer, that buffer will
|
||||||
|
@ -162,10 +173,12 @@ public:
|
||||||
StringBufferToJSVal(JSContext* cx, nsStringBuffer* buf, uint32_t length,
|
StringBufferToJSVal(JSContext* cx, nsStringBuffer* buf, uint32_t length,
|
||||||
JS::MutableHandleValue rval, bool* sharedBuffer)
|
JS::MutableHandleValue rval, bool* sharedBuffer)
|
||||||
{
|
{
|
||||||
if (buf == sCachedBuffer &&
|
JS::Zone *zone = js::GetContextZone(cx);
|
||||||
JS::GetGCThingZone(sCachedString) == js::GetContextZone(cx))
|
ZoneStringCache *cache = static_cast<ZoneStringCache*>(JS_GetZoneUserData(zone));
|
||||||
{
|
if (cache && buf == cache->mBuffer) {
|
||||||
rval.set(JS::StringValue(sCachedString));
|
MOZ_ASSERT(JS::GetGCThingZone(cache->mString) == zone);
|
||||||
|
JS::MarkStringAsLive(zone, cache->mString);
|
||||||
|
rval.setString(cache->mString);
|
||||||
*sharedBuffer = false;
|
*sharedBuffer = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -177,17 +190,20 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
rval.setString(str);
|
rval.setString(str);
|
||||||
sCachedString = str;
|
if (!cache) {
|
||||||
sCachedBuffer = buf;
|
cache = new ZoneStringCache();
|
||||||
|
JS_SetZoneUserData(zone, cache);
|
||||||
|
}
|
||||||
|
cache->mBuffer = buf;
|
||||||
|
cache->mString = str;
|
||||||
*sharedBuffer = true;
|
*sharedBuffer = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ClearCache();
|
static void FreeZoneCache(JS::Zone *zone);
|
||||||
|
static void ClearZoneCache(JS::Zone *zone);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static nsStringBuffer* sCachedBuffer;
|
|
||||||
static JSString* sCachedString;
|
|
||||||
static const JSStringFinalizer sDOMStringFinalizer;
|
static const JSStringFinalizer sDOMStringFinalizer;
|
||||||
|
|
||||||
static void FinalizeDOMString(const JSStringFinalizer *fin, jschar *chars);
|
static void FinalizeDOMString(const JSStringFinalizer *fin, jschar *chars);
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#include "GeckoProfiler.h"
|
#include "GeckoProfiler.h"
|
||||||
#include "mozilla/gfx/Tools.h"
|
#include "mozilla/gfx/Tools.h"
|
||||||
|
#include "mozilla/gfx/2D.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
@ -1942,6 +1943,7 @@ PaintInactiveLayer(nsDisplayListBuilder* aBuilder,
|
||||||
context = new gfxContext(surf);
|
context = new gfxContext(surf);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
basic->BeginTransaction();
|
||||||
basic->SetTarget(context);
|
basic->SetTarget(context);
|
||||||
|
|
||||||
if (aItem->GetType() == nsDisplayItem::TYPE_SVG_EFFECTS) {
|
if (aItem->GetType() == nsDisplayItem::TYPE_SVG_EFFECTS) {
|
||||||
|
@ -2347,7 +2349,7 @@ FrameLayerBuilder::AddThebesDisplayItem(ThebesLayer* aLayer,
|
||||||
{
|
{
|
||||||
ThebesDisplayItemLayerUserData* thebesData =
|
ThebesDisplayItemLayerUserData* thebesData =
|
||||||
static_cast<ThebesDisplayItemLayerUserData*>(aLayer->GetUserData(&gThebesDisplayItemLayerUserData));
|
static_cast<ThebesDisplayItemLayerUserData*>(aLayer->GetUserData(&gThebesDisplayItemLayerUserData));
|
||||||
nsRefPtr<LayerManager> tempManager;
|
nsRefPtr<BasicLayerManager> tempManager;
|
||||||
nsIntRect intClip;
|
nsIntRect intClip;
|
||||||
bool hasClip = false;
|
bool hasClip = false;
|
||||||
if (aLayerState != LAYER_NONE) {
|
if (aLayerState != LAYER_NONE) {
|
||||||
|
@ -2417,6 +2419,7 @@ FrameLayerBuilder::AddThebesDisplayItem(ThebesLayer* aLayer,
|
||||||
|
|
||||||
tempManager->SetRoot(layer);
|
tempManager->SetRoot(layer);
|
||||||
layerBuilder->WillEndTransaction();
|
layerBuilder->WillEndTransaction();
|
||||||
|
tempManager->AbortTransaction();
|
||||||
|
|
||||||
nsIntPoint offset = GetLastPaintOffset(aLayer) - GetTranslationForThebesLayer(aLayer);
|
nsIntPoint offset = GetLastPaintOffset(aLayer) - GetTranslationForThebesLayer(aLayer);
|
||||||
props->MoveBy(-offset);
|
props->MoveBy(-offset);
|
||||||
|
@ -2506,13 +2509,7 @@ FrameLayerBuilder::StoreDataForFrame(nsIFrame* aFrame,
|
||||||
FrameLayerBuilder::ClippedDisplayItem::~ClippedDisplayItem()
|
FrameLayerBuilder::ClippedDisplayItem::~ClippedDisplayItem()
|
||||||
{
|
{
|
||||||
if (mInactiveLayerManager) {
|
if (mInactiveLayerManager) {
|
||||||
// We always start a transaction during layer construction for all inactive
|
|
||||||
// layers, but we don't necessarily call EndTransaction during painting.
|
|
||||||
// If the transaaction is still open, end it to avoid assertions.
|
|
||||||
BasicLayerManager* basic = static_cast<BasicLayerManager*>(mInactiveLayerManager.get());
|
BasicLayerManager* basic = static_cast<BasicLayerManager*>(mInactiveLayerManager.get());
|
||||||
if (basic->InTransaction()) {
|
|
||||||
basic->EndTransaction(nullptr, nullptr);
|
|
||||||
}
|
|
||||||
basic->SetUserData(&gLayerManagerLayerBuilder, nullptr);
|
basic->SetUserData(&gLayerManagerLayerBuilder, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2523,7 +2520,7 @@ FrameLayerBuilder::AddLayerDisplayItem(Layer* aLayer,
|
||||||
const DisplayItemClip& aClip,
|
const DisplayItemClip& aClip,
|
||||||
LayerState aLayerState,
|
LayerState aLayerState,
|
||||||
const nsPoint& aTopLeft,
|
const nsPoint& aTopLeft,
|
||||||
LayerManager* aManager,
|
BasicLayerManager* aManager,
|
||||||
nsAutoPtr<nsDisplayItemGeometry> aGeometry)
|
nsAutoPtr<nsDisplayItemGeometry> aGeometry)
|
||||||
{
|
{
|
||||||
if (aLayer->Manager() != mRetainingManager)
|
if (aLayer->Manager() != mRetainingManager)
|
||||||
|
@ -3114,6 +3111,167 @@ static void DebugPaintItem(nsRenderingContext* aDest, nsDisplayItem *aItem, nsDi
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* static */ void
|
||||||
|
FrameLayerBuilder::RecomputeVisibilityForItems(nsTArray<ClippedDisplayItem>& aItems,
|
||||||
|
nsDisplayListBuilder *aBuilder,
|
||||||
|
const nsIntRegion& aRegionToDraw,
|
||||||
|
const nsIntPoint& aOffset,
|
||||||
|
int32_t aAppUnitsPerDevPixel,
|
||||||
|
float aXScale,
|
||||||
|
float aYScale)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
// Update visible regions. We need perform visibility analysis again
|
||||||
|
// because we may be asked to draw into part of a ThebesLayer that
|
||||||
|
// isn't actually visible in the window (e.g., because a ThebesLayer
|
||||||
|
// expanded its visible region to a rectangle internally), in which
|
||||||
|
// case the mVisibleRect stored in the display item may be wrong.
|
||||||
|
nsRegion visible = aRegionToDraw.ToAppUnits(aAppUnitsPerDevPixel);
|
||||||
|
visible.MoveBy(NSIntPixelsToAppUnits(aOffset.x, aAppUnitsPerDevPixel),
|
||||||
|
NSIntPixelsToAppUnits(aOffset.y, aAppUnitsPerDevPixel));
|
||||||
|
visible.ScaleInverseRoundOut(aXScale, aYScale);
|
||||||
|
|
||||||
|
for (i = aItems.Length(); i > 0; --i) {
|
||||||
|
ClippedDisplayItem* cdi = &aItems[i - 1];
|
||||||
|
const DisplayItemClip& clip = cdi->mItem->GetClip();
|
||||||
|
|
||||||
|
NS_ASSERTION(AppUnitsPerDevPixel(cdi->mItem) == aAppUnitsPerDevPixel,
|
||||||
|
"a thebes layer should contain items only at the same zoom");
|
||||||
|
|
||||||
|
NS_ABORT_IF_FALSE(clip.HasClip() ||
|
||||||
|
clip.GetRoundedRectCount() == 0,
|
||||||
|
"If we have rounded rects, we must have a clip rect");
|
||||||
|
|
||||||
|
if (!clip.IsRectAffectedByClip(visible.GetBounds())) {
|
||||||
|
cdi->mItem->RecomputeVisibility(aBuilder, &visible);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do a little dance to account for the fact that we're clipping
|
||||||
|
// to cdi->mClipRect
|
||||||
|
nsRegion clipped;
|
||||||
|
clipped.And(visible, clip.NonRoundedIntersection());
|
||||||
|
nsRegion finalClipped = clipped;
|
||||||
|
cdi->mItem->RecomputeVisibility(aBuilder, &finalClipped);
|
||||||
|
// If we have rounded clip rects, don't subtract from the visible
|
||||||
|
// region since we aren't displaying everything inside the rect.
|
||||||
|
if (clip.GetRoundedRectCount() == 0) {
|
||||||
|
nsRegion removed;
|
||||||
|
removed.Sub(clipped, finalClipped);
|
||||||
|
nsRegion newVisible;
|
||||||
|
newVisible.Sub(visible, removed);
|
||||||
|
// Don't let the visible region get too complex.
|
||||||
|
if (newVisible.GetNumRects() <= 15) {
|
||||||
|
visible = newVisible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
FrameLayerBuilder::PaintItems(nsTArray<ClippedDisplayItem>& aItems,
|
||||||
|
const nsIntRect& aRect,
|
||||||
|
gfxContext *aContext,
|
||||||
|
nsRenderingContext *aRC,
|
||||||
|
nsDisplayListBuilder* aBuilder,
|
||||||
|
nsPresContext* aPresContext,
|
||||||
|
const nsIntPoint& aOffset,
|
||||||
|
float aXScale, float aYScale,
|
||||||
|
int32_t aCommonClipCount)
|
||||||
|
{
|
||||||
|
int32_t appUnitsPerDevPixel = aPresContext->AppUnitsPerDevPixel();
|
||||||
|
nsRect boundRect = aRect.ToAppUnits(appUnitsPerDevPixel);
|
||||||
|
boundRect.MoveBy(NSIntPixelsToAppUnits(aOffset.x, appUnitsPerDevPixel),
|
||||||
|
NSIntPixelsToAppUnits(aOffset.y, appUnitsPerDevPixel));
|
||||||
|
boundRect.ScaleInverseRoundOut(aXScale, aYScale);
|
||||||
|
|
||||||
|
DisplayItemClip currentClip;
|
||||||
|
bool currentClipIsSetInContext = false;
|
||||||
|
DisplayItemClip tmpClip;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < aItems.Length(); ++i) {
|
||||||
|
ClippedDisplayItem* cdi = &aItems[i];
|
||||||
|
|
||||||
|
nsRect paintRect = cdi->mItem->GetVisibleRect().Intersect(boundRect);
|
||||||
|
if (paintRect.IsEmpty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// If the new desired clip state is different from the current state,
|
||||||
|
// update the clip.
|
||||||
|
const DisplayItemClip* clip = &cdi->mItem->GetClip();
|
||||||
|
if (clip->GetRoundedRectCount() > 0 &&
|
||||||
|
!clip->IsRectClippedByRoundedCorner(cdi->mItem->GetVisibleRect())) {
|
||||||
|
tmpClip = *clip;
|
||||||
|
tmpClip.RemoveRoundedCorners();
|
||||||
|
clip = &tmpClip;
|
||||||
|
}
|
||||||
|
if (currentClipIsSetInContext != clip->HasClip() ||
|
||||||
|
(clip->HasClip() && *clip != currentClip)) {
|
||||||
|
if (currentClipIsSetInContext) {
|
||||||
|
aContext->Restore();
|
||||||
|
}
|
||||||
|
currentClipIsSetInContext = clip->HasClip();
|
||||||
|
if (currentClipIsSetInContext) {
|
||||||
|
currentClip = *clip;
|
||||||
|
aContext->Save();
|
||||||
|
NS_ASSERTION(aCommonClipCount < 100,
|
||||||
|
"Maybe you really do have more than a hundred clipping rounded rects, or maybe something has gone wrong.");
|
||||||
|
currentClip.ApplyTo(aContext, aPresContext, aCommonClipCount);
|
||||||
|
aContext->NewPath();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cdi->mInactiveLayerManager) {
|
||||||
|
PaintInactiveLayer(aBuilder, cdi->mInactiveLayerManager, cdi->mItem, aContext, aRC);
|
||||||
|
} else {
|
||||||
|
nsIFrame* frame = cdi->mItem->Frame();
|
||||||
|
frame->AddStateBits(NS_FRAME_PAINTED_THEBES);
|
||||||
|
#ifdef MOZ_DUMP_PAINTING
|
||||||
|
|
||||||
|
if (gfxUtils::sDumpPainting) {
|
||||||
|
DebugPaintItem(aRC, cdi->mItem, aBuilder);
|
||||||
|
} else {
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
cdi->mItem->Paint(aBuilder, aRC);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CheckDOMModified())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentClipIsSetInContext) {
|
||||||
|
aContext->Restore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if it is preferred to draw the list of display
|
||||||
|
* items separately for each rect in the visible region rather
|
||||||
|
* than clipping to a complex region.
|
||||||
|
*/
|
||||||
|
static bool ShouldDrawRectsSeparately(gfxContext* aContext, DrawRegionClip aClip)
|
||||||
|
{
|
||||||
|
if (aContext->IsCairo() || aClip == CLIP_NONE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
DrawTarget *dt = aContext->GetDrawTarget();
|
||||||
|
return dt->GetType() == BACKEND_DIRECT2D;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DrawForcedBackgroundColor(gfxContext* aContext, Layer* aLayer, nscolor aBackgroundColor)
|
||||||
|
{
|
||||||
|
if (NS_GET_A(aBackgroundColor) > 0) {
|
||||||
|
nsIntRect r = aLayer->GetVisibleRegion().GetBounds();
|
||||||
|
aContext->NewPath();
|
||||||
|
aContext->Rectangle(gfxRect(r.x, r.y, r.width, r.height));
|
||||||
|
aContext->SetColor(gfxRGBA(aBackgroundColor));
|
||||||
|
aContext->Fill();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A note on residual transforms:
|
* A note on residual transforms:
|
||||||
*
|
*
|
||||||
|
@ -3146,6 +3304,7 @@ static void DebugPaintItem(nsRenderingContext* aDest, nsDisplayItem *aItem, nsDi
|
||||||
FrameLayerBuilder::DrawThebesLayer(ThebesLayer* aLayer,
|
FrameLayerBuilder::DrawThebesLayer(ThebesLayer* aLayer,
|
||||||
gfxContext* aContext,
|
gfxContext* aContext,
|
||||||
const nsIntRegion& aRegionToDraw,
|
const nsIntRegion& aRegionToDraw,
|
||||||
|
DrawRegionClip aClip,
|
||||||
const nsIntRegion& aRegionToInvalidate,
|
const nsIntRegion& aRegionToInvalidate,
|
||||||
void* aCallbackData)
|
void* aCallbackData)
|
||||||
{
|
{
|
||||||
|
@ -3160,163 +3319,77 @@ FrameLayerBuilder::DrawThebesLayer(ThebesLayer* aLayer,
|
||||||
if (layerBuilder->CheckDOMModified())
|
if (layerBuilder->CheckDOMModified())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
nsTArray<ClippedDisplayItem> items;
|
ThebesLayerItemsEntry* entry = layerBuilder->mThebesLayerItems.GetEntry(aLayer);
|
||||||
uint32_t commonClipCount;
|
NS_ASSERTION(entry, "We shouldn't be drawing into a layer with no items!");
|
||||||
nsIFrame* containerLayerFrame;
|
if (!entry->mContainerLayerFrame) {
|
||||||
{
|
|
||||||
ThebesLayerItemsEntry* entry = layerBuilder->mThebesLayerItems.GetEntry(aLayer);
|
|
||||||
NS_ASSERTION(entry, "We shouldn't be drawing into a layer with no items!");
|
|
||||||
items.SwapElements(entry->mItems);
|
|
||||||
commonClipCount = entry->mCommonClipCount;
|
|
||||||
containerLayerFrame = entry->mContainerLayerFrame;
|
|
||||||
// Later after this point, due to calls to DidEndTransaction
|
|
||||||
// for temporary layer managers, mThebesLayerItems can change,
|
|
||||||
// so 'entry' could become invalid.
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!containerLayerFrame) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ThebesDisplayItemLayerUserData* userData =
|
ThebesDisplayItemLayerUserData* userData =
|
||||||
static_cast<ThebesDisplayItemLayerUserData*>
|
static_cast<ThebesDisplayItemLayerUserData*>
|
||||||
(aLayer->GetUserData(&gThebesDisplayItemLayerUserData));
|
(aLayer->GetUserData(&gThebesDisplayItemLayerUserData));
|
||||||
NS_ASSERTION(userData, "where did our user data go?");
|
NS_ASSERTION(userData, "where did our user data go?");
|
||||||
if (NS_GET_A(userData->mForcedBackgroundColor) > 0) {
|
|
||||||
nsIntRect r = aLayer->GetVisibleRegion().GetBounds();
|
bool shouldDrawRectsSeparately = ShouldDrawRectsSeparately(aContext, aClip);
|
||||||
aContext->NewPath();
|
|
||||||
aContext->Rectangle(gfxRect(r.x, r.y, r.width, r.height));
|
if (!shouldDrawRectsSeparately) {
|
||||||
aContext->SetColor(gfxRGBA(userData->mForcedBackgroundColor));
|
if (aClip == CLIP_DRAW_SNAPPED) {
|
||||||
aContext->Fill();
|
gfxUtils::ClipToRegionSnapped(aContext, aRegionToDraw);
|
||||||
|
} else if (aClip == CLIP_DRAW) {
|
||||||
|
gfxUtils::ClipToRegion(aContext, aRegionToDraw);
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawForcedBackgroundColor(aContext, aLayer, userData->mForcedBackgroundColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// make the origin of the context coincide with the origin of the
|
// make the origin of the context coincide with the origin of the
|
||||||
// ThebesLayer
|
// ThebesLayer
|
||||||
gfxContextMatrixAutoSaveRestore saveMatrix(aContext);
|
gfxContextMatrixAutoSaveRestore saveMatrix(aContext);
|
||||||
nsIntPoint offset = GetTranslationForThebesLayer(aLayer);
|
nsIntPoint offset = GetTranslationForThebesLayer(aLayer);
|
||||||
// Apply the residual transform if it has been enabled, to ensure that
|
|
||||||
// snapping when we draw into aContext exactly matches the ideal transform.
|
|
||||||
// See above for why this is OK.
|
|
||||||
aContext->Translate(aLayer->GetResidualTranslation() - gfxPoint(offset.x, offset.y));
|
|
||||||
aContext->Scale(userData->mXScale, userData->mYScale);
|
|
||||||
|
|
||||||
nsPresContext* presContext = containerLayerFrame->PresContext();
|
nsPresContext* presContext = entry->mContainerLayerFrame->PresContext();
|
||||||
int32_t appUnitsPerDevPixel = presContext->AppUnitsPerDevPixel();
|
int32_t appUnitsPerDevPixel = presContext->AppUnitsPerDevPixel();
|
||||||
|
|
||||||
uint32_t i;
|
RecomputeVisibilityForItems(entry->mItems, builder, aRegionToDraw,
|
||||||
// Update visible regions. We need perform visibility analysis again
|
offset, appUnitsPerDevPixel,
|
||||||
// because we may be asked to draw into part of a ThebesLayer that
|
userData->mXScale, userData->mYScale);
|
||||||
// isn't actually visible in the window (e.g., because a ThebesLayer
|
|
||||||
// expanded its visible region to a rectangle internally), in which
|
|
||||||
// case the mVisibleRect stored in the display item may be wrong.
|
|
||||||
nsRegion visible = aRegionToDraw.ToAppUnits(appUnitsPerDevPixel);
|
|
||||||
visible.MoveBy(NSIntPixelsToAppUnits(offset.x, appUnitsPerDevPixel),
|
|
||||||
NSIntPixelsToAppUnits(offset.y, appUnitsPerDevPixel));
|
|
||||||
visible.ScaleInverseRoundOut(userData->mXScale, userData->mYScale);
|
|
||||||
|
|
||||||
for (i = items.Length(); i > 0; --i) {
|
|
||||||
ClippedDisplayItem* cdi = &items[i - 1];
|
|
||||||
const DisplayItemClip& clip = cdi->mItem->GetClip();
|
|
||||||
|
|
||||||
NS_ASSERTION(AppUnitsPerDevPixel(cdi->mItem) == appUnitsPerDevPixel,
|
|
||||||
"a thebes layer should contain items only at the same zoom");
|
|
||||||
|
|
||||||
NS_ABORT_IF_FALSE(clip.HasClip() ||
|
|
||||||
clip.GetRoundedRectCount() == 0,
|
|
||||||
"If we have rounded rects, we must have a clip rect");
|
|
||||||
|
|
||||||
if (!clip.IsRectAffectedByClip(visible.GetBounds())) {
|
|
||||||
cdi->mItem->RecomputeVisibility(builder, &visible);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do a little dance to account for the fact that we're clipping
|
|
||||||
// to cdi->mClipRect
|
|
||||||
nsRegion clipped;
|
|
||||||
clipped.And(visible, clip.NonRoundedIntersection());
|
|
||||||
nsRegion finalClipped = clipped;
|
|
||||||
cdi->mItem->RecomputeVisibility(builder, &finalClipped);
|
|
||||||
// If we have rounded clip rects, don't subtract from the visible
|
|
||||||
// region since we aren't displaying everything inside the rect.
|
|
||||||
if (clip.GetRoundedRectCount() == 0) {
|
|
||||||
nsRegion removed;
|
|
||||||
removed.Sub(clipped, finalClipped);
|
|
||||||
nsRegion newVisible;
|
|
||||||
newVisible.Sub(visible, removed);
|
|
||||||
// Don't let the visible region get too complex.
|
|
||||||
if (newVisible.GetNumRects() <= 15) {
|
|
||||||
visible = newVisible;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nsRefPtr<nsRenderingContext> rc = new nsRenderingContext();
|
nsRefPtr<nsRenderingContext> rc = new nsRenderingContext();
|
||||||
rc->Init(presContext->DeviceContext(), aContext);
|
rc->Init(presContext->DeviceContext(), aContext);
|
||||||
|
|
||||||
DisplayItemClip currentClip;
|
if (shouldDrawRectsSeparately) {
|
||||||
bool currentClipIsSetInContext = false;
|
nsIntRegionRectIterator it(aRegionToDraw);
|
||||||
DisplayItemClip tmpClip;
|
while (const nsIntRect* iterRect = it.Next()) {
|
||||||
|
gfxContextAutoSaveRestore save(aContext);
|
||||||
|
aContext->NewPath();
|
||||||
|
aContext->Rectangle(*iterRect, aClip == CLIP_DRAW_SNAPPED);
|
||||||
|
aContext->Clip();
|
||||||
|
|
||||||
for (i = 0; i < items.Length(); ++i) {
|
DrawForcedBackgroundColor(aContext, aLayer, userData->mForcedBackgroundColor);
|
||||||
ClippedDisplayItem* cdi = &items[i];
|
|
||||||
|
|
||||||
if (cdi->mItem->GetVisibleRect().IsEmpty())
|
// Apply the residual transform if it has been enabled, to ensure that
|
||||||
continue;
|
// snapping when we draw into aContext exactly matches the ideal transform.
|
||||||
|
// See above for why this is OK.
|
||||||
|
aContext->Translate(aLayer->GetResidualTranslation() - gfxPoint(offset.x, offset.y));
|
||||||
|
aContext->Scale(userData->mXScale, userData->mYScale);
|
||||||
|
|
||||||
// If the new desired clip state is different from the current state,
|
layerBuilder->PaintItems(entry->mItems, *iterRect, aContext, rc,
|
||||||
// update the clip.
|
builder, presContext,
|
||||||
const DisplayItemClip* clip = &cdi->mItem->GetClip();
|
offset, userData->mXScale, userData->mYScale,
|
||||||
if (clip->GetRoundedRectCount() > 0 &&
|
entry->mCommonClipCount);
|
||||||
!clip->IsRectClippedByRoundedCorner(cdi->mItem->GetVisibleRect())) {
|
|
||||||
tmpClip = *clip;
|
|
||||||
tmpClip.RemoveRoundedCorners();
|
|
||||||
clip = &tmpClip;
|
|
||||||
}
|
|
||||||
if (currentClipIsSetInContext != clip->HasClip() ||
|
|
||||||
(clip->HasClip() && *clip != currentClip)) {
|
|
||||||
if (currentClipIsSetInContext) {
|
|
||||||
aContext->Restore();
|
|
||||||
}
|
|
||||||
currentClipIsSetInContext = clip->HasClip();
|
|
||||||
if (currentClipIsSetInContext) {
|
|
||||||
currentClip = *clip;
|
|
||||||
aContext->Save();
|
|
||||||
NS_ASSERTION(commonClipCount < 100,
|
|
||||||
"Maybe you really do have more than a hundred clipping rounded rects, or maybe something has gone wrong.");
|
|
||||||
currentClip.ApplyTo(aContext, presContext, commonClipCount);
|
|
||||||
aContext->NewPath();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// Apply the residual transform if it has been enabled, to ensure that
|
||||||
|
// snapping when we draw into aContext exactly matches the ideal transform.
|
||||||
|
// See above for why this is OK.
|
||||||
|
aContext->Translate(aLayer->GetResidualTranslation() - gfxPoint(offset.x, offset.y));
|
||||||
|
aContext->Scale(userData->mXScale, userData->mYScale);
|
||||||
|
|
||||||
if (cdi->mInactiveLayerManager) {
|
layerBuilder->PaintItems(entry->mItems, aRegionToDraw.GetBounds(), aContext, rc,
|
||||||
PaintInactiveLayer(builder, cdi->mInactiveLayerManager, cdi->mItem, aContext, rc);
|
builder, presContext,
|
||||||
} else {
|
offset, userData->mXScale, userData->mYScale,
|
||||||
nsIFrame* frame = cdi->mItem->Frame();
|
entry->mCommonClipCount);
|
||||||
frame->AddStateBits(NS_FRAME_PAINTED_THEBES);
|
|
||||||
#ifdef MOZ_DUMP_PAINTING
|
|
||||||
|
|
||||||
if (gfxUtils::sDumpPainting) {
|
|
||||||
DebugPaintItem(rc, cdi->mItem, builder);
|
|
||||||
} else {
|
|
||||||
#else
|
|
||||||
{
|
|
||||||
#endif
|
|
||||||
cdi->mItem->Paint(builder, rc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (layerBuilder->CheckDOMModified())
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
ThebesLayerItemsEntry* entry =
|
|
||||||
layerBuilder->mThebesLayerItems.GetEntry(aLayer);
|
|
||||||
items.SwapElements(entry->mItems);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentClipIsSetInContext) {
|
|
||||||
aContext->Restore();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (presContext->GetPaintFlashing()) {
|
if (presContext->GetPaintFlashing()) {
|
||||||
|
|
|
@ -24,6 +24,7 @@ namespace mozilla {
|
||||||
namespace layers {
|
namespace layers {
|
||||||
class ContainerLayer;
|
class ContainerLayer;
|
||||||
class LayerManager;
|
class LayerManager;
|
||||||
|
class BasicLayerManager;
|
||||||
class ThebesLayer;
|
class ThebesLayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,6 +96,7 @@ public:
|
||||||
typedef layers::ThebesLayer ThebesLayer;
|
typedef layers::ThebesLayer ThebesLayer;
|
||||||
typedef layers::ImageLayer ImageLayer;
|
typedef layers::ImageLayer ImageLayer;
|
||||||
typedef layers::LayerManager LayerManager;
|
typedef layers::LayerManager LayerManager;
|
||||||
|
typedef layers::BasicLayerManager BasicLayerManager;
|
||||||
|
|
||||||
FrameLayerBuilder() :
|
FrameLayerBuilder() :
|
||||||
mRetainingManager(nullptr),
|
mRetainingManager(nullptr),
|
||||||
|
@ -242,6 +244,7 @@ public:
|
||||||
static void DrawThebesLayer(ThebesLayer* aLayer,
|
static void DrawThebesLayer(ThebesLayer* aLayer,
|
||||||
gfxContext* aContext,
|
gfxContext* aContext,
|
||||||
const nsIntRegion& aRegionToDraw,
|
const nsIntRegion& aRegionToDraw,
|
||||||
|
mozilla::layers::DrawRegionClip aClip,
|
||||||
const nsIntRegion& aRegionToInvalidate,
|
const nsIntRegion& aRegionToInvalidate,
|
||||||
void* aCallbackData);
|
void* aCallbackData);
|
||||||
|
|
||||||
|
@ -273,7 +276,7 @@ public:
|
||||||
const DisplayItemClip& aClip,
|
const DisplayItemClip& aClip,
|
||||||
LayerState aLayerState,
|
LayerState aLayerState,
|
||||||
const nsPoint& aTopLeft,
|
const nsPoint& aTopLeft,
|
||||||
LayerManager* aManager,
|
BasicLayerManager* aManager,
|
||||||
nsAutoPtr<nsDisplayItemGeometry> aGeometry);
|
nsAutoPtr<nsDisplayItemGeometry> aGeometry);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -420,7 +423,7 @@ public:
|
||||||
LayerManagerData* mParent;
|
LayerManagerData* mParent;
|
||||||
nsRefPtr<Layer> mLayer;
|
nsRefPtr<Layer> mLayer;
|
||||||
nsRefPtr<Layer> mOptLayer;
|
nsRefPtr<Layer> mOptLayer;
|
||||||
nsRefPtr<LayerManager> mInactiveManager;
|
nsRefPtr<BasicLayerManager> mInactiveManager;
|
||||||
nsAutoTArray<nsIFrame*, 1> mFrameList;
|
nsAutoTArray<nsIFrame*, 1> mFrameList;
|
||||||
nsAutoPtr<nsDisplayItemGeometry> mGeometry;
|
nsAutoPtr<nsDisplayItemGeometry> mGeometry;
|
||||||
DisplayItemClip mClip;
|
DisplayItemClip mClip;
|
||||||
|
@ -518,6 +521,24 @@ protected:
|
||||||
uint32_t mContainerLayerGeneration;
|
uint32_t mContainerLayerGeneration;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void RecomputeVisibilityForItems(nsTArray<ClippedDisplayItem>& aItems,
|
||||||
|
nsDisplayListBuilder* aBuilder,
|
||||||
|
const nsIntRegion& aRegionToDraw,
|
||||||
|
const nsIntPoint& aOffset,
|
||||||
|
int32_t aAppUnitsPerDevPixel,
|
||||||
|
float aXScale,
|
||||||
|
float aYScale);
|
||||||
|
|
||||||
|
void PaintItems(nsTArray<ClippedDisplayItem>& aItems,
|
||||||
|
const nsIntRect& aRect,
|
||||||
|
gfxContext* aContext,
|
||||||
|
nsRenderingContext* aRC,
|
||||||
|
nsDisplayListBuilder* aBuilder,
|
||||||
|
nsPresContext* aPresContext,
|
||||||
|
const nsIntPoint& aOffset,
|
||||||
|
float aXScale, float aYScale,
|
||||||
|
int32_t aCommonClipCount);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We accumulate ClippedDisplayItem elements in a hashtable during
|
* We accumulate ClippedDisplayItem elements in a hashtable during
|
||||||
* the paint process. This is the hashentry for that hashtable.
|
* the paint process. This is the hashentry for that hashtable.
|
||||||
|
|
|
@ -27,7 +27,7 @@ MACPORTS_URL = {'8': 'https://distfiles.macports.org/MacPorts/MacPorts-2.1.3-10.
|
||||||
'7': 'https://distfiles.macports.org/MacPorts/MacPorts-2.1.3-10.7-Lion.pkg',
|
'7': 'https://distfiles.macports.org/MacPorts/MacPorts-2.1.3-10.7-Lion.pkg',
|
||||||
'6': 'https://distfiles.macports.org/MacPorts/MacPorts-2.1.3-10.6-SnowLeopard.pkg',}
|
'6': 'https://distfiles.macports.org/MacPorts/MacPorts-2.1.3-10.6-SnowLeopard.pkg',}
|
||||||
|
|
||||||
MACPORTS_CLANG_PACKAGE = 'clang-3.2'
|
MACPORTS_CLANG_PACKAGE = 'clang-3.3'
|
||||||
|
|
||||||
RE_CLANG_VERSION = re.compile('Apple (?:clang|LLVM) version (\d+\.\d+)')
|
RE_CLANG_VERSION = re.compile('Apple (?:clang|LLVM) version (\d+\.\d+)')
|
||||||
|
|
||||||
|
|
|
@ -19,12 +19,26 @@ from manifestparser import TestManifest
|
||||||
from mozhttpd import MozHttpd
|
from mozhttpd import MozHttpd
|
||||||
|
|
||||||
from marionette import Marionette
|
from marionette import Marionette
|
||||||
from moztest.results import TestResultCollection
|
from moztest.results import TestResultCollection, TestResult, relevant_line
|
||||||
from marionette_test import MarionetteJSTestCase, MarionetteTestCase
|
from marionette_test import MarionetteJSTestCase, MarionetteTestCase
|
||||||
|
|
||||||
|
|
||||||
|
class MarionetteTest(TestResult):
|
||||||
|
|
||||||
|
@property
|
||||||
|
def test_name(self):
|
||||||
|
if self.test_class is not None:
|
||||||
|
return '%s.py %s.%s' % (self.test_class.split('.')[0],
|
||||||
|
self.test_class,
|
||||||
|
self.name)
|
||||||
|
else:
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
|
||||||
class MarionetteTestResult(unittest._TextTestResult, TestResultCollection):
|
class MarionetteTestResult(unittest._TextTestResult, TestResultCollection):
|
||||||
|
|
||||||
|
resultClass = MarionetteTest
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
self.marionette = kwargs.pop('marionette')
|
self.marionette = kwargs.pop('marionette')
|
||||||
TestResultCollection.__init__(self, 'MarionetteTest')
|
TestResultCollection.__init__(self, 'MarionetteTest')
|
||||||
|
@ -83,10 +97,25 @@ class MarionetteTestResult(unittest._TextTestResult, TestResultCollection):
|
||||||
else:
|
else:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def add_test_result(self, test, *args, **kwargs):
|
def add_test_result(self, test, result_expected='PASS',
|
||||||
self.add_result(test, *args, **kwargs)
|
result_actual='PASS', output='', context=None, **kwargs):
|
||||||
self[-1].time_start = test.start_time
|
def get_class(test):
|
||||||
self[-1].time_end = time.time() if test.start_time else 0
|
return test.__class__.__module__ + '.' + test.__class__.__name__
|
||||||
|
|
||||||
|
name = str(test).split()[0]
|
||||||
|
test_class = get_class(test)
|
||||||
|
if hasattr(test, 'jsFile'):
|
||||||
|
name = os.path.basename(test.jsFile)
|
||||||
|
test_class = None
|
||||||
|
|
||||||
|
t = self.resultClass(name=name, test_class=test_class,
|
||||||
|
time_start=test.start_time, result_expected=result_expected,
|
||||||
|
context=context, **kwargs)
|
||||||
|
t.finish(result_actual,
|
||||||
|
time_end=time.time() if test.start_time else 0,
|
||||||
|
reason=relevant_line(output),
|
||||||
|
output=output)
|
||||||
|
self.append(t)
|
||||||
|
|
||||||
def addError(self, test, err):
|
def addError(self, test, err):
|
||||||
self.add_test_result(test, output=self._exc_info_to_string(err, test), result_actual='ERROR')
|
self.add_test_result(test, output=self._exc_info_to_string(err, test), result_actual='ERROR')
|
||||||
|
|
|
@ -24,9 +24,7 @@ interface nsIAlertsService : nsISupports
|
||||||
* @param alertListener Used for callbacks. May be null if the caller
|
* @param alertListener Used for callbacks. May be null if the caller
|
||||||
* doesn't care about callbacks.
|
* doesn't care about callbacks.
|
||||||
* @param name The name of the notification. This is currently
|
* @param name The name of the notification. This is currently
|
||||||
* only used on OS X with Growl and Android.
|
* only used on Android. On Android the name is hashed
|
||||||
* On OS X with Growl, users can disable notifications
|
|
||||||
* with a given name. On Android the name is hashed
|
|
||||||
* and used as a notification ID. Notifications will
|
* and used as a notification ID. Notifications will
|
||||||
* replace previous notifications with the same name.
|
* replace previous notifications with the same name.
|
||||||
* @param dir Bidi override for the title. Valid values are
|
* @param dir Bidi override for the title. Valid values are
|
||||||
|
|
|
@ -53,7 +53,7 @@ function runTest() {
|
||||||
ok(true, "Alerts service is available");
|
ok(true, "Alerts service is available");
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
todo(false,
|
todo(false,
|
||||||
"Alerts service is not available. (Mac OS X without Growl?)", ex);
|
"Alerts service is not available.", ex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ function runTest() {
|
||||||
false, "foobarcookie", observer);
|
false, "foobarcookie", observer);
|
||||||
ok(true, "showAlertNotification() succeeded. Waiting for notification...");
|
ok(true, "showAlertNotification() succeeded. Waiting for notification...");
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
todo(false, "showAlertNotification() failed. (Mac OS X without Growl?)", ex);
|
todo(false, "showAlertNotification() failed.", ex);
|
||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ if (!("@mozilla.org/alerts-service;1" in Cc)) {
|
||||||
getService(Ci.nsIAlertsService);
|
getService(Ci.nsIAlertsService);
|
||||||
ok(true, "Alerts service is available");
|
ok(true, "Alerts service is available");
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
todo(false, "Alerts service is not available. (Mac OS X without Growl?)", ex);
|
todo(false, "Alerts service is not available.", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (notifier) {
|
if (notifier) {
|
||||||
|
@ -46,7 +46,7 @@ if (!("@mozilla.org/alerts-service;1" in Cc)) {
|
||||||
|
|
||||||
gNotificationIsAvailable = true;
|
gNotificationIsAvailable = true;
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
todo(false, "showAlertNotification() failed. (Mac OS X without Growl?)", ex);
|
todo(false, "showAlertNotification() failed.", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,7 +83,6 @@
|
||||||
<li><a href="about:license#gears">Google Gears License</a></li>
|
<li><a href="about:license#gears">Google Gears License</a></li>
|
||||||
<li><a href="about:license#gears-istumbler">Google Gears/iStumbler License</a></li>
|
<li><a href="about:license#gears-istumbler">Google Gears/iStumbler License</a></li>
|
||||||
<li><a href="about:license#vp8">Google VP8 License</a></li>
|
<li><a href="about:license#vp8">Google VP8 License</a></li>
|
||||||
<li><a href="about:license#growl">Growl License</a></li>
|
|
||||||
<li><a href="about:license#gyp">gyp License</a></li>
|
<li><a href="about:license#gyp">gyp License</a></li>
|
||||||
<li><a href="about:license#halloc">halloc License</a></li>
|
<li><a href="about:license#halloc">halloc License</a></li>
|
||||||
<li><a href="about:license#harfbuzz">HarfBuzz License</a></li>
|
<li><a href="about:license#harfbuzz">HarfBuzz License</a></li>
|
||||||
|
@ -2260,48 +2259,7 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
<h1><a id="growl"></a>Growl License</h1>
|
|
||||||
|
|
||||||
<p>This license applies to certain files in the directory
|
|
||||||
<span class="path">toolkit/components/alerts/mac/growl/</span>.
|
|
||||||
(This code only ships in the Mac OS X version of the product.)
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
Copyright (c) The Growl Project, 2004-2011
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
3. Neither the name of Growl nor the names of its contributors
|
|
||||||
may be used to endorse or promote products derived from this software
|
|
||||||
without specific prior written permission.
|
|
||||||
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
|
||||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
||||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
|
|
||||||
<h1><a id="gyp"></a>gyp License</h1>
|
<h1><a id="gyp"></a>gyp License</h1>
|
||||||
|
|
||||||
|
|
|
@ -452,6 +452,8 @@ CycleCollectedJSRuntime::CycleCollectedJSRuntime(uint32_t aMaxbytes,
|
||||||
JS_SetGrayGCRootsTracer(mJSRuntime, TraceGrayJS, this);
|
JS_SetGrayGCRootsTracer(mJSRuntime, TraceGrayJS, this);
|
||||||
JS_SetGCCallback(mJSRuntime, GCCallback, this);
|
JS_SetGCCallback(mJSRuntime, GCCallback, this);
|
||||||
JS_SetContextCallback(mJSRuntime, ContextCallback, this);
|
JS_SetContextCallback(mJSRuntime, ContextCallback, this);
|
||||||
|
JS_SetDestroyZoneCallback(mJSRuntime, XPCStringConvert::FreeZoneCache);
|
||||||
|
JS_SetSweepZoneCallback(mJSRuntime, XPCStringConvert::ClearZoneCache);
|
||||||
|
|
||||||
nsCycleCollector_registerJSRuntime(this);
|
nsCycleCollector_registerJSRuntime(this);
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче