mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 07:13:20 +00:00
Merge mozilla-central to autoland
This commit is contained in:
commit
e6b2438e24
@ -114,7 +114,7 @@ oddly_ordered_inclnames = set([
|
||||
'frontend/ReservedWordsGenerated.h', # Included in the body of frontend/TokenStream.h
|
||||
'gc/StatsPhasesGenerated.h', # Included in the body of gc/Statistics.h
|
||||
'gc/StatsPhasesGenerated.cpp', # Included in the body of gc/Statistics.cpp
|
||||
'jswin.h', # Must be #included before <psapi.h>
|
||||
'util/Windows.h', # Must be #included before <psapi.h>
|
||||
'machine/endian.h', # Must be included after <sys/types.h> on BSD
|
||||
'winbase.h', # Must precede other system headers(?)
|
||||
'windef.h' # Must precede other system headers(?)
|
||||
|
@ -101,6 +101,7 @@ support-files =
|
||||
[browser_dbg-asm.js]
|
||||
[browser_dbg-async-stepping.js]
|
||||
[browser_dbg-babel.js]
|
||||
skip-if = (os == "win" && ccov) # bug 1438797
|
||||
[browser_dbg-breaking.js]
|
||||
[browser_dbg-breaking-from-console.js]
|
||||
[browser_dbg-breakpoints.js]
|
||||
|
@ -303,6 +303,7 @@ define(function (require, exports, module) {
|
||||
dom.a({
|
||||
id: id ? id + "-tab" : "tab-" + index,
|
||||
tabIndex: isTabSelected ? 0 : -1,
|
||||
title,
|
||||
"aria-controls": id ? id + "-panel" : "panel-" + index,
|
||||
"aria-selected": isTabSelected,
|
||||
role: "tab",
|
||||
|
@ -908,24 +908,44 @@ let SourceActor = ActorClassWithSpec(sourceSpec, {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Compute columnToOffsetMaps for each script so that we can
|
||||
// find matching entrypoints for the column breakpoint.
|
||||
const columnToOffsetMaps = scripts.map(script =>
|
||||
[
|
||||
script,
|
||||
script.getAllColumnOffsets()
|
||||
.filter(({ lineNumber }) => lineNumber === generatedLine)
|
||||
]
|
||||
);
|
||||
|
||||
// This is a column breakpoint, so we are interested in all column
|
||||
// offsets that correspond to the given line *and* column number.
|
||||
for (let script of scripts) {
|
||||
let columnToOffsetMap = script.getAllColumnOffsets()
|
||||
.filter(({ lineNumber }) => {
|
||||
return lineNumber === generatedLine;
|
||||
});
|
||||
for (let [script, columnToOffsetMap] of columnToOffsetMaps) {
|
||||
for (let { columnNumber: column, offset } of columnToOffsetMap) {
|
||||
if (column >= generatedColumn && column <= generatedLastColumn) {
|
||||
entryPoints.push({ script, offsets: [offset] });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we don't find any matching entrypoints, then
|
||||
// we should check to see if the breakpoint is to the left of the first offset.
|
||||
if (entryPoints.length === 0) {
|
||||
for (let [script, columnToOffsetMap] of columnToOffsetMaps) {
|
||||
if (columnToOffsetMap.length > 0) {
|
||||
let { columnNumber: column, offset } = columnToOffsetMap[0];
|
||||
if (generatedColumn < column) {
|
||||
entryPoints.push({ script, offsets: [offset] });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (entryPoints.length === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
setBreakpointAtEntryPoints(actor, entryPoints);
|
||||
return true;
|
||||
}
|
||||
|
@ -0,0 +1,64 @@
|
||||
"use strict";
|
||||
|
||||
var SOURCE_URL = getFileUrl("setBreakpoint-on-column.js");
|
||||
|
||||
function run_test() {
|
||||
return async function () {
|
||||
do_test_pending();
|
||||
|
||||
DebuggerServer.registerModule("xpcshell-test/testactors");
|
||||
DebuggerServer.init(() => true);
|
||||
|
||||
let global = createTestGlobal("test");
|
||||
DebuggerServer.addTestGlobal(global);
|
||||
|
||||
let client = new DebuggerClient(DebuggerServer.connectPipe());
|
||||
await connect(client);
|
||||
|
||||
let { tabs } = await listTabs(client);
|
||||
let tab = findTab(tabs, "test");
|
||||
let [, tabClient] = await attachTab(client, tab);
|
||||
let [, threadClient] = await attachThread(tabClient);
|
||||
await resume(threadClient);
|
||||
|
||||
let promise = waitForNewSource(threadClient, SOURCE_URL);
|
||||
loadSubScript(SOURCE_URL, global);
|
||||
let { source } = await promise;
|
||||
let sourceClient = threadClient.source(source);
|
||||
|
||||
let location = { line: 4, column: 2 };
|
||||
let [packet, breakpointClient] = await setBreakpoint(
|
||||
sourceClient,
|
||||
location
|
||||
);
|
||||
|
||||
Assert.ok(!packet.isPending);
|
||||
Assert.equal(false, "actualLocation" in packet);
|
||||
|
||||
packet = await executeOnNextTickAndWaitForPause(function () {
|
||||
Cu.evalInSandbox("f()", global);
|
||||
}, client);
|
||||
|
||||
Assert.equal(packet.type, "paused");
|
||||
let why = packet.why;
|
||||
Assert.equal(why.type, "breakpoint");
|
||||
Assert.equal(why.actors.length, 1);
|
||||
Assert.equal(why.actors[0], breakpointClient.actor);
|
||||
|
||||
let frame = packet.frame;
|
||||
let where = frame.where;
|
||||
Assert.equal(where.source.actor, source.actor);
|
||||
Assert.equal(where.line, location.line);
|
||||
Assert.equal(where.column, 6);
|
||||
|
||||
let variables = frame.environment.bindings.variables;
|
||||
Assert.equal(variables.a.value.type, "undefined");
|
||||
Assert.equal(variables.b.value.type, "undefined");
|
||||
Assert.equal(variables.c.value.type, "undefined");
|
||||
|
||||
await resume(threadClient);
|
||||
await close(client);
|
||||
|
||||
do_test_finished();
|
||||
};
|
||||
}
|
@ -222,6 +222,7 @@ reason = bug 937197
|
||||
[test_get-executable-lines-source-map.js]
|
||||
[test_xpcshell_debugging.js]
|
||||
support-files = xpcshell_debugging_script.js
|
||||
[test_setBreakpoint-at-the-beginning-of-a-line.js]
|
||||
[test_setBreakpoint-on-column.js]
|
||||
[test_setBreakpoint-on-column-in-gcd-script.js]
|
||||
[test_setBreakpoint-on-column-with-no-offsets-at-end-of-line.js]
|
||||
|
@ -9,6 +9,8 @@
|
||||
#include "mozilla/dom/StyleSheetList.h"
|
||||
#include "nsDocument.h"
|
||||
#include "nsFocusManager.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsSVGUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@ -166,5 +168,120 @@ DocumentOrShadowRoot::GetFullscreenElement()
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Element*
|
||||
DocumentOrShadowRoot::ElementFromPoint(float aX, float aY)
|
||||
{
|
||||
return ElementFromPointHelper(aX, aY, false, true);
|
||||
}
|
||||
|
||||
void
|
||||
DocumentOrShadowRoot::ElementsFromPoint(float aX, float aY,
|
||||
nsTArray<RefPtr<Element>>& aElements)
|
||||
{
|
||||
ElementsFromPointHelper(aX, aY, nsIDocument::FLUSH_LAYOUT, aElements);
|
||||
}
|
||||
|
||||
Element*
|
||||
DocumentOrShadowRoot::ElementFromPointHelper(float aX, float aY,
|
||||
bool aIgnoreRootScrollFrame,
|
||||
bool aFlushLayout)
|
||||
{
|
||||
AutoTArray<RefPtr<Element>, 1> elementArray;
|
||||
ElementsFromPointHelper(aX, aY,
|
||||
((aIgnoreRootScrollFrame ? nsIDocument::IGNORE_ROOT_SCROLL_FRAME : 0) |
|
||||
(aFlushLayout ? nsIDocument::FLUSH_LAYOUT : 0) |
|
||||
nsIDocument::IS_ELEMENT_FROM_POINT),
|
||||
elementArray);
|
||||
if (elementArray.IsEmpty()) {
|
||||
return nullptr;
|
||||
}
|
||||
return elementArray[0];
|
||||
}
|
||||
|
||||
void
|
||||
DocumentOrShadowRoot::ElementsFromPointHelper(float aX, float aY,
|
||||
uint32_t aFlags,
|
||||
nsTArray<RefPtr<mozilla::dom::Element>>& aElements)
|
||||
{
|
||||
// As per the the spec, we return null if either coord is negative
|
||||
if (!(aFlags & nsIDocument::IGNORE_ROOT_SCROLL_FRAME) && (aX < 0 || aY < 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nscoord x = nsPresContext::CSSPixelsToAppUnits(aX);
|
||||
nscoord y = nsPresContext::CSSPixelsToAppUnits(aY);
|
||||
nsPoint pt(x, y);
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = AsNode().OwnerDoc();
|
||||
|
||||
// Make sure the layout information we get is up-to-date, and
|
||||
// ensure we get a root frame (for everything but XUL)
|
||||
if (aFlags & nsIDocument::FLUSH_LAYOUT) {
|
||||
doc->FlushPendingNotifications(FlushType::Layout);
|
||||
}
|
||||
|
||||
nsIPresShell* ps = doc->GetShell();
|
||||
if (!ps) {
|
||||
return;
|
||||
}
|
||||
nsIFrame* rootFrame = ps->GetRootFrame();
|
||||
|
||||
// XUL docs, unlike HTML, have no frame tree until everything's done loading
|
||||
if (!rootFrame) {
|
||||
return; // return null to premature XUL callers as a reminder to wait
|
||||
}
|
||||
|
||||
nsTArray<nsIFrame*> outFrames;
|
||||
// Emulate what GetFrameAtPoint does, since we want all the frames under our
|
||||
// point.
|
||||
nsLayoutUtils::GetFramesForArea(rootFrame, nsRect(pt, nsSize(1, 1)), outFrames,
|
||||
nsLayoutUtils::IGNORE_PAINT_SUPPRESSION | nsLayoutUtils::IGNORE_CROSS_DOC |
|
||||
((aFlags & nsIDocument::IGNORE_ROOT_SCROLL_FRAME) ? nsLayoutUtils::IGNORE_ROOT_SCROLL_FRAME : 0));
|
||||
|
||||
// Dunno when this would ever happen, as we should at least have a root frame under us?
|
||||
if (outFrames.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Used to filter out repeated elements in sequence.
|
||||
nsIContent* lastAdded = nullptr;
|
||||
|
||||
for (uint32_t i = 0; i < outFrames.Length(); i++) {
|
||||
nsIContent* node = doc->GetContentInThisDocument(outFrames[i]);
|
||||
|
||||
if (!node || !node->IsElement()) {
|
||||
// If this helper is called via ElementsFromPoint, we need to make sure
|
||||
// our frame is an element. Otherwise return whatever the top frame is
|
||||
// even if it isn't the top-painted element.
|
||||
// SVG 'text' element's SVGTextFrame doesn't respond to hit-testing, so
|
||||
// if 'node' is a child of such an element then we need to manually defer
|
||||
// to the parent here.
|
||||
if (!(aFlags & nsIDocument::IS_ELEMENT_FROM_POINT) &&
|
||||
!nsSVGUtils::IsInSVGTextSubtree(outFrames[i])) {
|
||||
continue;
|
||||
}
|
||||
node = node->GetParent();
|
||||
if (ShadowRoot* shadow = ShadowRoot::FromNodeOrNull(node)) {
|
||||
node = shadow->Host();
|
||||
}
|
||||
}
|
||||
|
||||
//XXXsmaug There is plenty of unspec'ed behavior here
|
||||
// https://github.com/w3c/webcomponents/issues/735
|
||||
// https://github.com/w3c/webcomponents/issues/736
|
||||
node = Retarget(node);
|
||||
|
||||
if (node && node != lastAdded) {
|
||||
aElements.AppendElement(node->AsElement());
|
||||
lastAdded = node;
|
||||
// If this helper is called via ElementFromPoint, just return the first
|
||||
// element we find.
|
||||
if (aFlags & nsIDocument::IS_ELEMENT_FROM_POINT) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -115,6 +115,30 @@ public:
|
||||
|
||||
Element* GetPointerLockElement();
|
||||
Element* GetFullscreenElement();
|
||||
|
||||
Element* ElementFromPoint(float aX, float aY);
|
||||
void ElementsFromPoint(float aX, float aY,
|
||||
nsTArray<RefPtr<mozilla::dom::Element>>& aElements);
|
||||
|
||||
/**
|
||||
* Helper for nsIDOMDocument::elementFromPoint implementation that allows
|
||||
* ignoring the scroll frame and/or avoiding layout flushes.
|
||||
*
|
||||
* @see nsIDOMWindowUtils::elementFromPoint
|
||||
*/
|
||||
Element* ElementFromPointHelper(float aX, float aY,
|
||||
bool aIgnoreRootScrollFrame,
|
||||
bool aFlushLayout);
|
||||
enum ElementsFromPointFlags
|
||||
{
|
||||
IGNORE_ROOT_SCROLL_FRAME = 1,
|
||||
FLUSH_LAYOUT = 2,
|
||||
IS_ELEMENT_FROM_POINT = 4
|
||||
};
|
||||
|
||||
void ElementsFromPointHelper(float aX, float aY, uint32_t aFlags,
|
||||
nsTArray<RefPtr<mozilla::dom::Element>>& aElements);
|
||||
|
||||
protected:
|
||||
nsIContent* Retarget(nsIContent* aContent) const;
|
||||
|
||||
|
@ -3726,7 +3726,7 @@ Element::GetTransformToAncestor(Element& aAncestor)
|
||||
// then the call to GetTransformToAncestor will return the transform
|
||||
// all the way up through the parent chain.
|
||||
transform = nsLayoutUtils::GetTransformToAncestor(primaryFrame,
|
||||
ancestorFrame, nsIFrame::IN_CSS_UNITS);
|
||||
ancestorFrame, nsIFrame::IN_CSS_UNITS).GetMatrix();
|
||||
}
|
||||
|
||||
DOMMatrixReadOnly* matrix = new DOMMatrix(this, transform, IsStyledByServo());
|
||||
@ -3743,7 +3743,7 @@ Element::GetTransformToParent()
|
||||
if (primaryFrame) {
|
||||
nsIFrame* parentFrame = primaryFrame->GetParent();
|
||||
transform = nsLayoutUtils::GetTransformToAncestor(primaryFrame,
|
||||
parentFrame, nsIFrame::IN_CSS_UNITS);
|
||||
parentFrame, nsIFrame::IN_CSS_UNITS).GetMatrix();
|
||||
}
|
||||
|
||||
DOMMatrixReadOnly* matrix = new DOMMatrix(this, transform, IsStyledByServo());
|
||||
@ -3758,7 +3758,7 @@ Element::GetTransformToViewport()
|
||||
Matrix4x4 transform;
|
||||
if (primaryFrame) {
|
||||
transform = nsLayoutUtils::GetTransformToAncestor(primaryFrame,
|
||||
nsLayoutUtils::GetDisplayRootFrame(primaryFrame), nsIFrame::IN_CSS_UNITS);
|
||||
nsLayoutUtils::GetDisplayRootFrame(primaryFrame), nsIFrame::IN_CSS_UNITS).GetMatrix();
|
||||
}
|
||||
|
||||
DOMMatrixReadOnly* matrix = new DOMMatrix(this, transform, IsStyledByServo());
|
||||
|
@ -3544,110 +3544,6 @@ nsIDocument::GetCurrentScript()
|
||||
return el;
|
||||
}
|
||||
|
||||
Element*
|
||||
nsIDocument::ElementFromPoint(float aX, float aY)
|
||||
{
|
||||
return ElementFromPointHelper(aX, aY, false, true);
|
||||
}
|
||||
|
||||
void
|
||||
nsIDocument::ElementsFromPoint(float aX, float aY,
|
||||
nsTArray<RefPtr<Element>>& aElements)
|
||||
{
|
||||
ElementsFromPointHelper(aX, aY, nsIDocument::FLUSH_LAYOUT, aElements);
|
||||
}
|
||||
|
||||
Element*
|
||||
nsDocument::ElementFromPointHelper(float aX, float aY,
|
||||
bool aIgnoreRootScrollFrame,
|
||||
bool aFlushLayout)
|
||||
{
|
||||
AutoTArray<RefPtr<Element>, 1> elementArray;
|
||||
ElementsFromPointHelper(aX, aY,
|
||||
((aIgnoreRootScrollFrame ? nsIDocument::IGNORE_ROOT_SCROLL_FRAME : 0) |
|
||||
(aFlushLayout ? nsIDocument::FLUSH_LAYOUT : 0) |
|
||||
nsIDocument::IS_ELEMENT_FROM_POINT),
|
||||
elementArray);
|
||||
if (elementArray.IsEmpty()) {
|
||||
return nullptr;
|
||||
}
|
||||
return elementArray[0];
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::ElementsFromPointHelper(float aX, float aY,
|
||||
uint32_t aFlags,
|
||||
nsTArray<RefPtr<mozilla::dom::Element>>& aElements)
|
||||
{
|
||||
// As per the the spec, we return null if either coord is negative
|
||||
if (!(aFlags & nsIDocument::IGNORE_ROOT_SCROLL_FRAME) && (aX < 0 || aY < 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nscoord x = nsPresContext::CSSPixelsToAppUnits(aX);
|
||||
nscoord y = nsPresContext::CSSPixelsToAppUnits(aY);
|
||||
nsPoint pt(x, y);
|
||||
|
||||
// Make sure the layout information we get is up-to-date, and
|
||||
// ensure we get a root frame (for everything but XUL)
|
||||
if (aFlags & nsIDocument::FLUSH_LAYOUT) {
|
||||
FlushPendingNotifications(FlushType::Layout);
|
||||
}
|
||||
|
||||
nsIPresShell *ps = GetShell();
|
||||
if (!ps) {
|
||||
return;
|
||||
}
|
||||
nsIFrame *rootFrame = ps->GetRootFrame();
|
||||
|
||||
// XUL docs, unlike HTML, have no frame tree until everything's done loading
|
||||
if (!rootFrame) {
|
||||
return; // return null to premature XUL callers as a reminder to wait
|
||||
}
|
||||
|
||||
nsTArray<nsIFrame*> outFrames;
|
||||
// Emulate what GetFrameAtPoint does, since we want all the frames under our
|
||||
// point.
|
||||
nsLayoutUtils::GetFramesForArea(rootFrame, nsRect(pt, nsSize(1, 1)), outFrames,
|
||||
nsLayoutUtils::IGNORE_PAINT_SUPPRESSION | nsLayoutUtils::IGNORE_CROSS_DOC |
|
||||
((aFlags & nsIDocument::IGNORE_ROOT_SCROLL_FRAME) ? nsLayoutUtils::IGNORE_ROOT_SCROLL_FRAME : 0));
|
||||
|
||||
// Dunno when this would ever happen, as we should at least have a root frame under us?
|
||||
if (outFrames.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Used to filter out repeated elements in sequence.
|
||||
nsIContent* lastAdded = nullptr;
|
||||
|
||||
for (uint32_t i = 0; i < outFrames.Length(); i++) {
|
||||
nsIContent* node = GetContentInThisDocument(outFrames[i]);
|
||||
|
||||
if (!node || !node->IsElement()) {
|
||||
// If this helper is called via ElementsFromPoint, we need to make sure
|
||||
// our frame is an element. Otherwise return whatever the top frame is
|
||||
// even if it isn't the top-painted element.
|
||||
// SVG 'text' element's SVGTextFrame doesn't respond to hit-testing, so
|
||||
// if 'node' is a child of such an element then we need to manually defer
|
||||
// to the parent here.
|
||||
if (!(aFlags & nsIDocument::IS_ELEMENT_FROM_POINT) &&
|
||||
!nsSVGUtils::IsInSVGTextSubtree(outFrames[i])) {
|
||||
continue;
|
||||
}
|
||||
node = node->GetParent();
|
||||
}
|
||||
if (node && node != lastAdded) {
|
||||
aElements.AppendElement(node->AsElement());
|
||||
lastAdded = node;
|
||||
// If this helper is called via ElementFromPoint, just return the first
|
||||
// element we find.
|
||||
if (aFlags & nsIDocument::IS_ELEMENT_FROM_POINT) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDocument::NodesFromRectHelper(float aX, float aY,
|
||||
float aTopSize, float aRightSize,
|
||||
@ -8539,7 +8435,7 @@ nsDocument::DoUnblockOnload()
|
||||
}
|
||||
|
||||
nsIContent*
|
||||
nsDocument::GetContentInThisDocument(nsIFrame* aFrame) const
|
||||
nsIDocument::GetContentInThisDocument(nsIFrame* aFrame) const
|
||||
{
|
||||
for (nsIFrame* f = aFrame; f;
|
||||
f = nsLayoutUtils::GetParentOrPlaceholderForCrossDoc(f)) {
|
||||
|
@ -690,14 +690,6 @@ public:
|
||||
nsAtom* aAttrName,
|
||||
const nsAString& aAttrValue) const override;
|
||||
|
||||
virtual Element* ElementFromPointHelper(float aX, float aY,
|
||||
bool aIgnoreRootScrollFrame,
|
||||
bool aFlushLayout) override;
|
||||
|
||||
virtual void ElementsFromPointHelper(float aX, float aY,
|
||||
uint32_t aFlags,
|
||||
nsTArray<RefPtr<mozilla::dom::Element>>& aElements) override;
|
||||
|
||||
virtual nsresult NodesFromRectHelper(float aX, float aY,
|
||||
float aTopSize, float aRightSize,
|
||||
float aBottomSize, float aLeftSize,
|
||||
@ -1225,16 +1217,6 @@ private:
|
||||
|
||||
nsresult InitCSP(nsIChannel* aChannel);
|
||||
|
||||
/**
|
||||
* Find the (non-anonymous) content in this document for aFrame. It will
|
||||
* be aFrame's content node if that content is in this document and not
|
||||
* anonymous. Otherwise, when aFrame is in a subdocument, we use the frame
|
||||
* element containing the subdocument containing aFrame, and/or find the
|
||||
* nearest non-anonymous ancestor in this document.
|
||||
* Returns null if there is no such element.
|
||||
*/
|
||||
nsIContent* GetContentInThisDocument(nsIFrame* aFrame) const;
|
||||
|
||||
// Just like EnableStyleSheetsForSet, but doesn't check whether
|
||||
// aSheetSet is null and allows the caller to control whether to set
|
||||
// aSheetSet as the preferred set in the CSSLoader.
|
||||
|
@ -2096,26 +2096,6 @@ public:
|
||||
nsAtom* aAttrName,
|
||||
const nsAString& aAttrValue) const = 0;
|
||||
|
||||
/**
|
||||
* Helper for nsIDOMDocument::elementFromPoint implementation that allows
|
||||
* ignoring the scroll frame and/or avoiding layout flushes.
|
||||
*
|
||||
* @see nsIDOMWindowUtils::elementFromPoint
|
||||
*/
|
||||
virtual Element* ElementFromPointHelper(float aX, float aY,
|
||||
bool aIgnoreRootScrollFrame,
|
||||
bool aFlushLayout) = 0;
|
||||
|
||||
enum ElementsFromPointFlags {
|
||||
IGNORE_ROOT_SCROLL_FRAME = 1,
|
||||
FLUSH_LAYOUT = 2,
|
||||
IS_ELEMENT_FROM_POINT = 4
|
||||
};
|
||||
|
||||
virtual void ElementsFromPointHelper(float aX, float aY,
|
||||
uint32_t aFlags,
|
||||
nsTArray<RefPtr<mozilla::dom::Element>>& aElements) = 0;
|
||||
|
||||
virtual nsresult NodesFromRectHelper(float aX, float aY,
|
||||
float aTopSize, float aRightSize,
|
||||
float aBottomSize, float aLeftSize,
|
||||
@ -2955,10 +2935,6 @@ public:
|
||||
void GetPreferredStyleSheetSet(nsAString& aSheetSet);
|
||||
virtual mozilla::dom::DOMStringList* StyleSheetSets() = 0;
|
||||
virtual void EnableStyleSheetsForSet(const nsAString& aSheetSet) = 0;
|
||||
Element* ElementFromPoint(float aX, float aY);
|
||||
void ElementsFromPoint(float aX,
|
||||
float aY,
|
||||
nsTArray<RefPtr<mozilla::dom::Element>>& aElements);
|
||||
|
||||
/**
|
||||
* Retrieve the location of the caret position (DOM node and character
|
||||
@ -3210,6 +3186,16 @@ public:
|
||||
|
||||
bool ModuleScriptsEnabled();
|
||||
|
||||
/**
|
||||
* Find the (non-anonymous) content in this document for aFrame. It will
|
||||
* be aFrame's content node if that content is in this document and not
|
||||
* anonymous. Otherwise, when aFrame is in a subdocument, we use the frame
|
||||
* element containing the subdocument containing aFrame, and/or find the
|
||||
* nearest non-anonymous ancestor in this document.
|
||||
* Returns null if there is no such element.
|
||||
*/
|
||||
nsIContent* GetContentInThisDocument(nsIFrame* aFrame) const;
|
||||
|
||||
protected:
|
||||
bool GetUseCounter(mozilla::UseCounter aUseCounter)
|
||||
{
|
||||
|
@ -285,8 +285,6 @@ partial interface Document {
|
||||
|
||||
// http://dev.w3.org/csswg/cssom-view/#extensions-to-the-document-interface
|
||||
partial interface Document {
|
||||
Element? elementFromPoint (float x, float y);
|
||||
sequence<Element> elementsFromPoint (float x, float y);
|
||||
CaretPosition? caretPositionFromPoint (float x, float y);
|
||||
|
||||
readonly attribute Element? scrollingElement;
|
||||
|
@ -12,10 +12,8 @@
|
||||
interface DocumentOrShadowRoot {
|
||||
// Not implemented yet: bug 1430308.
|
||||
// Selection? getSelection();
|
||||
// Not implemented yet: bug 1430301.
|
||||
// Element? elementFromPoint (float x, float y);
|
||||
// Not implemented yet: bug 1430301.
|
||||
// sequence<Element> elementsFromPoint (float x, float y);
|
||||
Element? elementFromPoint (float x, float y);
|
||||
sequence<Element> elementsFromPoint (float x, float y);
|
||||
// Not implemented yet: bug 1430307.
|
||||
// CaretPosition? caretPositionFromPoint (float x, float y);
|
||||
|
||||
|
410
gfx/2d/Matrix.h
410
gfx/2d/Matrix.h
@ -1851,6 +1851,416 @@ public:
|
||||
};
|
||||
};
|
||||
|
||||
/* This Matrix class will carry one additional type field in order to
|
||||
* track what type of 4x4 matrix we're dealing with, it can then execute
|
||||
* simplified versions of certain operations when applicable.
|
||||
* This does not allow access to the parent class directly, as a caller
|
||||
* could then mutate the parent class without updating the type.
|
||||
*/
|
||||
template <typename SourceUnits, typename TargetUnits>
|
||||
class Matrix4x4TypedFlagged : protected Matrix4x4Typed<SourceUnits, TargetUnits>
|
||||
{
|
||||
public:
|
||||
using Parent = Matrix4x4Typed<SourceUnits, TargetUnits>;
|
||||
using TargetPoint = PointTyped<TargetUnits>;
|
||||
using Parent::_11; using Parent::_12; using Parent::_13; using Parent::_14;
|
||||
using Parent::_21; using Parent::_22; using Parent::_23; using Parent::_24;
|
||||
using Parent::_31; using Parent::_32; using Parent::_33; using Parent::_34;
|
||||
using Parent::_41; using Parent::_42; using Parent::_43; using Parent::_44;
|
||||
|
||||
Matrix4x4TypedFlagged()
|
||||
: mType(MatrixType::Identity)
|
||||
{}
|
||||
|
||||
Matrix4x4TypedFlagged(Float a11, Float a12, Float a13, Float a14,
|
||||
Float a21, Float a22, Float a23, Float a24,
|
||||
Float a31, Float a32, Float a33, Float a34,
|
||||
Float a41, Float a42, Float a43, Float a44)
|
||||
: Parent(a11, a12, a13, a14, a21, a22, a23, a24,
|
||||
a31, a32, a33, a34, a41, a42, a43, a44)
|
||||
{
|
||||
Analyze();
|
||||
}
|
||||
|
||||
MOZ_IMPLICIT Matrix4x4TypedFlagged(const Parent& aOther)
|
||||
: Parent(aOther)
|
||||
{
|
||||
Analyze();
|
||||
}
|
||||
|
||||
template<class F>
|
||||
PointTyped<TargetUnits, F> TransformPoint(const PointTyped<SourceUnits, F> &aPoint) const
|
||||
{
|
||||
if (mType == MatrixType::Identity) {
|
||||
return aPoint;
|
||||
}
|
||||
|
||||
if (mType == MatrixType::Simple) {
|
||||
return TransformPointSimple(aPoint);
|
||||
}
|
||||
|
||||
return Parent::TransformPoint(aPoint);
|
||||
}
|
||||
|
||||
template<class F>
|
||||
RectTyped<TargetUnits, F> TransformAndClipBounds(const RectTyped<SourceUnits, F>& aRect,
|
||||
const RectTyped<TargetUnits, F>& aClip) const
|
||||
{
|
||||
if (mType == MatrixType::Identity) {
|
||||
return aRect;
|
||||
}
|
||||
|
||||
if (mType == MatrixType::Simple) {
|
||||
PointTyped<UnknownUnits, F> p1 = TransformPointSimple(aRect.TopLeft());
|
||||
PointTyped<UnknownUnits, F> p2 = TransformPointSimple(aRect.TopRight());
|
||||
PointTyped<UnknownUnits, F> p3 = TransformPointSimple(aRect.BottomLeft());
|
||||
PointTyped<UnknownUnits, F> p4 = TransformPointSimple(aRect.BottomRight());
|
||||
|
||||
F min_x = std::min(std::min(std::min(p1.x, p2.x), p3.x), p4.x);
|
||||
F max_x = std::max(std::max(std::max(p1.x, p2.x), p3.x), p4.x);
|
||||
F min_y = std::min(std::min(std::min(p1.y, p2.y), p3.y), p4.y);
|
||||
F max_y = std::max(std::max(std::max(p1.y, p2.y), p3.y), p4.y);
|
||||
|
||||
TargetPoint topLeft(std::max(min_x, aClip.x), std::max(min_y, aClip.y));
|
||||
F xMost = std::min(max_x, aClip.XMost()) - topLeft.x;
|
||||
F yMost = std::min(max_y, aClip.YMost()) - topLeft.y;
|
||||
|
||||
return RectTyped<TargetUnits, F>(topLeft.x, topLeft.y, xMost, yMost);
|
||||
}
|
||||
return Parent::TransformAndClipBounds(aRect, aClip);
|
||||
}
|
||||
|
||||
bool FuzzyEqual(const Parent& o) const
|
||||
{
|
||||
return Parent::FuzzyEqual(o);
|
||||
}
|
||||
|
||||
bool FuzzyEqual(const Matrix4x4TypedFlagged& o) const
|
||||
{
|
||||
if (mType == MatrixType::Identity && o.mType == MatrixType::Identity) {
|
||||
return true;
|
||||
}
|
||||
return Parent::FuzzyEqual(o);
|
||||
}
|
||||
|
||||
Matrix4x4TypedFlagged &PreTranslate(Float aX, Float aY, Float aZ)
|
||||
{
|
||||
if (mType == MatrixType::Identity) {
|
||||
_41 = aX;
|
||||
_42 = aY;
|
||||
_43 = aZ;
|
||||
|
||||
if (!aZ) {
|
||||
mType = MatrixType::Simple;
|
||||
return *this;
|
||||
}
|
||||
mType = MatrixType::Full;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Parent::PreTranslate(aX, aY, aZ);
|
||||
|
||||
if (aZ != 0) {
|
||||
mType = MatrixType::Full;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Matrix4x4TypedFlagged &PostTranslate(Float aX, Float aY, Float aZ)
|
||||
{
|
||||
if (mType == MatrixType::Identity) {
|
||||
_41 = aX;
|
||||
_42 = aY;
|
||||
_43 = aZ;
|
||||
|
||||
if (!aZ) {
|
||||
mType = MatrixType::Simple;
|
||||
return *this;
|
||||
}
|
||||
mType = MatrixType::Full;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Parent::PostTranslate(aX, aY, aZ);
|
||||
|
||||
if (aZ != 0) {
|
||||
mType = MatrixType::Full;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Matrix4x4TypedFlagged &ChangeBasis(Float aX, Float aY, Float aZ)
|
||||
{
|
||||
// Translate to the origin before applying this matrix
|
||||
PreTranslate(-aX, -aY, -aZ);
|
||||
|
||||
// Translate back into position after applying this matrix
|
||||
PostTranslate(aX, aY, aZ);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool IsIdentity() const
|
||||
{
|
||||
return mType == MatrixType::Identity;
|
||||
}
|
||||
|
||||
template<class F>
|
||||
Point4DTyped<TargetUnits, F>
|
||||
ProjectPoint(const PointTyped<SourceUnits, F>& aPoint) const {
|
||||
if (mType == MatrixType::Identity) {
|
||||
return Point4DTyped<TargetUnits, F>(aPoint.x, aPoint.y, 0, 1);
|
||||
}
|
||||
|
||||
if (mType == MatrixType::Simple) {
|
||||
TargetPoint point = TransformPointSimple(aPoint);
|
||||
return Point4DTyped<TargetUnits, F>(point.x, point.y, 0, 1);
|
||||
}
|
||||
|
||||
return Parent::ProjectPoint(aPoint);
|
||||
}
|
||||
|
||||
Matrix4x4TypedFlagged& ProjectTo2D() {
|
||||
if (mType == MatrixType::Full) {
|
||||
Parent::ProjectTo2D();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool IsSingular() const
|
||||
{
|
||||
if (mType == MatrixType::Identity) {
|
||||
return false;
|
||||
}
|
||||
return Parent::Determinant() == 0.0;
|
||||
}
|
||||
|
||||
bool Invert()
|
||||
{
|
||||
if (mType == MatrixType::Identity) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return Parent::Invert();
|
||||
}
|
||||
|
||||
Matrix4x4TypedFlagged<TargetUnits, SourceUnits> Inverse() const
|
||||
{
|
||||
typedef Matrix4x4TypedFlagged<TargetUnits, SourceUnits> InvertedMatrix;
|
||||
InvertedMatrix clone = InvertedMatrix::FromUnknownMatrix(ToUnknownMatrix());
|
||||
if (mType == MatrixType::Identity) {
|
||||
return clone;
|
||||
}
|
||||
DebugOnly<bool> inverted = clone.Invert();
|
||||
MOZ_ASSERT(inverted, "Attempted to get the inverse of a non-invertible matrix");
|
||||
|
||||
// Inverting a 2D Matrix should result in a 2D matrix, ergo mType doesn't change.
|
||||
return clone;
|
||||
}
|
||||
|
||||
template <typename NewTargetUnits>
|
||||
Matrix4x4TypedFlagged<SourceUnits, NewTargetUnits> operator*(const Matrix4x4Typed<TargetUnits, NewTargetUnits> &aMatrix) const
|
||||
{
|
||||
if (mType == MatrixType::Identity) {
|
||||
return aMatrix;
|
||||
}
|
||||
|
||||
if (mType == MatrixType::Simple) {
|
||||
Matrix4x4TypedFlagged<SourceUnits, NewTargetUnits> matrix;
|
||||
matrix._11 = _11 * aMatrix._11 + _12 * aMatrix._21;
|
||||
matrix._21 = _21 * aMatrix._11 + _22 * aMatrix._21;
|
||||
matrix._31 = aMatrix._31;
|
||||
matrix._41 = _41 * aMatrix._11 + _42 * aMatrix._21;
|
||||
matrix._12 = _11 * aMatrix._12 + _12 * aMatrix._22;
|
||||
matrix._22 = _21 * aMatrix._12 + _22 * aMatrix._22;
|
||||
matrix._32 = aMatrix._32;
|
||||
matrix._42 = _41 * aMatrix._12 + _42 * aMatrix._22;
|
||||
matrix._13 = _11 * aMatrix._13 + _12 * aMatrix._23;
|
||||
matrix._23 = _21 * aMatrix._13 + _22 * aMatrix._23;
|
||||
matrix._33 = aMatrix._33;
|
||||
matrix._43 = _41 * aMatrix._13 + _42 * aMatrix._23;
|
||||
matrix._14 = _11 * aMatrix._14 + _12 * aMatrix._24;
|
||||
matrix._24 = _21 * aMatrix._14 + _22 * aMatrix._24;
|
||||
matrix._34 = aMatrix._34;
|
||||
matrix._44 = _41 * aMatrix._14 + _42 * aMatrix._24;
|
||||
matrix.Analyze();
|
||||
return matrix;
|
||||
}
|
||||
|
||||
return Parent::operator*(aMatrix);
|
||||
}
|
||||
|
||||
template <typename NewTargetUnits>
|
||||
Matrix4x4TypedFlagged<SourceUnits, NewTargetUnits> operator*(const Matrix4x4TypedFlagged<TargetUnits, NewTargetUnits> &aMatrix) const
|
||||
{
|
||||
if (mType == MatrixType::Identity) {
|
||||
return aMatrix;
|
||||
}
|
||||
|
||||
if (aMatrix.mType == MatrixType::Identity) {
|
||||
return Matrix4x4TypedFlagged<SourceUnits, NewTargetUnits>::FromUnknownMatrix(this->ToUnknownMatrix());
|
||||
}
|
||||
|
||||
if (mType == MatrixType::Simple && aMatrix.mType == MatrixType::Simple) {
|
||||
Matrix4x4TypedFlagged<SourceUnits, NewTargetUnits> matrix;
|
||||
matrix._11 = _11 * aMatrix._11 + _12 * aMatrix._21;
|
||||
matrix._21 = _21 * aMatrix._11 + _22 * aMatrix._21;
|
||||
matrix._41 = _41 * aMatrix._11 + _42 * aMatrix._21 + aMatrix._41;
|
||||
matrix._12 = _11 * aMatrix._12 + _12 * aMatrix._22;
|
||||
matrix._22 = _21 * aMatrix._12 + _22 * aMatrix._22;
|
||||
matrix._42 = _41 * aMatrix._12 + _42 * aMatrix._22 + aMatrix._42;
|
||||
matrix.mType = MatrixType::Simple;
|
||||
return matrix;
|
||||
} else if (mType == MatrixType::Simple) {
|
||||
Matrix4x4TypedFlagged<SourceUnits, NewTargetUnits> matrix;
|
||||
matrix._11 = _11 * aMatrix._11 + _12 * aMatrix._21;
|
||||
matrix._21 = _21 * aMatrix._11 + _22 * aMatrix._21;
|
||||
matrix._31 = aMatrix._31;
|
||||
matrix._41 = _41 * aMatrix._11 + _42 * aMatrix._21 + aMatrix._41;
|
||||
matrix._12 = _11 * aMatrix._12 + _12 * aMatrix._22;
|
||||
matrix._22 = _21 * aMatrix._12 + _22 * aMatrix._22;
|
||||
matrix._32 = aMatrix._32;
|
||||
matrix._42 = _41 * aMatrix._12 + _42 * aMatrix._22 + aMatrix._42;
|
||||
matrix._13 = _11 * aMatrix._13 + _12 * aMatrix._23;
|
||||
matrix._23 = _21 * aMatrix._13 + _22 * aMatrix._23;
|
||||
matrix._33 = aMatrix._33;
|
||||
matrix._43 = _41 * aMatrix._13 + _42 * aMatrix._23 + aMatrix._43;
|
||||
matrix._14 = _11 * aMatrix._14 + _12 * aMatrix._24;
|
||||
matrix._24 = _21 * aMatrix._14 + _22 * aMatrix._24;
|
||||
matrix._34 = aMatrix._34;
|
||||
matrix._44 = _41 * aMatrix._14 + _42 * aMatrix._24 + aMatrix._44;
|
||||
matrix.mType = MatrixType::Full;
|
||||
return matrix;
|
||||
} else if (aMatrix.mType == MatrixType::Simple) {
|
||||
Matrix4x4TypedFlagged<SourceUnits, NewTargetUnits> matrix;
|
||||
matrix._11 = _11 * aMatrix._11 + _12 * aMatrix._21 + _14 * aMatrix._41;
|
||||
matrix._21 = _21 * aMatrix._11 + _22 * aMatrix._21 + _24 * aMatrix._41;
|
||||
matrix._31 = _31 * aMatrix._11 + _32 * aMatrix._21 + _34 * aMatrix._41;
|
||||
matrix._41 = _41 * aMatrix._11 + _42 * aMatrix._21 + _44 * aMatrix._41;
|
||||
matrix._12 = _11 * aMatrix._12 + _12 * aMatrix._22 + _14 * aMatrix._42;
|
||||
matrix._22 = _21 * aMatrix._12 + _22 * aMatrix._22 + _24 * aMatrix._42;
|
||||
matrix._32 = _31 * aMatrix._12 + _32 * aMatrix._22 + _34 * aMatrix._42;
|
||||
matrix._42 = _41 * aMatrix._12 + _42 * aMatrix._22 + _44 * aMatrix._42;
|
||||
matrix._13 = _13;
|
||||
matrix._23 = _23;
|
||||
matrix._33 = _33;
|
||||
matrix._43 = _43;
|
||||
matrix._14 = _14;
|
||||
matrix._24 = _24;
|
||||
matrix._34 = _34;
|
||||
matrix._44 = _44;
|
||||
matrix.mType = MatrixType::Full;
|
||||
return matrix;
|
||||
}
|
||||
|
||||
return Parent::operator*(aMatrix);
|
||||
}
|
||||
|
||||
bool Is2D() const
|
||||
{
|
||||
return mType != MatrixType::Full;
|
||||
}
|
||||
|
||||
bool CanDraw2D(Matrix* aMatrix = nullptr) const
|
||||
{
|
||||
if (mType != MatrixType::Full) {
|
||||
if (aMatrix) {
|
||||
aMatrix->_11 = _11;
|
||||
aMatrix->_12 = _12;
|
||||
aMatrix->_21 = _21;
|
||||
aMatrix->_22 = _22;
|
||||
aMatrix->_31 = _41;
|
||||
aMatrix->_32 = _42;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return Parent::CanDraw2D(aMatrix);
|
||||
}
|
||||
|
||||
bool Is2D(Matrix* aMatrix) const {
|
||||
if (!Is2D()) {
|
||||
return false;
|
||||
}
|
||||
if (aMatrix) {
|
||||
aMatrix->_11 = _11;
|
||||
aMatrix->_12 = _12;
|
||||
aMatrix->_21 = _21;
|
||||
aMatrix->_22 = _22;
|
||||
aMatrix->_31 = _41;
|
||||
aMatrix->_32 = _42;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class F>
|
||||
RectTyped<TargetUnits, F>
|
||||
ProjectRectBounds(const RectTyped<SourceUnits, F>& aRect, const RectTyped<TargetUnits, F>& aClip) const
|
||||
{
|
||||
return Parent::ProjectRectBounds(aRect, aClip);
|
||||
}
|
||||
|
||||
const Parent &GetMatrix() const { return *this; }
|
||||
private:
|
||||
enum class MatrixType : uint8_t
|
||||
{
|
||||
Identity,
|
||||
Simple, // 2x3 Matrix
|
||||
Full // 4x4 Matrix
|
||||
};
|
||||
|
||||
Matrix4x4TypedFlagged(Float a11, Float a12, Float a13, Float a14,
|
||||
Float a21, Float a22, Float a23, Float a24,
|
||||
Float a31, Float a32, Float a33, Float a34,
|
||||
Float a41, Float a42, Float a43, Float a44,
|
||||
typename Matrix4x4TypedFlagged::MatrixType aType)
|
||||
: Parent(a11, a12, a13, a14, a21, a22, a23, a24,
|
||||
a31, a32, a33, a34, a41, a42, a43, a44)
|
||||
{
|
||||
mType = aType;
|
||||
}
|
||||
static Matrix4x4TypedFlagged FromUnknownMatrix(const Matrix4x4Flagged& aUnknown) {
|
||||
return Matrix4x4TypedFlagged{ aUnknown._11, aUnknown._12, aUnknown._13, aUnknown._14,
|
||||
aUnknown._21, aUnknown._22, aUnknown._23, aUnknown._24,
|
||||
aUnknown._31, aUnknown._32, aUnknown._33, aUnknown._34,
|
||||
aUnknown._41, aUnknown._42, aUnknown._43, aUnknown._44, aUnknown.mType };
|
||||
}
|
||||
Matrix4x4Flagged ToUnknownMatrix() const {
|
||||
return Matrix4x4Flagged{ _11, _12, _13, _14,
|
||||
_21, _22, _23, _24,
|
||||
_31, _32, _33, _34,
|
||||
_41, _42, _43, _44, mType };
|
||||
}
|
||||
|
||||
template<class F>
|
||||
PointTyped<TargetUnits, F> TransformPointSimple(const PointTyped<SourceUnits, F> &aPoint) const
|
||||
{
|
||||
PointTyped<SourceUnits, F> temp;
|
||||
temp.x = aPoint.x * _11 + aPoint.y * +_21 + _41;
|
||||
temp.y = aPoint.x * _12 + aPoint.y * +_22 + _42;
|
||||
return temp;
|
||||
}
|
||||
|
||||
void Analyze() {
|
||||
if (Parent::IsIdentity()) {
|
||||
mType = MatrixType::Identity;
|
||||
return;
|
||||
}
|
||||
|
||||
if (Parent::Is2D()) {
|
||||
mType = MatrixType::Simple;
|
||||
return;
|
||||
}
|
||||
|
||||
mType = MatrixType::Full;
|
||||
}
|
||||
|
||||
MatrixType mType;
|
||||
};
|
||||
|
||||
using Matrix4x4Flagged = Matrix4x4TypedFlagged<UnknownUnits, UnknownUnits>;
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
||||
|
@ -27,8 +27,11 @@ struct UnknownUnits;
|
||||
|
||||
template<class SourceUnits, class TargetUnits>
|
||||
class Matrix4x4Typed;
|
||||
template<class SourceUnits, class TargetUnits>
|
||||
class Matrix4x4TypedFlagged;
|
||||
|
||||
typedef Matrix4x4Typed<UnknownUnits, UnknownUnits> Matrix4x4;
|
||||
typedef Matrix4x4TypedFlagged<UnknownUnits, UnknownUnits> Matrix4x4Flagged;
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
@ -259,6 +259,7 @@ public:
|
||||
POPLAYER,
|
||||
UNSCALEDFONTCREATION,
|
||||
UNSCALEDFONTDESTRUCTION,
|
||||
INTOLUMINANCE,
|
||||
};
|
||||
static const uint32_t kTotalEventTypes = RecordedEvent::FILTERNODESETINPUT + 1;
|
||||
|
||||
|
@ -905,7 +905,7 @@ class RecordedIntoLuminanceSource : public RecordedEventDerived<RecordedIntoLumi
|
||||
public:
|
||||
RecordedIntoLuminanceSource(ReferencePtr aRefPtr, DrawTarget *aDT,
|
||||
LuminanceType aLuminanceType, float aOpacity)
|
||||
: RecordedEventDerived(SNAPSHOT), mRefPtr(aRefPtr), mDT(aDT),
|
||||
: RecordedEventDerived(INTOLUMINANCE), mRefPtr(aRefPtr), mDT(aDT),
|
||||
mLuminanceType(aLuminanceType), mOpacity(aOpacity)
|
||||
{
|
||||
}
|
||||
@ -2800,7 +2800,7 @@ RecordedIntoLuminanceSource::Record(S &aStream) const
|
||||
|
||||
template<class S>
|
||||
RecordedIntoLuminanceSource::RecordedIntoLuminanceSource(S &aStream)
|
||||
: RecordedEventDerived(SNAPSHOT)
|
||||
: RecordedEventDerived(INTOLUMINANCE)
|
||||
{
|
||||
ReadElement(aStream, mRefPtr);
|
||||
ReadElement(aStream, mDT);
|
||||
@ -3413,7 +3413,8 @@ RecordedFilterNodeSetInput::OutputSimpleEventInfo(std::stringstream &aStringStre
|
||||
f(PUSHLAYER, RecordedPushLayer); \
|
||||
f(POPLAYER, RecordedPopLayer); \
|
||||
f(UNSCALEDFONTCREATION, RecordedUnscaledFontCreation); \
|
||||
f(UNSCALEDFONTDESTRUCTION, RecordedUnscaledFontDestruction);
|
||||
f(UNSCALEDFONTDESTRUCTION, RecordedUnscaledFontDestruction); \
|
||||
f(INTOLUMINANCE, RecordedIntoLuminanceSource);
|
||||
|
||||
template<class S>
|
||||
RecordedEvent *
|
||||
|
@ -71,14 +71,14 @@ GetTransformIn3DContext(Layer* aLayer) {
|
||||
* @return local transform for layers not participating 3D rendering
|
||||
* context, or the accmulated transform in the context for else.
|
||||
*/
|
||||
static Matrix4x4
|
||||
static Matrix4x4Flagged
|
||||
GetTransformForInvalidation(Layer* aLayer) {
|
||||
return (!aLayer->Is3DContextLeaf() && !aLayer->Extend3DContext() ?
|
||||
aLayer->GetLocalTransform() : GetTransformIn3DContext(aLayer));
|
||||
}
|
||||
|
||||
static IntRect
|
||||
TransformRect(const IntRect& aRect, const Matrix4x4& aTransform)
|
||||
TransformRect(const IntRect& aRect, const Matrix4x4Flagged& aTransform)
|
||||
{
|
||||
if (aRect.IsEmpty()) {
|
||||
return IntRect();
|
||||
@ -97,7 +97,7 @@ TransformRect(const IntRect& aRect, const Matrix4x4& aTransform)
|
||||
}
|
||||
|
||||
static void
|
||||
AddTransformedRegion(nsIntRegion& aDest, const nsIntRegion& aSource, const Matrix4x4& aTransform)
|
||||
AddTransformedRegion(nsIntRegion& aDest, const nsIntRegion& aSource, const Matrix4x4Flagged& aTransform)
|
||||
{
|
||||
for (auto iter = aSource.RectIter(); !iter.Done(); iter.Next()) {
|
||||
aDest.Or(aDest, TransformRect(iter.Get(), aTransform));
|
||||
@ -328,7 +328,7 @@ public:
|
||||
UniquePtr<LayerPropertiesBase> mMaskLayer;
|
||||
nsTArray<UniquePtr<LayerPropertiesBase>> mAncestorMaskLayers;
|
||||
nsIntRegion mVisibleRegion;
|
||||
Matrix4x4 mTransform;
|
||||
Matrix4x4Flagged mTransform;
|
||||
float mPostXScale;
|
||||
float mPostYScale;
|
||||
float mOpacity;
|
||||
@ -507,7 +507,7 @@ public:
|
||||
|
||||
if (!mLayer->Extend3DContext()) {
|
||||
// |result| contains invalid regions only of children.
|
||||
result.Transform(GetTransformForInvalidation(mLayer));
|
||||
result.Transform(GetTransformForInvalidation(mLayer).GetMatrix());
|
||||
}
|
||||
// else, effective transforms have applied on children.
|
||||
|
||||
|
@ -55,6 +55,7 @@ gfxHarfBuzzShaper::gfxHarfBuzzShaper(gfxFont *aFont)
|
||||
mUVSTableOffset(0),
|
||||
mNumLongHMetrics(0),
|
||||
mNumLongVMetrics(0),
|
||||
mDefaultVOrg(-1.0),
|
||||
mUseFontGetGlyph(aFont->ProvidesGetGlyph()),
|
||||
mUseFontGlyphWidths(false),
|
||||
mInitialized(false),
|
||||
@ -422,15 +423,17 @@ gfxHarfBuzzShaper::HBGetGlyphVOrigin(hb_font_t *font, void *font_data,
|
||||
{
|
||||
const gfxHarfBuzzShaper::FontCallbackData *fcd =
|
||||
static_cast<const gfxHarfBuzzShaper::FontCallbackData*>(font_data);
|
||||
fcd->mShaper->GetGlyphVOrigin(glyph, x, y);
|
||||
fcd->mShaper->GetGlyphVOrigin(*fcd->mDrawTarget, glyph, x, y);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
gfxHarfBuzzShaper::GetGlyphVOrigin(hb_codepoint_t aGlyph,
|
||||
gfxHarfBuzzShaper::GetGlyphVOrigin(DrawTarget& aDT, hb_codepoint_t aGlyph,
|
||||
hb_position_t *aX, hb_position_t *aY) const
|
||||
{
|
||||
*aX = 0.5 * GetGlyphHAdvance(aGlyph);
|
||||
*aX = 0.5 * (mUseFontGlyphWidths
|
||||
? mFont->GetGlyphWidth(aDT, aGlyph)
|
||||
: GetGlyphHAdvance(aGlyph));
|
||||
|
||||
if (mVORGTable) {
|
||||
// We checked in Initialize() that the VORG table is safely readable,
|
||||
@ -493,27 +496,42 @@ gfxHarfBuzzShaper::GetGlyphVOrigin(hb_codepoint_t aGlyph,
|
||||
}
|
||||
}
|
||||
|
||||
// XXX should we consider using OS/2 sTypo* metrics if available?
|
||||
if (mDefaultVOrg < 0.0) {
|
||||
// XXX should we consider using OS/2 sTypo* metrics if available?
|
||||
|
||||
gfxFontEntry::AutoTable hheaTable(GetFont()->GetFontEntry(),
|
||||
TRUETYPE_TAG('h','h','e','a'));
|
||||
if (hheaTable) {
|
||||
uint32_t len;
|
||||
const MetricsHeader* hhea =
|
||||
reinterpret_cast<const MetricsHeader*>(hb_blob_get_data(hheaTable,
|
||||
&len));
|
||||
if (len >= sizeof(MetricsHeader)) {
|
||||
// divide up the default advance we're using (1em) in proportion
|
||||
// to ascender:descender from the hhea table
|
||||
int16_t a = int16_t(hhea->ascender);
|
||||
int16_t d = int16_t(hhea->descender);
|
||||
*aY = FloatToFixed(GetFont()->GetAdjustedSize() * a / (a - d));
|
||||
return;
|
||||
gfxFontEntry::AutoTable hheaTable(GetFont()->GetFontEntry(),
|
||||
TRUETYPE_TAG('h','h','e','a'));
|
||||
if (hheaTable) {
|
||||
uint32_t len;
|
||||
const MetricsHeader* hhea =
|
||||
reinterpret_cast<const MetricsHeader*>(hb_blob_get_data(hheaTable,
|
||||
&len));
|
||||
if (len >= sizeof(MetricsHeader)) {
|
||||
// divide up the default advance we're using (1em) in proportion
|
||||
// to ascender:descender from the hhea table
|
||||
int16_t a = int16_t(hhea->ascender);
|
||||
int16_t d = int16_t(hhea->descender);
|
||||
mDefaultVOrg =
|
||||
FloatToFixed(GetFont()->GetAdjustedSize() * a / (a - d));
|
||||
}
|
||||
}
|
||||
|
||||
if (mDefaultVOrg < 0.0) {
|
||||
// Last resort, for non-sfnt fonts: get the horizontal metrics and
|
||||
// compute a default VOrg from their ascent and descent.
|
||||
const gfxFont::Metrics& mtx = mFont->GetHorizontalMetrics();
|
||||
gfxFloat advance = mFont->GetMetrics(gfxFont::eVertical).aveCharWidth;
|
||||
gfxFloat ascent = mtx.emAscent;
|
||||
gfxFloat height = ascent + mtx.emDescent;
|
||||
// vOrigin that will place the glyph so that its origin is shifted
|
||||
// down most of the way within overall (vertical) advance, in
|
||||
// proportion to the font ascent as a part of the overall font
|
||||
// height.
|
||||
mDefaultVOrg = FloatToFixed(advance * ascent / height);
|
||||
}
|
||||
}
|
||||
|
||||
NS_NOTREACHED("we shouldn't be here!");
|
||||
*aY = FloatToFixed(GetFont()->GetAdjustedSize() / 2);
|
||||
*aY = mDefaultVOrg;
|
||||
}
|
||||
|
||||
static hb_bool_t
|
||||
@ -1331,19 +1349,19 @@ gfxHarfBuzzShaper::LoadHmtxTable()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
void
|
||||
gfxHarfBuzzShaper::InitializeVertical()
|
||||
{
|
||||
// We only try this once. If we don't have a mHmtxTable after that,
|
||||
// this font can't handle vertical shaping, so return false.
|
||||
// We only do this once. If we don't have a mHmtxTable after that,
|
||||
// we'll be making up fallback metrics.
|
||||
if (mVerticalInitialized) {
|
||||
return mHmtxTable != nullptr;
|
||||
return;
|
||||
}
|
||||
mVerticalInitialized = true;
|
||||
|
||||
if (!mHmtxTable) {
|
||||
if (!LoadHmtxTable()) {
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1404,8 +1422,6 @@ gfxHarfBuzzShaper::InitializeVertical()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -1431,9 +1447,7 @@ gfxHarfBuzzShaper::ShapeText(DrawTarget *aDrawTarget,
|
||||
}
|
||||
|
||||
if (aVertical) {
|
||||
if (!InitializeVertical()) {
|
||||
return false;
|
||||
}
|
||||
InitializeVertical();
|
||||
if (!mFont->GetFontEntry()->
|
||||
SupportsOpenTypeFeature(aScript, HB_TAG('v','e','r','t'))) {
|
||||
mUseVerticalPresentationForms = true;
|
||||
|
@ -52,7 +52,8 @@ public:
|
||||
|
||||
hb_position_t GetGlyphVAdvance(hb_codepoint_t glyph) const;
|
||||
|
||||
void GetGlyphVOrigin(hb_codepoint_t aGlyph,
|
||||
void GetGlyphVOrigin(mozilla::gfx::DrawTarget& aDT,
|
||||
hb_codepoint_t aGlyph,
|
||||
hb_position_t *aX, hb_position_t *aY) const;
|
||||
|
||||
// get harfbuzz horizontal advance in 16.16 fixed point format.
|
||||
@ -114,7 +115,7 @@ protected:
|
||||
nsTArray<nsPoint>& aPositions,
|
||||
uint32_t aAppUnitsPerDevUnit);
|
||||
|
||||
bool InitializeVertical();
|
||||
void InitializeVertical();
|
||||
bool LoadHmtxTable();
|
||||
|
||||
struct Glyf { // we only need the bounding-box at the beginning
|
||||
@ -176,6 +177,10 @@ protected:
|
||||
// Similarly for vhea if it's a vertical font.
|
||||
mutable int32_t mNumLongVMetrics;
|
||||
|
||||
// Default y-coordinate for glyph vertical origin, used if the font
|
||||
// does not actually have vertical-layout metrics.
|
||||
mutable gfxFloat mDefaultVOrg;
|
||||
|
||||
// Whether the font implements GetGlyph, or we should read tables
|
||||
// directly
|
||||
bool mUseFontGetGlyph;
|
||||
|
@ -16,9 +16,9 @@ namespace JS {
|
||||
// A wrapper around the internal C++ representation of SpiderMonkey WeakMaps,
|
||||
// usable outside the engine.
|
||||
//
|
||||
// The supported template specializations are enumerated in WeakMapPtr.cpp. If
|
||||
// you want to use this class for a different key/value combination, add it to
|
||||
// the list and the compiler will generate the relevant machinery.
|
||||
// The supported template specializations are enumerated in gc/WeakMapPtr.cpp.
|
||||
// If you want to use this class for a different key/value combination, add it
|
||||
// to the list and the compiler will generate the relevant machinery.
|
||||
template <typename K, typename V>
|
||||
class JS_PUBLIC_API(WeakMapPtr)
|
||||
{
|
||||
|
@ -14,13 +14,11 @@
|
||||
#include "jsapi.h"
|
||||
#include "jsarray.h"
|
||||
#include "jsnum.h"
|
||||
#ifdef XP_WIN
|
||||
# include "jswin.h"
|
||||
#endif
|
||||
#include "jswrapper.h"
|
||||
|
||||
#include "jit/AtomicOperations.h"
|
||||
#include "js/Conversions.h"
|
||||
#include "util/Windows.h"
|
||||
#include "vm/ArrayBufferObject.h"
|
||||
#include "vm/GlobalObject.h"
|
||||
#include "vm/Interpreter.h"
|
||||
|
@ -9,9 +9,8 @@
|
||||
#include "mozilla/HashFunctions.h"
|
||||
#include "mozilla/Range.h"
|
||||
|
||||
#include "jshashutil.h"
|
||||
|
||||
#include "frontend/BytecodeCompiler.h"
|
||||
#include "gc/HashUtil.h"
|
||||
#include "vm/Debugger.h"
|
||||
#include "vm/GlobalObject.h"
|
||||
#include "vm/JSContext.h"
|
||||
|
@ -4,7 +4,7 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "json.h"
|
||||
#include "builtin/JSON.h"
|
||||
|
||||
#include "mozilla/FloatingPoint.h"
|
||||
#include "mozilla/Range.h"
|
@ -4,8 +4,8 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef json_h
|
||||
#define json_h
|
||||
#ifndef builtin_JSON_h
|
||||
#define builtin_JSON_h
|
||||
|
||||
#include "mozilla/Range.h"
|
||||
|
||||
@ -40,4 +40,4 @@ ParseJSONWithReviver(JSContext* cx, const mozilla::Range<const CharT> chars,
|
||||
|
||||
} // namespace js
|
||||
|
||||
#endif /* json_h */
|
||||
#endif /* builtin_JSON_h */
|
@ -6,13 +6,12 @@
|
||||
|
||||
#include "builtin/MapObject.h"
|
||||
|
||||
#include "jsiter.h"
|
||||
|
||||
#include "ds/OrderedHashTable.h"
|
||||
#include "gc/FreeOp.h"
|
||||
#include "js/Utility.h"
|
||||
#include "vm/GlobalObject.h"
|
||||
#include "vm/Interpreter.h"
|
||||
#include "vm/Iteration.h"
|
||||
#include "vm/JSContext.h"
|
||||
#include "vm/JSObject.h"
|
||||
#include "vm/SelfHosting.h"
|
||||
|
@ -12,13 +12,13 @@
|
||||
|
||||
#include "jsexn.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "jsiter.h"
|
||||
|
||||
#include "gc/Heap.h"
|
||||
#include "js/Debug.h"
|
||||
#include "vm/AsyncFunction.h"
|
||||
#include "vm/AsyncIteration.h"
|
||||
#include "vm/Debugger.h"
|
||||
#include "vm/Iteration.h"
|
||||
#include "vm/JSContext.h"
|
||||
|
||||
#include "vm/Debugger-inl.h"
|
||||
|
@ -2278,14 +2278,16 @@ ASTSerializer::statement(ParseNode* pn, MutableHandleValue dst)
|
||||
case ParseNodeKind::ExportFrom:
|
||||
return exportDeclaration(pn, dst);
|
||||
|
||||
case ParseNodeKind::Semi:
|
||||
if (pn->pn_kid) {
|
||||
RootedValue expr(cx);
|
||||
return expression(pn->pn_kid, &expr) &&
|
||||
builder.expressionStatement(expr, &pn->pn_pos, dst);
|
||||
}
|
||||
case ParseNodeKind::EmptyStatement:
|
||||
return builder.emptyStatement(&pn->pn_pos, dst);
|
||||
|
||||
case ParseNodeKind::ExpressionStatement:
|
||||
{
|
||||
RootedValue expr(cx);
|
||||
return expression(pn->pn_kid, &expr) &&
|
||||
builder.expressionStatement(expr, &pn->pn_pos, dst);
|
||||
}
|
||||
|
||||
case ParseNodeKind::LexicalScope:
|
||||
pn = pn->pn_expr;
|
||||
if (!pn->isKind(ParseNodeKind::StatementList))
|
||||
@ -2456,9 +2458,6 @@ ASTSerializer::statement(ParseNode* pn, MutableHandleValue dst)
|
||||
return builder.classMethods(methods, dst);
|
||||
}
|
||||
|
||||
case ParseNodeKind::Nop:
|
||||
return builder.emptyStatement(&pn->pn_pos, dst);
|
||||
|
||||
default:
|
||||
LOCAL_NOT_REACHED("unexpected statement type");
|
||||
}
|
||||
|
@ -18,7 +18,6 @@
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "jsiter.h"
|
||||
#include "jsprf.h"
|
||||
#include "jswrapper.h"
|
||||
|
||||
@ -42,6 +41,7 @@
|
||||
#include "vm/Debugger.h"
|
||||
#include "vm/GlobalObject.h"
|
||||
#include "vm/Interpreter.h"
|
||||
#include "vm/Iteration.h"
|
||||
#include "vm/JSContext.h"
|
||||
#include "vm/JSObject.h"
|
||||
#include "vm/ProxyObject.h"
|
||||
|
@ -7,9 +7,8 @@
|
||||
#ifndef builtin_TypedObject_h
|
||||
#define builtin_TypedObject_h
|
||||
|
||||
#include "jsweakmap.h"
|
||||
|
||||
#include "builtin/TypedObjectConstants.h"
|
||||
#include "gc/WeakMap.h"
|
||||
#include "js/Conversions.h"
|
||||
#include "vm/ArrayBufferObject.h"
|
||||
#include "vm/JSObject.h"
|
||||
|
@ -7,8 +7,7 @@
|
||||
#ifndef builtin_WeakMapObject_h
|
||||
#define builtin_WeakMapObject_h
|
||||
|
||||
#include "jsweakmap.h"
|
||||
|
||||
#include "gc/WeakMap.h"
|
||||
#include "vm/JSObject.h"
|
||||
|
||||
namespace js {
|
||||
|
@ -7,10 +7,10 @@
|
||||
#include "builtin/WeakSetObject.h"
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "jsiter.h"
|
||||
|
||||
#include "builtin/MapObject.h"
|
||||
#include "vm/GlobalObject.h"
|
||||
#include "vm/Iteration.h"
|
||||
#include "vm/JSContext.h"
|
||||
#include "vm/SelfHosting.h"
|
||||
|
||||
|
@ -14,27 +14,22 @@
|
||||
#include <limits>
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(XP_WIN)
|
||||
#include <float.h>
|
||||
# include <float.h>
|
||||
#endif
|
||||
|
||||
#if defined(SOLARIS)
|
||||
#include <ieeefp.h>
|
||||
# include <ieeefp.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SSIZE_T
|
||||
#include <sys/types.h>
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#if defined(XP_UNIX)
|
||||
#include <errno.h>
|
||||
# include <errno.h>
|
||||
#endif
|
||||
|
||||
#include "jsexn.h"
|
||||
#include "jsnum.h"
|
||||
#include "jsprf.h"
|
||||
#include "jswin.h"
|
||||
|
||||
#include "builtin/TypedObject.h"
|
||||
#include "ctypes/Library.h"
|
||||
@ -43,6 +38,7 @@
|
||||
#include "gc/Zone.h"
|
||||
#include "jit/AtomicOperations.h"
|
||||
#include "js/Vector.h"
|
||||
#include "util/Windows.h"
|
||||
#include "vm/JSContext.h"
|
||||
#include "vm/JSFunction.h"
|
||||
|
||||
|
@ -9,11 +9,11 @@
|
||||
// in the same process.
|
||||
|
||||
#ifdef WIN32
|
||||
#include "jswin.h"
|
||||
# include "util/Windows.h"
|
||||
#else
|
||||
#define __cdecl
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
# define __cdecl
|
||||
# include <stdarg.h>
|
||||
# include <string.h>
|
||||
#endif
|
||||
|
||||
#include "vprof.h"
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include "mozilla/Atomics.h"
|
||||
|
||||
#if defined(XP_WIN)
|
||||
# include "jswin.h"
|
||||
# include "util/Windows.h"
|
||||
#elif defined(XP_UNIX) && !defined(XP_DARWIN)
|
||||
# include <signal.h>
|
||||
# include <sys/types.h>
|
||||
|
@ -1217,8 +1217,6 @@ BinASTParser::parseVariableDeclarationAux(const BinKind kind, const BinFields& f
|
||||
return raiseMissingField("VariableDeclaration", BinField::Declarations);
|
||||
|
||||
result->setKind(pnk);
|
||||
|
||||
MOZ_ASSERT(!result->isKind(ParseNodeKind::Nop));
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -20,13 +20,13 @@
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "jsnum.h"
|
||||
#include "jsopcode.h"
|
||||
#include "jstypes.h"
|
||||
#include "jsutil.h"
|
||||
|
||||
#include "ds/Nestable.h"
|
||||
#include "frontend/Parser.h"
|
||||
#include "frontend/TokenStream.h"
|
||||
#include "vm/BytecodeUtil.h"
|
||||
#include "vm/Debugger.h"
|
||||
#include "vm/GeneratorObject.h"
|
||||
#include "vm/JSAtom.h"
|
||||
@ -3067,7 +3067,7 @@ BytecodeEmitter::checkSideEffects(ParseNode* pn, bool* answer)
|
||||
|
||||
switch (pn->getKind()) {
|
||||
// Trivial cases with no side effects.
|
||||
case ParseNodeKind::Nop:
|
||||
case ParseNodeKind::EmptyStatement:
|
||||
case ParseNodeKind::String:
|
||||
case ParseNodeKind::TemplateString:
|
||||
case ParseNodeKind::RegExp:
|
||||
@ -3199,12 +3199,9 @@ BytecodeEmitter::checkSideEffects(ParseNode* pn, bool* answer)
|
||||
return checkSideEffects(expr, answer);
|
||||
}
|
||||
|
||||
case ParseNodeKind::Semi:
|
||||
case ParseNodeKind::ExpressionStatement:
|
||||
MOZ_ASSERT(pn->isArity(PN_UNARY));
|
||||
if (ParseNode* expr = pn->pn_kid)
|
||||
return checkSideEffects(expr, answer);
|
||||
*answer = false;
|
||||
return true;
|
||||
return checkSideEffects(pn->pn_kid, answer);
|
||||
|
||||
// Binary cases with obvious side effects.
|
||||
case ParseNodeKind::Assign:
|
||||
@ -8714,13 +8711,9 @@ BytecodeEmitter::emitStatementList(ParseNode* pn)
|
||||
}
|
||||
|
||||
bool
|
||||
BytecodeEmitter::emitStatement(ParseNode* pn)
|
||||
BytecodeEmitter::emitExpressionStatement(ParseNode* pn)
|
||||
{
|
||||
MOZ_ASSERT(pn->isKind(ParseNodeKind::Semi));
|
||||
|
||||
ParseNode* pn2 = pn->pn_kid;
|
||||
if (!pn2)
|
||||
return true;
|
||||
MOZ_ASSERT(pn->isKind(ParseNodeKind::ExpressionStatement));
|
||||
|
||||
if (!updateSourceCoordNotes(pn->pn_pos.begin))
|
||||
return false;
|
||||
@ -8742,8 +8735,9 @@ BytecodeEmitter::emitStatement(ParseNode* pn)
|
||||
useful = wantval = !script->noScriptRval();
|
||||
|
||||
/* Don't eliminate expressions with side effects. */
|
||||
ParseNode* expr = pn->pn_kid;
|
||||
if (!useful) {
|
||||
if (!checkSideEffects(pn2, &useful))
|
||||
if (!checkSideEffects(expr, &useful))
|
||||
return false;
|
||||
|
||||
/*
|
||||
@ -8762,8 +8756,8 @@ BytecodeEmitter::emitStatement(ParseNode* pn)
|
||||
if (useful) {
|
||||
JSOp op = wantval ? JSOP_SETRVAL : JSOP_POP;
|
||||
ValueUsage valueUsage = wantval ? ValueUsage::WantValue : ValueUsage::IgnoreValue;
|
||||
MOZ_ASSERT_IF(pn2->isKind(ParseNodeKind::Assign), pn2->isOp(JSOP_NOP));
|
||||
if (!emitTree(pn2, valueUsage))
|
||||
MOZ_ASSERT_IF(expr->isKind(ParseNodeKind::Assign), expr->isOp(JSOP_NOP));
|
||||
if (!emitTree(expr, valueUsage))
|
||||
return false;
|
||||
if (!emit1(op))
|
||||
return false;
|
||||
@ -8789,11 +8783,11 @@ BytecodeEmitter::emitStatement(ParseNode* pn)
|
||||
}
|
||||
|
||||
if (directive) {
|
||||
if (!reportExtraWarning(pn2, JSMSG_CONTRARY_NONDIRECTIVE, directive))
|
||||
if (!reportExtraWarning(expr, JSMSG_CONTRARY_NONDIRECTIVE, directive))
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!reportExtraWarning(pn2, JSMSG_USELESS_EXPR))
|
||||
if (!reportExtraWarning(expr, JSMSG_USELESS_EXPR))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -10742,8 +10736,11 @@ BytecodeEmitter::emitTree(ParseNode* pn, ValueUsage valueUsage /* = ValueUsage::
|
||||
return false;
|
||||
break;
|
||||
|
||||
case ParseNodeKind::Semi:
|
||||
if (!emitStatement(pn))
|
||||
case ParseNodeKind::EmptyStatement:
|
||||
break;
|
||||
|
||||
case ParseNodeKind::ExpressionStatement:
|
||||
if (!emitExpressionStatement(pn))
|
||||
return false;
|
||||
break;
|
||||
|
||||
@ -10990,10 +10987,6 @@ BytecodeEmitter::emitTree(ParseNode* pn, ValueUsage valueUsage /* = ValueUsage::
|
||||
return false;
|
||||
break;
|
||||
|
||||
case ParseNodeKind::Nop:
|
||||
MOZ_ASSERT(pn->getArity() == PN_NULLARY);
|
||||
break;
|
||||
|
||||
case ParseNodeKind::Class:
|
||||
if (!emitClass(pn))
|
||||
return false;
|
||||
|
@ -11,14 +11,13 @@
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
#include "jsiter.h"
|
||||
#include "jsopcode.h"
|
||||
|
||||
#include "ds/InlineTable.h"
|
||||
#include "frontend/EitherParser.h"
|
||||
#include "frontend/SharedContext.h"
|
||||
#include "frontend/SourceNotes.h"
|
||||
#include "vm/BytecodeUtil.h"
|
||||
#include "vm/Interpreter.h"
|
||||
#include "vm/Iteration.h"
|
||||
#include "vm/JSContext.h"
|
||||
#include "vm/JSScript.h"
|
||||
|
||||
@ -767,7 +766,7 @@ struct MOZ_STACK_CLASS BytecodeEmitter
|
||||
MOZ_MUST_USE bool emitAssignment(ParseNode* lhs, ParseNodeKind pnk, ParseNode* rhs);
|
||||
|
||||
MOZ_MUST_USE bool emitReturn(ParseNode* pn);
|
||||
MOZ_MUST_USE bool emitStatement(ParseNode* pn);
|
||||
MOZ_MUST_USE bool emitExpressionStatement(ParseNode* pn);
|
||||
MOZ_MUST_USE bool emitStatementList(ParseNode* pn);
|
||||
|
||||
MOZ_MUST_USE bool emitDeleteName(ParseNode* pn);
|
||||
|
@ -102,14 +102,14 @@ ContainsHoistedDeclaration(JSContext* cx, ParseNode* node, bool* result)
|
||||
return true;
|
||||
|
||||
// Statements with no sub-components at all.
|
||||
case ParseNodeKind::Nop: // induced by function f() {} function f() {}
|
||||
case ParseNodeKind::EmptyStatement:
|
||||
case ParseNodeKind::Debugger:
|
||||
MOZ_ASSERT(node->isArity(PN_NULLARY));
|
||||
*result = false;
|
||||
return true;
|
||||
|
||||
// Statements containing only an expression have no declarations.
|
||||
case ParseNodeKind::Semi:
|
||||
case ParseNodeKind::ExpressionStatement:
|
||||
case ParseNodeKind::Throw:
|
||||
case ParseNodeKind::Return:
|
||||
MOZ_ASSERT(node->isArity(PN_UNARY));
|
||||
@ -1590,7 +1590,7 @@ Fold(JSContext* cx, ParseNode** pnp, PerHandlerParser<FullParseHandler>& parser)
|
||||
ParseNode* pn = *pnp;
|
||||
|
||||
switch (pn->getKind()) {
|
||||
case ParseNodeKind::Nop:
|
||||
case ParseNodeKind::EmptyStatement:
|
||||
case ParseNodeKind::RegExp:
|
||||
case ParseNodeKind::String:
|
||||
case ParseNodeKind::True:
|
||||
@ -1655,6 +1655,7 @@ Fold(JSContext* cx, ParseNode** pnp, PerHandlerParser<FullParseHandler>& parser)
|
||||
case ParseNodeKind::PostDecrement:
|
||||
return FoldIncrementDecrement(cx, pn, parser);
|
||||
|
||||
case ParseNodeKind::ExpressionStatement:
|
||||
case ParseNodeKind::Throw:
|
||||
case ParseNodeKind::MutateProto:
|
||||
case ParseNodeKind::ComputedName:
|
||||
@ -1668,7 +1669,6 @@ Fold(JSContext* cx, ParseNode** pnp, PerHandlerParser<FullParseHandler>& parser)
|
||||
MOZ_ASSERT(pn->isArity(PN_BINARY));
|
||||
return Fold(cx, &pn->pn_left, parser);
|
||||
|
||||
case ParseNodeKind::Semi:
|
||||
case ParseNodeKind::This:
|
||||
MOZ_ASSERT(pn->isArity(PN_UNARY));
|
||||
if (ParseNode*& expr = pn->pn_kid)
|
||||
|
@ -494,7 +494,7 @@ class FullParseHandler
|
||||
}
|
||||
|
||||
ParseNode* newEmptyStatement(const TokenPos& pos) {
|
||||
return new_<UnaryNode>(ParseNodeKind::Semi, pos, nullptr);
|
||||
return new_<NullaryNode>(ParseNodeKind::EmptyStatement, pos);
|
||||
}
|
||||
|
||||
ParseNode* newImportDeclaration(ParseNode* importSpecSet,
|
||||
@ -541,7 +541,8 @@ class FullParseHandler
|
||||
|
||||
ParseNode* newExprStatement(ParseNode* expr, uint32_t end) {
|
||||
MOZ_ASSERT(expr->pn_pos.end <= end);
|
||||
return new_<UnaryNode>(ParseNodeKind::Semi, TokenPos(expr->pn_pos.begin, end), expr);
|
||||
return new_<UnaryNode>(ParseNodeKind::ExpressionStatement,
|
||||
TokenPos(expr->pn_pos.begin, end), expr);
|
||||
}
|
||||
|
||||
ParseNode* newIfStatement(uint32_t begin, ParseNode* cond, ParseNode* thenBranch,
|
||||
@ -777,7 +778,7 @@ class FullParseHandler
|
||||
kind == ParseNodeKind::Var ||
|
||||
kind == ParseNodeKind::Break ||
|
||||
kind == ParseNodeKind::Throw ||
|
||||
(kind == ParseNodeKind::Semi && !node->pn_kid);
|
||||
kind == ParseNodeKind::EmptyStatement;
|
||||
}
|
||||
|
||||
bool isSuperBase(ParseNode* node) {
|
||||
|
@ -4,11 +4,10 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef frontend_NameAnalysis_h
|
||||
#define frontend_NameAnalysis_h
|
||||
|
||||
#include "jsopcode.h"
|
||||
#ifndef frontend_NameAnalysisTypes_h
|
||||
#define frontend_NameAnalysisTypes_h
|
||||
|
||||
#include "vm/BytecodeUtil.h"
|
||||
#include "vm/Scope.h"
|
||||
|
||||
namespace js {
|
||||
@ -377,4 +376,4 @@ struct IsPod<js::frontend::NameLocation> : TrueType {};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // frontend_NameAnalysis_h
|
||||
#endif // frontend_NameAnalysisTypes_h
|
||||
|
@ -388,7 +388,7 @@ class NameResolver
|
||||
switch (cur->getKind()) {
|
||||
// Nodes with no children that might require name resolution need no
|
||||
// further work.
|
||||
case ParseNodeKind::Nop:
|
||||
case ParseNodeKind::EmptyStatement:
|
||||
case ParseNodeKind::String:
|
||||
case ParseNodeKind::TemplateString:
|
||||
case ParseNodeKind::RegExp:
|
||||
@ -422,6 +422,7 @@ class NameResolver
|
||||
break;
|
||||
|
||||
// Nodes with a single non-null child requiring name resolution.
|
||||
case ParseNodeKind::ExpressionStatement:
|
||||
case ParseNodeKind::TypeOfExpr:
|
||||
case ParseNodeKind::Void:
|
||||
case ParseNodeKind::Not:
|
||||
@ -447,7 +448,6 @@ class NameResolver
|
||||
break;
|
||||
|
||||
// Nodes with a single nullable child.
|
||||
case ParseNodeKind::Semi:
|
||||
case ParseNodeKind::This:
|
||||
MOZ_ASSERT(cur->isArity(PN_UNARY));
|
||||
if (ParseNode* expr = cur->pn_kid) {
|
||||
|
@ -183,7 +183,7 @@ PushNodeChildren(ParseNode* pn, NodeStack* stack)
|
||||
switch (pn->getKind()) {
|
||||
// Trivial nodes that refer to no nodes, are referred to by nothing
|
||||
// but their parents, are never used, and are never a definition.
|
||||
case ParseNodeKind::Nop:
|
||||
case ParseNodeKind::EmptyStatement:
|
||||
case ParseNodeKind::String:
|
||||
case ParseNodeKind::TemplateString:
|
||||
case ParseNodeKind::RegExp:
|
||||
@ -204,6 +204,7 @@ PushNodeChildren(ParseNode* pn, NodeStack* stack)
|
||||
return PushResult::Recyclable;
|
||||
|
||||
// Nodes with a single non-null child.
|
||||
case ParseNodeKind::ExpressionStatement:
|
||||
case ParseNodeKind::TypeOfName:
|
||||
case ParseNodeKind::TypeOfExpr:
|
||||
case ParseNodeKind::Void:
|
||||
@ -228,8 +229,7 @@ PushNodeChildren(ParseNode* pn, NodeStack* stack)
|
||||
return PushUnaryNodeChild(pn, stack);
|
||||
|
||||
// Nodes with a single nullable child.
|
||||
case ParseNodeKind::This:
|
||||
case ParseNodeKind::Semi: {
|
||||
case ParseNodeKind::This: {
|
||||
MOZ_ASSERT(pn->isArity(PN_UNARY));
|
||||
if (pn->pn_kid)
|
||||
stack->push(pn->pn_kid);
|
||||
|
@ -43,8 +43,8 @@ class FunctionBox;
|
||||
class ObjectBox;
|
||||
|
||||
#define FOR_EACH_PARSE_NODE_KIND(F) \
|
||||
F(Nop) \
|
||||
F(Semi) \
|
||||
F(EmptyStatement) \
|
||||
F(ExpressionStatement) \
|
||||
F(Comma) \
|
||||
F(Conditional) \
|
||||
F(Colon) \
|
||||
@ -305,10 +305,11 @@ IsTypeofKind(ParseNodeKind kind)
|
||||
* pn_lexdef (NOT pn_expr) set
|
||||
* pn_right: initializer
|
||||
* Return unary pn_kid: return expr or null
|
||||
* Semi unary pn_kid: expr or null statement
|
||||
* pn_prologue: true if Directive Prologue member
|
||||
* in original source, not introduced via
|
||||
* constant folding or other tree rewriting
|
||||
* ExpressionStatement unary pn_kid: expr
|
||||
* pn_prologue: true if Directive Prologue member
|
||||
* in original source, not introduced via
|
||||
* constant folding or other tree rewriting
|
||||
* EmptyStatement nullary (no fields)
|
||||
* Label name pn_atom: label, pn_expr: labeled statement
|
||||
* Import binary pn_left: ImportSpecList import specifiers
|
||||
* pn_right: String module specifier
|
||||
@ -683,10 +684,10 @@ class ParseNode
|
||||
* nodes; we use it to determine the extent of the prologue.
|
||||
*/
|
||||
JSAtom* isStringExprStatement() const {
|
||||
if (getKind() == ParseNodeKind::Semi) {
|
||||
if (getKind() == ParseNodeKind::ExpressionStatement) {
|
||||
MOZ_ASSERT(pn_arity == PN_UNARY);
|
||||
ParseNode* kid = pn_kid;
|
||||
if (kid && kid->getKind() == ParseNodeKind::String && !kid->pn_parens)
|
||||
if (kid->getKind() == ParseNodeKind::String && !kid->pn_parens)
|
||||
return kid->pn_atom;
|
||||
}
|
||||
return nullptr;
|
||||
|
@ -24,7 +24,6 @@
|
||||
#include "mozilla/TypeTraits.h"
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "jsopcode.h"
|
||||
#include "jstypes.h"
|
||||
|
||||
#include "builtin/ModuleObject.h"
|
||||
@ -33,6 +32,7 @@
|
||||
#include "frontend/FoldConstants.h"
|
||||
#include "frontend/TokenStream.h"
|
||||
#include "irregexp/RegExpParser.h"
|
||||
#include "vm/BytecodeUtil.h"
|
||||
#include "vm/JSAtom.h"
|
||||
#include "vm/JSContext.h"
|
||||
#include "vm/JSFunction.h"
|
||||
|
@ -168,7 +168,6 @@
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/TypeTraits.h"
|
||||
|
||||
#include "jsiter.h"
|
||||
#include "jspubtd.h"
|
||||
|
||||
#include "ds/Nestable.h"
|
||||
@ -181,6 +180,7 @@
|
||||
#include "frontend/SharedContext.h"
|
||||
#include "frontend/SyntaxParseHandler.h"
|
||||
#include "frontend/TokenStream.h"
|
||||
#include "vm/Iteration.h"
|
||||
|
||||
namespace js {
|
||||
|
||||
|
@ -7,7 +7,6 @@
|
||||
#ifndef frontend_SharedContext_h
|
||||
#define frontend_SharedContext_h
|
||||
|
||||
#include "jsopcode.h"
|
||||
#include "jspubtd.h"
|
||||
#include "jstypes.h"
|
||||
|
||||
@ -15,6 +14,7 @@
|
||||
#include "ds/InlineTable.h"
|
||||
#include "frontend/ParseNode.h"
|
||||
#include "frontend/TokenStream.h"
|
||||
#include "vm/BytecodeUtil.h"
|
||||
#include "vm/EnvironmentObject.h"
|
||||
#include "vm/JSAtom.h"
|
||||
#include "vm/JSScript.h"
|
||||
|
@ -6,10 +6,10 @@
|
||||
|
||||
#include "gc/AtomMarking-inl.h"
|
||||
|
||||
#include "gc/Iteration.h"
|
||||
#include "gc/PublicIterators.h"
|
||||
#include "vm/JSCompartment.h"
|
||||
|
||||
#include "jsgcinlines.h"
|
||||
#include "gc/GC-inl.h"
|
||||
#include "gc/Heap-inl.h"
|
||||
|
||||
namespace js {
|
||||
|
@ -4,10 +4,10 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef jsgcinlines_h
|
||||
#define jsgcinlines_h
|
||||
#ifndef gc_GC_inl_h
|
||||
#define gc_GC_inl_h
|
||||
|
||||
#include "jsgc.h"
|
||||
#include "gc/GC.h"
|
||||
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
@ -348,4 +348,4 @@ class ZoneCellIter : public ZoneCellIter<TenuredCell> {
|
||||
} /* namespace gc */
|
||||
} /* namespace js */
|
||||
|
||||
#endif /* jsgcinlines_h */
|
||||
#endif /* gc_GC_inl_h */
|
@ -185,7 +185,7 @@
|
||||
* this bitmap is managed.
|
||||
*/
|
||||
|
||||
#include "jsgcinlines.h"
|
||||
#include "gc/GC-inl.h"
|
||||
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
@ -204,15 +204,12 @@
|
||||
# include <sys/mman.h>
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "jsprf.h"
|
||||
#include "jstypes.h"
|
||||
#include "jsutil.h"
|
||||
#include "jsweakmap.h"
|
||||
#ifdef XP_WIN
|
||||
# include "jswin.h"
|
||||
#endif
|
||||
|
||||
#include "gc/FindSCCs.h"
|
||||
#include "gc/FreeOp.h"
|
||||
@ -220,11 +217,13 @@
|
||||
#include "gc/GCTrace.h"
|
||||
#include "gc/Memory.h"
|
||||
#include "gc/Policy.h"
|
||||
#include "gc/WeakMap.h"
|
||||
#include "jit/BaselineJIT.h"
|
||||
#include "jit/IonCode.h"
|
||||
#include "jit/JitcodeMap.h"
|
||||
#include "js/SliceBudget.h"
|
||||
#include "proxy/DeadObjectProxy.h"
|
||||
#include "util/Windows.h"
|
||||
#include "vm/Debugger.h"
|
||||
#include "vm/GeckoProfiler.h"
|
||||
#include "vm/JSAtom.h"
|
||||
@ -241,10 +240,10 @@
|
||||
#include "vm/TraceLogging.h"
|
||||
#include "vm/WrapperObject.h"
|
||||
|
||||
#include "gc/GCIteration-inl.h"
|
||||
#include "gc/Heap-inl.h"
|
||||
#include "gc/Marking-inl.h"
|
||||
#include "gc/Nursery-inl.h"
|
||||
#include "gc/PrivateIterators-inl.h"
|
||||
#include "vm/GeckoProfiler-inl.h"
|
||||
#include "vm/JSObject-inl.h"
|
||||
#include "vm/JSScript-inl.h"
|
@ -8,8 +8,8 @@
|
||||
* JS engine garbage collector API.
|
||||
*/
|
||||
|
||||
#ifndef jsgc_h
|
||||
#define jsgc_h
|
||||
#ifndef gc_GC_h
|
||||
#define gc_GC_h
|
||||
|
||||
#include "jsapi.h"
|
||||
|
||||
@ -144,7 +144,7 @@ enum VerifierType {
|
||||
|
||||
extern const char* ZealModeHelpText;
|
||||
|
||||
/* Check that write barriers have been used correctly. See jsgc.cpp. */
|
||||
/* Check that write barriers have been used correctly. See gc/Verifier.cpp. */
|
||||
void
|
||||
VerifyBarriers(JSRuntime* rt, VerifierType type);
|
||||
|
||||
@ -214,4 +214,4 @@ UninlinedIsInsideNursery(const gc::Cell* cell);
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
#endif /* jsgc_h */
|
||||
#endif /* gc_GC_h */
|
@ -897,7 +897,7 @@ class GCRuntime
|
||||
* mainly useful to embedders.
|
||||
*
|
||||
* We use zeal_ == 4 to enable write barrier verification. See the comment
|
||||
* in jsgc.cpp for more information about this.
|
||||
* in gc/Verifier.cpp for more information about this.
|
||||
*
|
||||
* zeal_ values from 8 to 10 periodically run different types of
|
||||
* incremental GC.
|
||||
|
@ -4,8 +4,8 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef jshashutil_h
|
||||
#define jshashutil_h
|
||||
#ifndef gc_HashUtil_h
|
||||
#define gc_HashUtil_h
|
||||
|
||||
#include "gc/Zone.h"
|
||||
#include "vm/JSContext.h"
|
@ -33,10 +33,9 @@
|
||||
#include "vm/UnboxedObject.h"
|
||||
#include "wasm/WasmJS.h"
|
||||
|
||||
#include "jsgcinlines.h"
|
||||
|
||||
#include "gc/GCIteration-inl.h"
|
||||
#include "gc/GC-inl.h"
|
||||
#include "gc/Nursery-inl.h"
|
||||
#include "gc/PrivateIterators-inl.h"
|
||||
#include "vm/JSCompartment-inl.h"
|
||||
#include "vm/NativeObject-inl.h"
|
||||
#include "vm/String-inl.h"
|
||||
@ -3398,7 +3397,7 @@ IsAboutToBeFinalizedInternal(T** thingp)
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
struct IsAboutToBeFinalizedFunctor : public IdentityDefaultAdaptor<S> {
|
||||
struct IsAboutToBeFinalizedInternalFunctor : public IdentityDefaultAdaptor<S> {
|
||||
template <typename T> S operator()(T* t, bool* rv) {
|
||||
*rv = IsAboutToBeFinalizedInternal(&t);
|
||||
return js::gc::RewrapTaggedPointer<S, T>::wrap(t);
|
||||
@ -3410,7 +3409,7 @@ static bool
|
||||
IsAboutToBeFinalizedInternal(T* thingp)
|
||||
{
|
||||
bool rv = false;
|
||||
*thingp = DispatchTyped(IsAboutToBeFinalizedFunctor<T>(), *thingp, &rv);
|
||||
*thingp = DispatchTyped(IsAboutToBeFinalizedInternalFunctor<T>(), *thingp, &rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -14,24 +14,24 @@
|
||||
|
||||
#if defined(XP_WIN)
|
||||
|
||||
#include "mozilla/Sprintf.h"
|
||||
#include "jswin.h"
|
||||
#include <psapi.h>
|
||||
# include "mozilla/Sprintf.h"
|
||||
# include "util/Windows.h"
|
||||
# include <psapi.h>
|
||||
|
||||
#elif defined(SOLARIS)
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
# include <sys/mman.h>
|
||||
# include <unistd.h>
|
||||
|
||||
#elif defined(XP_UNIX)
|
||||
|
||||
#include <algorithm>
|
||||
#include <errno.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
# include <algorithm>
|
||||
# include <errno.h>
|
||||
# include <sys/mman.h>
|
||||
# include <sys/resource.h>
|
||||
# include <sys/stat.h>
|
||||
# include <sys/types.h>
|
||||
# include <unistd.h>
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -16,8 +16,8 @@
|
||||
|
||||
#include "gc/FreeOp.h"
|
||||
#include "gc/GCInternals.h"
|
||||
#include "gc/Iteration.h"
|
||||
#include "gc/Memory.h"
|
||||
#include "gc/PublicIterators.h"
|
||||
#include "jit/JitFrames.h"
|
||||
#include "vm/ArrayObject.h"
|
||||
#include "vm/Debugger.h"
|
||||
|
@ -8,12 +8,12 @@
|
||||
* GC-internal iterators for various data structures.
|
||||
*/
|
||||
|
||||
#ifndef gc_GCIteration_h
|
||||
#define gc_GCIteration_h
|
||||
#ifndef gc_PrivateIterators_inl_h
|
||||
#define gc_PrivateIterators_inl_h
|
||||
|
||||
#include "gc/Iteration.h"
|
||||
#include "gc/PublicIterators.h"
|
||||
|
||||
#include "jsgcinlines.h"
|
||||
#include "gc/GC-inl.h"
|
||||
|
||||
namespace js {
|
||||
namespace gc {
|
||||
@ -122,4 +122,4 @@ typedef CompartmentsIterT<SweepGroupZonesIter> SweepGroupCompartmentsIter;
|
||||
} // namespace gc
|
||||
} // namespace js
|
||||
|
||||
#endif // gc_GCIteration_h
|
||||
#endif // gc_PrivateIterators_inl_h
|
@ -11,7 +11,7 @@
|
||||
#include "vm/JSCompartment.h"
|
||||
#include "vm/Runtime.h"
|
||||
|
||||
#include "gc/GCIteration-inl.h"
|
||||
#include "gc/PrivateIterators-inl.h"
|
||||
#include "vm/JSContext-inl.h"
|
||||
|
||||
using namespace js;
|
@ -8,8 +8,8 @@
|
||||
* Iterators for various data structures.
|
||||
*/
|
||||
|
||||
#ifndef gc_Iteration_h
|
||||
#define gc_Iteration_h
|
||||
#ifndef gc_PublicIterators_h
|
||||
#define gc_PublicIterators_h
|
||||
|
||||
#include "gc/Zone.h"
|
||||
|
||||
@ -224,4 +224,4 @@ typedef CompartmentsIterT<ZonesIter> CompartmentsIter;
|
||||
|
||||
} // namespace js
|
||||
|
||||
#endif // gc_Iteration_h
|
||||
#endif // gc_PublicIterators_h
|
@ -23,8 +23,8 @@
|
||||
#include "vm/JSContext.h"
|
||||
#include "vm/JSONParser.h"
|
||||
|
||||
#include "gc/GCIteration-inl.h"
|
||||
#include "gc/Nursery-inl.h"
|
||||
#include "gc/PrivateIterators-inl.h"
|
||||
#include "vm/JSObject-inl.h"
|
||||
|
||||
using namespace js;
|
||||
|
@ -17,10 +17,10 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "jsgc.h"
|
||||
#include "jsprf.h"
|
||||
#include "jsutil.h"
|
||||
|
||||
#include "gc/GC.h"
|
||||
#include "gc/Memory.h"
|
||||
#include "vm/Debugger.h"
|
||||
#include "vm/HelperThreads.h"
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include "vm/ArgumentsObject.h"
|
||||
#include "vm/Runtime.h"
|
||||
|
||||
#include "jsgcinlines.h"
|
||||
#include "gc/GC-inl.h"
|
||||
|
||||
using namespace js;
|
||||
using namespace js::gc;
|
||||
|
@ -13,16 +13,15 @@
|
||||
#include "NamespaceImports.h"
|
||||
|
||||
#include "gc/GCInternals.h"
|
||||
#include "gc/Iteration.h"
|
||||
#include "gc/Marking.h"
|
||||
#include "gc/PublicIterators.h"
|
||||
#include "gc/Zone.h"
|
||||
#include "vm/JSFunction.h"
|
||||
#include "vm/JSScript.h"
|
||||
#include "vm/Shape.h"
|
||||
#include "vm/Symbol.h"
|
||||
|
||||
#include "jsgcinlines.h"
|
||||
|
||||
#include "gc/GC-inl.h"
|
||||
#include "vm/JSCompartment-inl.h"
|
||||
#include "vm/ObjectGroup-inl.h"
|
||||
|
||||
|
@ -15,13 +15,12 @@
|
||||
#include "jsprf.h"
|
||||
|
||||
#include "gc/GCInternals.h"
|
||||
#include "gc/Iteration.h"
|
||||
#include "gc/PublicIterators.h"
|
||||
#include "gc/Zone.h"
|
||||
#include "js/HashTable.h"
|
||||
#include "vm/JSContext.h"
|
||||
|
||||
#include "jsgcinlines.h"
|
||||
|
||||
#include "gc/GC-inl.h"
|
||||
#include "gc/Marking-inl.h"
|
||||
#include "vm/JSContext-inl.h"
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "jsweakmap.h"
|
||||
#include "gc/WeakMap.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
#include "jsfriendapi.h"
|
||||
#include "jswrapper.h"
|
||||
|
||||
#include "gc/Iteration.h"
|
||||
#include "gc/PublicIterators.h"
|
||||
#include "vm/GlobalObject.h"
|
||||
#include "vm/JSContext.h"
|
||||
#include "vm/JSObject.h"
|
@ -4,8 +4,8 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef jsweakmap_h
|
||||
#define jsweakmap_h
|
||||
#ifndef gc_WeakMap_h
|
||||
#define gc_WeakMap_h
|
||||
|
||||
#include "mozilla/LinkedList.h"
|
||||
#include "mozilla/Move.h"
|
||||
@ -414,4 +414,4 @@ struct DeletePolicy<js::ObjectValueMap> : public js::GCManagedDeletePolicy<js::O
|
||||
|
||||
} /* namespace JS */
|
||||
|
||||
#endif /* jsweakmap_h */
|
||||
#endif /* gc_WeakMap_h */
|
@ -6,7 +6,7 @@
|
||||
|
||||
#include "js/WeakMapPtr.h"
|
||||
|
||||
#include "jsweakmap.h"
|
||||
#include "gc/WeakMap.h"
|
||||
|
||||
//
|
||||
// Machinery for the externally-linkable JS::WeakMapPtr, which wraps js::WeakMap
|
@ -6,16 +6,15 @@
|
||||
|
||||
#include "gc/Zone.h"
|
||||
|
||||
#include "gc/Iteration.h"
|
||||
#include "gc/Policy.h"
|
||||
#include "gc/PublicIterators.h"
|
||||
#include "jit/BaselineJIT.h"
|
||||
#include "jit/Ion.h"
|
||||
#include "jit/JitCompartment.h"
|
||||
#include "vm/Debugger.h"
|
||||
#include "vm/Runtime.h"
|
||||
|
||||
#include "jsgcinlines.h"
|
||||
|
||||
#include "gc/GC-inl.h"
|
||||
#include "gc/Marking-inl.h"
|
||||
#include "vm/JSCompartment-inl.h"
|
||||
|
||||
|
@ -178,7 +178,7 @@ struct Zone : public JS::shadow::Zone,
|
||||
size_t* atomsMarkBitmaps);
|
||||
|
||||
// Iterate over all cells in the zone. See the definition of ZoneCellIter
|
||||
// in jsgcinlines.h for the possible arguments and documentation.
|
||||
// in gc/GC-inl.h for the possible arguments and documentation.
|
||||
template <typename T, typename... Args>
|
||||
js::gc::ZoneCellIter<T> cellIter(Args&&... args) {
|
||||
return js::gc::ZoneCellIter<T>(const_cast<Zone*>(this), mozilla::Forward<Args>(args)...);
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
#include "gc/ZoneGroup.h"
|
||||
|
||||
#include "gc/Iteration.h"
|
||||
#include "gc/PublicIterators.h"
|
||||
#include "jit/IonBuilder.h"
|
||||
#include "jit/JitCompartment.h"
|
||||
#include "vm/JSContext.h"
|
||||
|
@ -33,9 +33,8 @@
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/Move.h"
|
||||
|
||||
#include "jsgc.h"
|
||||
|
||||
#include "frontend/TokenStream.h"
|
||||
#include "gc/GC.h"
|
||||
#include "irregexp/RegExpCharacters.h"
|
||||
#include "vm/ErrorReporting.h"
|
||||
#include "vm/StringBuffer.h"
|
||||
|
29
js/src/jit-test/tests/cacheir/unaryarith.js
Normal file
29
js/src/jit-test/tests/cacheir/unaryarith.js
Normal file
@ -0,0 +1,29 @@
|
||||
setJitCompilerOption('ion.forceinlineCaches', 1);
|
||||
|
||||
function warmup(fun, input_array, output_array) {
|
||||
assertEq(output_array.length, input_array.length);
|
||||
for (var index = 0; index < input_array.length; index++) {
|
||||
input = input_array[index];
|
||||
output = output_array[index];
|
||||
for (var i = 0; i < 30; i++) {
|
||||
var y = fun(input);
|
||||
assertEq(y, output)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var fun1 = (x) => { return -x; }
|
||||
var fun2 = (x) => { return -x; }
|
||||
|
||||
var fun3 = (x) => { return ~x; }
|
||||
var fun4 = (x) => { return ~x; }
|
||||
|
||||
warmup(fun1, [1, 2], [-1, -2]);
|
||||
warmup(fun2, [0], [-0]);
|
||||
|
||||
warmup(fun2, [3, 4], [-3, -4]);
|
||||
warmup(fun1, [1.2, 1.4], [-1.2, -1.4]);
|
||||
|
||||
warmup(fun3, [-1, 0], [0, -1]);
|
||||
warmup(fun4, [-1.0, 0.0, 1.2, 3], [0, -1, -2, -4]);
|
||||
|
@ -2105,6 +2105,7 @@ BaselineCacheIRCompiler::init(CacheKind kind)
|
||||
case CacheKind::TypeOf:
|
||||
case CacheKind::GetIterator:
|
||||
case CacheKind::ToBool:
|
||||
case CacheKind::UnaryArith:
|
||||
MOZ_ASSERT(numInputs == 1);
|
||||
allocator.initInputLocation(0, R0);
|
||||
break;
|
||||
|
@ -1930,7 +1930,7 @@ BaselineCompiler::emitUnaryArith()
|
||||
frame.popRegsAndSync(1);
|
||||
|
||||
// Call IC
|
||||
ICUnaryArith_Fallback::Compiler stubCompiler(cx, ICStubCompiler::Engine::Baseline);
|
||||
ICUnaryArith_Fallback::Compiler stubCompiler(cx);
|
||||
if (!emitOpIC(stubCompiler.getStub(&stubSpace_)))
|
||||
return false;
|
||||
|
||||
|
@ -44,8 +44,8 @@ class BaselineFrame
|
||||
|
||||
// Frame has execution observed by a Debugger.
|
||||
//
|
||||
// See comment above 'isDebuggee' in jscompartment.h for explanation of
|
||||
// invariants of debuggee compartments, scripts, and frames.
|
||||
// See comment above 'isDebuggee' in vm/JSCompartment.h for explanation
|
||||
// of invariants of debuggee compartments, scripts, and frames.
|
||||
DEBUGGEE = 1 << 6,
|
||||
|
||||
// (1 << 7 and 1 << 8 are unused)
|
||||
|
@ -4533,5 +4533,89 @@ ICRest_Fallback::Compiler::generateStubCode(MacroAssembler& masm)
|
||||
return tailCallVM(DoRestFallbackInfo, masm);
|
||||
}
|
||||
|
||||
//
|
||||
// UnaryArith_Fallback
|
||||
//
|
||||
|
||||
static bool
|
||||
DoUnaryArithFallback(JSContext* cx, BaselineFrame* frame, ICUnaryArith_Fallback* stub,
|
||||
HandleValue val, MutableHandleValue res)
|
||||
{
|
||||
// This fallback stub may trigger debug mode toggling.
|
||||
DebugModeOSRVolatileStub<ICUnaryArith_Fallback*> debug_stub(ICStubEngine::Baseline, frame, stub);
|
||||
|
||||
RootedScript script(cx, frame->script());
|
||||
jsbytecode* pc = stub->icEntry()->pc(script);
|
||||
JSOp op = JSOp(*pc);
|
||||
FallbackICSpew(cx, stub, "UnaryArith(%s)", CodeName[op]);
|
||||
|
||||
switch (op) {
|
||||
case JSOP_BITNOT: {
|
||||
int32_t result;
|
||||
if (!BitNot(cx, val, &result))
|
||||
return false;
|
||||
res.setInt32(result);
|
||||
break;
|
||||
}
|
||||
case JSOP_NEG:
|
||||
if (!NegOperation(cx, val, res))
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("Unexpected op");
|
||||
}
|
||||
|
||||
// Check if debug mode toggling made the stub invalid.
|
||||
if (debug_stub.invalid())
|
||||
return true;
|
||||
|
||||
if (res.isDouble())
|
||||
stub->setSawDoubleResult();
|
||||
|
||||
if (stub->state().maybeTransition())
|
||||
stub->discardStubs(cx);
|
||||
|
||||
if (stub->state().canAttachStub()) {
|
||||
UnaryArithIRGenerator gen(cx, script, pc, stub->state().mode(),
|
||||
op, val, res);
|
||||
if (gen.tryAttachStub()) {
|
||||
bool attached = false;
|
||||
ICStub* newStub = AttachBaselineCacheIRStub(cx, gen.writerRef(), gen.cacheKind(),
|
||||
BaselineCacheIRStubKind::Regular,
|
||||
ICStubEngine::Baseline, script, stub, &attached);
|
||||
if (newStub) {
|
||||
JitSpew(JitSpew_BaselineIC, " Attached (shared) CacheIR stub for %s", CodeName[op]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
typedef bool (*DoUnaryArithFallbackFn)(JSContext*, BaselineFrame*, ICUnaryArith_Fallback*,
|
||||
HandleValue, MutableHandleValue);
|
||||
static const VMFunction DoUnaryArithFallbackInfo =
|
||||
FunctionInfo<DoUnaryArithFallbackFn>(DoUnaryArithFallback, "DoUnaryArithFallback", TailCall,
|
||||
PopValues(1));
|
||||
|
||||
bool
|
||||
ICUnaryArith_Fallback::Compiler::generateStubCode(MacroAssembler& masm)
|
||||
{
|
||||
MOZ_ASSERT(R0 == JSReturnOperand);
|
||||
|
||||
// Restore the tail call register.
|
||||
EmitRestoreTailCallReg(masm);
|
||||
|
||||
// Ensure stack is fully synced for the expression decompiler.
|
||||
masm.pushValue(R0);
|
||||
|
||||
// Push arguments.
|
||||
masm.pushValue(R0);
|
||||
masm.push(ICStubReg);
|
||||
pushStubPayload(masm, R0.scratchReg());
|
||||
|
||||
return tailCallVM(DoUnaryArithFallbackInfo, masm);
|
||||
}
|
||||
|
||||
} // namespace jit
|
||||
} // namespace js
|
||||
|
@ -9,8 +9,6 @@
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
|
||||
#include "jsopcode.h"
|
||||
|
||||
#include "builtin/TypedObject.h"
|
||||
#include "gc/Barrier.h"
|
||||
#include "jit/BaselineICList.h"
|
||||
@ -19,6 +17,7 @@
|
||||
#include "jit/SharedICRegisters.h"
|
||||
#include "js/GCVector.h"
|
||||
#include "vm/ArrayObject.h"
|
||||
#include "vm/BytecodeUtil.h"
|
||||
#include "vm/JSCompartment.h"
|
||||
#include "vm/JSContext.h"
|
||||
#include "vm/UnboxedObject.h"
|
||||
@ -1460,6 +1459,44 @@ class ICRetSub_Resume : public ICStub
|
||||
};
|
||||
};
|
||||
|
||||
// UnaryArith
|
||||
// JSOP_BITNOT
|
||||
// JSOP_NEG
|
||||
|
||||
class ICUnaryArith_Fallback : public ICFallbackStub
|
||||
{
|
||||
friend class ICStubSpace;
|
||||
|
||||
explicit ICUnaryArith_Fallback(JitCode* stubCode)
|
||||
: ICFallbackStub(UnaryArith_Fallback, stubCode)
|
||||
{
|
||||
extra_ = 0;
|
||||
}
|
||||
|
||||
public:
|
||||
bool sawDoubleResult() {
|
||||
return extra_;
|
||||
}
|
||||
void setSawDoubleResult() {
|
||||
extra_ = 1;
|
||||
}
|
||||
|
||||
// Compiler for this stub kind.
|
||||
class Compiler : public ICStubCompiler {
|
||||
protected:
|
||||
MOZ_MUST_USE bool generateStubCode(MacroAssembler& masm) override;
|
||||
|
||||
public:
|
||||
explicit Compiler(JSContext* cx)
|
||||
: ICStubCompiler(cx, ICStub::UnaryArith_Fallback, Engine::Baseline)
|
||||
{}
|
||||
|
||||
ICStub* getStub(ICStubSpace* space) override {
|
||||
return newStub<ICUnaryArith_Fallback>(space, getStubCode());
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
inline bool
|
||||
IsCacheableDOMProxy(JSObject* obj)
|
||||
{
|
||||
|
@ -34,6 +34,8 @@ namespace jit {
|
||||
\
|
||||
_(ToNumber_Fallback) \
|
||||
\
|
||||
_(UnaryArith_Fallback) \
|
||||
\
|
||||
_(Call_Fallback) \
|
||||
_(Call_Scripted) \
|
||||
_(Call_AnyScripted) \
|
||||
|
@ -334,11 +334,9 @@ BaselineInspector::expectedResultType(jsbytecode* pc)
|
||||
return MIRType::Double;
|
||||
return MIRType::Int32;
|
||||
case ICStub::BinaryArith_BooleanWithInt32:
|
||||
case ICStub::UnaryArith_Int32:
|
||||
case ICStub::BinaryArith_DoubleWithInt32:
|
||||
return MIRType::Int32;
|
||||
case ICStub::BinaryArith_Double:
|
||||
case ICStub::UnaryArith_Double:
|
||||
return MIRType::Double;
|
||||
case ICStub::BinaryArith_StringConcat:
|
||||
case ICStub::BinaryArith_StringObjectConcat:
|
||||
|
@ -22,11 +22,10 @@
|
||||
#include "vm/TraceLogging.h"
|
||||
#include "wasm/WasmInstance.h"
|
||||
|
||||
#include "jsopcodeinlines.h"
|
||||
|
||||
#include "gc/GCIteration-inl.h"
|
||||
#include "gc/PrivateIterators-inl.h"
|
||||
#include "jit/JitFrames-inl.h"
|
||||
#include "jit/MacroAssembler-inl.h"
|
||||
#include "vm/BytecodeUtil-inl.h"
|
||||
#include "vm/JSObject-inl.h"
|
||||
#include "vm/JSScript-inl.h"
|
||||
#include "vm/Stack-inl.h"
|
||||
|
@ -6,12 +6,10 @@
|
||||
|
||||
#include "jit/BytecodeAnalysis.h"
|
||||
|
||||
#include "jsopcode.h"
|
||||
|
||||
#include "jit/JitSpewer.h"
|
||||
#include "vm/BytecodeUtil.h"
|
||||
|
||||
#include "jsopcodeinlines.h"
|
||||
|
||||
#include "vm/BytecodeUtil-inl.h"
|
||||
#include "vm/JSScript-inl.h"
|
||||
|
||||
using namespace js;
|
||||
|
@ -4683,4 +4683,86 @@ GetIntrinsicIRGenerator::tryAttachStub()
|
||||
writer.returnFromIC();
|
||||
trackAttached("GetIntrinsic");
|
||||
return true;
|
||||
}
|
||||
UnaryArithIRGenerator::UnaryArithIRGenerator(JSContext* cx, HandleScript script, jsbytecode* pc, ICState::Mode mode,
|
||||
JSOp op, HandleValue val, HandleValue res)
|
||||
: IRGenerator(cx, script, pc, CacheKind::UnaryArith, mode),
|
||||
op_(op),
|
||||
val_(val),
|
||||
res_(res)
|
||||
{ }
|
||||
|
||||
void
|
||||
UnaryArithIRGenerator::trackAttached(const char* name)
|
||||
{
|
||||
#ifdef JS_CACHEIR_SPEW
|
||||
if (const CacheIRSpewer::Guard& sp = CacheIRSpewer::Guard(*this, name)) {
|
||||
sp.valueProperty("val", val_);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
UnaryArithIRGenerator::tryAttachStub()
|
||||
{
|
||||
if (tryAttachInt32())
|
||||
return true;
|
||||
if (tryAttachNumber())
|
||||
return true;
|
||||
|
||||
trackAttached(IRGenerator::NotAttached);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
UnaryArithIRGenerator::tryAttachInt32()
|
||||
{
|
||||
if (!val_.isInt32() || !res_.isInt32())
|
||||
return false;
|
||||
|
||||
ValOperandId valId(writer.setInputOperandId(0));
|
||||
|
||||
Int32OperandId intId = writer.guardIsInt32(valId);
|
||||
switch (op_) {
|
||||
case JSOP_BITNOT:
|
||||
writer.int32NotResult(intId);
|
||||
trackAttached("UnaryArith.Int32Not");
|
||||
break;
|
||||
case JSOP_NEG:
|
||||
writer.int32NegationResult(intId);
|
||||
trackAttached("UnaryArith.Int32Neg");
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("Unexected OP");
|
||||
}
|
||||
|
||||
writer.returnFromIC();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
UnaryArithIRGenerator::tryAttachNumber()
|
||||
{
|
||||
if (!val_.isNumber() || !res_.isNumber() || !cx_->runtime()->jitSupportsFloatingPoint)
|
||||
return false;
|
||||
|
||||
ValOperandId valId(writer.setInputOperandId(0));
|
||||
writer.guardType(valId, JSVAL_TYPE_DOUBLE);
|
||||
Int32OperandId truncatedId;
|
||||
switch (op_) {
|
||||
case JSOP_BITNOT:
|
||||
truncatedId = writer.truncateDoubleToUInt32(valId);
|
||||
writer.int32NotResult(truncatedId);
|
||||
trackAttached("UnaryArith.DoubleNot");
|
||||
break;
|
||||
case JSOP_NEG:
|
||||
writer.doubleNegationResult(valId);
|
||||
trackAttached("UnaryArith.DoubleNeg");
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("Unexpected OP");
|
||||
}
|
||||
|
||||
writer.returnFromIC();
|
||||
return true;
|
||||
}
|
@ -153,7 +153,8 @@ class TypedOperandId : public OperandId
|
||||
_(GetIterator) \
|
||||
_(Compare) \
|
||||
_(ToBool) \
|
||||
_(Call)
|
||||
_(Call) \
|
||||
_(UnaryArith)
|
||||
|
||||
enum class CacheKind : uint8_t
|
||||
{
|
||||
@ -171,6 +172,7 @@ extern const char* CacheKindNames[];
|
||||
_(GuardIsString) \
|
||||
_(GuardIsSymbol) \
|
||||
_(GuardIsNumber) \
|
||||
_(GuardIsInt32) \
|
||||
_(GuardIsInt32Index) \
|
||||
_(GuardType) \
|
||||
_(GuardShape) \
|
||||
@ -207,6 +209,8 @@ extern const char* CacheKindNames[];
|
||||
_(LoadEnclosingEnvironment) \
|
||||
_(LoadWrapperTarget) \
|
||||
\
|
||||
_(TruncateDoubleToUInt32) \
|
||||
\
|
||||
_(MegamorphicLoadSlotResult) \
|
||||
_(MegamorphicLoadSlotByValueResult) \
|
||||
_(MegamorphicStoreSlot) \
|
||||
@ -272,6 +276,9 @@ extern const char* CacheKindNames[];
|
||||
_(LoadStringResult) \
|
||||
_(LoadInstanceOfObjectResult) \
|
||||
_(LoadTypeOfObjectResult) \
|
||||
_(Int32NotResult) \
|
||||
_(Int32NegationResult) \
|
||||
_(DoubleNegationResult) \
|
||||
_(LoadInt32TruthyResult) \
|
||||
_(LoadDoubleTruthyResult) \
|
||||
_(LoadStringTruthyResult) \
|
||||
@ -523,6 +530,12 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter
|
||||
writeOpWithOperandId(CacheOp::GuardIsSymbol, val);
|
||||
return SymbolOperandId(val.id());
|
||||
}
|
||||
Int32OperandId guardIsInt32(ValOperandId val) {
|
||||
Int32OperandId res(nextOperandId_++);
|
||||
writeOpWithOperandId(CacheOp::GuardIsInt32, val);
|
||||
writeOperandId(res);
|
||||
return res;
|
||||
}
|
||||
Int32OperandId guardIsInt32Index(ValOperandId val) {
|
||||
Int32OperandId res(nextOperandId_++);
|
||||
writeOpWithOperandId(CacheOp::GuardIsInt32Index, val);
|
||||
@ -715,6 +728,13 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter
|
||||
return res;
|
||||
}
|
||||
|
||||
Int32OperandId truncateDoubleToUInt32(ValOperandId val) {
|
||||
Int32OperandId res(nextOperandId_++);
|
||||
writeOpWithOperandId(CacheOp::TruncateDoubleToUInt32, val);
|
||||
writeOperandId(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
ValOperandId loadDOMExpandoValue(ObjOperandId obj) {
|
||||
ValOperandId res(nextOperandId_++);
|
||||
writeOpWithOperandId(CacheOp::LoadDOMExpandoValue, obj);
|
||||
@ -899,6 +919,15 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter
|
||||
buffer_.writeByte(uint32_t(hasOwn));
|
||||
}
|
||||
|
||||
void int32NotResult(Int32OperandId id) {
|
||||
writeOpWithOperandId(CacheOp::Int32NotResult, id);
|
||||
}
|
||||
void int32NegationResult(Int32OperandId id) {
|
||||
writeOpWithOperandId(CacheOp::Int32NegationResult, id);
|
||||
}
|
||||
void doubleNegationResult(ValOperandId val) {
|
||||
writeOpWithOperandId(CacheOp::DoubleNegationResult, val);
|
||||
}
|
||||
void loadBooleanResult(bool val) {
|
||||
writeOp(CacheOp::LoadBooleanResult);
|
||||
buffer_.writeByte(uint32_t(val));
|
||||
@ -1653,6 +1682,24 @@ class MOZ_RAII GetIntrinsicIRGenerator : public IRGenerator
|
||||
bool tryAttachStub();
|
||||
};
|
||||
|
||||
class MOZ_RAII UnaryArithIRGenerator : public IRGenerator
|
||||
{
|
||||
JSOp op_;
|
||||
HandleValue val_;
|
||||
HandleValue res_;
|
||||
|
||||
bool tryAttachInt32();
|
||||
bool tryAttachNumber();
|
||||
|
||||
void trackAttached(const char* name);
|
||||
|
||||
public:
|
||||
UnaryArithIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc, ICState::Mode mode,
|
||||
JSOp op, HandleValue val, HandleValue res);
|
||||
|
||||
bool tryAttachStub();
|
||||
};
|
||||
|
||||
} // namespace jit
|
||||
} // namespace js
|
||||
|
||||
|
@ -18,6 +18,7 @@ using namespace js;
|
||||
using namespace js::jit;
|
||||
|
||||
using mozilla::Maybe;
|
||||
using mozilla::BitwiseCast;
|
||||
|
||||
ValueOperand
|
||||
CacheRegisterAllocator::useValueRegister(MacroAssembler& masm, ValOperandId op)
|
||||
@ -1311,6 +1312,29 @@ CacheIRCompiler::emitGuardIsSymbol()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheIRCompiler::emitGuardIsInt32()
|
||||
{
|
||||
ValOperandId inputId = reader.valOperandId();
|
||||
Register output = allocator.defineRegister(masm, reader.int32OperandId());
|
||||
|
||||
if (allocator.knownType(inputId) == JSVAL_TYPE_INT32) {
|
||||
Register input = allocator.useRegister(masm, Int32OperandId(inputId.id()));
|
||||
masm.move32(input, output);
|
||||
return true;
|
||||
}
|
||||
ValueOperand input = allocator.useValueRegister(masm, inputId);
|
||||
|
||||
FailurePath* failure;
|
||||
if (!addFailurePath(&failure))
|
||||
return false;
|
||||
|
||||
Label notInt32, done;
|
||||
masm.branchTestInt32(Assembler::NotEqual, input, failure->label());
|
||||
masm.unboxInt32(input, output);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheIRCompiler::emitGuardIsInt32Index()
|
||||
{
|
||||
@ -1779,6 +1803,92 @@ CacheIRCompiler::emitLoadInt32ArrayLengthResult()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheIRCompiler::emitInt32NegationResult()
|
||||
{
|
||||
AutoOutputRegister output(*this);
|
||||
Register val = allocator.useRegister(masm, reader.int32OperandId());
|
||||
|
||||
FailurePath* failure;
|
||||
if (!addFailurePath(&failure))
|
||||
return false;
|
||||
|
||||
// Guard against 0 and MIN_INT, both result in a double.
|
||||
masm.branchTest32(Assembler::Zero, val, Imm32(0x7fffffff), failure->label());
|
||||
masm.neg32(val);
|
||||
masm.tagValue(JSVAL_TYPE_INT32, val, output.valueReg());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheIRCompiler::emitInt32NotResult()
|
||||
{
|
||||
AutoOutputRegister output(*this);
|
||||
Register val = allocator.useRegister(masm, reader.int32OperandId());
|
||||
masm.not32(val);
|
||||
masm.tagValue(JSVAL_TYPE_INT32, val, output.valueReg());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheIRCompiler::emitDoubleNegationResult()
|
||||
{
|
||||
AutoOutputRegister output(*this);
|
||||
ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId());
|
||||
|
||||
FailurePath* failure;
|
||||
if (!addFailurePath(&failure))
|
||||
return false;
|
||||
|
||||
// If we're compiling a Baseline IC, FloatReg0 is always available.
|
||||
Label failurePopReg, done;
|
||||
if (mode_ != Mode::Baseline)
|
||||
masm.push(FloatReg0);
|
||||
|
||||
masm.ensureDouble(val, FloatReg0, (mode_ != Mode::Baseline) ? &failurePopReg : failure->label());
|
||||
masm.negateDouble(FloatReg0);
|
||||
masm.boxDouble(FloatReg0, output.valueReg(), FloatReg0);
|
||||
|
||||
if (mode_ != Mode::Baseline) {
|
||||
masm.pop(FloatReg0);
|
||||
masm.jump(&done);
|
||||
|
||||
masm.bind(&failurePopReg);
|
||||
masm.pop(FloatReg0);
|
||||
masm.jump(failure->label());
|
||||
}
|
||||
|
||||
masm.bind(&done);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheIRCompiler::emitTruncateDoubleToUInt32()
|
||||
{
|
||||
ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId());
|
||||
Register res = allocator.defineRegister(masm, reader.int32OperandId());
|
||||
|
||||
Label doneTruncate, truncateABICall;
|
||||
if (mode_ != Mode::Baseline)
|
||||
masm.push(FloatReg0);
|
||||
|
||||
masm.unboxDouble(val, FloatReg0);
|
||||
masm.branchTruncateDoubleMaybeModUint32(FloatReg0, res, &truncateABICall);
|
||||
masm.jump(&doneTruncate);
|
||||
|
||||
masm.bind(&truncateABICall);
|
||||
masm.setupUnalignedABICall(res);
|
||||
masm.passABIArg(FloatReg0, MoveOp::DOUBLE);
|
||||
masm.callWithABI(BitwiseCast<void*, int32_t(*)(double)>(JS::ToInt32),
|
||||
MoveOp::GENERAL, CheckUnsafeCallWithABI::DontCheckOther);
|
||||
masm.storeCallInt32Result(res);
|
||||
|
||||
masm.bind(&doneTruncate);
|
||||
if (mode_ != Mode::Baseline)
|
||||
masm.pop(FloatReg0);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheIRCompiler::emitLoadArgumentsObjectLengthResult()
|
||||
{
|
||||
|
@ -21,6 +21,7 @@ namespace jit {
|
||||
_(GuardIsString) \
|
||||
_(GuardIsSymbol) \
|
||||
_(GuardIsNumber) \
|
||||
_(GuardIsInt32) \
|
||||
_(GuardIsInt32Index) \
|
||||
_(GuardType) \
|
||||
_(GuardClass) \
|
||||
@ -44,6 +45,10 @@ namespace jit {
|
||||
_(LoadUndefinedResult) \
|
||||
_(LoadBooleanResult) \
|
||||
_(LoadInt32ArrayLengthResult) \
|
||||
_(Int32NegationResult) \
|
||||
_(Int32NotResult) \
|
||||
_(DoubleNegationResult) \
|
||||
_(TruncateDoubleToUInt32) \
|
||||
_(LoadArgumentsObjectLengthResult) \
|
||||
_(LoadFunctionLengthResult) \
|
||||
_(LoadStringLengthResult) \
|
||||
|
@ -15,6 +15,8 @@
|
||||
#include "mozilla/MathAlgorithms.h"
|
||||
#include "mozilla/ScopeExit.h"
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include "jslibmath.h"
|
||||
#include "jsmath.h"
|
||||
#include "jsnum.h"
|
||||
@ -173,12 +175,16 @@ typedef bool (*IonInICFn)(JSContext*, HandleScript, IonInIC*, HandleValue, Handl
|
||||
static const VMFunction IonInICInfo =
|
||||
FunctionInfo<IonInICFn>(IonInIC::update, "IonInIC::update");
|
||||
|
||||
|
||||
typedef bool (*IonInstanceOfICFn)(JSContext*, HandleScript, IonInstanceOfIC*,
|
||||
HandleValue lhs, HandleObject rhs, bool* res);
|
||||
static const VMFunction IonInstanceOfInfo =
|
||||
FunctionInfo<IonInstanceOfICFn>(IonInstanceOfIC::update, "IonInstanceOfIC::update");
|
||||
|
||||
typedef bool (*IonUnaryArithICFn)(JSContext* cx, HandleScript outerScript, IonUnaryArithIC* stub,
|
||||
HandleValue val, MutableHandleValue res);
|
||||
static const VMFunction IonUnaryArithICInfo =
|
||||
FunctionInfo<IonUnaryArithICFn>(IonUnaryArithIC::update, "IonUnaryArithIC::update");
|
||||
|
||||
void
|
||||
CodeGenerator::visitOutOfLineICFallback(OutOfLineICFallback* ool)
|
||||
{
|
||||
@ -355,6 +361,22 @@ CodeGenerator::visitOutOfLineICFallback(OutOfLineICFallback* ool)
|
||||
masm.jump(ool->rejoin());
|
||||
return;
|
||||
}
|
||||
case CacheKind::UnaryArith: {
|
||||
IonUnaryArithIC* unaryArithIC = ic->asUnaryArithIC();
|
||||
|
||||
saveLive(lir);
|
||||
|
||||
pushArg(unaryArithIC->input());
|
||||
icInfo_[cacheInfoIndex].icOffsetForPush = pushArgWithPatch(ImmWord(-1));
|
||||
pushArg(ImmGCPtr(gen->info().script()));
|
||||
callVM(IonUnaryArithICInfo, lir);
|
||||
|
||||
StoreValueTo(unaryArithIC->output()).generate(this);
|
||||
restoreLiveIgnore(lir, StoreValueTo(unaryArithIC->output()).clobbered());
|
||||
|
||||
masm.jump(ool->rejoin());
|
||||
return;
|
||||
}
|
||||
case CacheKind::Call:
|
||||
case CacheKind::Compare:
|
||||
case CacheKind::TypeOf:
|
||||
@ -2735,22 +2757,14 @@ CodeGenerator::visitBinarySharedStub(LBinarySharedStub* lir)
|
||||
}
|
||||
|
||||
void
|
||||
CodeGenerator::visitUnarySharedStub(LUnarySharedStub* lir)
|
||||
CodeGenerator::visitUnaryCache(LUnaryCache* lir)
|
||||
{
|
||||
JSOp jsop = JSOp(*lir->mir()->resumePoint()->pc());
|
||||
switch (jsop) {
|
||||
case JSOP_BITNOT:
|
||||
case JSOP_NEG:
|
||||
emitSharedStub(ICStub::Kind::UnaryArith_Fallback, lir);
|
||||
break;
|
||||
case JSOP_CALLPROP:
|
||||
case JSOP_GETPROP:
|
||||
case JSOP_LENGTH:
|
||||
emitSharedStub(ICStub::Kind::GetProp_Fallback, lir);
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("Unsupported jsop in shared stubs.");
|
||||
}
|
||||
LiveRegisterSet liveRegs = lir->safepoint()->liveRegs();
|
||||
TypedOrValueRegister input = TypedOrValueRegister(ToValue(lir, LUnaryCache::Input));
|
||||
ValueOperand output = GetValueOutput(lir);
|
||||
|
||||
IonUnaryArithIC ic(liveRegs, input, output);
|
||||
addIC(lir, allocateIC(ic));
|
||||
}
|
||||
|
||||
void
|
||||
@ -5346,7 +5360,7 @@ struct ScriptCountBlockState
|
||||
{
|
||||
// Prefix stream of assembly instructions with their LIR instruction
|
||||
// name and any associated high level info.
|
||||
if (const char* extra = ins->extraName())
|
||||
if (const char* extra = ins->getExtraName())
|
||||
printer.printf("[%s:%s]\n", ins->opName(), extra);
|
||||
else
|
||||
printer.printf("[%s]\n", ins->opName());
|
||||
@ -5681,7 +5695,7 @@ CodeGenerator::generateBody()
|
||||
|
||||
#ifdef JS_JITSPEW
|
||||
JitSpewStart(JitSpew_Codegen, "instruction %s", iter->opName());
|
||||
if (const char* extra = iter->extraName())
|
||||
if (const char* extra = iter->getExtraName())
|
||||
JitSpewCont(JitSpew_Codegen, ":%s", extra);
|
||||
JitSpewFin(JitSpew_Codegen);
|
||||
#endif
|
||||
@ -5713,12 +5727,20 @@ CodeGenerator::generateBody()
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
setElement(*iter); // needed to encode correct snapshot location.
|
||||
|
||||
#ifdef DEBUG
|
||||
emitDebugForceBailing(*iter);
|
||||
#endif
|
||||
|
||||
iter->accept(this);
|
||||
switch (iter->op()) {
|
||||
#define LIROP(op) case LNode::LOp_##op: visit##op(iter->to##op()); break;
|
||||
LIR_OPCODE_LIST(LIROP)
|
||||
#undef LIROP
|
||||
case LNode::LOp_Invalid:
|
||||
default:
|
||||
MOZ_CRASH("Invalid LIR op");
|
||||
}
|
||||
|
||||
// Track the end native offset of optimizations.
|
||||
if (iter->mirRaw() && iter->mirRaw()->trackedOptimizations())
|
||||
@ -9935,11 +9957,6 @@ CodeGenerator::linkSharedStubs(JSContext* cx)
|
||||
stub = stubCompiler.getStub(&stubSpace_);
|
||||
break;
|
||||
}
|
||||
case ICStub::Kind::UnaryArith_Fallback: {
|
||||
ICUnaryArith_Fallback::Compiler stubCompiler(cx, ICStubCompiler::Engine::IonSharedIC);
|
||||
stub = stubCompiler.getStub(&stubSpace_);
|
||||
break;
|
||||
}
|
||||
case ICStub::Kind::Compare_Fallback: {
|
||||
ICCompare_Fallback::Compiler stubCompiler(cx, ICStubCompiler::Engine::IonSharedIC);
|
||||
stub = stubCompiler.getStub(&stubSpace_);
|
||||
@ -13234,5 +13251,8 @@ CodeGenerator::visitGetPrototypeOf(LGetPrototypeOf* lir)
|
||||
masm.bind(ool->rejoin());
|
||||
}
|
||||
|
||||
static_assert(!std::is_polymorphic<CodeGenerator>::value,
|
||||
"CodeGenerator should not have any virtual methods");
|
||||
|
||||
} // namespace jit
|
||||
} // namespace js
|
||||
|
@ -79,89 +79,89 @@ class CodeGenerator final : public CodeGeneratorSpecific
|
||||
MOZ_MUST_USE bool link(JSContext* cx, CompilerConstraintList* constraints);
|
||||
MOZ_MUST_USE bool linkSharedStubs(JSContext* cx);
|
||||
|
||||
void visitOsiPoint(LOsiPoint* lir) override;
|
||||
void visitGoto(LGoto* lir) override;
|
||||
void visitTableSwitch(LTableSwitch* ins) override;
|
||||
void visitTableSwitchV(LTableSwitchV* ins) override;
|
||||
void visitCloneLiteral(LCloneLiteral* lir) override;
|
||||
void visitParameter(LParameter* lir) override;
|
||||
void visitCallee(LCallee* lir) override;
|
||||
void visitIsConstructing(LIsConstructing* lir) override;
|
||||
void visitStart(LStart* lir) override;
|
||||
void visitReturn(LReturn* ret) override;
|
||||
void visitDefVar(LDefVar* lir) override;
|
||||
void visitDefLexical(LDefLexical* lir) override;
|
||||
void visitDefFun(LDefFun* lir) override;
|
||||
void visitOsrEntry(LOsrEntry* lir) override;
|
||||
void visitOsrEnvironmentChain(LOsrEnvironmentChain* lir) override;
|
||||
void visitOsrValue(LOsrValue* lir) override;
|
||||
void visitOsrReturnValue(LOsrReturnValue* lir) override;
|
||||
void visitOsrArgumentsObject(LOsrArgumentsObject* lir) override;
|
||||
void visitStackArgT(LStackArgT* lir) override;
|
||||
void visitStackArgV(LStackArgV* lir) override;
|
||||
void visitMoveGroup(LMoveGroup* group) override;
|
||||
void visitValueToInt32(LValueToInt32* lir) override;
|
||||
void visitValueToDouble(LValueToDouble* lir) override;
|
||||
void visitValueToFloat32(LValueToFloat32* lir) override;
|
||||
void visitFloat32ToDouble(LFloat32ToDouble* lir) override;
|
||||
void visitDoubleToFloat32(LDoubleToFloat32* lir) override;
|
||||
void visitInt32ToFloat32(LInt32ToFloat32* lir) override;
|
||||
void visitInt32ToDouble(LInt32ToDouble* lir) override;
|
||||
void visitOsiPoint(LOsiPoint* lir);
|
||||
void visitGoto(LGoto* lir);
|
||||
void visitTableSwitch(LTableSwitch* ins);
|
||||
void visitTableSwitchV(LTableSwitchV* ins);
|
||||
void visitCloneLiteral(LCloneLiteral* lir);
|
||||
void visitParameter(LParameter* lir);
|
||||
void visitCallee(LCallee* lir);
|
||||
void visitIsConstructing(LIsConstructing* lir);
|
||||
void visitStart(LStart* lir);
|
||||
void visitReturn(LReturn* ret);
|
||||
void visitDefVar(LDefVar* lir);
|
||||
void visitDefLexical(LDefLexical* lir);
|
||||
void visitDefFun(LDefFun* lir);
|
||||
void visitOsrEntry(LOsrEntry* lir);
|
||||
void visitOsrEnvironmentChain(LOsrEnvironmentChain* lir);
|
||||
void visitOsrValue(LOsrValue* lir);
|
||||
void visitOsrReturnValue(LOsrReturnValue* lir);
|
||||
void visitOsrArgumentsObject(LOsrArgumentsObject* lir);
|
||||
void visitStackArgT(LStackArgT* lir);
|
||||
void visitStackArgV(LStackArgV* lir);
|
||||
void visitMoveGroup(LMoveGroup* group);
|
||||
void visitValueToInt32(LValueToInt32* lir);
|
||||
void visitValueToDouble(LValueToDouble* lir);
|
||||
void visitValueToFloat32(LValueToFloat32* lir);
|
||||
void visitFloat32ToDouble(LFloat32ToDouble* lir);
|
||||
void visitDoubleToFloat32(LDoubleToFloat32* lir);
|
||||
void visitInt32ToFloat32(LInt32ToFloat32* lir);
|
||||
void visitInt32ToDouble(LInt32ToDouble* lir);
|
||||
void emitOOLTestObject(Register objreg, Label* ifTruthy, Label* ifFalsy, Register scratch);
|
||||
void visitTestOAndBranch(LTestOAndBranch* lir) override;
|
||||
void visitTestVAndBranch(LTestVAndBranch* lir) override;
|
||||
void visitFunctionDispatch(LFunctionDispatch* lir) override;
|
||||
void visitObjectGroupDispatch(LObjectGroupDispatch* lir) override;
|
||||
void visitBooleanToString(LBooleanToString* lir) override;
|
||||
void visitTestOAndBranch(LTestOAndBranch* lir);
|
||||
void visitTestVAndBranch(LTestVAndBranch* lir);
|
||||
void visitFunctionDispatch(LFunctionDispatch* lir);
|
||||
void visitObjectGroupDispatch(LObjectGroupDispatch* lir);
|
||||
void visitBooleanToString(LBooleanToString* lir);
|
||||
void emitIntToString(Register input, Register output, Label* ool);
|
||||
void visitIntToString(LIntToString* lir) override;
|
||||
void visitDoubleToString(LDoubleToString* lir) override;
|
||||
void visitValueToString(LValueToString* lir) override;
|
||||
void visitValueToObject(LValueToObject* lir) override;
|
||||
void visitValueToObjectOrNull(LValueToObjectOrNull* lir) override;
|
||||
void visitInteger(LInteger* lir) override;
|
||||
void visitInteger64(LInteger64* lir) override;
|
||||
void visitRegExp(LRegExp* lir) override;
|
||||
void visitRegExpMatcher(LRegExpMatcher* lir) override;
|
||||
void visitIntToString(LIntToString* lir);
|
||||
void visitDoubleToString(LDoubleToString* lir);
|
||||
void visitValueToString(LValueToString* lir);
|
||||
void visitValueToObject(LValueToObject* lir);
|
||||
void visitValueToObjectOrNull(LValueToObjectOrNull* lir);
|
||||
void visitInteger(LInteger* lir);
|
||||
void visitInteger64(LInteger64* lir);
|
||||
void visitRegExp(LRegExp* lir);
|
||||
void visitRegExpMatcher(LRegExpMatcher* lir);
|
||||
void visitOutOfLineRegExpMatcher(OutOfLineRegExpMatcher* ool);
|
||||
void visitRegExpSearcher(LRegExpSearcher* lir) override;
|
||||
void visitRegExpSearcher(LRegExpSearcher* lir);
|
||||
void visitOutOfLineRegExpSearcher(OutOfLineRegExpSearcher* ool);
|
||||
void visitRegExpTester(LRegExpTester* lir) override;
|
||||
void visitRegExpTester(LRegExpTester* lir);
|
||||
void visitOutOfLineRegExpTester(OutOfLineRegExpTester* ool);
|
||||
void visitRegExpPrototypeOptimizable(LRegExpPrototypeOptimizable* lir) override;
|
||||
void visitRegExpPrototypeOptimizable(LRegExpPrototypeOptimizable* lir);
|
||||
void visitOutOfLineRegExpPrototypeOptimizable(OutOfLineRegExpPrototypeOptimizable* ool);
|
||||
void visitRegExpInstanceOptimizable(LRegExpInstanceOptimizable* lir) override;
|
||||
void visitRegExpInstanceOptimizable(LRegExpInstanceOptimizable* lir);
|
||||
void visitOutOfLineRegExpInstanceOptimizable(OutOfLineRegExpInstanceOptimizable* ool);
|
||||
void visitGetFirstDollarIndex(LGetFirstDollarIndex* lir) override;
|
||||
void visitStringReplace(LStringReplace* lir) override;
|
||||
void visitGetFirstDollarIndex(LGetFirstDollarIndex* lir);
|
||||
void visitStringReplace(LStringReplace* lir);
|
||||
void emitSharedStub(ICStub::Kind kind, LInstruction* lir);
|
||||
void visitBinarySharedStub(LBinarySharedStub* lir) override;
|
||||
void visitUnarySharedStub(LUnarySharedStub* lir) override;
|
||||
void visitNullarySharedStub(LNullarySharedStub* lir) override;
|
||||
void visitClassConstructor(LClassConstructor* lir) override;
|
||||
void visitLambda(LLambda* lir) override;
|
||||
void visitBinarySharedStub(LBinarySharedStub* lir);
|
||||
void visitUnaryCache(LUnaryCache* lir);
|
||||
void visitNullarySharedStub(LNullarySharedStub* lir);
|
||||
void visitClassConstructor(LClassConstructor* lir);
|
||||
void visitLambda(LLambda* lir);
|
||||
void visitOutOfLineLambdaArrow(OutOfLineLambdaArrow* ool);
|
||||
void visitLambdaArrow(LLambdaArrow* lir) override;
|
||||
void visitLambdaForSingleton(LLambdaForSingleton* lir) override;
|
||||
void visitSetFunName(LSetFunName* lir) override;
|
||||
void visitPointer(LPointer* lir) override;
|
||||
void visitKeepAliveObject(LKeepAliveObject* lir) override;
|
||||
void visitSlots(LSlots* lir) override;
|
||||
void visitLoadSlotT(LLoadSlotT* lir) override;
|
||||
void visitLoadSlotV(LLoadSlotV* lir) override;
|
||||
void visitStoreSlotT(LStoreSlotT* lir) override;
|
||||
void visitStoreSlotV(LStoreSlotV* lir) override;
|
||||
void visitElements(LElements* lir) override;
|
||||
void visitConvertElementsToDoubles(LConvertElementsToDoubles* lir) override;
|
||||
void visitMaybeToDoubleElement(LMaybeToDoubleElement* lir) override;
|
||||
void visitMaybeCopyElementsForWrite(LMaybeCopyElementsForWrite* lir) override;
|
||||
void visitGuardObjectIdentity(LGuardObjectIdentity* guard) override;
|
||||
void visitGuardReceiverPolymorphic(LGuardReceiverPolymorphic* lir) override;
|
||||
void visitGuardUnboxedExpando(LGuardUnboxedExpando* lir) override;
|
||||
void visitLoadUnboxedExpando(LLoadUnboxedExpando* lir) override;
|
||||
void visitTypeBarrierV(LTypeBarrierV* lir) override;
|
||||
void visitTypeBarrierO(LTypeBarrierO* lir) override;
|
||||
void visitMonitorTypes(LMonitorTypes* lir) override;
|
||||
void visitLambdaArrow(LLambdaArrow* lir);
|
||||
void visitLambdaForSingleton(LLambdaForSingleton* lir);
|
||||
void visitSetFunName(LSetFunName* lir);
|
||||
void visitPointer(LPointer* lir);
|
||||
void visitKeepAliveObject(LKeepAliveObject* lir);
|
||||
void visitSlots(LSlots* lir);
|
||||
void visitLoadSlotT(LLoadSlotT* lir);
|
||||
void visitLoadSlotV(LLoadSlotV* lir);
|
||||
void visitStoreSlotT(LStoreSlotT* lir);
|
||||
void visitStoreSlotV(LStoreSlotV* lir);
|
||||
void visitElements(LElements* lir);
|
||||
void visitConvertElementsToDoubles(LConvertElementsToDoubles* lir);
|
||||
void visitMaybeToDoubleElement(LMaybeToDoubleElement* lir);
|
||||
void visitMaybeCopyElementsForWrite(LMaybeCopyElementsForWrite* lir);
|
||||
void visitGuardObjectIdentity(LGuardObjectIdentity* guard);
|
||||
void visitGuardReceiverPolymorphic(LGuardReceiverPolymorphic* lir);
|
||||
void visitGuardUnboxedExpando(LGuardUnboxedExpando* lir);
|
||||
void visitLoadUnboxedExpando(LLoadUnboxedExpando* lir);
|
||||
void visitTypeBarrierV(LTypeBarrierV* lir);
|
||||
void visitTypeBarrierO(LTypeBarrierO* lir);
|
||||
void visitMonitorTypes(LMonitorTypes* lir);
|
||||
void emitPostWriteBarrier(const LAllocation* obj);
|
||||
void emitPostWriteBarrier(Register objreg);
|
||||
void emitPostWriteBarrierS(Address address, Register prev, Register next);
|
||||
@ -169,24 +169,24 @@ class CodeGenerator final : public CodeGeneratorSpecific
|
||||
void visitPostWriteBarrierCommon(LPostBarrierType* lir, OutOfLineCode* ool);
|
||||
template <class LPostBarrierType>
|
||||
void visitPostWriteBarrierCommonV(LPostBarrierType* lir, OutOfLineCode* ool);
|
||||
void visitPostWriteBarrierO(LPostWriteBarrierO* lir) override;
|
||||
void visitPostWriteElementBarrierO(LPostWriteElementBarrierO* lir) override;
|
||||
void visitPostWriteBarrierV(LPostWriteBarrierV* lir) override;
|
||||
void visitPostWriteElementBarrierV(LPostWriteElementBarrierV* lir) override;
|
||||
void visitPostWriteBarrierS(LPostWriteBarrierS* lir) override;
|
||||
void visitPostWriteElementBarrierS(LPostWriteElementBarrierS* lir) override;
|
||||
void visitPostWriteBarrierO(LPostWriteBarrierO* lir);
|
||||
void visitPostWriteElementBarrierO(LPostWriteElementBarrierO* lir);
|
||||
void visitPostWriteBarrierV(LPostWriteBarrierV* lir);
|
||||
void visitPostWriteElementBarrierV(LPostWriteElementBarrierV* lir);
|
||||
void visitPostWriteBarrierS(LPostWriteBarrierS* lir);
|
||||
void visitPostWriteElementBarrierS(LPostWriteElementBarrierS* lir);
|
||||
void visitOutOfLineCallPostWriteBarrier(OutOfLineCallPostWriteBarrier* ool);
|
||||
void visitOutOfLineCallPostWriteElementBarrier(OutOfLineCallPostWriteElementBarrier* ool);
|
||||
void visitCallNative(LCallNative* call) override;
|
||||
void visitCallNative(LCallNative* call);
|
||||
void emitCallInvokeFunction(LInstruction* call, Register callereg,
|
||||
bool isConstructing, bool ignoresReturnValue,
|
||||
uint32_t argc, uint32_t unusedStack);
|
||||
void visitCallGeneric(LCallGeneric* call) override;
|
||||
void visitCallGeneric(LCallGeneric* call);
|
||||
void emitCallInvokeFunctionShuffleNewTarget(LCallKnown *call,
|
||||
Register calleeReg,
|
||||
uint32_t numFormals,
|
||||
uint32_t unusedStack);
|
||||
void visitCallKnown(LCallKnown* call) override;
|
||||
void visitCallKnown(LCallKnown* call);
|
||||
template<typename T> void emitApplyGeneric(T* apply);
|
||||
template<typename T> void emitCallInvokeFunction(T* apply, Register extraStackSize);
|
||||
void emitAllocateSpaceForApply(Register argcreg, Register extraStackSpace, Label* end);
|
||||
@ -194,243 +194,243 @@ class CodeGenerator final : public CodeGeneratorSpecific
|
||||
size_t argvSrcOffset, size_t argvDstOffset);
|
||||
void emitPopArguments(Register extraStackSize);
|
||||
void emitPushArguments(LApplyArgsGeneric* apply, Register extraStackSpace);
|
||||
void visitApplyArgsGeneric(LApplyArgsGeneric* apply) override;
|
||||
void visitApplyArgsGeneric(LApplyArgsGeneric* apply);
|
||||
void emitPushArguments(LApplyArrayGeneric* apply, Register extraStackSpace);
|
||||
void visitApplyArrayGeneric(LApplyArrayGeneric* apply) override;
|
||||
void visitBail(LBail* lir) override;
|
||||
void visitUnreachable(LUnreachable* unreachable) override;
|
||||
void visitEncodeSnapshot(LEncodeSnapshot* lir) override;
|
||||
void visitGetDynamicName(LGetDynamicName* lir) override;
|
||||
void visitCallDirectEval(LCallDirectEval* lir) override;
|
||||
void visitDoubleToInt32(LDoubleToInt32* lir) override;
|
||||
void visitFloat32ToInt32(LFloat32ToInt32* lir) override;
|
||||
void visitApplyArrayGeneric(LApplyArrayGeneric* apply);
|
||||
void visitBail(LBail* lir);
|
||||
void visitUnreachable(LUnreachable* unreachable);
|
||||
void visitEncodeSnapshot(LEncodeSnapshot* lir);
|
||||
void visitGetDynamicName(LGetDynamicName* lir);
|
||||
void visitCallDirectEval(LCallDirectEval* lir);
|
||||
void visitDoubleToInt32(LDoubleToInt32* lir);
|
||||
void visitFloat32ToInt32(LFloat32ToInt32* lir);
|
||||
void visitNewArrayCallVM(LNewArray* lir);
|
||||
void visitNewArray(LNewArray* lir) override;
|
||||
void visitNewArray(LNewArray* lir);
|
||||
void visitOutOfLineNewArray(OutOfLineNewArray* ool);
|
||||
void visitNewArrayCopyOnWrite(LNewArrayCopyOnWrite* lir) override;
|
||||
void visitNewArrayDynamicLength(LNewArrayDynamicLength* lir) override;
|
||||
void visitNewIterator(LNewIterator* lir) override;
|
||||
void visitNewTypedArray(LNewTypedArray* lir) override;
|
||||
void visitNewTypedArrayDynamicLength(LNewTypedArrayDynamicLength* lir) override;
|
||||
void visitNewArrayCopyOnWrite(LNewArrayCopyOnWrite* lir);
|
||||
void visitNewArrayDynamicLength(LNewArrayDynamicLength* lir);
|
||||
void visitNewIterator(LNewIterator* lir);
|
||||
void visitNewTypedArray(LNewTypedArray* lir);
|
||||
void visitNewTypedArrayDynamicLength(LNewTypedArrayDynamicLength* lir);
|
||||
void visitNewObjectVMCall(LNewObject* lir);
|
||||
void visitNewObject(LNewObject* lir) override;
|
||||
void visitNewObject(LNewObject* lir);
|
||||
void visitOutOfLineNewObject(OutOfLineNewObject* ool);
|
||||
void visitNewTypedObject(LNewTypedObject* lir) override;
|
||||
void visitSimdBox(LSimdBox* lir) override;
|
||||
void visitSimdUnbox(LSimdUnbox* lir) override;
|
||||
void visitNewNamedLambdaObject(LNewNamedLambdaObject* lir) override;
|
||||
void visitNewCallObject(LNewCallObject* lir) override;
|
||||
void visitNewSingletonCallObject(LNewSingletonCallObject* lir) override;
|
||||
void visitNewStringObject(LNewStringObject* lir) override;
|
||||
void visitNewDerivedTypedObject(LNewDerivedTypedObject* lir) override;
|
||||
void visitInitElem(LInitElem* lir) override;
|
||||
void visitInitElemGetterSetter(LInitElemGetterSetter* lir) override;
|
||||
void visitMutateProto(LMutateProto* lir) override;
|
||||
void visitInitPropGetterSetter(LInitPropGetterSetter* lir) override;
|
||||
void visitCreateThis(LCreateThis* lir) override;
|
||||
void visitCreateThisWithProto(LCreateThisWithProto* lir) override;
|
||||
void visitCreateThisWithTemplate(LCreateThisWithTemplate* lir) override;
|
||||
void visitCreateArgumentsObject(LCreateArgumentsObject* lir) override;
|
||||
void visitGetArgumentsObjectArg(LGetArgumentsObjectArg* lir) override;
|
||||
void visitSetArgumentsObjectArg(LSetArgumentsObjectArg* lir) override;
|
||||
void visitReturnFromCtor(LReturnFromCtor* lir) override;
|
||||
void visitComputeThis(LComputeThis* lir) override;
|
||||
void visitImplicitThis(LImplicitThis* lir) override;
|
||||
void visitArrayLength(LArrayLength* lir) override;
|
||||
void visitSetArrayLength(LSetArrayLength* lir) override;
|
||||
void visitGetNextEntryForIterator(LGetNextEntryForIterator* lir) override;
|
||||
void visitTypedArrayLength(LTypedArrayLength* lir) override;
|
||||
void visitTypedArrayElements(LTypedArrayElements* lir) override;
|
||||
void visitSetDisjointTypedElements(LSetDisjointTypedElements* lir) override;
|
||||
void visitTypedObjectElements(LTypedObjectElements* lir) override;
|
||||
void visitSetTypedObjectOffset(LSetTypedObjectOffset* lir) override;
|
||||
void visitTypedObjectDescr(LTypedObjectDescr* ins) override;
|
||||
void visitStringLength(LStringLength* lir) override;
|
||||
void visitSubstr(LSubstr* lir) override;
|
||||
void visitInitializedLength(LInitializedLength* lir) override;
|
||||
void visitSetInitializedLength(LSetInitializedLength* lir) override;
|
||||
void visitNotO(LNotO* ins) override;
|
||||
void visitNotV(LNotV* ins) override;
|
||||
void visitBoundsCheck(LBoundsCheck* lir) override;
|
||||
void visitBoundsCheckRange(LBoundsCheckRange* lir) override;
|
||||
void visitBoundsCheckLower(LBoundsCheckLower* lir) override;
|
||||
void visitSpectreMaskIndex(LSpectreMaskIndex* lir) override;
|
||||
void visitLoadFixedSlotV(LLoadFixedSlotV* ins) override;
|
||||
void visitLoadFixedSlotAndUnbox(LLoadFixedSlotAndUnbox* lir) override;
|
||||
void visitLoadFixedSlotT(LLoadFixedSlotT* ins) override;
|
||||
void visitStoreFixedSlotV(LStoreFixedSlotV* ins) override;
|
||||
void visitStoreFixedSlotT(LStoreFixedSlotT* ins) override;
|
||||
void visitNewTypedObject(LNewTypedObject* lir);
|
||||
void visitSimdBox(LSimdBox* lir);
|
||||
void visitSimdUnbox(LSimdUnbox* lir);
|
||||
void visitNewNamedLambdaObject(LNewNamedLambdaObject* lir);
|
||||
void visitNewCallObject(LNewCallObject* lir);
|
||||
void visitNewSingletonCallObject(LNewSingletonCallObject* lir);
|
||||
void visitNewStringObject(LNewStringObject* lir);
|
||||
void visitNewDerivedTypedObject(LNewDerivedTypedObject* lir);
|
||||
void visitInitElem(LInitElem* lir);
|
||||
void visitInitElemGetterSetter(LInitElemGetterSetter* lir);
|
||||
void visitMutateProto(LMutateProto* lir);
|
||||
void visitInitPropGetterSetter(LInitPropGetterSetter* lir);
|
||||
void visitCreateThis(LCreateThis* lir);
|
||||
void visitCreateThisWithProto(LCreateThisWithProto* lir);
|
||||
void visitCreateThisWithTemplate(LCreateThisWithTemplate* lir);
|
||||
void visitCreateArgumentsObject(LCreateArgumentsObject* lir);
|
||||
void visitGetArgumentsObjectArg(LGetArgumentsObjectArg* lir);
|
||||
void visitSetArgumentsObjectArg(LSetArgumentsObjectArg* lir);
|
||||
void visitReturnFromCtor(LReturnFromCtor* lir);
|
||||
void visitComputeThis(LComputeThis* lir);
|
||||
void visitImplicitThis(LImplicitThis* lir);
|
||||
void visitArrayLength(LArrayLength* lir);
|
||||
void visitSetArrayLength(LSetArrayLength* lir);
|
||||
void visitGetNextEntryForIterator(LGetNextEntryForIterator* lir);
|
||||
void visitTypedArrayLength(LTypedArrayLength* lir);
|
||||
void visitTypedArrayElements(LTypedArrayElements* lir);
|
||||
void visitSetDisjointTypedElements(LSetDisjointTypedElements* lir);
|
||||
void visitTypedObjectElements(LTypedObjectElements* lir);
|
||||
void visitSetTypedObjectOffset(LSetTypedObjectOffset* lir);
|
||||
void visitTypedObjectDescr(LTypedObjectDescr* ins);
|
||||
void visitStringLength(LStringLength* lir);
|
||||
void visitSubstr(LSubstr* lir);
|
||||
void visitInitializedLength(LInitializedLength* lir);
|
||||
void visitSetInitializedLength(LSetInitializedLength* lir);
|
||||
void visitNotO(LNotO* ins);
|
||||
void visitNotV(LNotV* ins);
|
||||
void visitBoundsCheck(LBoundsCheck* lir);
|
||||
void visitBoundsCheckRange(LBoundsCheckRange* lir);
|
||||
void visitBoundsCheckLower(LBoundsCheckLower* lir);
|
||||
void visitSpectreMaskIndex(LSpectreMaskIndex* lir);
|
||||
void visitLoadFixedSlotV(LLoadFixedSlotV* ins);
|
||||
void visitLoadFixedSlotAndUnbox(LLoadFixedSlotAndUnbox* lir);
|
||||
void visitLoadFixedSlotT(LLoadFixedSlotT* ins);
|
||||
void visitStoreFixedSlotV(LStoreFixedSlotV* ins);
|
||||
void visitStoreFixedSlotT(LStoreFixedSlotT* ins);
|
||||
void emitGetPropertyPolymorphic(LInstruction* lir, Register obj,
|
||||
Register scratch, const TypedOrValueRegister& output);
|
||||
void visitGetPropertyPolymorphicV(LGetPropertyPolymorphicV* ins) override;
|
||||
void visitGetPropertyPolymorphicT(LGetPropertyPolymorphicT* ins) override;
|
||||
void visitGetPropertyPolymorphicV(LGetPropertyPolymorphicV* ins);
|
||||
void visitGetPropertyPolymorphicT(LGetPropertyPolymorphicT* ins);
|
||||
void emitSetPropertyPolymorphic(LInstruction* lir, Register obj,
|
||||
Register scratch, const ConstantOrRegister& value);
|
||||
void visitSetPropertyPolymorphicV(LSetPropertyPolymorphicV* ins) override;
|
||||
void visitSetPropertyPolymorphicT(LSetPropertyPolymorphicT* ins) override;
|
||||
void visitAbsI(LAbsI* lir) override;
|
||||
void visitAtan2D(LAtan2D* lir) override;
|
||||
void visitHypot(LHypot* lir) override;
|
||||
void visitPowI(LPowI* lir) override;
|
||||
void visitPowD(LPowD* lir) override;
|
||||
void visitPowV(LPowV* lir) override;
|
||||
void visitMathFunctionD(LMathFunctionD* ins) override;
|
||||
void visitMathFunctionF(LMathFunctionF* ins) override;
|
||||
void visitModD(LModD* ins) override;
|
||||
void visitMinMaxI(LMinMaxI* lir) override;
|
||||
void visitBinaryV(LBinaryV* lir) override;
|
||||
void visitSetPropertyPolymorphicV(LSetPropertyPolymorphicV* ins);
|
||||
void visitSetPropertyPolymorphicT(LSetPropertyPolymorphicT* ins);
|
||||
void visitAbsI(LAbsI* lir);
|
||||
void visitAtan2D(LAtan2D* lir);
|
||||
void visitHypot(LHypot* lir);
|
||||
void visitPowI(LPowI* lir);
|
||||
void visitPowD(LPowD* lir);
|
||||
void visitPowV(LPowV* lir);
|
||||
void visitMathFunctionD(LMathFunctionD* ins);
|
||||
void visitMathFunctionF(LMathFunctionF* ins);
|
||||
void visitModD(LModD* ins);
|
||||
void visitMinMaxI(LMinMaxI* lir);
|
||||
void visitBinaryV(LBinaryV* lir);
|
||||
void emitCompareS(LInstruction* lir, JSOp op, Register left, Register right, Register output);
|
||||
void visitCompareS(LCompareS* lir) override;
|
||||
void visitCompareStrictS(LCompareStrictS* lir) override;
|
||||
void visitCompareVM(LCompareVM* lir) override;
|
||||
void visitIsNullOrLikeUndefinedV(LIsNullOrLikeUndefinedV* lir) override;
|
||||
void visitIsNullOrLikeUndefinedT(LIsNullOrLikeUndefinedT* lir) override;
|
||||
void visitIsNullOrLikeUndefinedAndBranchV(LIsNullOrLikeUndefinedAndBranchV* lir) override;
|
||||
void visitIsNullOrLikeUndefinedAndBranchT(LIsNullOrLikeUndefinedAndBranchT* lir) override;
|
||||
void visitCompareS(LCompareS* lir);
|
||||
void visitCompareStrictS(LCompareStrictS* lir);
|
||||
void visitCompareVM(LCompareVM* lir);
|
||||
void visitIsNullOrLikeUndefinedV(LIsNullOrLikeUndefinedV* lir);
|
||||
void visitIsNullOrLikeUndefinedT(LIsNullOrLikeUndefinedT* lir);
|
||||
void visitIsNullOrLikeUndefinedAndBranchV(LIsNullOrLikeUndefinedAndBranchV* lir);
|
||||
void visitIsNullOrLikeUndefinedAndBranchT(LIsNullOrLikeUndefinedAndBranchT* lir);
|
||||
void emitSameValue(FloatRegister left, FloatRegister right, FloatRegister temp,
|
||||
Register output);
|
||||
void visitSameValueD(LSameValueD* lir) override;
|
||||
void visitSameValueV(LSameValueV* lir) override;
|
||||
void visitSameValueVM(LSameValueVM* lir) override;
|
||||
void visitSameValueD(LSameValueD* lir);
|
||||
void visitSameValueV(LSameValueV* lir);
|
||||
void visitSameValueVM(LSameValueVM* lir);
|
||||
void emitConcat(LInstruction* lir, Register lhs, Register rhs, Register output);
|
||||
void visitConcat(LConcat* lir) override;
|
||||
void visitCharCodeAt(LCharCodeAt* lir) override;
|
||||
void visitFromCharCode(LFromCharCode* lir) override;
|
||||
void visitFromCodePoint(LFromCodePoint* lir) override;
|
||||
void visitStringConvertCase(LStringConvertCase* lir) override;
|
||||
void visitSinCos(LSinCos *lir) override;
|
||||
void visitStringSplit(LStringSplit* lir) override;
|
||||
void visitFunctionEnvironment(LFunctionEnvironment* lir) override;
|
||||
void visitHomeObject(LHomeObject* lir) override;
|
||||
void visitHomeObjectSuperBase(LHomeObjectSuperBase* lir) override;
|
||||
void visitNewLexicalEnvironmentObject(LNewLexicalEnvironmentObject* lir) override;
|
||||
void visitCopyLexicalEnvironmentObject(LCopyLexicalEnvironmentObject* lir) override;
|
||||
void visitCallGetProperty(LCallGetProperty* lir) override;
|
||||
void visitCallGetElement(LCallGetElement* lir) override;
|
||||
void visitCallSetElement(LCallSetElement* lir) override;
|
||||
void visitCallInitElementArray(LCallInitElementArray* lir) override;
|
||||
void visitThrow(LThrow* lir) override;
|
||||
void visitTypeOfV(LTypeOfV* lir) override;
|
||||
void visitConcat(LConcat* lir);
|
||||
void visitCharCodeAt(LCharCodeAt* lir);
|
||||
void visitFromCharCode(LFromCharCode* lir);
|
||||
void visitFromCodePoint(LFromCodePoint* lir);
|
||||
void visitStringConvertCase(LStringConvertCase* lir);
|
||||
void visitSinCos(LSinCos *lir);
|
||||
void visitStringSplit(LStringSplit* lir);
|
||||
void visitFunctionEnvironment(LFunctionEnvironment* lir);
|
||||
void visitHomeObject(LHomeObject* lir);
|
||||
void visitHomeObjectSuperBase(LHomeObjectSuperBase* lir);
|
||||
void visitNewLexicalEnvironmentObject(LNewLexicalEnvironmentObject* lir);
|
||||
void visitCopyLexicalEnvironmentObject(LCopyLexicalEnvironmentObject* lir);
|
||||
void visitCallGetProperty(LCallGetProperty* lir);
|
||||
void visitCallGetElement(LCallGetElement* lir);
|
||||
void visitCallSetElement(LCallSetElement* lir);
|
||||
void visitCallInitElementArray(LCallInitElementArray* lir);
|
||||
void visitThrow(LThrow* lir);
|
||||
void visitTypeOfV(LTypeOfV* lir);
|
||||
void visitOutOfLineTypeOfV(OutOfLineTypeOfV* ool);
|
||||
void visitToAsync(LToAsync* lir) override;
|
||||
void visitToAsyncGen(LToAsyncGen* lir) override;
|
||||
void visitToAsyncIter(LToAsyncIter* lir) override;
|
||||
void visitToIdV(LToIdV* lir) override;
|
||||
void visitToAsync(LToAsync* lir);
|
||||
void visitToAsyncGen(LToAsyncGen* lir);
|
||||
void visitToAsyncIter(LToAsyncIter* lir);
|
||||
void visitToIdV(LToIdV* lir);
|
||||
template<typename T> void emitLoadElementT(LLoadElementT* lir, const T& source);
|
||||
void visitLoadElementT(LLoadElementT* lir) override;
|
||||
void visitLoadElementV(LLoadElementV* load) override;
|
||||
void visitLoadElementHole(LLoadElementHole* lir) override;
|
||||
void visitLoadUnboxedPointerV(LLoadUnboxedPointerV* lir) override;
|
||||
void visitLoadUnboxedPointerT(LLoadUnboxedPointerT* lir) override;
|
||||
void visitUnboxObjectOrNull(LUnboxObjectOrNull* lir) override;
|
||||
void visitLoadElementT(LLoadElementT* lir);
|
||||
void visitLoadElementV(LLoadElementV* load);
|
||||
void visitLoadElementHole(LLoadElementHole* lir);
|
||||
void visitLoadUnboxedPointerV(LLoadUnboxedPointerV* lir);
|
||||
void visitLoadUnboxedPointerT(LLoadUnboxedPointerT* lir);
|
||||
void visitUnboxObjectOrNull(LUnboxObjectOrNull* lir);
|
||||
template <SwitchTableType tableType>
|
||||
void visitOutOfLineSwitch(OutOfLineSwitch<tableType>* ool);
|
||||
void visitLoadElementFromStateV(LLoadElementFromStateV* lir) override;
|
||||
void visitStoreElementT(LStoreElementT* lir) override;
|
||||
void visitStoreElementV(LStoreElementV* lir) override;
|
||||
void visitLoadElementFromStateV(LLoadElementFromStateV* lir);
|
||||
void visitStoreElementT(LStoreElementT* lir);
|
||||
void visitStoreElementV(LStoreElementV* lir);
|
||||
template <typename T> void emitStoreElementHoleT(T* lir);
|
||||
template <typename T> void emitStoreElementHoleV(T* lir);
|
||||
void visitStoreElementHoleT(LStoreElementHoleT* lir) override;
|
||||
void visitStoreElementHoleV(LStoreElementHoleV* lir) override;
|
||||
void visitFallibleStoreElementV(LFallibleStoreElementV* lir) override;
|
||||
void visitFallibleStoreElementT(LFallibleStoreElementT* lir) override;
|
||||
void visitStoreUnboxedPointer(LStoreUnboxedPointer* lir) override;
|
||||
void visitConvertUnboxedObjectToNative(LConvertUnboxedObjectToNative* lir) override;
|
||||
void visitStoreElementHoleT(LStoreElementHoleT* lir);
|
||||
void visitStoreElementHoleV(LStoreElementHoleV* lir);
|
||||
void visitFallibleStoreElementV(LFallibleStoreElementV* lir);
|
||||
void visitFallibleStoreElementT(LFallibleStoreElementT* lir);
|
||||
void visitStoreUnboxedPointer(LStoreUnboxedPointer* lir);
|
||||
void visitConvertUnboxedObjectToNative(LConvertUnboxedObjectToNative* lir);
|
||||
void emitArrayPopShift(LInstruction* lir, const MArrayPopShift* mir, Register obj,
|
||||
Register elementsTemp, Register lengthTemp, TypedOrValueRegister out);
|
||||
void visitArrayPopShiftV(LArrayPopShiftV* lir) override;
|
||||
void visitArrayPopShiftT(LArrayPopShiftT* lir) override;
|
||||
void visitArrayPopShiftV(LArrayPopShiftV* lir);
|
||||
void visitArrayPopShiftT(LArrayPopShiftT* lir);
|
||||
void emitArrayPush(LInstruction* lir, const MArrayPush* mir, Register obj,
|
||||
const ConstantOrRegister& value, Register elementsTemp, Register length);
|
||||
void visitArrayPushV(LArrayPushV* lir) override;
|
||||
void visitArrayPushT(LArrayPushT* lir) override;
|
||||
void visitArraySlice(LArraySlice* lir) override;
|
||||
void visitArrayJoin(LArrayJoin* lir) override;
|
||||
void visitLoadUnboxedScalar(LLoadUnboxedScalar* lir) override;
|
||||
void visitLoadTypedArrayElementHole(LLoadTypedArrayElementHole* lir) override;
|
||||
void visitStoreUnboxedScalar(LStoreUnboxedScalar* lir) override;
|
||||
void visitStoreTypedArrayElementHole(LStoreTypedArrayElementHole* lir) override;
|
||||
void visitAtomicIsLockFree(LAtomicIsLockFree* lir) override;
|
||||
void visitGuardSharedTypedArray(LGuardSharedTypedArray* lir) override;
|
||||
void visitClampIToUint8(LClampIToUint8* lir) override;
|
||||
void visitClampDToUint8(LClampDToUint8* lir) override;
|
||||
void visitClampVToUint8(LClampVToUint8* lir) override;
|
||||
void visitGetIteratorCache(LGetIteratorCache* lir) override;
|
||||
void visitIteratorMore(LIteratorMore* lir) override;
|
||||
void visitIsNoIterAndBranch(LIsNoIterAndBranch* lir) override;
|
||||
void visitIteratorEnd(LIteratorEnd* lir) override;
|
||||
void visitArgumentsLength(LArgumentsLength* lir) override;
|
||||
void visitGetFrameArgument(LGetFrameArgument* lir) override;
|
||||
void visitSetFrameArgumentT(LSetFrameArgumentT* lir) override;
|
||||
void visitSetFrameArgumentC(LSetFrameArgumentC* lir) override;
|
||||
void visitSetFrameArgumentV(LSetFrameArgumentV* lir) override;
|
||||
void visitRunOncePrologue(LRunOncePrologue* lir) override;
|
||||
void visitArrayPushV(LArrayPushV* lir);
|
||||
void visitArrayPushT(LArrayPushT* lir);
|
||||
void visitArraySlice(LArraySlice* lir);
|
||||
void visitArrayJoin(LArrayJoin* lir);
|
||||
void visitLoadUnboxedScalar(LLoadUnboxedScalar* lir);
|
||||
void visitLoadTypedArrayElementHole(LLoadTypedArrayElementHole* lir);
|
||||
void visitStoreUnboxedScalar(LStoreUnboxedScalar* lir);
|
||||
void visitStoreTypedArrayElementHole(LStoreTypedArrayElementHole* lir);
|
||||
void visitAtomicIsLockFree(LAtomicIsLockFree* lir);
|
||||
void visitGuardSharedTypedArray(LGuardSharedTypedArray* lir);
|
||||
void visitClampIToUint8(LClampIToUint8* lir);
|
||||
void visitClampDToUint8(LClampDToUint8* lir);
|
||||
void visitClampVToUint8(LClampVToUint8* lir);
|
||||
void visitGetIteratorCache(LGetIteratorCache* lir);
|
||||
void visitIteratorMore(LIteratorMore* lir);
|
||||
void visitIsNoIterAndBranch(LIsNoIterAndBranch* lir);
|
||||
void visitIteratorEnd(LIteratorEnd* lir);
|
||||
void visitArgumentsLength(LArgumentsLength* lir);
|
||||
void visitGetFrameArgument(LGetFrameArgument* lir);
|
||||
void visitSetFrameArgumentT(LSetFrameArgumentT* lir);
|
||||
void visitSetFrameArgumentC(LSetFrameArgumentC* lir);
|
||||
void visitSetFrameArgumentV(LSetFrameArgumentV* lir);
|
||||
void visitRunOncePrologue(LRunOncePrologue* lir);
|
||||
void emitRest(LInstruction* lir, Register array, Register numActuals,
|
||||
Register temp0, Register temp1, unsigned numFormals,
|
||||
JSObject* templateObject, bool saveAndRestore, Register resultreg);
|
||||
void visitRest(LRest* lir) override;
|
||||
void visitCallSetProperty(LCallSetProperty* ins) override;
|
||||
void visitCallDeleteProperty(LCallDeleteProperty* lir) override;
|
||||
void visitCallDeleteElement(LCallDeleteElement* lir) override;
|
||||
void visitBitNotV(LBitNotV* lir) override;
|
||||
void visitBitOpV(LBitOpV* lir) override;
|
||||
void visitRest(LRest* lir);
|
||||
void visitCallSetProperty(LCallSetProperty* ins);
|
||||
void visitCallDeleteProperty(LCallDeleteProperty* lir);
|
||||
void visitCallDeleteElement(LCallDeleteElement* lir);
|
||||
void visitBitNotV(LBitNotV* lir);
|
||||
void visitBitOpV(LBitOpV* lir);
|
||||
void emitInstanceOf(LInstruction* ins, JSObject* prototypeObject);
|
||||
void visitInCache(LInCache* ins) override;
|
||||
void visitInArray(LInArray* ins) override;
|
||||
void visitInstanceOfO(LInstanceOfO* ins) override;
|
||||
void visitInstanceOfV(LInstanceOfV* ins) override;
|
||||
void visitInstanceOfCache(LInstanceOfCache* ins) override;
|
||||
void visitGetDOMProperty(LGetDOMProperty* lir) override;
|
||||
void visitGetDOMMemberV(LGetDOMMemberV* lir) override;
|
||||
void visitGetDOMMemberT(LGetDOMMemberT* lir) override;
|
||||
void visitSetDOMProperty(LSetDOMProperty* lir) override;
|
||||
void visitCallDOMNative(LCallDOMNative* lir) override;
|
||||
void visitCallGetIntrinsicValue(LCallGetIntrinsicValue* lir) override;
|
||||
void visitCallBindVar(LCallBindVar* lir) override;
|
||||
void visitInCache(LInCache* ins);
|
||||
void visitInArray(LInArray* ins);
|
||||
void visitInstanceOfO(LInstanceOfO* ins);
|
||||
void visitInstanceOfV(LInstanceOfV* ins);
|
||||
void visitInstanceOfCache(LInstanceOfCache* ins);
|
||||
void visitGetDOMProperty(LGetDOMProperty* lir);
|
||||
void visitGetDOMMemberV(LGetDOMMemberV* lir);
|
||||
void visitGetDOMMemberT(LGetDOMMemberT* lir);
|
||||
void visitSetDOMProperty(LSetDOMProperty* lir);
|
||||
void visitCallDOMNative(LCallDOMNative* lir);
|
||||
void visitCallGetIntrinsicValue(LCallGetIntrinsicValue* lir);
|
||||
void visitCallBindVar(LCallBindVar* lir);
|
||||
enum CallableOrConstructor {
|
||||
Callable,
|
||||
Constructor
|
||||
};
|
||||
template <CallableOrConstructor mode>
|
||||
void emitIsCallableOrConstructor(Register object, Register output, Label* failure);
|
||||
void visitIsCallableO(LIsCallableO* lir) override;
|
||||
void visitIsCallableV(LIsCallableV* lir) override;
|
||||
void visitIsCallableO(LIsCallableO* lir);
|
||||
void visitIsCallableV(LIsCallableV* lir);
|
||||
void visitOutOfLineIsCallable(OutOfLineIsCallable* ool);
|
||||
void visitIsConstructor(LIsConstructor* lir) override;
|
||||
void visitIsConstructor(LIsConstructor* lir);
|
||||
void visitOutOfLineIsConstructor(OutOfLineIsConstructor* ool);
|
||||
void visitIsArrayO(LIsArrayO* lir) override;
|
||||
void visitIsArrayV(LIsArrayV* lir) override;
|
||||
void visitIsTypedArray(LIsTypedArray* lir) override;
|
||||
void visitIsObject(LIsObject* lir) override;
|
||||
void visitIsObjectAndBranch(LIsObjectAndBranch* lir) override;
|
||||
void visitHasClass(LHasClass* lir) override;
|
||||
void visitObjectClassToString(LObjectClassToString* lir) override;
|
||||
void visitWasmParameter(LWasmParameter* lir) override;
|
||||
void visitWasmParameterI64(LWasmParameterI64* lir) override;
|
||||
void visitWasmReturn(LWasmReturn* ret) override;
|
||||
void visitWasmReturnI64(LWasmReturnI64* ret) override;
|
||||
void visitWasmReturnVoid(LWasmReturnVoid* ret) override;
|
||||
void visitLexicalCheck(LLexicalCheck* ins) override;
|
||||
void visitThrowRuntimeLexicalError(LThrowRuntimeLexicalError* ins) override;
|
||||
void visitGlobalNameConflictsCheck(LGlobalNameConflictsCheck* ins) override;
|
||||
void visitDebugger(LDebugger* ins) override;
|
||||
void visitNewTarget(LNewTarget* ins) override;
|
||||
void visitArrowNewTarget(LArrowNewTarget* ins) override;
|
||||
void visitCheckReturn(LCheckReturn* ins) override;
|
||||
void visitCheckIsObj(LCheckIsObj* ins) override;
|
||||
void visitCheckIsCallable(LCheckIsCallable* ins) override;
|
||||
void visitCheckObjCoercible(LCheckObjCoercible* ins) override;
|
||||
void visitDebugCheckSelfHosted(LDebugCheckSelfHosted* ins) override;
|
||||
void visitNaNToZero(LNaNToZero* ins) override;
|
||||
void visitIsArrayO(LIsArrayO* lir);
|
||||
void visitIsArrayV(LIsArrayV* lir);
|
||||
void visitIsTypedArray(LIsTypedArray* lir);
|
||||
void visitIsObject(LIsObject* lir);
|
||||
void visitIsObjectAndBranch(LIsObjectAndBranch* lir);
|
||||
void visitHasClass(LHasClass* lir);
|
||||
void visitObjectClassToString(LObjectClassToString* lir);
|
||||
void visitWasmParameter(LWasmParameter* lir);
|
||||
void visitWasmParameterI64(LWasmParameterI64* lir);
|
||||
void visitWasmReturn(LWasmReturn* ret);
|
||||
void visitWasmReturnI64(LWasmReturnI64* ret);
|
||||
void visitWasmReturnVoid(LWasmReturnVoid* ret);
|
||||
void visitLexicalCheck(LLexicalCheck* ins);
|
||||
void visitThrowRuntimeLexicalError(LThrowRuntimeLexicalError* ins);
|
||||
void visitGlobalNameConflictsCheck(LGlobalNameConflictsCheck* ins);
|
||||
void visitDebugger(LDebugger* ins);
|
||||
void visitNewTarget(LNewTarget* ins);
|
||||
void visitArrowNewTarget(LArrowNewTarget* ins);
|
||||
void visitCheckReturn(LCheckReturn* ins);
|
||||
void visitCheckIsObj(LCheckIsObj* ins);
|
||||
void visitCheckIsCallable(LCheckIsCallable* ins);
|
||||
void visitCheckObjCoercible(LCheckObjCoercible* ins);
|
||||
void visitDebugCheckSelfHosted(LDebugCheckSelfHosted* ins);
|
||||
void visitNaNToZero(LNaNToZero* ins);
|
||||
void visitOutOfLineNaNToZero(OutOfLineNaNToZero* ool);
|
||||
void visitFinishBoundFunctionInit(LFinishBoundFunctionInit* lir) override;
|
||||
void visitIsPackedArray(LIsPackedArray* lir) override;
|
||||
void visitGetPrototypeOf(LGetPrototypeOf* lir) override;
|
||||
void visitFinishBoundFunctionInit(LFinishBoundFunctionInit* lir);
|
||||
void visitIsPackedArray(LIsPackedArray* lir);
|
||||
void visitGetPrototypeOf(LGetPrototypeOf* lir);
|
||||
|
||||
void visitCheckOverRecursed(LCheckOverRecursed* lir) override;
|
||||
void visitCheckOverRecursed(LCheckOverRecursed* lir);
|
||||
void visitCheckOverRecursedFailure(CheckOverRecursedFailure* ool);
|
||||
|
||||
void visitUnboxFloatingPoint(LUnboxFloatingPoint* lir) override;
|
||||
void visitUnboxFloatingPoint(LUnboxFloatingPoint* lir);
|
||||
void visitOutOfLineUnboxFloatingPoint(OutOfLineUnboxFloatingPoint* ool);
|
||||
void visitOutOfLineStoreElementHole(OutOfLineStoreElementHole* ool);
|
||||
|
||||
@ -439,36 +439,36 @@ class CodeGenerator final : public CodeGeneratorSpecific
|
||||
|
||||
void visitOutOfLineICFallback(OutOfLineICFallback* ool);
|
||||
|
||||
void visitGetPropertyCacheV(LGetPropertyCacheV* ins) override;
|
||||
void visitGetPropertyCacheT(LGetPropertyCacheT* ins) override;
|
||||
void visitGetPropSuperCacheV(LGetPropSuperCacheV* ins) override;
|
||||
void visitBindNameCache(LBindNameCache* ins) override;
|
||||
void visitGetPropertyCacheV(LGetPropertyCacheV* ins);
|
||||
void visitGetPropertyCacheT(LGetPropertyCacheT* ins);
|
||||
void visitGetPropSuperCacheV(LGetPropSuperCacheV* ins);
|
||||
void visitBindNameCache(LBindNameCache* ins);
|
||||
void visitCallSetProperty(LInstruction* ins);
|
||||
void visitSetPropertyCache(LSetPropertyCache* ins) override;
|
||||
void visitGetNameCache(LGetNameCache* ins) override;
|
||||
void visitHasOwnCache(LHasOwnCache* ins) override;
|
||||
void visitSetPropertyCache(LSetPropertyCache* ins);
|
||||
void visitGetNameCache(LGetNameCache* ins);
|
||||
void visitHasOwnCache(LHasOwnCache* ins);
|
||||
|
||||
void visitAssertRangeI(LAssertRangeI* ins) override;
|
||||
void visitAssertRangeD(LAssertRangeD* ins) override;
|
||||
void visitAssertRangeF(LAssertRangeF* ins) override;
|
||||
void visitAssertRangeV(LAssertRangeV* ins) override;
|
||||
void visitAssertRangeI(LAssertRangeI* ins);
|
||||
void visitAssertRangeD(LAssertRangeD* ins);
|
||||
void visitAssertRangeF(LAssertRangeF* ins);
|
||||
void visitAssertRangeV(LAssertRangeV* ins);
|
||||
|
||||
void visitAssertResultV(LAssertResultV* ins) override;
|
||||
void visitAssertResultT(LAssertResultT* ins) override;
|
||||
void visitAssertResultV(LAssertResultV* ins);
|
||||
void visitAssertResultT(LAssertResultT* ins);
|
||||
void emitAssertResultV(const ValueOperand output, const TemporaryTypeSet* typeset);
|
||||
void emitAssertObjectOrStringResult(Register input, MIRType type, const TemporaryTypeSet* typeset);
|
||||
|
||||
void visitInterruptCheck(LInterruptCheck* lir) override;
|
||||
void visitInterruptCheck(LInterruptCheck* lir);
|
||||
void visitOutOfLineInterruptCheckImplicit(OutOfLineInterruptCheckImplicit* ins);
|
||||
void visitWasmTrap(LWasmTrap* lir) override;
|
||||
void visitWasmLoadTls(LWasmLoadTls* ins) override;
|
||||
void visitWasmBoundsCheck(LWasmBoundsCheck* ins) override;
|
||||
void visitWasmAlignmentCheck(LWasmAlignmentCheck* ins) override;
|
||||
void visitRecompileCheck(LRecompileCheck* ins) override;
|
||||
void visitRotate(LRotate* ins) override;
|
||||
void visitWasmTrap(LWasmTrap* lir);
|
||||
void visitWasmLoadTls(LWasmLoadTls* ins);
|
||||
void visitWasmBoundsCheck(LWasmBoundsCheck* ins);
|
||||
void visitWasmAlignmentCheck(LWasmAlignmentCheck* ins);
|
||||
void visitRecompileCheck(LRecompileCheck* ins);
|
||||
void visitRotate(LRotate* ins);
|
||||
|
||||
void visitRandom(LRandom* ins) override;
|
||||
void visitSignExtendInt32(LSignExtendInt32* ins) override;
|
||||
void visitRandom(LRandom* ins);
|
||||
void visitSignExtendInt32(LSignExtendInt32* ins);
|
||||
|
||||
#ifdef DEBUG
|
||||
void emitDebugForceBailing(LInstruction* lir);
|
||||
|
@ -4,8 +4,9 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "jsgc.h"
|
||||
#include "jit/CompileWrappers.h"
|
||||
|
||||
#include "gc/GC.h"
|
||||
#include "jit/Ion.h"
|
||||
#include "jit/JitCompartment.h"
|
||||
|
||||
|
@ -54,7 +54,7 @@
|
||||
#include "vm/TraceLogging.h"
|
||||
#include "vtune/VTuneWrapper.h"
|
||||
|
||||
#include "gc/GCIteration-inl.h"
|
||||
#include "gc/PrivateIterators-inl.h"
|
||||
#include "jit/JitFrames-inl.h"
|
||||
#include "jit/MacroAssembler-inl.h"
|
||||
#include "jit/shared/Lowering-shared-inl.h"
|
||||
|
@ -19,9 +19,8 @@
|
||||
#include "vm/RegExpObject.h"
|
||||
#include "vm/SelfHosting.h"
|
||||
|
||||
#include "jsopcodeinlines.h"
|
||||
|
||||
#include "jit/shared/Lowering-shared-inl.h"
|
||||
#include "vm/BytecodeUtil-inl.h"
|
||||
#include "vm/JSObject-inl.h"
|
||||
#include "vm/JSScript-inl.h"
|
||||
|
||||
|
@ -25,11 +25,10 @@
|
||||
#include "vm/RegExpStatics.h"
|
||||
#include "vm/TraceLogging.h"
|
||||
|
||||
#include "jsopcodeinlines.h"
|
||||
|
||||
#include "gc/Nursery-inl.h"
|
||||
#include "jit/CompileInfo-inl.h"
|
||||
#include "jit/shared/Lowering-shared-inl.h"
|
||||
#include "vm/BytecodeUtil-inl.h"
|
||||
#include "vm/EnvironmentObject-inl.h"
|
||||
#include "vm/JSScript-inl.h"
|
||||
#include "vm/NativeObject-inl.h"
|
||||
@ -3547,11 +3546,6 @@ IonBuilder::arithTrySharedStub(bool* emitted, JSOp op,
|
||||
if (actualOp == JSOP_POS)
|
||||
return Ok();
|
||||
|
||||
// FIXME: The JSOP_BITNOT path doesn't track optimizations yet.
|
||||
if (actualOp != JSOP_BITNOT) {
|
||||
trackOptimizationAttempt(TrackedStrategy::BinaryArith_SharedCache);
|
||||
trackOptimizationSuccess();
|
||||
}
|
||||
|
||||
MInstruction* stub = nullptr;
|
||||
switch (actualOp) {
|
||||
@ -3560,8 +3554,7 @@ IonBuilder::arithTrySharedStub(bool* emitted, JSOp op,
|
||||
MOZ_ASSERT_IF(op == JSOP_MUL,
|
||||
left->maybeConstantValue() && left->maybeConstantValue()->toInt32() == -1);
|
||||
MOZ_ASSERT_IF(op != JSOP_MUL, !left);
|
||||
|
||||
stub = MUnarySharedStub::New(alloc(), right);
|
||||
stub = MUnaryCache::New(alloc(), right);
|
||||
break;
|
||||
case JSOP_ADD:
|
||||
case JSOP_SUB:
|
||||
|
@ -542,6 +542,19 @@ IonCacheIRCompiler::init()
|
||||
AnyRegister(ic->rhs())));
|
||||
break;
|
||||
}
|
||||
case CacheKind::UnaryArith: {
|
||||
IonUnaryArithIC *ic = ic_->asUnaryArithIC();
|
||||
ValueOperand output = ic->output();
|
||||
|
||||
available.add(output);
|
||||
|
||||
liveRegs_.emplace(ic->liveRegs());
|
||||
outputUnchecked_.emplace(TypedOrValueRegister(output));
|
||||
|
||||
MOZ_ASSERT(numInputs == 1);
|
||||
allocator.initInputLocation(0, ic->input());
|
||||
break;
|
||||
}
|
||||
case CacheKind::Call:
|
||||
case CacheKind::Compare:
|
||||
case CacheKind::TypeOf:
|
||||
|
@ -60,6 +60,8 @@ IonIC::scratchRegisterForEntryJump()
|
||||
return asGetIteratorIC()->temp1();
|
||||
case CacheKind::InstanceOf:
|
||||
return asInstanceOfIC()->output();
|
||||
case CacheKind::UnaryArith:
|
||||
return asUnaryArithIC()->output().scratchReg();
|
||||
case CacheKind::Call:
|
||||
case CacheKind::Compare:
|
||||
case CacheKind::TypeOf:
|
||||
@ -505,6 +507,48 @@ IonInstanceOfIC::update(JSContext* cx, HandleScript outerScript, IonInstanceOfIC
|
||||
return HasInstance(cx, rhs, lhs, res);
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
IonUnaryArithIC::update(JSContext* cx, HandleScript outerScript, IonUnaryArithIC* ic,
|
||||
HandleValue val, MutableHandleValue res)
|
||||
{
|
||||
IonScript* ionScript = outerScript->ionScript();
|
||||
RootedScript script(cx, ic->script());
|
||||
jsbytecode* pc = ic->pc();
|
||||
JSOp op = JSOp(*pc);
|
||||
|
||||
switch (op) {
|
||||
case JSOP_BITNOT: {
|
||||
int32_t result;
|
||||
if (!BitNot(cx, val, &result))
|
||||
return false;
|
||||
res.setInt32(result);
|
||||
break;
|
||||
}
|
||||
case JSOP_NEG:
|
||||
if (!NegOperation(cx, val, res))
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("Unexpected op");
|
||||
}
|
||||
|
||||
if (ic->state().maybeTransition())
|
||||
ic->discardStubs(cx->zone());
|
||||
|
||||
if (ic->state().canAttachStub()) {
|
||||
bool attached = false;
|
||||
UnaryArithIRGenerator gen(cx, script, pc, ic->state().mode(), op, val, res);
|
||||
|
||||
if (gen.tryAttachStub())
|
||||
ic->attachCacheIRStub(cx, gen.writerRef(), gen.cacheKind(), ionScript, &attached);
|
||||
|
||||
if (!attached)
|
||||
ic->state().trackNotAttached();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t*
|
||||
IonICStub::stubDataStart()
|
||||
{
|
||||
|
@ -65,6 +65,7 @@ class IonGetIteratorIC;
|
||||
class IonHasOwnIC;
|
||||
class IonInIC;
|
||||
class IonInstanceOfIC;
|
||||
class IonUnaryArithIC;
|
||||
|
||||
class IonIC
|
||||
{
|
||||
@ -172,6 +173,10 @@ class IonIC
|
||||
MOZ_ASSERT(kind_ == CacheKind::InstanceOf);
|
||||
return (IonInstanceOfIC*)this;
|
||||
}
|
||||
IonUnaryArithIC* asUnaryArithIC() {
|
||||
MOZ_ASSERT(kind_ == CacheKind::UnaryArith);
|
||||
return (IonUnaryArithIC*)this;
|
||||
}
|
||||
|
||||
void updateBaseAddress(JitCode* code, MacroAssembler& masm);
|
||||
|
||||
@ -475,6 +480,30 @@ class IonInstanceOfIC : public IonIC
|
||||
HandleValue lhs, HandleObject rhs, bool* attached);
|
||||
};
|
||||
|
||||
class IonUnaryArithIC : public IonIC
|
||||
{
|
||||
LiveRegisterSet liveRegs_;
|
||||
|
||||
TypedOrValueRegister input_;
|
||||
ValueOperand output_;
|
||||
|
||||
public:
|
||||
|
||||
IonUnaryArithIC(LiveRegisterSet liveRegs, TypedOrValueRegister input, ValueOperand output)
|
||||
: IonIC(CacheKind::UnaryArith),
|
||||
liveRegs_(liveRegs),
|
||||
input_(input),
|
||||
output_(output)
|
||||
{ }
|
||||
|
||||
LiveRegisterSet liveRegs() const { return liveRegs_; }
|
||||
TypedOrValueRegister input() const { return input_; }
|
||||
ValueOperand output() const { return output_; }
|
||||
|
||||
static MOZ_MUST_USE bool update(JSContext* cx, HandleScript outerScript, IonUnaryArithIC* stub,
|
||||
HandleValue val, MutableHandleValue res);
|
||||
};
|
||||
|
||||
} // namespace jit
|
||||
} // namespace js
|
||||
|
||||
|
@ -484,6 +484,11 @@ LDefinition::dump() const
|
||||
void
|
||||
LNode::printOperands(GenericPrinter& out)
|
||||
{
|
||||
if (isMoveGroup()) {
|
||||
toMoveGroup()->printOperands(out);
|
||||
return;
|
||||
}
|
||||
|
||||
size_t numOperands = isPhi() ? toPhi()->numOperands() : toInstruction()->numOperands();
|
||||
|
||||
for (size_t i = 0; i < numOperands; i++) {
|
||||
@ -596,6 +601,17 @@ LNode::dump()
|
||||
out.finish();
|
||||
}
|
||||
|
||||
const char*
|
||||
LNode::getExtraName() const
|
||||
{
|
||||
switch (op()) {
|
||||
default: MOZ_CRASH("Unexpected LIR op");
|
||||
# define LIROP(x) case LNode::LOp_##x: return to##x()->extraName();
|
||||
LIR_OPCODE_LIST(LIROP)
|
||||
# undef LIROP
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LInstruction::initSafepoint(TempAllocator& alloc)
|
||||
{
|
||||
|
@ -710,10 +710,14 @@ class LNode
|
||||
|
||||
// Hook for opcodes to add extra high level detail about what code will be
|
||||
// emitted for the op.
|
||||
virtual const char* extraName() const {
|
||||
private:
|
||||
const char* extraName() const {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
public:
|
||||
const char* getExtraName() const;
|
||||
|
||||
virtual Opcode op() const = 0;
|
||||
|
||||
bool isInstruction() const {
|
||||
@ -766,11 +770,11 @@ class LNode
|
||||
// output register will be restored to its original value when bailing out.
|
||||
inline bool recoversInput() const;
|
||||
|
||||
virtual void dump(GenericPrinter& out);
|
||||
void dump(GenericPrinter& out);
|
||||
void dump();
|
||||
static void printName(GenericPrinter& out, Opcode op);
|
||||
virtual void printName(GenericPrinter& out);
|
||||
virtual void printOperands(GenericPrinter& out);
|
||||
void printName(GenericPrinter& out);
|
||||
void printOperands(GenericPrinter& out);
|
||||
|
||||
public:
|
||||
// Opcode testing and casts.
|
||||
@ -783,15 +787,9 @@ class LNode
|
||||
LIR_OPCODE_LIST(LIROP)
|
||||
# undef LIROP
|
||||
|
||||
virtual void accept(LElementVisitor* visitor) = 0;
|
||||
|
||||
#define LIR_HEADER(opcode) \
|
||||
Opcode op() const override { \
|
||||
return LInstruction::LOp_##opcode; \
|
||||
} \
|
||||
void accept(LElementVisitor* visitor) override { \
|
||||
visitor->setElement(this); \
|
||||
visitor->visit##opcode(this); \
|
||||
}
|
||||
};
|
||||
|
||||
@ -910,7 +908,6 @@ class LElementVisitor
|
||||
return ins_;
|
||||
}
|
||||
|
||||
public:
|
||||
void setElement(LNode* ins) {
|
||||
ins_ = ins;
|
||||
if (ins->mirRaw()) {
|
||||
@ -926,8 +923,7 @@ class LElementVisitor
|
||||
lastNotInlinedPC_(nullptr)
|
||||
{}
|
||||
|
||||
public:
|
||||
#define VISIT_INS(op) virtual void visit##op(L##op*) { MOZ_CRASH("NYI: " #op); }
|
||||
#define VISIT_INS(op) void visit##op(L##op*) { MOZ_CRASH("NYI: " #op); }
|
||||
LIR_OPCODE_LIST(VISIT_INS)
|
||||
#undef VISIT_INS
|
||||
};
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
#include "jit/Linker.h"
|
||||
|
||||
#include "jsgc.h"
|
||||
#include "gc/GC.h"
|
||||
|
||||
#include "gc/StoreBuffer-inl.h"
|
||||
|
||||
|
@ -14,9 +14,8 @@
|
||||
#include "jit/MIRGraph.h"
|
||||
#include "wasm/WasmSignalHandlers.h"
|
||||
|
||||
#include "jsopcodeinlines.h"
|
||||
|
||||
#include "jit/shared/Lowering-shared-inl.h"
|
||||
#include "vm/BytecodeUtil-inl.h"
|
||||
#include "vm/JSObject-inl.h"
|
||||
|
||||
using namespace js;
|
||||
@ -2532,13 +2531,13 @@ LIRGenerator::visitBinarySharedStub(MBinarySharedStub* ins)
|
||||
}
|
||||
|
||||
void
|
||||
LIRGenerator::visitUnarySharedStub(MUnarySharedStub* ins)
|
||||
LIRGenerator::visitUnaryCache(MUnaryCache* ins)
|
||||
{
|
||||
MDefinition* input = ins->getOperand(0);
|
||||
MOZ_ASSERT(ins->type() == MIRType::Value);
|
||||
|
||||
LUnarySharedStub* lir = new(alloc()) LUnarySharedStub(useBoxFixedAtStart(input, R0));
|
||||
defineSharedStubReturn(lir, ins);
|
||||
LUnaryCache* lir = new(alloc()) LUnaryCache(useBox(input));
|
||||
defineBox(lir, ins);
|
||||
assignSafepoint(lir, ins);
|
||||
}
|
||||
|
||||
|
@ -187,7 +187,7 @@ class LIRGenerator : public LIRGeneratorSpecific
|
||||
void visitGetFirstDollarIndex(MGetFirstDollarIndex* ins) override;
|
||||
void visitStringReplace(MStringReplace* ins) override;
|
||||
void visitBinarySharedStub(MBinarySharedStub* ins) override;
|
||||
void visitUnarySharedStub(MUnarySharedStub* ins) override;
|
||||
void visitUnaryCache(MUnaryCache* ins) override;
|
||||
void visitNullarySharedStub(MNullarySharedStub* ins) override;
|
||||
void visitClassConstructor(MClassConstructor* ins) override;
|
||||
void visitLambda(MLambda* ins) override;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user