mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge inbound to m-c a=merge
This commit is contained in:
commit
a2b32b5515
@ -254,7 +254,7 @@ IPCAccessibilityActive()
|
||||
#ifdef MOZ_B2G
|
||||
return false;
|
||||
#else
|
||||
return XRE_GetProcessType() != GeckoProcessType_Default;
|
||||
return XRE_GetProcessType() == GeckoProcessType_Content;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,8 @@ NS_IMPL_ISUPPORTS_INHERITED0(XULListboxAccessibleWrap,
|
||||
XULListboxAccessible)
|
||||
|
||||
IMPL_IUNKNOWN_QUERY_HEAD(XULListboxAccessibleWrap)
|
||||
IMPL_IUNKNOWN_QUERY_CLASS_COND(ia2AccessibleTable, IsMulticolumn());
|
||||
IMPL_IUNKNOWN_QUERY_CLASS_COND(ia2AccessibleTable,
|
||||
!IsDefunct() && IsMulticolumn());
|
||||
IMPL_IUNKNOWN_QUERY_CLASS(AccessibleWrap)
|
||||
IMPL_IUNKNOWN_QUERY_TAIL
|
||||
|
||||
|
@ -103,7 +103,8 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] != "gonk":
|
||||
path = d.split('/')
|
||||
module_path = ''.join('.' + p if p.find('-') == -1 else "['%s']" % p for p in path)
|
||||
dir_path = d + '/'
|
||||
filelist = ["'source/lib/%s%s'" % (dir_path, f) for f in sorted(files)]
|
||||
filelist = ["'source/lib/%s%s'" % (dir_path, f)
|
||||
for f in sorted(files, key=lambda x: x.lower())]
|
||||
js_modules.append("EXTRA_JS_MODULES.commonjs%s += [\n %s,\n]\n"
|
||||
% (module_path, ',\n '.join(filelist)))
|
||||
stringified = '\n'.join(js_modules)
|
||||
|
@ -112,15 +112,7 @@ pref("layout.reflow.synthMouseMove", false);
|
||||
pref("layers.enable-tiles", true);
|
||||
pref("layers.low-precision-buffer", true);
|
||||
pref("layers.low-precision-opacity", "0.5");
|
||||
/*
|
||||
Cross Process Mutex is not supported on Mac OS X so progressive
|
||||
paint cannot be enabled for B2G on Mac OS X desktop
|
||||
*/
|
||||
#ifdef MOZ_WIDGET_COCOA
|
||||
pref("layers.progressive-paint", false);
|
||||
#else
|
||||
pref("layers.progressive-paint", true);
|
||||
#endif
|
||||
|
||||
/* download manager (don't show the window or alert) */
|
||||
pref("browser.download.useDownloadDir", true);
|
||||
|
@ -506,37 +506,37 @@ skip-if = e10s
|
||||
[browser_dbg_variables-view-override-02.js]
|
||||
skip-if = e10s
|
||||
[browser_dbg_variables-view-popup-01.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-popup-02.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-popup-03.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-popup-04.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-popup-05.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-popup-06.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-popup-07.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-popup-08.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-popup-09.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-popup-10.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-popup-11.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-popup-12.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-popup-13.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-popup-14.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-popup-15.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-popup-16.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-reexpand-01.js]
|
||||
skip-if = e10s
|
||||
[browser_dbg_variables-view-reexpand-02.js]
|
||||
|
@ -10,7 +10,7 @@ const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html";
|
||||
|
||||
function test() {
|
||||
Task.spawn(function() {
|
||||
let [tab, debuggee, panel] = yield initDebugger(TAB_URL);
|
||||
let [tab,, panel] = yield initDebugger(TAB_URL);
|
||||
let win = panel.panelWin;
|
||||
let bubble = win.DebuggerView.VariableBubble;
|
||||
let tooltip = bubble._tooltip.panel;
|
||||
@ -29,8 +29,7 @@ function test() {
|
||||
"The inspected property's value is colorized correctly.");
|
||||
}
|
||||
|
||||
// Allow this generator function to yield first.
|
||||
executeSoon(() => debuggee.start());
|
||||
callInTab(tab, "start");
|
||||
yield waitForSourceAndCaretAndScopes(panel, ".html", 24);
|
||||
|
||||
// Inspect variables.
|
||||
|
@ -10,7 +10,7 @@ const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html";
|
||||
|
||||
function test() {
|
||||
Task.spawn(function() {
|
||||
let [tab, debuggee, panel] = yield initDebugger(TAB_URL);
|
||||
let [tab,, panel] = yield initDebugger(TAB_URL);
|
||||
let win = panel.panelWin;
|
||||
let bubble = win.DebuggerView.VariableBubble;
|
||||
let tooltip = bubble._tooltip.panel;
|
||||
@ -27,8 +27,7 @@ function test() {
|
||||
"The inspected property's value is colorized correctly.");
|
||||
}
|
||||
|
||||
// Allow this generator function to yield first.
|
||||
executeSoon(() => debuggee.start());
|
||||
callInTab(tab, "start");
|
||||
yield waitForSourceAndCaretAndScopes(panel, ".html", 24);
|
||||
|
||||
// Inspect properties.
|
||||
|
@ -9,12 +9,11 @@ const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html";
|
||||
|
||||
function test() {
|
||||
Task.spawn(function() {
|
||||
let [tab, debuggee, panel] = yield initDebugger(TAB_URL);
|
||||
let [tab,, panel] = yield initDebugger(TAB_URL);
|
||||
let win = panel.panelWin;
|
||||
let bubble = win.DebuggerView.VariableBubble;
|
||||
|
||||
// Allow this generator function to yield first.
|
||||
executeSoon(() => debuggee.start());
|
||||
callInTab(tab, "start");
|
||||
yield waitForSourceAndCaretAndScopes(panel, ".html", 24);
|
||||
|
||||
// Inspect variable.
|
||||
|
@ -9,12 +9,11 @@ const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html";
|
||||
|
||||
function test() {
|
||||
Task.spawn(function() {
|
||||
let [tab, debuggee, panel] = yield initDebugger(TAB_URL);
|
||||
let [tab,, panel] = yield initDebugger(TAB_URL);
|
||||
let win = panel.panelWin;
|
||||
let bubble = win.DebuggerView.VariableBubble;
|
||||
|
||||
// Allow this generator function to yield first.
|
||||
executeSoon(() => debuggee.start());
|
||||
callInTab(tab, "start");
|
||||
yield waitForSourceAndCaretAndScopes(panel, ".html", 24);
|
||||
|
||||
// Inspect variable.
|
||||
|
@ -10,7 +10,7 @@ const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html";
|
||||
|
||||
function test() {
|
||||
Task.spawn(function() {
|
||||
let [tab, debuggee, panel] = yield initDebugger(TAB_URL);
|
||||
let [tab,, panel] = yield initDebugger(TAB_URL);
|
||||
let win = panel.panelWin;
|
||||
let bubble = win.DebuggerView.VariableBubble;
|
||||
let tooltip = bubble._tooltip.panel;
|
||||
@ -38,8 +38,7 @@ function test() {
|
||||
"The second property's value is correct.");
|
||||
}
|
||||
|
||||
// Allow this generator function to yield first.
|
||||
executeSoon(() => debuggee.start());
|
||||
callInTab(tab, "start");
|
||||
yield waitForSourceAndCaretAndScopes(panel, ".html", 24);
|
||||
|
||||
// Inspect variable.
|
||||
|
@ -11,7 +11,7 @@ const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html";
|
||||
function test() {
|
||||
requestLongerTimeout(2);
|
||||
Task.spawn(function() {
|
||||
let [tab, debuggee, panel] = yield initDebugger(TAB_URL);
|
||||
let [tab,, panel] = yield initDebugger(TAB_URL);
|
||||
let win = panel.panelWin;
|
||||
let bubble = win.DebuggerView.VariableBubble;
|
||||
let tooltip = bubble._tooltip.panel;
|
||||
@ -64,8 +64,7 @@ function test() {
|
||||
"The seventh property's value is correct.");
|
||||
}
|
||||
|
||||
// Allow this generator function to yield first.
|
||||
executeSoon(() => debuggee.start());
|
||||
callInTab(tab, "start");
|
||||
yield waitForSourceAndCaretAndScopes(panel, ".html", 24);
|
||||
|
||||
// Inspect variable.
|
||||
|
@ -10,7 +10,7 @@ const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html";
|
||||
|
||||
function test() {
|
||||
Task.spawn(function() {
|
||||
let [tab, debuggee, panel] = yield initDebugger(TAB_URL);
|
||||
let [tab,, panel] = yield initDebugger(TAB_URL);
|
||||
let win = panel.panelWin;
|
||||
let bubble = win.DebuggerView.VariableBubble;
|
||||
let tooltip = bubble._tooltip.panel;
|
||||
@ -42,8 +42,7 @@ function test() {
|
||||
"There should be some properties displayed.");
|
||||
}
|
||||
|
||||
// Allow this generator function to yield first.
|
||||
executeSoon(() => debuggee.start());
|
||||
callInTab(tab, "start");
|
||||
yield waitForSourceAndCaretAndScopes(panel, ".html", 24);
|
||||
|
||||
// Inspect variables.
|
||||
|
@ -9,7 +9,7 @@ const TAB_URL = EXAMPLE_URL + "doc_scope-variable.html";
|
||||
|
||||
function test() {
|
||||
Task.spawn(function() {
|
||||
let [tab, debuggee, panel] = yield initDebugger(TAB_URL);
|
||||
let [tab,, panel] = yield initDebugger(TAB_URL);
|
||||
let win = panel.panelWin;
|
||||
let events = win.EVENTS;
|
||||
let editor = win.DebuggerView.editor;
|
||||
@ -40,8 +40,7 @@ function test() {
|
||||
"Editor caret location is correct.");
|
||||
}
|
||||
|
||||
// Allow this generator function to yield first.
|
||||
executeSoon(() => debuggee.test());
|
||||
callInTab(tab, "test");
|
||||
yield waitForSourceAndCaretAndScopes(panel, ".html", 20);
|
||||
checkView(0, 20);
|
||||
|
||||
|
@ -9,13 +9,12 @@ const TAB_URL = EXAMPLE_URL + "doc_scope-variable-3.html";
|
||||
|
||||
function test() {
|
||||
Task.spawn(function() {
|
||||
let [tab, debuggee, panel] = yield initDebugger(TAB_URL);
|
||||
let [tab,, panel] = yield initDebugger(TAB_URL);
|
||||
let win = panel.panelWin;
|
||||
let bubble = win.DebuggerView.VariableBubble;
|
||||
let tooltip = bubble._tooltip.panel;
|
||||
|
||||
// Allow this generator function to yield first.
|
||||
executeSoon(() => debuggee.test());
|
||||
callInTab(tab, "test");
|
||||
yield waitForSourceAndCaretAndScopes(panel, ".html", 15);
|
||||
|
||||
yield openVarPopup(panel, { line: 12, ch: 10 });
|
||||
|
@ -11,7 +11,7 @@ const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html";
|
||||
|
||||
function test() {
|
||||
Task.spawn(function() {
|
||||
let [tab, debuggee, panel] = yield initDebugger(TAB_URL);
|
||||
let [tab,, panel] = yield initDebugger(TAB_URL);
|
||||
let win = panel.panelWin;
|
||||
let events = win.EVENTS;
|
||||
let editor = win.DebuggerView.editor;
|
||||
@ -20,8 +20,7 @@ function test() {
|
||||
let expressions = win.DebuggerView.WatchExpressions;
|
||||
let tooltip = bubble._tooltip.panel;
|
||||
|
||||
// Allow this generator function to yield first.
|
||||
executeSoon(() => debuggee.start());
|
||||
callInTab(tab, "start");
|
||||
yield waitForSourceAndCaretAndScopes(panel, ".html", 24);
|
||||
|
||||
let expressionsEvaluated = waitForDebuggerEvents(panel, events.FETCHED_WATCH_EXPRESSIONS);
|
||||
|
@ -9,7 +9,7 @@ const TAB_URL = EXAMPLE_URL + "doc_watch-expression-button.html";
|
||||
|
||||
function test() {
|
||||
Task.spawn(function() {
|
||||
let [tab, debuggee, panel] = yield initDebugger(TAB_URL);
|
||||
let [tab,, panel] = yield initDebugger(TAB_URL);
|
||||
let win = panel.panelWin;
|
||||
let events = win.EVENTS;
|
||||
let watch = win.DebuggerView.WatchExpressions;
|
||||
@ -37,8 +37,7 @@ function test() {
|
||||
"The expression at index 0 is correct.");
|
||||
}
|
||||
|
||||
// Allow this generator function to yield first.
|
||||
executeSoon(() => debuggee.start());
|
||||
callInTab(tab, "start");
|
||||
yield waitForSourceAndCaretAndScopes(panel, ".html", 19);
|
||||
|
||||
// Inspect primitive value variable.
|
||||
|
@ -10,7 +10,7 @@ const TAB_URL = EXAMPLE_URL + "doc_watch-expression-button.html";
|
||||
|
||||
function test() {
|
||||
Task.spawn(function() {
|
||||
let [tab, debuggee, panel] = yield initDebugger(TAB_URL);
|
||||
let [tab,, panel] = yield initDebugger(TAB_URL);
|
||||
let win = panel.panelWin;
|
||||
let events = win.EVENTS;
|
||||
let watch = win.DebuggerView.WatchExpressions;
|
||||
@ -27,8 +27,7 @@ function test() {
|
||||
"The expression count is correct.");
|
||||
}
|
||||
|
||||
// Allow this generator function to yield first.
|
||||
executeSoon(() => debuggee.start());
|
||||
callInTab(tab, "start");
|
||||
yield waitForSourceAndCaretAndScopes(panel, ".html", 19);
|
||||
|
||||
// Inspect primitive value variable.
|
||||
|
@ -10,7 +10,7 @@ const TAB_URL = EXAMPLE_URL + "doc_domnode-variables.html";
|
||||
|
||||
function test() {
|
||||
Task.spawn(function() {
|
||||
let [tab, debuggee, panel] = yield initDebugger(TAB_URL);
|
||||
let [tab,, panel] = yield initDebugger(TAB_URL);
|
||||
let win = panel.panelWin;
|
||||
let bubble = win.DebuggerView.VariableBubble;
|
||||
let tooltip = bubble._tooltip.panel;
|
||||
@ -28,8 +28,7 @@ function test() {
|
||||
ok(false, "DOMNode " + propertyName + " wasn't found in the tooltip");
|
||||
}
|
||||
|
||||
// Allow this generator function to yield first.
|
||||
executeSoon(() => debuggee.start());
|
||||
callInTab(tab, "start");
|
||||
yield waitForSourceAndCaretAndScopes(panel, ".html", 19);
|
||||
|
||||
// Inspect the div DOM variable.
|
||||
|
@ -10,12 +10,11 @@ const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html";
|
||||
|
||||
function test() {
|
||||
Task.spawn(function*() {
|
||||
let [tab, debuggee, panel] = yield initDebugger(TAB_URL);
|
||||
let [tab,, panel] = yield initDebugger(TAB_URL);
|
||||
let win = panel.panelWin;
|
||||
let bubble = win.DebuggerView.VariableBubble;
|
||||
|
||||
// Allow this generator function to yield first.
|
||||
executeSoon(() => debuggee.start());
|
||||
callInTab(tab, "start");
|
||||
yield waitForSourceAndCaretAndScopes(panel, ".html", 24);
|
||||
|
||||
// Select some text.
|
||||
|
@ -9,13 +9,12 @@ const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html";
|
||||
|
||||
function test() {
|
||||
Task.spawn(function() {
|
||||
let [tab, debuggee, panel] = yield initDebugger(TAB_URL);
|
||||
let [tab,, panel] = yield initDebugger(TAB_URL);
|
||||
let win = panel.panelWin;
|
||||
let bubble = win.DebuggerView.VariableBubble;
|
||||
let tooltip = bubble._tooltip.panel;
|
||||
|
||||
// Allow this generator function to yield first.
|
||||
executeSoon(() => debuggee.start());
|
||||
callInTab(tab, "start");
|
||||
yield waitForSourceAndCaretAndScopes(panel, ".html", 24);
|
||||
|
||||
yield openVarPopup(panel, { line: 15, ch: 12 });
|
||||
|
@ -10,7 +10,7 @@ const TAB_URL = EXAMPLE_URL + "doc_recursion-stack.html";
|
||||
|
||||
function test() {
|
||||
Task.spawn(function() {
|
||||
let [tab, debuggee, panel] = yield initDebugger(TAB_URL);
|
||||
let [tab,, panel] = yield initDebugger(TAB_URL);
|
||||
let win = panel.panelWin;
|
||||
let events = win.EVENTS;
|
||||
let editor = win.DebuggerView.editor;
|
||||
@ -51,8 +51,7 @@ function test() {
|
||||
return finished;
|
||||
}
|
||||
|
||||
// Allow this generator function to yield first.
|
||||
executeSoon(() => debuggee.recurse());
|
||||
callInTab(tab, "recurse");
|
||||
yield waitForSourceAndCaretAndScopes(panel, ".html", 26);
|
||||
yield checkView(0, 26);
|
||||
|
||||
|
@ -158,6 +158,8 @@ bool Exception::sEverMadeOneFromFactory = false;
|
||||
NS_IMPL_CLASSINFO(Exception, nullptr, nsIClassInfo::DOM_OBJECT,
|
||||
NS_XPCEXCEPTION_CID)
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Exception)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRY(Exception)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIException)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIXPCException)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIException)
|
||||
|
@ -396,10 +396,9 @@ NS_IMPL_ISUPPORTS(MediaDeviceErrorCallback, nsIDOMGetUserMediaErrorCallback)
|
||||
NS_IMETHODIMP
|
||||
MediaDeviceErrorCallback::OnError(nsISupports* aError)
|
||||
{
|
||||
MediaStreamError *error = nullptr;
|
||||
nsresult rv = CallQueryInterface(aError, &error);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
nsRefPtr<MediaStreamError> error = do_QueryObject(aError);
|
||||
if (!error) {
|
||||
return NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
|
||||
nsString name;
|
||||
|
@ -835,13 +835,18 @@ RTCPeerConnection.prototype = {
|
||||
throw new this._win.DOMError("",
|
||||
"Invalid candidate passed to addIceCandidate!");
|
||||
}
|
||||
|
||||
this._queueOrRun({
|
||||
func: this._addIceCandidate,
|
||||
args: [cand, onSuccess, onError],
|
||||
wait: false
|
||||
});
|
||||
},
|
||||
|
||||
_addIceCandidate: function(cand, onSuccess, onError) {
|
||||
this._onAddIceCandidateSuccess = onSuccess || null;
|
||||
this._onAddIceCandidateError = onError || null;
|
||||
|
||||
this._queueOrRun({ func: this._addIceCandidate, args: [cand], wait: false });
|
||||
},
|
||||
|
||||
_addIceCandidate: function(cand) {
|
||||
this._impl.addIceCandidate(cand.candidate, cand.sdpMid || "",
|
||||
(cand.sdpMLineIndex === null) ? 0 :
|
||||
cand.sdpMLineIndex + 1);
|
||||
|
@ -50,5 +50,6 @@ partial interface WorkerGlobalScope {
|
||||
void dump(optional DOMString str);
|
||||
|
||||
// XXXbz no spec for this yet, because the webperf WG is a bit dysfunctional
|
||||
[Constant, Cached]
|
||||
readonly attribute Performance performance;
|
||||
};
|
||||
|
@ -3048,7 +3048,7 @@ void AsyncPanZoomController::UpdateSharedCompositorFrameMetrics()
|
||||
FrameMetrics* frame = mSharedFrameMetricsBuffer ?
|
||||
static_cast<FrameMetrics*>(mSharedFrameMetricsBuffer->memory()) : nullptr;
|
||||
|
||||
if (frame && mSharedLock && gfxPrefs::UseProgressiveTilePainting()) {
|
||||
if (frame && mSharedLock && gfxPlatform::GetPlatform()->UseProgressivePaint()) {
|
||||
mSharedLock->Lock();
|
||||
*frame = mFrameMetrics.MakePODObject();
|
||||
mSharedLock->Unlock();
|
||||
@ -3062,7 +3062,7 @@ void AsyncPanZoomController::ShareCompositorFrameMetrics() {
|
||||
// Only create the shared memory buffer if it hasn't already been created,
|
||||
// we are using progressive tile painting, and we have a
|
||||
// compositor to pass the shared memory back to the content process/thread.
|
||||
if (!mSharedFrameMetricsBuffer && compositor && gfxPrefs::UseProgressiveTilePainting()) {
|
||||
if (!mSharedFrameMetricsBuffer && compositor && gfxPlatform::GetPlatform()->UseProgressivePaint()) {
|
||||
|
||||
// Create shared memory and initialize it with the current FrameMetrics value
|
||||
mSharedFrameMetricsBuffer = new ipc::SharedMemoryBasic;
|
||||
|
@ -193,7 +193,7 @@ ClientTiledPaintedLayer::UseFastPath()
|
||||
}
|
||||
const FrameMetrics& parentMetrics = scrollAncestor.Metrics();
|
||||
|
||||
bool multipleTransactionsNeeded = gfxPrefs::UseProgressiveTilePainting()
|
||||
bool multipleTransactionsNeeded = gfxPlatform::GetPlatform()->UseProgressivePaint()
|
||||
|| gfxPrefs::UseLowPrecisionBuffer()
|
||||
|| !parentMetrics.mCriticalDisplayPort.IsEmpty();
|
||||
bool isFixed = GetIsFixedPosition() || GetParent()->GetIsFixedPosition();
|
||||
@ -214,7 +214,7 @@ ClientTiledPaintedLayer::RenderHighPrecision(nsIntRegion& aInvalidRegion,
|
||||
|
||||
// Only draw progressively when the resolution is unchanged, and we're not
|
||||
// in a reftest scenario (that's what the HasShadowManager() check is for).
|
||||
if (gfxPrefs::UseProgressiveTilePainting() &&
|
||||
if (gfxPlatform::GetPlatform()->UseProgressivePaint() &&
|
||||
!ClientManager()->HasShadowTarget() &&
|
||||
mContentClient->mTiledBuffer.GetFrameResolution() == mPaintData.mResolution) {
|
||||
// Store the old valid region, then clear it before painting.
|
||||
|
@ -876,7 +876,7 @@ LayerManagerComposite::ComputeRenderIntegrity()
|
||||
{
|
||||
// We only ever have incomplete rendering when progressive tiles are enabled.
|
||||
Layer* root = GetRoot();
|
||||
if (!gfxPrefs::UseProgressiveTilePainting() || !root) {
|
||||
if (!gfxPlatform::GetPlatform()->UseProgressivePaint() || !root) {
|
||||
return 1.f;
|
||||
}
|
||||
|
||||
|
@ -263,9 +263,10 @@ public:
|
||||
virtual bool UseAcceleratedSkiaCanvas();
|
||||
virtual void InitializeSkiaCacheLimits();
|
||||
|
||||
/// This should be used instead of directly accessing the preference,
|
||||
/// These should be used instead of directly accessing the preference,
|
||||
/// as different platforms may override the behaviour.
|
||||
virtual bool UseTiling() { return gfxPrefs::LayersTilesEnabledDoNotUseDirectly(); }
|
||||
virtual bool UseProgressivePaint() { return gfxPrefs::ProgressivePaintDoNotUseDirectly(); }
|
||||
|
||||
void GetAzureBackendInfo(mozilla::widget::InfoObject &aObj) {
|
||||
aObj.DefineProperty("AzureCanvasBackend", GetBackendName(mPreferredCanvasBackend));
|
||||
|
@ -411,6 +411,14 @@ gfxPlatformMac::UseTiling()
|
||||
return nsCocoaFeatures::OnLionOrLater() && gfxPlatform::UseTiling();
|
||||
}
|
||||
|
||||
bool
|
||||
gfxPlatformMac::UseProgressivePaint()
|
||||
{
|
||||
// Progressive painting requires cross-process mutexes, which don't work so
|
||||
// well on OS X 10.6 so we disable there.
|
||||
return nsCocoaFeatures::OnLionOrLater() && gfxPlatform::UseProgressivePaint();
|
||||
}
|
||||
|
||||
void
|
||||
gfxPlatformMac::GetPlatformCMSOutputProfile(void* &mem, size_t &size)
|
||||
{
|
||||
|
@ -71,6 +71,7 @@ public:
|
||||
bool UseAcceleratedCanvas();
|
||||
|
||||
virtual bool UseTiling() MOZ_OVERRIDE;
|
||||
virtual bool UseProgressivePaint() MOZ_OVERRIDE;
|
||||
|
||||
// lower threshold on font anti-aliasing
|
||||
uint32_t GetAntiAliasingThreshold() { return mFontAntiAliasingThreshold; }
|
||||
|
@ -293,7 +293,7 @@ private:
|
||||
DECL_GFX_PREF(Live, "layers.orientation.sync.timeout", OrientationSyncMillis, uint32_t, (uint32_t)0);
|
||||
DECL_GFX_PREF(Once, "layers.prefer-d3d9", LayersPreferD3D9, bool, false);
|
||||
DECL_GFX_PREF(Once, "layers.prefer-opengl", LayersPreferOpenGL, bool, false);
|
||||
DECL_GFX_PREF(Once, "layers.progressive-paint", UseProgressiveTilePainting, bool, false);
|
||||
DECL_GFX_PREF(Once, "layers.progressive-paint", ProgressivePaintDoNotUseDirectly, bool, false);
|
||||
DECL_GFX_PREF(Once, "layers.uniformity-info", UniformityInfo, bool, false);
|
||||
DECL_GFX_PREF(Once, "layers.gralloc.disable", DisableGralloc, bool, false);
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
#include "base/process.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
#if defined(OS_POSIX)
|
||||
#include <pthread.h>
|
||||
#include "SharedMemoryBasic.h"
|
||||
#include "mozilla/Atomics.h"
|
||||
@ -32,9 +32,9 @@ struct ParamTraits;
|
||||
// preferred to making bare calls to CrossProcessMutex.Lock and Unlock.
|
||||
//
|
||||
namespace mozilla {
|
||||
#ifdef XP_WIN
|
||||
#if defined(OS_WIN)
|
||||
typedef HANDLE CrossProcessMutexHandle;
|
||||
#elif defined(OS_LINUX)
|
||||
#elif defined(OS_POSIX)
|
||||
typedef mozilla::ipc::SharedMemoryBasic::Handle CrossProcessMutexHandle;
|
||||
#else
|
||||
// Stub for other platforms. We can't use uintptr_t here since different
|
||||
@ -98,9 +98,9 @@ private:
|
||||
CrossProcessMutex(const CrossProcessMutex&);
|
||||
CrossProcessMutex &operator=(const CrossProcessMutex&);
|
||||
|
||||
#ifdef XP_WIN
|
||||
#if defined(OS_WIN)
|
||||
HANDLE mMutex;
|
||||
#elif defined(OS_LINUX)
|
||||
#elif defined(OS_POSIX)
|
||||
nsRefPtr<mozilla::ipc::SharedMemoryBasic> mSharedBuffer;
|
||||
pthread_mutex_t* mMutex;
|
||||
mozilla::Atomic<int32_t>* mCount;
|
||||
|
@ -8,6 +8,10 @@
|
||||
#include "nsDebug.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
|
||||
#ifdef OS_MACOSX
|
||||
#include "nsCocoaFeatures.h"
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
struct MutexData {
|
||||
@ -41,6 +45,15 @@ CrossProcessMutex::CrossProcessMutex(const char*)
|
||||
: mMutex(nullptr)
|
||||
, mCount(nullptr)
|
||||
{
|
||||
#ifdef OS_MACOSX
|
||||
if (!nsCocoaFeatures::OnLionOrLater()) {
|
||||
// Don't allow using the cross-process mutex before OS X 10.7 because it
|
||||
// probably doesn't work very well. See discussion in bug 1072093 for more
|
||||
// details.
|
||||
MOZ_CRASH();
|
||||
}
|
||||
#endif
|
||||
|
||||
mSharedBuffer = new ipc::SharedMemoryBasic;
|
||||
if (!mSharedBuffer->Create(sizeof(MutexData))) {
|
||||
MOZ_CRASH();
|
||||
|
@ -59,7 +59,7 @@ if CONFIG['OS_ARCH'] == 'WINNT':
|
||||
SOURCES += [
|
||||
'CrossProcessMutex_windows.cpp',
|
||||
]
|
||||
elif CONFIG['OS_ARCH'] == 'Linux':
|
||||
elif CONFIG['OS_ARCH'] in ('Linux', 'Darwin'):
|
||||
UNIFIED_SOURCES += [
|
||||
'CrossProcessMutex_posix.cpp',
|
||||
]
|
||||
|
@ -8392,6 +8392,7 @@ GenerateAsyncInterruptExit(ModuleCompiler &m, Label *throwLabel)
|
||||
// during jump delay slot.
|
||||
masm.pop(HeapReg);
|
||||
masm.as_jr(HeapReg);
|
||||
masm.loadAsmJSHeapRegisterFromGlobalData();
|
||||
#elif defined(JS_CODEGEN_ARM)
|
||||
masm.setFramePushed(0); // set to zero so we can use masm.framePushed() below
|
||||
masm.PushRegsInMask(RegisterSet(GeneralRegisterSet(Registers::AllMask & ~(1<<Registers::sp)), FloatRegisterSet(uint32_t(0)))); // save all GP registers,excep sp
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "jscntxt.h"
|
||||
|
||||
#include "frontend/BytecodeCompiler.h"
|
||||
#include "vm/Debugger.h"
|
||||
#include "vm/GlobalObject.h"
|
||||
#include "vm/JSONParser.h"
|
||||
|
||||
@ -480,6 +481,9 @@ js::ExecuteInGlobalAndReturnScope(JSContext *cx, HandleObject global, HandleScri
|
||||
script = CloneScript(cx, NullPtr(), NullPtr(), script);
|
||||
if (!script)
|
||||
return false;
|
||||
|
||||
Rooted<GlobalObject *> global(cx, script->compileAndGo() ? &script->global() : nullptr);
|
||||
Debugger::onNewScript(cx, script, global);
|
||||
}
|
||||
|
||||
RootedObject scope(cx, JS_NewObject(cx, nullptr, JS::NullPtr(), JS::NullPtr()));
|
||||
|
@ -2017,7 +2017,8 @@ EvalReturningScope(JSContext *cx, unsigned argc, jsval *vp)
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
RootedString str(cx);
|
||||
if (!JS_ConvertArguments(cx, args, "S", str.address()))
|
||||
RootedObject global(cx);
|
||||
if (!JS_ConvertArguments(cx, args, "S/o", str.address(), global.address()))
|
||||
return false;
|
||||
|
||||
AutoStableStringChars strChars(cx);
|
||||
@ -2043,15 +2044,91 @@ EvalReturningScope(JSContext *cx, unsigned argc, jsval *vp)
|
||||
if (!JS::Compile(cx, JS::NullPtr(), options, srcBuf, &script))
|
||||
return false;
|
||||
|
||||
RootedObject global(cx, JS::CurrentGlobalOrNull(cx));
|
||||
if (global) {
|
||||
global = CheckedUnwrap(global);
|
||||
if (!global) {
|
||||
JS_ReportError(cx, "Permission denied to access global");
|
||||
return false;
|
||||
}
|
||||
if (!global->is<GlobalObject>()) {
|
||||
JS_ReportError(cx, "Argument must be a global object");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
global = JS::CurrentGlobalOrNull(cx);
|
||||
}
|
||||
|
||||
RootedObject scope(cx);
|
||||
if (!js::ExecuteInGlobalAndReturnScope(cx, global, script, &scope))
|
||||
|
||||
{
|
||||
// If we're switching globals here, ExecuteInGlobalAndReturnScope will
|
||||
// take care of cloning the script into that compartment before
|
||||
// executing it.
|
||||
AutoCompartment ac(cx, global);
|
||||
|
||||
if (!js::ExecuteInGlobalAndReturnScope(cx, global, script, &scope))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!cx->compartment()->wrap(cx, &scope))
|
||||
return false;
|
||||
|
||||
args.rval().setObject(*scope);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
ShellCloneAndExecuteScript(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
RootedString str(cx);
|
||||
RootedObject global(cx);
|
||||
if (!JS_ConvertArguments(cx, args, "So", str.address(), global.address()))
|
||||
return false;
|
||||
|
||||
AutoStableStringChars strChars(cx);
|
||||
if (!strChars.initTwoByte(cx, str))
|
||||
return false;
|
||||
|
||||
mozilla::Range<const char16_t> chars = strChars.twoByteRange();
|
||||
size_t srclen = chars.length();
|
||||
const char16_t *src = chars.start().get();
|
||||
|
||||
JS::AutoFilename filename;
|
||||
unsigned lineno;
|
||||
|
||||
DescribeScriptedCaller(cx, &filename, &lineno);
|
||||
|
||||
JS::CompileOptions options(cx);
|
||||
options.setFileAndLine(filename.get(), lineno);
|
||||
options.setNoScriptRval(true);
|
||||
options.setCompileAndGo(false);
|
||||
|
||||
JS::SourceBufferHolder srcBuf(src, srclen, JS::SourceBufferHolder::NoOwnership);
|
||||
RootedScript script(cx);
|
||||
if (!JS::Compile(cx, JS::NullPtr(), options, srcBuf, &script))
|
||||
return false;
|
||||
|
||||
global = CheckedUnwrap(global);
|
||||
if (!global) {
|
||||
JS_ReportError(cx, "Permission denied to access global");
|
||||
return false;
|
||||
}
|
||||
if (!global->is<GlobalObject>()) {
|
||||
JS_ReportError(cx, "Argument must be a global object");
|
||||
return false;
|
||||
}
|
||||
|
||||
AutoCompartment ac(cx, global);
|
||||
|
||||
if (!JS::CloneAndExecuteScript(cx, global, script))
|
||||
return false;
|
||||
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
IsSimdAvailable(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
@ -2399,8 +2476,14 @@ gc::ZealModeHelpText),
|
||||
#endif
|
||||
|
||||
JS_FN_HELP("evalReturningScope", EvalReturningScope, 1, 0,
|
||||
"evalReturningScope(scriptStr)",
|
||||
" Evaluate the script in a new scope and return the scope."),
|
||||
"evalReturningScope(scriptStr, [global])",
|
||||
" Evaluate the script in a new scope and return the scope.\n"
|
||||
" If |global| is present, clone the script to |global| before executing."),
|
||||
|
||||
JS_FN_HELP("cloneAndExecuteScript", ShellCloneAndExecuteScript, 2, 0,
|
||||
"cloneAndExecuteScript(source, global)",
|
||||
" Compile |source| in the current compartment, clone it into |global|'s\n"
|
||||
" compartment, and run it there."),
|
||||
|
||||
JS_FN_HELP("backtrace", DumpBacktrace, 1, 0,
|
||||
"backtrace()",
|
||||
|
@ -505,7 +505,7 @@ CreatePrototypeObjectForComplexTypeInstance(JSContext *cx,
|
||||
return result;
|
||||
}
|
||||
|
||||
const Class UnsizedArrayTypeDescr::class_ = {
|
||||
const Class ArrayTypeDescr::class_ = {
|
||||
"ArrayType",
|
||||
JSCLASS_HAS_RESERVED_SLOTS(JS_DESCR_SLOTS),
|
||||
JS_PropertyStub,
|
||||
@ -518,24 +518,7 @@ const Class UnsizedArrayTypeDescr::class_ = {
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
OutlineTypedObject::constructUnsized,
|
||||
nullptr
|
||||
};
|
||||
|
||||
const Class SizedArrayTypeDescr::class_ = {
|
||||
"ArrayType",
|
||||
JSCLASS_HAS_RESERVED_SLOTS(JS_DESCR_SLOTS),
|
||||
JS_PropertyStub,
|
||||
JS_DeletePropertyStub,
|
||||
JS_PropertyStub,
|
||||
JS_StrictPropertyStub,
|
||||
JS_EnumerateStub,
|
||||
JS_ResolveStub,
|
||||
JS_ConvertStub,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
TypedObject::constructSized,
|
||||
TypedObject::construct,
|
||||
nullptr
|
||||
};
|
||||
|
||||
@ -545,7 +528,6 @@ const JSPropertySpec ArrayMetaTypeDescr::typeObjectProperties[] = {
|
||||
|
||||
const JSFunctionSpec ArrayMetaTypeDescr::typeObjectMethods[] = {
|
||||
{"array", {nullptr, nullptr}, 1, 0, "ArrayShorthand"},
|
||||
JS_FN("dimension", UnsizedArrayTypeDescr::dimension, 1, 0),
|
||||
JS_SELF_HOSTED_FN("toSource", "DescrToSource", 0, 0),
|
||||
{"equivalent", {nullptr, nullptr}, 1, 0, "TypeDescrEquivalent"},
|
||||
JS_SELF_HOSTED_FN("build", "TypedObjectArrayTypeBuild", 3, 0),
|
||||
@ -577,11 +559,9 @@ bool
|
||||
js::CreateUserSizeAndAlignmentProperties(JSContext *cx, HandleTypeDescr descr)
|
||||
{
|
||||
// If data is transparent, also store the public slots.
|
||||
if (descr->transparent() && descr->is<SizedTypeDescr>()) {
|
||||
Rooted<SizedTypeDescr*> sizedDescr(cx, &descr->as<SizedTypeDescr>());
|
||||
|
||||
if (descr->transparent()) {
|
||||
// byteLength
|
||||
RootedValue typeByteLength(cx, Int32Value(sizedDescr->size()));
|
||||
RootedValue typeByteLength(cx, Int32Value(descr->size()));
|
||||
if (!JSObject::defineProperty(cx, descr, cx->names().byteLength,
|
||||
typeByteLength,
|
||||
nullptr, nullptr,
|
||||
@ -591,7 +571,7 @@ js::CreateUserSizeAndAlignmentProperties(JSContext *cx, HandleTypeDescr descr)
|
||||
}
|
||||
|
||||
// byteAlignment
|
||||
RootedValue typeByteAlignment(cx, Int32Value(sizedDescr->alignment()));
|
||||
RootedValue typeByteAlignment(cx, Int32Value(descr->alignment()));
|
||||
if (!JSObject::defineProperty(cx, descr, cx->names().byteAlignment,
|
||||
typeByteAlignment,
|
||||
nullptr, nullptr,
|
||||
@ -619,38 +599,29 @@ js::CreateUserSizeAndAlignmentProperties(JSContext *cx, HandleTypeDescr descr)
|
||||
}
|
||||
}
|
||||
|
||||
// variable -- true for unsized arrays
|
||||
RootedValue variable(cx, BooleanValue(!descr->is<SizedTypeDescr>()));
|
||||
if (!JSObject::defineProperty(cx, descr, cx->names().variable,
|
||||
variable,
|
||||
nullptr, nullptr,
|
||||
JSPROP_READONLY | JSPROP_PERMANENT))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T *
|
||||
ArrayTypeDescr *
|
||||
ArrayMetaTypeDescr::create(JSContext *cx,
|
||||
HandleObject arrayTypePrototype,
|
||||
HandleSizedTypeDescr elementType,
|
||||
HandleTypeDescr elementType,
|
||||
HandleAtom stringRepr,
|
||||
int32_t size)
|
||||
int32_t size,
|
||||
int32_t length)
|
||||
{
|
||||
Rooted<T*> obj(cx);
|
||||
obj = NewObjectWithProto<T>(cx, arrayTypePrototype, nullptr, SingletonObject);
|
||||
Rooted<ArrayTypeDescr*> obj(cx);
|
||||
obj = NewObjectWithProto<ArrayTypeDescr>(cx, arrayTypePrototype, nullptr, SingletonObject);
|
||||
if (!obj)
|
||||
return nullptr;
|
||||
|
||||
obj->initReservedSlot(JS_DESCR_SLOT_KIND, Int32Value(T::Kind));
|
||||
obj->initReservedSlot(JS_DESCR_SLOT_KIND, Int32Value(ArrayTypeDescr::Kind));
|
||||
obj->initReservedSlot(JS_DESCR_SLOT_STRING_REPR, StringValue(stringRepr));
|
||||
obj->initReservedSlot(JS_DESCR_SLOT_ALIGNMENT, Int32Value(elementType->alignment()));
|
||||
obj->initReservedSlot(JS_DESCR_SLOT_SIZE, Int32Value(size));
|
||||
obj->initReservedSlot(JS_DESCR_SLOT_OPAQUE, BooleanValue(elementType->opaque()));
|
||||
obj->initReservedSlot(JS_DESCR_SLOT_ARRAY_ELEM_TYPE, ObjectValue(*elementType));
|
||||
obj->initReservedSlot(JS_DESCR_SLOT_ARRAY_LENGTH, Int32Value(length));
|
||||
|
||||
RootedValue elementTypeVal(cx, ObjectValue(*elementType));
|
||||
if (!JSObject::defineProperty(cx, obj, cx->names().elementType,
|
||||
@ -658,6 +629,12 @@ ArrayMetaTypeDescr::create(JSContext *cx,
|
||||
JSPROP_READONLY | JSPROP_PERMANENT))
|
||||
return nullptr;
|
||||
|
||||
RootedValue lengthValue(cx, NumberValue(length));
|
||||
if (!JSObject::defineProperty(cx, obj, cx->names().length,
|
||||
lengthValue, nullptr, nullptr,
|
||||
JSPROP_READONLY | JSPROP_PERMANENT))
|
||||
return nullptr;
|
||||
|
||||
if (!CreateUserSizeAndAlignmentProperties(cx, obj))
|
||||
return nullptr;
|
||||
|
||||
@ -687,25 +664,42 @@ ArrayMetaTypeDescr::construct(JSContext *cx, unsigned argc, Value *vp)
|
||||
|
||||
RootedObject arrayTypeGlobal(cx, &args.callee());
|
||||
|
||||
// Expect one argument which is a sized type object
|
||||
if (args.length() < 1) {
|
||||
// Expect two arguments. The first is a type object, the second is a length.
|
||||
if (args.length() < 2) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_MORE_ARGS_NEEDED,
|
||||
"ArrayType", "0", "");
|
||||
"ArrayType", "1", "");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!args[0].isObject() || !args[0].toObject().is<SizedTypeDescr>()) {
|
||||
if (!args[0].isObject() || !args[0].toObject().is<TypeDescr>()) {
|
||||
ReportCannotConvertTo(cx, args[0], "ArrayType element specifier");
|
||||
return false;
|
||||
}
|
||||
|
||||
Rooted<SizedTypeDescr*> elementType(cx);
|
||||
elementType = &args[0].toObject().as<SizedTypeDescr>();
|
||||
if (!args[1].isInt32() || args[1].toInt32() < 0) {
|
||||
ReportCannotConvertTo(cx, args[1], "ArrayType length specifier");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Construct a canonical string `new ArrayType(<elementType>)`:
|
||||
Rooted<TypeDescr*> elementType(cx, &args[0].toObject().as<TypeDescr>());
|
||||
|
||||
int32_t length = args[1].toInt32();
|
||||
|
||||
// Compute the byte size.
|
||||
CheckedInt32 size = CheckedInt32(elementType->size()) * length;
|
||||
if (!size.isValid()) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr,
|
||||
JSMSG_TYPEDOBJECT_TOO_BIG);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Construct a canonical string `new ArrayType(<elementType>, N)`:
|
||||
StringBuffer contents(cx);
|
||||
contents.append("new ArrayType(");
|
||||
contents.append(&elementType->stringRepr());
|
||||
contents.append(", ");
|
||||
if (!NumberValueToStringBuffer(cx, NumberValue(length), contents))
|
||||
return false;
|
||||
contents.append(")");
|
||||
RootedAtom stringRepr(cx, contents.finishAtom());
|
||||
if (!stringRepr)
|
||||
@ -717,91 +711,11 @@ ArrayMetaTypeDescr::construct(JSContext *cx, unsigned argc, Value *vp)
|
||||
return false;
|
||||
|
||||
// Create the instance of ArrayType
|
||||
Rooted<UnsizedArrayTypeDescr *> obj(cx);
|
||||
obj = create<UnsizedArrayTypeDescr>(cx, arrayTypePrototype, elementType,
|
||||
stringRepr, 0);
|
||||
Rooted<ArrayTypeDescr *> obj(cx);
|
||||
obj = create(cx, arrayTypePrototype, elementType, stringRepr, size.value(), length);
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
// Add `length` property, which is undefined for an unsized array.
|
||||
if (!JSObject::defineProperty(cx, obj, cx->names().length,
|
||||
UndefinedHandleValue, nullptr, nullptr,
|
||||
JSPROP_READONLY | JSPROP_PERMANENT))
|
||||
return false;
|
||||
|
||||
args.rval().setObject(*obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*static*/ bool
|
||||
UnsizedArrayTypeDescr::dimension(JSContext *cx, unsigned int argc, jsval *vp)
|
||||
{
|
||||
// Expect that the `this` pointer is an unsized array type
|
||||
// and the first argument is an integer size.
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
if (args.length() != 1 ||
|
||||
!args.thisv().isObject() ||
|
||||
!args.thisv().toObject().is<UnsizedArrayTypeDescr>() ||
|
||||
!args[0].isInt32() ||
|
||||
args[0].toInt32() < 0)
|
||||
{
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr,
|
||||
JSMSG_TYPEDOBJECT_ARRAYTYPE_BAD_ARGS);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Extract arguments.
|
||||
Rooted<UnsizedArrayTypeDescr*> unsizedTypeDescr(cx);
|
||||
unsizedTypeDescr = &args.thisv().toObject().as<UnsizedArrayTypeDescr>();
|
||||
int32_t length = args[0].toInt32();
|
||||
Rooted<SizedTypeDescr*> elementType(cx, &unsizedTypeDescr->elementType());
|
||||
|
||||
// Compute the size.
|
||||
CheckedInt32 size = CheckedInt32(elementType->size()) * length;
|
||||
if (!size.isValid()) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr,
|
||||
JSMSG_TYPEDOBJECT_TOO_BIG);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Construct a canonical string `new ArrayType(<elementType>).dimension(N)`:
|
||||
StringBuffer contents(cx);
|
||||
contents.append("new ArrayType(");
|
||||
contents.append(&elementType->stringRepr());
|
||||
contents.append(").dimension(");
|
||||
if (!NumberValueToStringBuffer(cx, NumberValue(length), contents))
|
||||
return false;
|
||||
contents.append(")");
|
||||
RootedAtom stringRepr(cx, contents.finishAtom());
|
||||
if (!stringRepr)
|
||||
return false;
|
||||
|
||||
// Create the sized type object.
|
||||
Rooted<SizedArrayTypeDescr*> obj(cx);
|
||||
obj = ArrayMetaTypeDescr::create<SizedArrayTypeDescr>(cx, unsizedTypeDescr,
|
||||
elementType,
|
||||
stringRepr, size.value());
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
obj->initReservedSlot(JS_DESCR_SLOT_SIZED_ARRAY_LENGTH,
|
||||
Int32Value(length));
|
||||
|
||||
// Add `length` property.
|
||||
RootedValue lengthVal(cx, Int32Value(length));
|
||||
if (!JSObject::defineProperty(cx, obj, cx->names().length,
|
||||
lengthVal, nullptr, nullptr,
|
||||
JSPROP_READONLY | JSPROP_PERMANENT))
|
||||
return false;
|
||||
|
||||
// Add `unsized` property, which is a link from the sized
|
||||
// array to the unsized array.
|
||||
RootedValue unsizedTypeDescrValue(cx, ObjectValue(*unsizedTypeDescr));
|
||||
if (!JSObject::defineProperty(cx, obj, cx->names().unsized,
|
||||
unsizedTypeDescrValue, nullptr, nullptr,
|
||||
JSPROP_READONLY | JSPROP_PERMANENT))
|
||||
return false;
|
||||
|
||||
args.rval().setObject(*obj);
|
||||
return true;
|
||||
}
|
||||
@ -812,7 +726,7 @@ js::IsTypedObjectArray(JSObject &obj)
|
||||
if (!obj.is<TypedObject>())
|
||||
return false;
|
||||
TypeDescr& d = obj.as<TypedObject>().typeDescr();
|
||||
return d.is<SizedArrayTypeDescr>() || d.is<UnsizedArrayTypeDescr>();
|
||||
return d.is<ArrayTypeDescr>();
|
||||
}
|
||||
|
||||
/*********************************
|
||||
@ -832,7 +746,7 @@ const Class StructTypeDescr::class_ = {
|
||||
nullptr, /* finalize */
|
||||
nullptr, /* call */
|
||||
nullptr, /* hasInstance */
|
||||
TypedObject::constructSized,
|
||||
TypedObject::construct,
|
||||
nullptr /* trace */
|
||||
};
|
||||
|
||||
@ -893,7 +807,7 @@ StructMetaTypeDescr::create(JSContext *cx,
|
||||
|
||||
RootedValue fieldTypeVal(cx);
|
||||
RootedId id(cx);
|
||||
Rooted<SizedTypeDescr*> fieldType(cx);
|
||||
Rooted<TypeDescr*> fieldType(cx);
|
||||
for (unsigned int i = 0; i < ids.length(); i++) {
|
||||
id = ids[i];
|
||||
|
||||
@ -909,7 +823,7 @@ StructMetaTypeDescr::create(JSContext *cx,
|
||||
// The value should be a type descriptor.
|
||||
if (!JSObject::getGeneric(cx, fields, fields, id, &fieldTypeVal))
|
||||
return nullptr;
|
||||
fieldType = ToObjectIf<SizedTypeDescr>(fieldTypeVal);
|
||||
fieldType = ToObjectIf<TypeDescr>(fieldTypeVal);
|
||||
if (!fieldType) {
|
||||
ReportCannotConvertTo(cx, fieldTypeVal, "StructType field specifier");
|
||||
return nullptr;
|
||||
@ -1168,22 +1082,22 @@ StructTypeDescr::maybeForwardedFieldOffset(size_t index) const
|
||||
return AssertedCast<size_t>(fieldOffsets.getDenseElement(index).toInt32());
|
||||
}
|
||||
|
||||
SizedTypeDescr&
|
||||
TypeDescr&
|
||||
StructTypeDescr::fieldDescr(size_t index) const
|
||||
{
|
||||
NativeObject &fieldDescrs = fieldInfoObject(JS_DESCR_SLOT_STRUCT_FIELD_TYPES);
|
||||
MOZ_ASSERT(index < fieldDescrs.getDenseInitializedLength());
|
||||
return fieldDescrs.getDenseElement(index).toObject().as<SizedTypeDescr>();
|
||||
return fieldDescrs.getDenseElement(index).toObject().as<TypeDescr>();
|
||||
}
|
||||
|
||||
SizedTypeDescr&
|
||||
TypeDescr&
|
||||
StructTypeDescr::maybeForwardedFieldDescr(size_t index) const
|
||||
{
|
||||
NativeObject &fieldDescrs = maybeForwardedFieldInfoObject(JS_DESCR_SLOT_STRUCT_FIELD_TYPES);
|
||||
MOZ_ASSERT(index < fieldDescrs.getDenseInitializedLength());
|
||||
JSObject &descr =
|
||||
*MaybeForwarded(&fieldDescrs.getDenseElement(index).toObject());
|
||||
return descr.as<SizedTypeDescr>();
|
||||
return descr.as<TypeDescr>();
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
@ -1468,9 +1382,7 @@ TypedObject::offset() const
|
||||
int32_t
|
||||
TypedObject::length() const
|
||||
{
|
||||
if (typeDescr().is<SizedArrayTypeDescr>())
|
||||
return typeDescr().as<SizedArrayTypeDescr>().length();
|
||||
return as<OutlineTypedObject>().unsizedLength();
|
||||
return typeDescr().as<ArrayTypeDescr>().length();
|
||||
}
|
||||
|
||||
uint8_t *
|
||||
@ -1617,18 +1529,14 @@ OutlineTypedObject::createUnattachedWithClass(JSContext *cx,
|
||||
if (!proto)
|
||||
return nullptr;
|
||||
|
||||
gc::AllocKind allocKind = allocKindForTypeDescriptor(type);
|
||||
NewObjectKind newKind = (heap == gc::TenuredHeap) ? MaybeSingletonObject : GenericObject;
|
||||
JSObject *obj = NewObjectWithClassProto(cx, clasp, proto, nullptr, allocKind, newKind);
|
||||
JSObject *obj = NewObjectWithClassProto(cx, clasp, proto, nullptr, gc::FINALIZE_OBJECT0, newKind);
|
||||
if (!obj)
|
||||
return nullptr;
|
||||
|
||||
OutlineTypedObject *typedObj = &obj->as<OutlineTypedObject>();
|
||||
|
||||
typedObj->setOwnerAndData(nullptr, nullptr);
|
||||
if (type->kind() == type::UnsizedArray)
|
||||
typedObj->setUnsizedLength(length);
|
||||
|
||||
return typedObj;
|
||||
}
|
||||
|
||||
@ -1668,7 +1576,7 @@ OutlineTypedObject::attach(JSContext *cx, TypedObject &typedObj, int32_t offset)
|
||||
}
|
||||
|
||||
// Returns a suitable JS_TYPEDOBJ_SLOT_LENGTH value for an instance of
|
||||
// the type `type`. `type` must not be an unsized array.
|
||||
// the type `type`.
|
||||
static int32_t
|
||||
TypedObjLengthFromType(TypeDescr &descr)
|
||||
{
|
||||
@ -1679,17 +1587,14 @@ TypedObjLengthFromType(TypeDescr &descr)
|
||||
case type::Simd:
|
||||
return 0;
|
||||
|
||||
case type::SizedArray:
|
||||
return descr.as<SizedArrayTypeDescr>().length();
|
||||
|
||||
case type::UnsizedArray:
|
||||
MOZ_CRASH("TypedObjLengthFromType() invoked on unsized type");
|
||||
case type::Array:
|
||||
return descr.as<ArrayTypeDescr>().length();
|
||||
}
|
||||
MOZ_CRASH("Invalid kind");
|
||||
}
|
||||
|
||||
/*static*/ OutlineTypedObject *
|
||||
OutlineTypedObject::createDerived(JSContext *cx, HandleSizedTypeDescr type,
|
||||
OutlineTypedObject::createDerived(JSContext *cx, HandleTypeDescr type,
|
||||
HandleTypedObject typedObj, int32_t offset)
|
||||
{
|
||||
MOZ_ASSERT(offset <= typedObj->size());
|
||||
@ -1713,11 +1618,9 @@ OutlineTypedObject::createDerived(JSContext *cx, HandleSizedTypeDescr type,
|
||||
TypedObject::createZeroed(JSContext *cx, HandleTypeDescr descr, int32_t length, gc::InitialHeap heap)
|
||||
{
|
||||
// If possible, create an object with inline data.
|
||||
if (descr->is<SizedTypeDescr>() &&
|
||||
(size_t) descr->as<SizedTypeDescr>().size() <= InlineTypedObject::MaximumSize)
|
||||
{
|
||||
if ((size_t) descr->size() <= InlineTypedObject::MaximumSize) {
|
||||
InlineTypedObject *obj = InlineTypedObject::create(cx, descr, heap);
|
||||
descr->as<SizedTypeDescr>().initInstances(cx->runtime(), obj->inlineTypedMem(), 1);
|
||||
descr->initInstances(cx->runtime(), obj->inlineTypedMem(), 1);
|
||||
return obj;
|
||||
}
|
||||
|
||||
@ -1727,49 +1630,14 @@ TypedObject::createZeroed(JSContext *cx, HandleTypeDescr descr, int32_t length,
|
||||
return nullptr;
|
||||
|
||||
// Allocate and initialize the memory for this instance.
|
||||
// Also initialize the JS_TYPEDOBJ_SLOT_LENGTH slot.
|
||||
switch (descr->kind()) {
|
||||
case type::Scalar:
|
||||
case type::Reference:
|
||||
case type::Struct:
|
||||
case type::Simd:
|
||||
case type::SizedArray:
|
||||
{
|
||||
size_t totalSize = descr->as<SizedTypeDescr>().size();
|
||||
Rooted<ArrayBufferObject*> buffer(cx);
|
||||
buffer = ArrayBufferObject::create(cx, totalSize);
|
||||
if (!buffer)
|
||||
return nullptr;
|
||||
descr->as<SizedTypeDescr>().initInstances(cx->runtime(), buffer->dataPointer(), 1);
|
||||
obj->attach(cx, *buffer, 0);
|
||||
return obj;
|
||||
}
|
||||
|
||||
case type::UnsizedArray:
|
||||
{
|
||||
Rooted<SizedTypeDescr*> elementTypeRepr(cx);
|
||||
elementTypeRepr = &descr->as<UnsizedArrayTypeDescr>().elementType();
|
||||
|
||||
CheckedInt32 totalSize = CheckedInt32(elementTypeRepr->size()) * length;
|
||||
if (!totalSize.isValid()) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr,
|
||||
JSMSG_TYPEDOBJECT_TOO_BIG);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Rooted<ArrayBufferObject*> buffer(cx);
|
||||
buffer = ArrayBufferObject::create(cx, totalSize.value());
|
||||
if (!buffer)
|
||||
return nullptr;
|
||||
|
||||
if (length)
|
||||
elementTypeRepr->initInstances(cx->runtime(), buffer->dataPointer(), length);
|
||||
obj->attach(cx, *buffer, 0);
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_CRASH("Bad TypeRepresentation Kind");
|
||||
size_t totalSize = descr->size();
|
||||
Rooted<ArrayBufferObject*> buffer(cx);
|
||||
buffer = ArrayBufferObject::create(cx, totalSize);
|
||||
if (!buffer)
|
||||
return nullptr;
|
||||
descr->initInstances(cx->runtime(), buffer->dataPointer(), 1);
|
||||
obj->attach(cx, *buffer, 0);
|
||||
return obj;
|
||||
}
|
||||
|
||||
static bool
|
||||
@ -1823,22 +1691,7 @@ OutlineTypedObject::obj_trace(JSTracer *trc, JSObject *object)
|
||||
if (!descr.opaque() || !typedObj.maybeForwardedIsAttached())
|
||||
return;
|
||||
|
||||
switch (descr.kind()) {
|
||||
case type::Scalar:
|
||||
case type::Reference:
|
||||
case type::Struct:
|
||||
case type::SizedArray:
|
||||
case type::Simd:
|
||||
descr.as<SizedTypeDescr>().traceInstances(trc, mem, 1);
|
||||
break;
|
||||
|
||||
case type::UnsizedArray:
|
||||
{
|
||||
SizedTypeDescr &elemType = descr.as<UnsizedArrayTypeDescr>().maybeForwardedElementType();
|
||||
elemType.traceInstances(trc, mem, typedObj.unsizedLength());
|
||||
break;
|
||||
}
|
||||
}
|
||||
descr.traceInstances(trc, mem, 1);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -1854,8 +1707,7 @@ TypedObject::obj_lookupGeneric(JSContext *cx, HandleObject obj, HandleId id,
|
||||
case type::Simd:
|
||||
break;
|
||||
|
||||
case type::SizedArray:
|
||||
case type::UnsizedArray:
|
||||
case type::Array:
|
||||
{
|
||||
uint32_t index;
|
||||
if (js_IdIsIndex(id, &index))
|
||||
@ -1982,8 +1834,7 @@ TypedObject::obj_getGeneric(JSContext *cx, HandleObject obj, HandleObject receiv
|
||||
case type::Simd:
|
||||
break;
|
||||
|
||||
case type::SizedArray:
|
||||
case type::UnsizedArray:
|
||||
case type::Array:
|
||||
if (JSID_IS_ATOM(id, cx->names().length)) {
|
||||
if (!typedObj->isAttached()) {
|
||||
JS_ReportErrorNumber(
|
||||
@ -2005,7 +1856,7 @@ TypedObject::obj_getGeneric(JSContext *cx, HandleObject obj, HandleObject receiv
|
||||
break;
|
||||
|
||||
size_t offset = descr->fieldOffset(fieldIndex);
|
||||
Rooted<SizedTypeDescr*> fieldType(cx, &descr->fieldDescr(fieldIndex));
|
||||
Rooted<TypeDescr*> fieldType(cx, &descr->fieldDescr(fieldIndex));
|
||||
return Reify(cx, fieldType, typedObj, offset, vp);
|
||||
}
|
||||
}
|
||||
@ -2042,13 +1893,8 @@ TypedObject::obj_getElement(JSContext *cx, HandleObject obj, HandleObject receiv
|
||||
case type::Struct:
|
||||
break;
|
||||
|
||||
case type::SizedArray:
|
||||
return obj_getArrayElement<SizedArrayTypeDescr>(cx, typedObj, descr,
|
||||
index, vp);
|
||||
|
||||
case type::UnsizedArray:
|
||||
return obj_getArrayElement<UnsizedArrayTypeDescr>(cx, typedObj, descr,
|
||||
index, vp);
|
||||
case type::Array:
|
||||
return obj_getArrayElement(cx, typedObj, descr, index, vp);
|
||||
}
|
||||
|
||||
RootedObject proto(cx, obj->getProto());
|
||||
@ -2060,7 +1906,6 @@ TypedObject::obj_getElement(JSContext *cx, HandleObject obj, HandleObject receiv
|
||||
return JSObject::getElement(cx, proto, receiver, index, vp);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
/*static*/ bool
|
||||
TypedObject::obj_getArrayElement(JSContext *cx,
|
||||
Handle<TypedObject*> typedObj,
|
||||
@ -2068,14 +1913,12 @@ TypedObject::obj_getArrayElement(JSContext *cx,
|
||||
uint32_t index,
|
||||
MutableHandleValue vp)
|
||||
{
|
||||
MOZ_ASSERT(typeDescr->is<T>());
|
||||
|
||||
if (index >= (size_t) typedObj->length()) {
|
||||
vp.setUndefined();
|
||||
return true;
|
||||
}
|
||||
|
||||
Rooted<SizedTypeDescr*> elementType(cx, &typeDescr->as<T>().elementType());
|
||||
Rooted<TypeDescr*> elementType(cx, &typeDescr->as<ArrayTypeDescr>().elementType());
|
||||
size_t offset = elementType->size() * index;
|
||||
return Reify(cx, elementType, typedObj, offset, vp);
|
||||
}
|
||||
@ -2099,8 +1942,7 @@ TypedObject::obj_setGeneric(JSContext *cx, HandleObject obj, HandleId id,
|
||||
case type::Simd:
|
||||
break;
|
||||
|
||||
case type::SizedArray:
|
||||
case type::UnsizedArray:
|
||||
case type::Array:
|
||||
if (JSID_IS_ATOM(id, cx->names().length)) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage,
|
||||
nullptr, JSMSG_CANT_REDEFINE_ARRAY_LENGTH);
|
||||
@ -2116,7 +1958,7 @@ TypedObject::obj_setGeneric(JSContext *cx, HandleObject obj, HandleId id,
|
||||
break;
|
||||
|
||||
size_t offset = descr->fieldOffset(fieldIndex);
|
||||
Rooted<SizedTypeDescr*> fieldType(cx, &descr->fieldDescr(fieldIndex));
|
||||
Rooted<TypeDescr*> fieldType(cx, &descr->fieldDescr(fieldIndex));
|
||||
return ConvertAndCopyTo(cx, fieldType, typedObj, offset, vp);
|
||||
}
|
||||
}
|
||||
@ -2148,17 +1990,13 @@ TypedObject::obj_setElement(JSContext *cx, HandleObject obj, uint32_t index,
|
||||
case type::Struct:
|
||||
break;
|
||||
|
||||
case type::SizedArray:
|
||||
return obj_setArrayElement<SizedArrayTypeDescr>(cx, typedObj, descr, index, vp);
|
||||
|
||||
case type::UnsizedArray:
|
||||
return obj_setArrayElement<UnsizedArrayTypeDescr>(cx, typedObj, descr, index, vp);
|
||||
case type::Array:
|
||||
return obj_setArrayElement(cx, typedObj, descr, index, vp);
|
||||
}
|
||||
|
||||
return ReportTypedObjTypeError(cx, JSMSG_OBJECT_NOT_EXTENSIBLE, typedObj);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
/*static*/ bool
|
||||
TypedObject::obj_setArrayElement(JSContext *cx,
|
||||
Handle<TypedObject*> typedObj,
|
||||
@ -2166,16 +2004,14 @@ TypedObject::obj_setArrayElement(JSContext *cx,
|
||||
uint32_t index,
|
||||
MutableHandleValue vp)
|
||||
{
|
||||
MOZ_ASSERT(descr->is<T>());
|
||||
|
||||
if (index >= (size_t) typedObj->length()) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage,
|
||||
nullptr, JSMSG_TYPEDOBJECT_BINARYARRAY_BAD_INDEX);
|
||||
return false;
|
||||
}
|
||||
|
||||
Rooted<SizedTypeDescr*> elementType(cx);
|
||||
elementType = &descr->as<T>().elementType();
|
||||
Rooted<TypeDescr*> elementType(cx);
|
||||
elementType = &descr->as<ArrayTypeDescr>().elementType();
|
||||
size_t offset = elementType->size() * index;
|
||||
return ConvertAndCopyTo(cx, elementType, typedObj, offset, vp);
|
||||
}
|
||||
@ -2194,8 +2030,7 @@ TypedObject::obj_getGenericAttributes(JSContext *cx, HandleObject obj,
|
||||
case type::Simd:
|
||||
break;
|
||||
|
||||
case type::SizedArray:
|
||||
case type::UnsizedArray:
|
||||
case type::Array:
|
||||
if (js_IdIsIndex(id, &index)) {
|
||||
*attrsp = JSPROP_ENUMERATE | JSPROP_PERMANENT;
|
||||
return true;
|
||||
@ -2235,8 +2070,7 @@ IsOwnId(JSContext *cx, HandleObject obj, HandleId id)
|
||||
case type::Simd:
|
||||
return false;
|
||||
|
||||
case type::SizedArray:
|
||||
case type::UnsizedArray:
|
||||
case type::Array:
|
||||
return js_IdIsIndex(id, &index) || JSID_IS_ATOM(id, cx->names().length);
|
||||
|
||||
case type::Struct:
|
||||
@ -2305,8 +2139,7 @@ TypedObject::obj_enumerate(JSContext *cx, HandleObject obj, JSIterateOp enum_op,
|
||||
}
|
||||
break;
|
||||
|
||||
case type::SizedArray:
|
||||
case type::UnsizedArray:
|
||||
case type::Array:
|
||||
switch (enum_op) {
|
||||
case JSENUMERATE_INIT_ALL:
|
||||
case JSENUMERATE_INIT:
|
||||
@ -2366,8 +2199,6 @@ TypedObject::obj_enumerate(JSContext *cx, HandleObject obj, JSIterateOp enum_op,
|
||||
void
|
||||
OutlineTypedObject::neuter(void *newData)
|
||||
{
|
||||
if (typeDescr().kind() == type::UnsizedArray)
|
||||
setUnsizedLength(0);
|
||||
setData(reinterpret_cast<uint8_t *>(newData));
|
||||
}
|
||||
|
||||
@ -2418,7 +2249,7 @@ InlineTypedObject::obj_trace(JSTracer *trc, JSObject *object)
|
||||
// may not have had their slots updated yet.
|
||||
TypeDescr &descr = typedObj.maybeForwardedTypeDescr();
|
||||
|
||||
descr.as<SizedTypeDescr>().traceInstances(trc, typedObj.inlineTypedMem(), 1);
|
||||
descr.traceInstances(trc, typedObj.inlineTypedMem(), 1);
|
||||
}
|
||||
|
||||
ArrayBufferObject *
|
||||
@ -2437,7 +2268,7 @@ InlineTransparentTypedObject::getOrCreateBuffer(JSContext *cx)
|
||||
|
||||
ArrayBufferObject::BufferContents contents =
|
||||
ArrayBufferObject::BufferContents::createPlain(inlineTypedMem());
|
||||
size_t nbytes = typeDescr().as<SizedTypeDescr>().size();
|
||||
size_t nbytes = typeDescr().size();
|
||||
|
||||
// Prevent GC under ArrayBufferObject::create, which might move this object
|
||||
// and its contents.
|
||||
@ -2594,11 +2425,8 @@ LengthForType(TypeDescr &descr)
|
||||
case type::Simd:
|
||||
return 0;
|
||||
|
||||
case type::SizedArray:
|
||||
return descr.as<SizedArrayTypeDescr>().length();
|
||||
|
||||
case type::UnsizedArray:
|
||||
return 0;
|
||||
case type::Array:
|
||||
return descr.as<ArrayTypeDescr>().length();
|
||||
}
|
||||
|
||||
MOZ_CRASH("Invalid kind");
|
||||
@ -2633,15 +2461,15 @@ CheckOffset(int32_t offset,
|
||||
}
|
||||
|
||||
/*static*/ bool
|
||||
TypedObject::constructSized(JSContext *cx, unsigned int argc, Value *vp)
|
||||
TypedObject::construct(JSContext *cx, unsigned int argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
MOZ_ASSERT(args.callee().is<SizedTypeDescr>());
|
||||
Rooted<SizedTypeDescr*> callee(cx, &args.callee().as<SizedTypeDescr>());
|
||||
MOZ_ASSERT(args.callee().is<TypeDescr>());
|
||||
Rooted<TypeDescr*> callee(cx, &args.callee().as<TypeDescr>());
|
||||
|
||||
// Typed object constructors for sized types are overloaded in
|
||||
// three ways, in order of precedence:
|
||||
// Typed object constructors are overloaded in three ways, in order of
|
||||
// precedence:
|
||||
//
|
||||
// new TypeObj()
|
||||
// new TypeObj(buffer, [offset])
|
||||
@ -2726,162 +2554,6 @@ TypedObject::constructSized(JSContext *cx, unsigned int argc, Value *vp)
|
||||
return false;
|
||||
}
|
||||
|
||||
/*static*/ bool
|
||||
TypedObject::constructUnsized(JSContext *cx, unsigned int argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
MOZ_ASSERT(args.callee().is<TypeDescr>());
|
||||
Rooted<UnsizedArrayTypeDescr*> callee(cx);
|
||||
callee = &args.callee().as<UnsizedArrayTypeDescr>();
|
||||
|
||||
// Typed object constructors for unsized arrays are overloaded in
|
||||
// four ways, in order of precedence:
|
||||
//
|
||||
// new TypeObj(buffer, [offset, [length]]) // [1]
|
||||
// new TypeObj(length) // [1]
|
||||
// new TypeObj(data)
|
||||
// new TypeObj()
|
||||
//
|
||||
// [1] Explicit lengths only available for unsized arrays.
|
||||
|
||||
// Zero argument constructor:
|
||||
if (args.length() == 0) {
|
||||
Rooted<TypedObject*> obj(cx, createZeroed(cx, callee, 0));
|
||||
if (!obj)
|
||||
return false;
|
||||
args.rval().setObject(*obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Length constructor.
|
||||
if (args[0].isInt32()) {
|
||||
int32_t length = args[0].toInt32();
|
||||
if (length < 0) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage,
|
||||
nullptr, JSMSG_TYPEDOBJECT_BAD_ARGS);
|
||||
return false;
|
||||
}
|
||||
Rooted<TypedObject*> obj(cx, createZeroed(cx, callee, length));
|
||||
if (!obj)
|
||||
return false;
|
||||
args.rval().setObject(*obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Buffer constructor.
|
||||
if (args[0].isObject() && args[0].toObject().is<ArrayBufferObject>()) {
|
||||
Rooted<ArrayBufferObject*> buffer(cx);
|
||||
buffer = &args[0].toObject().as<ArrayBufferObject>();
|
||||
|
||||
if (callee->opaque()) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage,
|
||||
nullptr, JSMSG_TYPEDOBJECT_BAD_ARGS);
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t offset;
|
||||
if (args.length() >= 2 && !args[1].isUndefined()) {
|
||||
if (!args[1].isInt32()) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage,
|
||||
nullptr, JSMSG_TYPEDOBJECT_BAD_ARGS);
|
||||
return false;
|
||||
}
|
||||
|
||||
offset = args[1].toInt32();
|
||||
} else {
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
if (!CheckOffset(offset, 0, callee->alignment(), buffer->byteLength())) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage,
|
||||
nullptr, JSMSG_TYPEDOBJECT_BAD_ARGS);
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t elemSize = callee->elementType().size();
|
||||
int32_t bytesRemaining = buffer->byteLength() - offset;
|
||||
int32_t maximumLength = bytesRemaining / elemSize;
|
||||
|
||||
int32_t length;
|
||||
if (args.length() >= 3 && !args[2].isUndefined()) {
|
||||
if (!args[2].isInt32()) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage,
|
||||
nullptr, JSMSG_TYPEDOBJECT_BAD_ARGS);
|
||||
return false;
|
||||
}
|
||||
length = args[2].toInt32();
|
||||
|
||||
if (length < 0 || length > maximumLength) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage,
|
||||
nullptr, JSMSG_TYPEDOBJECT_BAD_ARGS);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if ((bytesRemaining % elemSize) != 0) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage,
|
||||
nullptr, JSMSG_TYPEDOBJECT_BAD_ARGS);
|
||||
return false;
|
||||
}
|
||||
|
||||
length = maximumLength;
|
||||
}
|
||||
|
||||
if (buffer->isNeutered()) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage,
|
||||
nullptr, JSMSG_TYPEDOBJECT_BAD_ARGS);
|
||||
return false;
|
||||
}
|
||||
|
||||
Rooted<OutlineTypedObject*> obj(cx);
|
||||
obj = OutlineTypedObject::createUnattached(cx, callee, length);
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
obj->attach(cx, args[0].toObject().as<ArrayBufferObject>(), offset);
|
||||
}
|
||||
|
||||
// Data constructor for unsized values
|
||||
if (args[0].isObject()) {
|
||||
// Read length out of the object.
|
||||
RootedObject arg(cx, &args[0].toObject());
|
||||
RootedValue lengthVal(cx);
|
||||
if (!JSObject::getProperty(cx, arg, arg, cx->names().length, &lengthVal))
|
||||
return false;
|
||||
if (!lengthVal.isInt32()) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage,
|
||||
nullptr, JSMSG_TYPEDOBJECT_BAD_ARGS);
|
||||
return false;
|
||||
}
|
||||
int32_t length = lengthVal.toInt32();
|
||||
|
||||
// Check that length * elementSize does not overflow.
|
||||
int32_t elementSize = callee->elementType().size();
|
||||
int32_t byteLength;
|
||||
if (!SafeMul(elementSize, length, &byteLength)) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage,
|
||||
nullptr, JSMSG_TYPEDOBJECT_BAD_ARGS);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create the unsized array.
|
||||
Rooted<TypedObject*> obj(cx, createZeroed(cx, callee, length));
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
// Initialize from `arg`
|
||||
if (!ConvertAndCopyTo(cx, obj, args[0]))
|
||||
return false;
|
||||
args.rval().setObject(*obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Something bogus.
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage,
|
||||
nullptr, JSMSG_TYPEDOBJECT_BAD_ARGS);
|
||||
return false;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Intrinsics
|
||||
*/
|
||||
@ -2891,9 +2563,9 @@ js::NewOpaqueTypedObject(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
MOZ_ASSERT(args.length() == 1);
|
||||
MOZ_ASSERT(args[0].isObject() && args[0].toObject().is<SizedTypeDescr>());
|
||||
MOZ_ASSERT(args[0].isObject() && args[0].toObject().is<TypeDescr>());
|
||||
|
||||
Rooted<SizedTypeDescr*> descr(cx, &args[0].toObject().as<SizedTypeDescr>());
|
||||
Rooted<TypeDescr*> descr(cx, &args[0].toObject().as<TypeDescr>());
|
||||
int32_t length = TypedObjLengthFromType(*descr);
|
||||
Rooted<OutlineTypedObject*> obj(cx);
|
||||
obj = OutlineTypedObject::createUnattachedWithClass(cx, &OutlineOpaqueTypedObject::class_, descr, length);
|
||||
@ -2908,11 +2580,11 @@ js::NewDerivedTypedObject(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
MOZ_ASSERT(args.length() == 3);
|
||||
MOZ_ASSERT(args[0].isObject() && args[0].toObject().is<SizedTypeDescr>());
|
||||
MOZ_ASSERT(args[0].isObject() && args[0].toObject().is<TypeDescr>());
|
||||
MOZ_ASSERT(args[1].isObject() && args[1].toObject().is<TypedObject>());
|
||||
MOZ_ASSERT(args[2].isInt32());
|
||||
|
||||
Rooted<SizedTypeDescr*> descr(cx, &args[0].toObject().as<SizedTypeDescr>());
|
||||
Rooted<TypeDescr*> descr(cx, &args[0].toObject().as<TypeDescr>());
|
||||
Rooted<TypedObject*> typedObj(cx, &args[1].toObject().as<TypedObject>());
|
||||
int32_t offset = args[2].toInt32();
|
||||
|
||||
@ -3057,8 +2729,7 @@ js::TypeDescrIsArrayType(ThreadSafeContext *, unsigned argc, Value *vp)
|
||||
MOZ_ASSERT(args[0].isObject());
|
||||
MOZ_ASSERT(args[0].toObject().is<js::TypeDescr>());
|
||||
JSObject& obj = args[0].toObject();
|
||||
args.rval().setBoolean(obj.is<js::SizedArrayTypeDescr>() ||
|
||||
obj.is<js::UnsizedArrayTypeDescr>());
|
||||
args.rval().setBoolean(obj.is<js::ArrayTypeDescr>());
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3066,36 +2737,6 @@ JS_JITINFO_NATIVE_PARALLEL_THREADSAFE(js::TypeDescrIsArrayTypeJitInfo,
|
||||
TypeDescrIsArrayTypeJitInfo,
|
||||
js::TypeDescrIsArrayType);
|
||||
|
||||
bool
|
||||
js::TypeDescrIsSizedArrayType(ThreadSafeContext *, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
MOZ_ASSERT(args.length() == 1);
|
||||
MOZ_ASSERT(args[0].isObject());
|
||||
MOZ_ASSERT(args[0].toObject().is<js::TypeDescr>());
|
||||
args.rval().setBoolean(args[0].toObject().is<js::SizedArrayTypeDescr>());
|
||||
return true;
|
||||
}
|
||||
|
||||
JS_JITINFO_NATIVE_PARALLEL_THREADSAFE(js::TypeDescrIsSizedArrayTypeJitInfo,
|
||||
TypeDescrIsSizedArrayTypeJitInfo,
|
||||
js::TypeDescrIsSizedArrayType);
|
||||
|
||||
bool
|
||||
js::TypeDescrIsUnsizedArrayType(ThreadSafeContext *, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
MOZ_ASSERT(args.length() == 1);
|
||||
MOZ_ASSERT(args[0].isObject());
|
||||
MOZ_ASSERT(args[0].toObject().is<js::TypeDescr>());
|
||||
args.rval().setBoolean(args[0].toObject().is<js::UnsizedArrayTypeDescr>());
|
||||
return true;
|
||||
}
|
||||
|
||||
JS_JITINFO_NATIVE_PARALLEL_THREADSAFE(js::TypeDescrIsUnsizedArrayTypeJitInfo,
|
||||
TypeDescrIsUnsizedArrayTypeJitInfo,
|
||||
js::TypeDescrIsUnsizedArrayType);
|
||||
|
||||
bool
|
||||
js::TypedObjectIsAttached(ThreadSafeContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
@ -3311,7 +2952,7 @@ JS_FOR_EACH_REFERENCE_TYPE_REPR(JS_LOAD_REFERENCE_CLASS_IMPL)
|
||||
|
||||
template<typename V>
|
||||
static void
|
||||
visitReferences(SizedTypeDescr &descr,
|
||||
visitReferences(TypeDescr &descr,
|
||||
uint8_t *mem,
|
||||
V& visitor)
|
||||
{
|
||||
@ -3327,10 +2968,10 @@ visitReferences(SizedTypeDescr &descr,
|
||||
visitor.visitReference(descr.as<ReferenceTypeDescr>(), mem);
|
||||
return;
|
||||
|
||||
case type::SizedArray:
|
||||
case type::Array:
|
||||
{
|
||||
SizedArrayTypeDescr &arrayDescr = descr.as<SizedArrayTypeDescr>();
|
||||
SizedTypeDescr &elementDescr = arrayDescr.maybeForwardedElementType();
|
||||
ArrayTypeDescr &arrayDescr = descr.as<ArrayTypeDescr>();
|
||||
TypeDescr &elementDescr = arrayDescr.maybeForwardedElementType();
|
||||
for (int32_t i = 0; i < arrayDescr.length(); i++) {
|
||||
visitReferences(elementDescr, mem, visitor);
|
||||
mem += elementDescr.size();
|
||||
@ -3338,16 +2979,11 @@ visitReferences(SizedTypeDescr &descr,
|
||||
return;
|
||||
}
|
||||
|
||||
case type::UnsizedArray:
|
||||
{
|
||||
MOZ_CRASH("Only Sized Type representations");
|
||||
}
|
||||
|
||||
case type::Struct:
|
||||
{
|
||||
StructTypeDescr &structDescr = descr.as<StructTypeDescr>();
|
||||
for (size_t i = 0; i < structDescr.maybeForwardedFieldCount(); i++) {
|
||||
SizedTypeDescr &descr = structDescr.maybeForwardedFieldDescr(i);
|
||||
TypeDescr &descr = structDescr.maybeForwardedFieldDescr(i);
|
||||
size_t offset = structDescr.maybeForwardedFieldOffset(i);
|
||||
visitReferences(descr, mem + offset, visitor);
|
||||
}
|
||||
@ -3406,7 +3042,7 @@ js::MemoryInitVisitor::visitReference(ReferenceTypeDescr &descr, uint8_t *mem)
|
||||
}
|
||||
|
||||
void
|
||||
SizedTypeDescr::initInstances(const JSRuntime *rt, uint8_t *mem, size_t length)
|
||||
TypeDescr::initInstances(const JSRuntime *rt, uint8_t *mem, size_t length)
|
||||
{
|
||||
MOZ_ASSERT(length >= 1);
|
||||
|
||||
@ -3476,7 +3112,7 @@ js::MemoryTracingVisitor::visitReference(ReferenceTypeDescr &descr, uint8_t *mem
|
||||
}
|
||||
|
||||
void
|
||||
SizedTypeDescr::traceInstances(JSTracer *trace, uint8_t *mem, size_t length)
|
||||
TypeDescr::traceInstances(JSTracer *trace, uint8_t *mem, size_t length)
|
||||
{
|
||||
MemoryTracingVisitor visitor(trace);
|
||||
|
||||
|
@ -119,25 +119,19 @@ enum Kind {
|
||||
Reference = JS_TYPEREPR_REFERENCE_KIND,
|
||||
Simd = JS_TYPEREPR_SIMD_KIND,
|
||||
Struct = JS_TYPEREPR_STRUCT_KIND,
|
||||
SizedArray = JS_TYPEREPR_SIZED_ARRAY_KIND,
|
||||
UnsizedArray = JS_TYPEREPR_UNSIZED_ARRAY_KIND,
|
||||
Array = JS_TYPEREPR_ARRAY_KIND
|
||||
};
|
||||
|
||||
static inline bool isSized(type::Kind kind) {
|
||||
return kind > JS_TYPEREPR_MAX_UNSIZED_KIND;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Typed Prototypes
|
||||
|
||||
class SizedTypeDescr;
|
||||
class SimpleTypeDescr;
|
||||
class ComplexTypeDescr;
|
||||
class SimdTypeDescr;
|
||||
class StructTypeDescr;
|
||||
class SizedTypedProto;
|
||||
class TypedProto;
|
||||
|
||||
/*
|
||||
* The prototype for a typed object. Currently, carries a link to the
|
||||
@ -174,10 +168,6 @@ class TypeDescr : public NativeObject
|
||||
static const Class class_;
|
||||
|
||||
public:
|
||||
static bool isSized(type::Kind kind) {
|
||||
return kind > JS_TYPEREPR_MAX_UNSIZED_KIND;
|
||||
}
|
||||
|
||||
TypedProto &typedProto() const {
|
||||
return getReservedSlot(JS_DESCR_SLOT_TYPROTO).toObject().as<TypedProto>();
|
||||
}
|
||||
@ -201,13 +191,7 @@ class TypeDescr : public NativeObject
|
||||
int32_t alignment() const {
|
||||
return getReservedSlot(JS_DESCR_SLOT_ALIGNMENT).toInt32();
|
||||
}
|
||||
};
|
||||
|
||||
typedef Handle<TypeDescr*> HandleTypeDescr;
|
||||
|
||||
class SizedTypeDescr : public TypeDescr
|
||||
{
|
||||
public:
|
||||
int32_t size() const {
|
||||
return getReservedSlot(JS_DESCR_SLOT_SIZE).toInt32();
|
||||
}
|
||||
@ -216,9 +200,9 @@ class SizedTypeDescr : public TypeDescr
|
||||
void traceInstances(JSTracer *trace, uint8_t *mem, size_t length);
|
||||
};
|
||||
|
||||
typedef Handle<SizedTypeDescr*> HandleSizedTypeDescr;
|
||||
typedef Handle<TypeDescr*> HandleTypeDescr;
|
||||
|
||||
class SimpleTypeDescr : public SizedTypeDescr
|
||||
class SimpleTypeDescr : public TypeDescr
|
||||
{
|
||||
};
|
||||
|
||||
@ -328,7 +312,7 @@ class ReferenceTypeDescr : public SimpleTypeDescr
|
||||
|
||||
// Type descriptors whose instances are objects and hence which have
|
||||
// an associated `prototype` property.
|
||||
class ComplexTypeDescr : public SizedTypeDescr
|
||||
class ComplexTypeDescr : public TypeDescr
|
||||
{
|
||||
public:
|
||||
// Returns the prototype that instances of this type descriptor
|
||||
@ -372,6 +356,8 @@ bool IsTypedObjectArray(JSObject& obj);
|
||||
|
||||
bool CreateUserSizeAndAlignmentProperties(JSContext *cx, HandleTypeDescr obj);
|
||||
|
||||
class ArrayTypeDescr;
|
||||
|
||||
/*
|
||||
* Properties and methods of the `ArrayType` meta type object. There
|
||||
* is no `class_` field because `ArrayType` is just a native
|
||||
@ -380,25 +366,18 @@ bool CreateUserSizeAndAlignmentProperties(JSContext *cx, HandleTypeDescr obj);
|
||||
class ArrayMetaTypeDescr : public JSObject
|
||||
{
|
||||
private:
|
||||
friend class UnsizedArrayTypeDescr;
|
||||
|
||||
// Helper for creating a new ArrayType object, either sized or unsized.
|
||||
// The template parameter `T` should be either `UnsizedArrayTypeDescr`
|
||||
// or `SizedArrayTypeDescr`.
|
||||
// Helper for creating a new ArrayType object.
|
||||
//
|
||||
// - `arrayTypePrototype` - prototype for the new object to be created,
|
||||
// either ArrayType.prototype or
|
||||
// unsizedArrayType.__proto__ depending on
|
||||
// whether this is a sized or unsized array
|
||||
// - `arrayTypePrototype` - prototype for the new object to be created
|
||||
// - `elementType` - type object for the elements in the array
|
||||
// - `stringRepr` - canonical string representation for the array
|
||||
// - `size` - length of the array (0 if unsized)
|
||||
template<class T>
|
||||
static T *create(JSContext *cx,
|
||||
HandleObject arrayTypePrototype,
|
||||
HandleSizedTypeDescr elementType,
|
||||
HandleAtom stringRepr,
|
||||
int32_t size);
|
||||
// - `size` - length of the array
|
||||
static ArrayTypeDescr *create(JSContext *cx,
|
||||
HandleObject arrayTypePrototype,
|
||||
HandleTypeDescr elementType,
|
||||
HandleAtom stringRepr,
|
||||
int32_t size,
|
||||
int32_t length);
|
||||
|
||||
public:
|
||||
// Properties and methods to be installed on ArrayType.prototype,
|
||||
@ -417,54 +396,25 @@ class ArrayMetaTypeDescr : public JSObject
|
||||
};
|
||||
|
||||
/*
|
||||
* Type descriptor created by `new ArrayType(typeObj)`
|
||||
*
|
||||
* These have a prototype, and hence *could* be a subclass of
|
||||
* `ComplexTypeDescr`, but it would require some reshuffling of the
|
||||
* hierarchy, and it's not worth the trouble since they will be going
|
||||
* away as part of bug 973238.
|
||||
* Type descriptor created by `new ArrayType(type, n)`
|
||||
*/
|
||||
class UnsizedArrayTypeDescr : public TypeDescr
|
||||
class ArrayTypeDescr : public ComplexTypeDescr
|
||||
{
|
||||
public:
|
||||
static const Class class_;
|
||||
static const type::Kind Kind = type::UnsizedArray;
|
||||
static const type::Kind Kind = type::Array;
|
||||
|
||||
// This is the sized method on unsized array type objects. It
|
||||
// produces a sized variant.
|
||||
static bool dimension(JSContext *cx, unsigned int argc, jsval *vp);
|
||||
|
||||
SizedTypeDescr &elementType() const {
|
||||
return getReservedSlot(JS_DESCR_SLOT_ARRAY_ELEM_TYPE).toObject().as<SizedTypeDescr>();
|
||||
TypeDescr &elementType() const {
|
||||
return getReservedSlot(JS_DESCR_SLOT_ARRAY_ELEM_TYPE).toObject().as<TypeDescr>();
|
||||
}
|
||||
|
||||
SizedTypeDescr &maybeForwardedElementType() const {
|
||||
JSObject *elemType =
|
||||
MaybeForwarded(&getReservedSlot(JS_DESCR_SLOT_ARRAY_ELEM_TYPE).toObject());
|
||||
return elemType->as<SizedTypeDescr>();
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Type descriptor created by `unsizedArrayTypeObj.dimension()`
|
||||
*/
|
||||
class SizedArrayTypeDescr : public ComplexTypeDescr
|
||||
{
|
||||
public:
|
||||
static const Class class_;
|
||||
static const type::Kind Kind = type::SizedArray;
|
||||
|
||||
SizedTypeDescr &elementType() const {
|
||||
return getReservedSlot(JS_DESCR_SLOT_ARRAY_ELEM_TYPE).toObject().as<SizedTypeDescr>();
|
||||
}
|
||||
|
||||
SizedTypeDescr &maybeForwardedElementType() const {
|
||||
TypeDescr &maybeForwardedElementType() const {
|
||||
JSObject *elemType = &getReservedSlot(JS_DESCR_SLOT_ARRAY_ELEM_TYPE).toObject();
|
||||
return MaybeForwarded(elemType)->as<SizedTypeDescr>();
|
||||
return MaybeForwarded(elemType)->as<TypeDescr>();
|
||||
}
|
||||
|
||||
int32_t length() const {
|
||||
return getReservedSlot(JS_DESCR_SLOT_SIZED_ARRAY_LENGTH).toInt32();
|
||||
return getReservedSlot(JS_DESCR_SLOT_ARRAY_LENGTH).toInt32();
|
||||
}
|
||||
};
|
||||
|
||||
@ -512,8 +462,8 @@ class StructTypeDescr : public ComplexTypeDescr
|
||||
JSAtom &fieldName(size_t index) const;
|
||||
|
||||
// Return the type descr of the field at index `index`.
|
||||
SizedTypeDescr &fieldDescr(size_t index) const;
|
||||
SizedTypeDescr &maybeForwardedFieldDescr(size_t index) const;
|
||||
TypeDescr &fieldDescr(size_t index) const;
|
||||
TypeDescr &maybeForwardedFieldDescr(size_t index) const;
|
||||
|
||||
// Return the offset of the field at index `index`.
|
||||
size_t fieldOffset(size_t index) const;
|
||||
@ -553,14 +503,12 @@ class TypedObject : public JSObject
|
||||
private:
|
||||
static const bool IsTypedObjectClass = true;
|
||||
|
||||
template<class T>
|
||||
static bool obj_getArrayElement(JSContext *cx,
|
||||
Handle<TypedObject*> typedObj,
|
||||
Handle<TypeDescr*> typeDescr,
|
||||
uint32_t index,
|
||||
MutableHandleValue vp);
|
||||
|
||||
template<class T>
|
||||
static bool obj_setArrayElement(JSContext *cx,
|
||||
Handle<TypedObject*> typedObj,
|
||||
Handle<TypeDescr*> typeDescr,
|
||||
@ -600,9 +548,6 @@ class TypedObject : public JSObject
|
||||
static bool obj_getElement(JSContext *cx, HandleObject obj, HandleObject receiver,
|
||||
uint32_t index, MutableHandleValue vp);
|
||||
|
||||
static bool obj_getUnsizedArrayElement(JSContext *cx, HandleObject obj, HandleObject receiver,
|
||||
uint32_t index, MutableHandleValue vp);
|
||||
|
||||
static bool obj_setGeneric(JSContext *cx, HandleObject obj, HandleId id,
|
||||
MutableHandleValue vp, bool strict);
|
||||
static bool obj_setProperty(JSContext *cx, HandleObject obj, HandlePropertyName name,
|
||||
@ -645,20 +590,7 @@ class TypedObject : public JSObject
|
||||
bool maybeForwardedIsAttached() const;
|
||||
|
||||
int32_t size() const {
|
||||
switch (typeDescr().kind()) {
|
||||
case type::Scalar:
|
||||
case type::Simd:
|
||||
case type::Reference:
|
||||
case type::Struct:
|
||||
case type::SizedArray:
|
||||
return typeDescr().as<SizedTypeDescr>().size();
|
||||
|
||||
case type::UnsizedArray: {
|
||||
SizedTypeDescr &elementType = typeDescr().as<UnsizedArrayTypeDescr>().elementType();
|
||||
return elementType.size() * length();
|
||||
}
|
||||
}
|
||||
MOZ_CRASH("unhandled typerepresentation kind");
|
||||
return typeDescr().size();
|
||||
}
|
||||
|
||||
uint8_t *typedMem(size_t offset) const {
|
||||
@ -679,12 +611,9 @@ class TypedObject : public JSObject
|
||||
static TypedObject *createZeroed(JSContext *cx, HandleTypeDescr typeObj, int32_t length,
|
||||
gc::InitialHeap heap = gc::DefaultHeap);
|
||||
|
||||
// User-accessible constructor (`new TypeDescriptor(...)`) used for sized
|
||||
// types. Note that the callee here is the type descriptor.
|
||||
static bool constructSized(JSContext *cx, unsigned argc, Value *vp);
|
||||
|
||||
// As `constructSized`, but for unsized array types.
|
||||
static bool constructUnsized(JSContext *cx, unsigned argc, Value *vp);
|
||||
// User-accessible constructor (`new TypeDescriptor(...)`). Note that the
|
||||
// callee here is the type descriptor.
|
||||
static bool construct(JSContext *cx, unsigned argc, Value *vp);
|
||||
|
||||
/* Accessors for self hosted code. */
|
||||
static bool GetBuffer(JSContext *cx, unsigned argc, Value *vp);
|
||||
@ -703,30 +632,12 @@ class OutlineTypedObject : public TypedObject
|
||||
// Data pointer to some offset in the owner's contents.
|
||||
uint8_t *data_;
|
||||
|
||||
// The length for unsized array objects. For other outline objects the
|
||||
// space for this field is not allocated and cannot be accessed.
|
||||
uint32_t unsizedLength_;
|
||||
|
||||
void setOwnerAndData(JSObject *owner, uint8_t *data);
|
||||
|
||||
void setUnsizedLength(uint32_t length) {
|
||||
MOZ_ASSERT(typeDescr().is<UnsizedArrayTypeDescr>());
|
||||
unsizedLength_ = length;
|
||||
}
|
||||
|
||||
public:
|
||||
static gc::AllocKind allocKindForTypeDescriptor(TypeDescr *descr) {
|
||||
// Use a larger allocation kind for unsized arrays, to accommodate the
|
||||
// unsized length.
|
||||
if (descr->is<UnsizedArrayTypeDescr>())
|
||||
return gc::FINALIZE_OBJECT2;
|
||||
return gc::FINALIZE_OBJECT0;
|
||||
}
|
||||
|
||||
// JIT accessors.
|
||||
static size_t offsetOfData() { return offsetof(OutlineTypedObject, data_); }
|
||||
static size_t offsetOfOwner() { return offsetof(OutlineTypedObject, owner_); }
|
||||
static size_t offsetOfUnsizedLength() { return offsetof(OutlineTypedObject, unsizedLength_); }
|
||||
|
||||
JSObject &owner() const {
|
||||
MOZ_ASSERT(owner_);
|
||||
@ -741,11 +652,6 @@ class OutlineTypedObject : public TypedObject
|
||||
return data_;
|
||||
}
|
||||
|
||||
int32_t unsizedLength() const {
|
||||
MOZ_ASSERT(typeDescr().is<UnsizedArrayTypeDescr>());
|
||||
return unsizedLength_;
|
||||
}
|
||||
|
||||
void setData(uint8_t *data) {
|
||||
data_ = data;
|
||||
}
|
||||
@ -772,7 +678,7 @@ class OutlineTypedObject : public TypedObject
|
||||
// at the given offset. The typedObj will be a handle iff type is a
|
||||
// handle and a typed object otherwise.
|
||||
static OutlineTypedObject *createDerived(JSContext *cx,
|
||||
HandleSizedTypeDescr type,
|
||||
HandleTypeDescr type,
|
||||
Handle<TypedObject*> typedContents,
|
||||
int32_t offset);
|
||||
|
||||
@ -816,7 +722,7 @@ class InlineTypedObject : public TypedObject
|
||||
sizeof(NativeObject) - sizeof(TypedObject) + NativeObject::MAX_FIXED_SLOTS * sizeof(Value);
|
||||
|
||||
static gc::AllocKind allocKindForTypeDescriptor(TypeDescr *descr) {
|
||||
size_t nbytes = descr->as<SizedTypeDescr>().size();
|
||||
size_t nbytes = descr->size();
|
||||
MOZ_ASSERT(nbytes <= MaximumSize);
|
||||
|
||||
size_t dataSlots = AlignBytes(nbytes, sizeof(Value) / sizeof(Value));
|
||||
@ -932,12 +838,6 @@ extern const JSJitInfo TypeDescrIsSimpleTypeJitInfo;
|
||||
bool TypeDescrIsArrayType(ThreadSafeContext *, unsigned argc, Value *vp);
|
||||
extern const JSJitInfo TypeDescrIsArrayTypeJitInfo;
|
||||
|
||||
bool TypeDescrIsSizedArrayType(ThreadSafeContext *, unsigned argc, Value *vp);
|
||||
extern const JSJitInfo TypeDescrIsSizedArrayTypeJitInfo;
|
||||
|
||||
bool TypeDescrIsUnsizedArrayType(ThreadSafeContext *, unsigned argc, Value *vp);
|
||||
extern const JSJitInfo TypeDescrIsUnsizedArrayTypeJitInfo;
|
||||
|
||||
/*
|
||||
* Usage: TypedObjectIsAttached(obj)
|
||||
*
|
||||
@ -1101,22 +1001,15 @@ inline bool
|
||||
IsComplexTypeDescrClass(const Class* clasp)
|
||||
{
|
||||
return clasp == &StructTypeDescr::class_ ||
|
||||
clasp == &SizedArrayTypeDescr::class_ ||
|
||||
clasp == &ArrayTypeDescr::class_ ||
|
||||
clasp == &SimdTypeDescr::class_;
|
||||
}
|
||||
|
||||
inline bool
|
||||
IsSizedTypeDescrClass(const Class* clasp)
|
||||
{
|
||||
return IsSimpleTypeDescrClass(clasp) ||
|
||||
IsComplexTypeDescrClass(clasp);
|
||||
}
|
||||
|
||||
inline bool
|
||||
IsTypeDescrClass(const Class* clasp)
|
||||
{
|
||||
return IsSizedTypeDescrClass(clasp) ||
|
||||
clasp == &UnsizedArrayTypeDescr::class_;
|
||||
return IsSimpleTypeDescrClass(clasp) ||
|
||||
IsComplexTypeDescrClass(clasp);
|
||||
}
|
||||
|
||||
inline bool
|
||||
@ -1161,13 +1054,6 @@ JSObject::is<js::SimpleTypeDescr>() const
|
||||
return IsSimpleTypeDescrClass(getClass());
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool
|
||||
JSObject::is<js::SizedTypeDescr>() const
|
||||
{
|
||||
return IsSizedTypeDescrClass(getClass());
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool
|
||||
JSObject::is<js::ComplexTypeDescr>() const
|
||||
|
@ -19,8 +19,8 @@
|
||||
UnsafeGetReservedSlot(obj, JS_DESCR_SLOT_TYPE)
|
||||
#define DESCR_ARRAY_ELEMENT_TYPE(obj) \
|
||||
UnsafeGetReservedSlot(obj, JS_DESCR_SLOT_ARRAY_ELEM_TYPE)
|
||||
#define DESCR_SIZED_ARRAY_LENGTH(obj) \
|
||||
TO_INT32(UnsafeGetReservedSlot(obj, JS_DESCR_SLOT_SIZED_ARRAY_LENGTH))
|
||||
#define DESCR_ARRAY_LENGTH(obj) \
|
||||
TO_INT32(UnsafeGetReservedSlot(obj, JS_DESCR_SLOT_ARRAY_LENGTH))
|
||||
#define DESCR_STRUCT_FIELD_NAMES(obj) \
|
||||
UnsafeGetReservedSlot(obj, JS_DESCR_SLOT_STRUCT_FIELD_NAMES)
|
||||
#define DESCR_STRUCT_FIELD_TYPES(obj) \
|
||||
@ -70,12 +70,9 @@ function TypedObjectGet(descr, typedObj, offset) {
|
||||
case JS_TYPEREPR_SIMD_KIND:
|
||||
return TypedObjectGetSimd(descr, typedObj, offset);
|
||||
|
||||
case JS_TYPEREPR_SIZED_ARRAY_KIND:
|
||||
case JS_TYPEREPR_ARRAY_KIND:
|
||||
case JS_TYPEREPR_STRUCT_KIND:
|
||||
return TypedObjectGetDerived(descr, typedObj, offset);
|
||||
|
||||
case JS_TYPEREPR_UNSIZED_ARRAY_KIND:
|
||||
assert(false, "Unhandled repr kind: " + DESCR_KIND(descr));
|
||||
}
|
||||
|
||||
assert(false, "Unhandled kind: " + DESCR_KIND(descr));
|
||||
@ -201,14 +198,8 @@ function TypedObjectSet(descr, typedObj, offset, fromValue) {
|
||||
TypedObjectSetSimd(descr, typedObj, offset, fromValue);
|
||||
return;
|
||||
|
||||
case JS_TYPEREPR_SIZED_ARRAY_KIND:
|
||||
var length = DESCR_SIZED_ARRAY_LENGTH(descr);
|
||||
if (TypedObjectSetArray(descr, length, typedObj, offset, fromValue))
|
||||
return;
|
||||
break;
|
||||
|
||||
case JS_TYPEREPR_UNSIZED_ARRAY_KIND:
|
||||
var length = typedObj.length;
|
||||
case JS_TYPEREPR_ARRAY_KIND:
|
||||
var length = DESCR_ARRAY_LENGTH(descr);
|
||||
if (TypedObjectSetArray(descr, length, typedObj, offset, fromValue))
|
||||
return;
|
||||
break;
|
||||
@ -427,22 +418,13 @@ function TypedArrayRedimension(newArrayType) {
|
||||
// Peel away the outermost array layers from the type of `this` to find
|
||||
// the core element type. In the process, count the number of elements.
|
||||
var oldArrayType = TypedObjectTypeDescr(this);
|
||||
var oldArrayReprKind = DESCR_KIND(oldArrayType);
|
||||
var oldElementType = oldArrayType;
|
||||
var oldElementCount = 1;
|
||||
switch (oldArrayReprKind) {
|
||||
case JS_TYPEREPR_UNSIZED_ARRAY_KIND:
|
||||
oldElementCount *= this.length;
|
||||
oldElementType = oldElementType.elementType;
|
||||
break;
|
||||
|
||||
case JS_TYPEREPR_SIZED_ARRAY_KIND:
|
||||
break;
|
||||
|
||||
default:
|
||||
if (DESCR_KIND(oldArrayType) != JS_TYPEREPR_ARRAY_KIND)
|
||||
ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS);
|
||||
}
|
||||
while (DESCR_KIND(oldElementType) === JS_TYPEREPR_SIZED_ARRAY_KIND) {
|
||||
|
||||
while (DESCR_KIND(oldElementType) === JS_TYPEREPR_ARRAY_KIND) {
|
||||
oldElementCount *= oldElementType.length;
|
||||
oldElementType = oldElementType.elementType;
|
||||
}
|
||||
@ -451,7 +433,7 @@ function TypedArrayRedimension(newArrayType) {
|
||||
// process, count the number of elements.
|
||||
var newElementType = newArrayType;
|
||||
var newElementCount = 1;
|
||||
while (DESCR_KIND(newElementType) == JS_TYPEREPR_SIZED_ARRAY_KIND) {
|
||||
while (DESCR_KIND(newElementType) == JS_TYPEREPR_ARRAY_KIND) {
|
||||
newElementCount *= newElementType.length;
|
||||
newElementType = newElementType.elementType;
|
||||
}
|
||||
@ -536,11 +518,11 @@ function ArrayShorthand(...dims) {
|
||||
var T = GetTypedObjectModule();
|
||||
|
||||
if (dims.length == 0)
|
||||
return new T.ArrayType(this);
|
||||
ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS);
|
||||
|
||||
var accum = this;
|
||||
for (var i = dims.length - 1; i >= 0; i--)
|
||||
accum = new T.ArrayType(accum).dimension(dims[i]);
|
||||
accum = new T.ArrayType(accum, dims[i]);
|
||||
return accum;
|
||||
}
|
||||
|
||||
@ -560,11 +542,7 @@ function StorageOfTypedObject(obj) {
|
||||
ThrowError(JSMSG_TYPEDOBJECT_HANDLE_UNATTACHED);
|
||||
|
||||
var descr = TypedObjectTypeDescr(obj);
|
||||
var byteLength;
|
||||
if (DESCR_KIND(descr) == JS_TYPEREPR_UNSIZED_ARRAY_KIND)
|
||||
byteLength = DESCR_SIZE(descr.elementType) * obj.length;
|
||||
else
|
||||
byteLength = DESCR_SIZE(descr);
|
||||
var byteLength = DESCR_SIZE(descr);
|
||||
|
||||
return { buffer: TypedObjectBuffer(obj),
|
||||
byteLength: byteLength,
|
||||
@ -605,14 +583,13 @@ function TypeOfTypedObject(obj) {
|
||||
|
||||
// Warning: user exposed!
|
||||
function TypedObjectArrayTypeBuild(a,b,c) {
|
||||
// Arguments (this sized) : [depth], func
|
||||
// Arguments (this unsized) : length, [depth], func
|
||||
// Arguments : [depth], func
|
||||
|
||||
if (!IsObject(this) || !ObjectIsTypeDescr(this))
|
||||
ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS);
|
||||
var kind = DESCR_KIND(this);
|
||||
switch (kind) {
|
||||
case JS_TYPEREPR_SIZED_ARRAY_KIND:
|
||||
case JS_TYPEREPR_ARRAY_KIND:
|
||||
if (typeof a === "function") // XXX here and elsewhere: these type dispatches are fragile at best.
|
||||
return BuildTypedSeqImpl(this, this.length, 1, a);
|
||||
else if (typeof a === "number" && typeof b === "function")
|
||||
@ -621,16 +598,6 @@ function TypedObjectArrayTypeBuild(a,b,c) {
|
||||
ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS);
|
||||
else
|
||||
ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS);
|
||||
case JS_TYPEREPR_UNSIZED_ARRAY_KIND:
|
||||
var len = a;
|
||||
if (typeof b === "function")
|
||||
return BuildTypedSeqImpl(this, len, 1, b);
|
||||
else if (typeof b === "number" && typeof c === "function")
|
||||
return BuildTypedSeqImpl(this, len, b, c);
|
||||
else if (typeof b === "number")
|
||||
ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS);
|
||||
else
|
||||
ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS);
|
||||
default:
|
||||
ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS);
|
||||
}
|
||||
@ -731,7 +698,7 @@ function TypedArrayScatter(a, b, c, d) {
|
||||
if (!TypeDescrIsArrayType(thisType))
|
||||
ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS);
|
||||
|
||||
if (!IsObject(a) || !ObjectIsTypeDescr(a) || !TypeDescrIsSizedArrayType(a))
|
||||
if (!IsObject(a) || !ObjectIsTypeDescr(a) || !TypeDescrIsArrayType(a))
|
||||
ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS);
|
||||
|
||||
if (d !== undefined && typeof d !== "function")
|
||||
@ -828,7 +795,7 @@ function BuildTypedSeqImpl(arrayType, len, depth, func) {
|
||||
ComputeIterationSpace(arrayType, depth, len);
|
||||
|
||||
// Create a zeroed instance with no data
|
||||
var result = arrayType.variable ? new arrayType(len) : new arrayType();
|
||||
var result = new arrayType();
|
||||
|
||||
var indices = NewDenseArray(depth);
|
||||
for (var i = 0; i < depth; i++) {
|
||||
@ -921,11 +888,11 @@ function MapUntypedSeqImpl(inArray, outputType, maybeFunc) {
|
||||
// Skip check for compatible iteration spaces; any normal JS array
|
||||
// is trivially compatible with any iteration space of depth 1.
|
||||
|
||||
var outLength = outputType.variable ? inArray.length : outputType.length;
|
||||
var outLength = outputType.length;
|
||||
var outGrainType = outputType.elementType;
|
||||
|
||||
// Create a zeroed instance with no data
|
||||
var result = outputType.variable ? new outputType(inArray.length) : new outputType();
|
||||
var result = new outputType();
|
||||
|
||||
var outUnitSize = DESCR_SIZE(outGrainType);
|
||||
var outGrainTypeIsComplex = !TypeDescrIsSimpleType(outGrainType);
|
||||
@ -975,14 +942,14 @@ function MapTypedSeqImpl(inArray, depth, outputType, func) {
|
||||
if (!IsObject(inGrainType) || !ObjectIsTypeDescr(inGrainType))
|
||||
ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS);
|
||||
var [iterationSpace, outGrainType, totalLength] =
|
||||
ComputeIterationSpace(outputType, depth, outputType.variable ? inArray.length : outputType.length);
|
||||
ComputeIterationSpace(outputType, depth, outputType.length);
|
||||
for (var i = 0; i < depth; i++)
|
||||
if (inIterationSpace[i] !== iterationSpace[i])
|
||||
// TypeError("Incompatible iteration space in input and output type");
|
||||
ThrowError(JSMSG_TYPEDOBJECT_ARRAYTYPE_BAD_ARGS);
|
||||
|
||||
// Create a zeroed instance with no data
|
||||
var result = outputType.variable ? new outputType(inArray.length) : new outputType();
|
||||
var result = new outputType();
|
||||
|
||||
var inGrainTypeIsComplex = !TypeDescrIsSimpleType(inGrainType);
|
||||
var outGrainTypeIsComplex = !TypeDescrIsSimpleType(outGrainType);
|
||||
@ -1083,7 +1050,7 @@ function MapTypedParImpl(inArray, depth, outputType, func) {
|
||||
depth <= 0 ||
|
||||
TO_INT32(depth) !== depth ||
|
||||
!TypeDescrIsArrayType(inArrayType) ||
|
||||
!TypeDescrIsUnsizedArrayType(outputType))
|
||||
!TypeDescrIsArrayType(outputType))
|
||||
{
|
||||
// defer error cases to seq implementation:
|
||||
return MapTypedSeqImpl(inArray, depth, outputType, func);
|
||||
@ -1161,7 +1128,7 @@ function MapTypedParImplDepth1(inArray, inArrayType, outArrayType, func) {
|
||||
const length = inArray.length;
|
||||
const mode = undefined;
|
||||
|
||||
const outArray = new outArrayType(length);
|
||||
const outArray = new outArrayType();
|
||||
if (length === 0)
|
||||
return outArray;
|
||||
|
||||
@ -1307,7 +1274,7 @@ function ReduceTypedSeqImpl(array, outputType, func, initial) {
|
||||
function ScatterTypedSeqImpl(array, outputType, indices, defaultValue, conflictFunc) {
|
||||
assert(IsObject(array) && ObjectIsTypedObject(array), "Scatter called on non-object or untyped input array.");
|
||||
assert(IsObject(outputType) && ObjectIsTypeDescr(outputType), "Scatter called on non-type-object outputType");
|
||||
assert(TypeDescrIsSizedArrayType(outputType), "Scatter called on non-sized array type");
|
||||
assert(TypeDescrIsArrayType(outputType), "Scatter called on non-array type");
|
||||
assert(conflictFunc === undefined || typeof conflictFunc === "function", "Scatter called with invalid conflictFunc");
|
||||
|
||||
var result = new outputType();
|
||||
@ -1356,8 +1323,10 @@ function FilterTypedSeqImpl(array, func) {
|
||||
inOffset += size;
|
||||
}
|
||||
|
||||
var resultType = (arrayType.variable ? arrayType : arrayType.unsized);
|
||||
var result = new resultType(count);
|
||||
var T = GetTypedObjectModule();
|
||||
|
||||
var resultType = new T.ArrayType(elementType, count);
|
||||
var result = new resultType();
|
||||
for (var i = 0, j = 0; i < array.length; i++) {
|
||||
if (GET_BIT(flags, i))
|
||||
result[j++] = array[i];
|
||||
|
@ -27,7 +27,7 @@
|
||||
#define JS_DESCR_SLOT_KIND 0 // Atomized string representation
|
||||
#define JS_DESCR_SLOT_STRING_REPR 1 // Atomized string representation
|
||||
#define JS_DESCR_SLOT_ALIGNMENT 2 // Alignment in bytes
|
||||
#define JS_DESCR_SLOT_SIZE 3 // Size in bytes, if sized, else 0
|
||||
#define JS_DESCR_SLOT_SIZE 3 // Size in bytes, else 0
|
||||
#define JS_DESCR_SLOT_OPAQUE 4 // Atomized string representation
|
||||
#define JS_DESCR_SLOT_TYPROTO 5 // Prototype for instances, if any
|
||||
|
||||
@ -37,8 +37,8 @@
|
||||
// Slots on all array descriptors
|
||||
#define JS_DESCR_SLOT_ARRAY_ELEM_TYPE 6
|
||||
|
||||
// Slots on sized array descriptors
|
||||
#define JS_DESCR_SLOT_SIZED_ARRAY_LENGTH 7
|
||||
// Slots on array descriptors
|
||||
#define JS_DESCR_SLOT_ARRAY_LENGTH 7
|
||||
|
||||
// Slots on struct type objects
|
||||
#define JS_DESCR_SLOT_STRUCT_FIELD_NAMES 6
|
||||
@ -51,12 +51,10 @@
|
||||
// These constants are for use exclusively in JS code. In C++ code,
|
||||
// prefer TypeRepresentation::Scalar etc, which allows you to
|
||||
// write a switch which will receive a warning if you omit a case.
|
||||
#define JS_TYPEREPR_UNSIZED_ARRAY_KIND 0
|
||||
#define JS_TYPEREPR_MAX_UNSIZED_KIND 0 // Unsized kinds go above here
|
||||
#define JS_TYPEREPR_SCALAR_KIND 1
|
||||
#define JS_TYPEREPR_REFERENCE_KIND 2
|
||||
#define JS_TYPEREPR_STRUCT_KIND 3
|
||||
#define JS_TYPEREPR_SIZED_ARRAY_KIND 4
|
||||
#define JS_TYPEREPR_ARRAY_KIND 4
|
||||
#define JS_TYPEREPR_SIMD_KIND 5
|
||||
|
||||
// These constants are for use exclusively in JS code. In C++ code,
|
||||
|
@ -275,8 +275,7 @@ frontend::CompileScript(ExclusiveContext *cx, LifoAlloc *alloc, HandleObject sco
|
||||
Directives directives(options.strictOption);
|
||||
GlobalSharedContext globalsc(cx, scopeChain, directives, options.extraWarningsOption);
|
||||
|
||||
bool savedCallerFun = options.compileAndGo &&
|
||||
evalCaller && evalCaller->functionOrCallerFunction();
|
||||
bool savedCallerFun = evalCaller && evalCaller->functionOrCallerFunction();
|
||||
Rooted<JSScript*> script(cx, JSScript::Create(cx, NullPtr(), savedCallerFun,
|
||||
options, staticLevel, sourceObject, 0,
|
||||
srcBuf.length()));
|
||||
@ -312,7 +311,7 @@ frontend::CompileScript(ExclusiveContext *cx, LifoAlloc *alloc, HandleObject sco
|
||||
if (evalCaller && evalCaller->strict())
|
||||
globalsc.strict = true;
|
||||
|
||||
if (options.compileAndGo && evalCaller && evalCaller->functionOrCallerFunction()) {
|
||||
if (savedCallerFun) {
|
||||
/*
|
||||
* An eval script in a caller frame needs to have its enclosing
|
||||
* function captured in case it refers to an upvar, and someone
|
||||
|
@ -404,11 +404,9 @@ GetObjectAllocKindForCopy(const Nursery &nursery, JSObject *obj)
|
||||
return InlineTypedObject::allocKindForTypeDescriptor(descr);
|
||||
}
|
||||
|
||||
// Outline typed objects have special requirements for their allocation kind.
|
||||
if (obj->is<OutlineTypedObject>()) {
|
||||
TypeDescr *descr = &obj->as<OutlineTypedObject>().typeDescr();
|
||||
return OutlineTypedObject::allocKindForTypeDescriptor(descr);
|
||||
}
|
||||
// Outline typed objects use the minimum allocation kind.
|
||||
if (obj->is<OutlineTypedObject>())
|
||||
return FINALIZE_OBJECT0;
|
||||
|
||||
// The only non-native objects in existence are proxies and typed objects.
|
||||
MOZ_ASSERT(obj->isNative());
|
||||
|
@ -1,10 +1,9 @@
|
||||
// Fuzz bug 981650: Test creating an unsized array type based on an instance of
|
||||
// Fuzz bug 981650: Test creating an array type based on an instance of
|
||||
// that same type.
|
||||
|
||||
if (typeof TypedObject === "undefined")
|
||||
quit();
|
||||
|
||||
var T = TypedObject;
|
||||
var AT = new T.ArrayType(T.int32);
|
||||
var v = new AT(10);
|
||||
new AT(v);
|
||||
var v = new T.ArrayType(T.int32, 10);
|
||||
new v(v);
|
||||
|
@ -9,14 +9,14 @@ load(libdir + "asserts.js")
|
||||
var {StructType, uint32, Object, Any, storage, objectType} = TypedObject;
|
||||
|
||||
function main(variant) { // once a C programmer, always a C programmer.
|
||||
var Uints = uint32.array();
|
||||
var Uints = uint32.array(0);
|
||||
var Unit = new StructType({}); // Empty struct type
|
||||
var buffer = new ArrayBuffer(0); // Empty buffer
|
||||
var p = new Unit(buffer); // OK
|
||||
neuter(buffer, variant);
|
||||
assertThrowsInstanceOf(() => new Unit(buffer), TypeError,
|
||||
"Able to instantiate atop neutered buffer");
|
||||
assertThrowsInstanceOf(() => new Uints(buffer, 0), TypeError,
|
||||
assertThrowsInstanceOf(() => new Uints(buffer), TypeError,
|
||||
"Able to instantiate atop neutered buffer");
|
||||
}
|
||||
|
||||
|
@ -13,11 +13,11 @@ if (!this.hasOwnProperty("TypedObject"))
|
||||
var N = 100;
|
||||
var T = TypedObject;
|
||||
var Point = new T.StructType({x: T.uint32, y: T.uint32, z: T.uint32});
|
||||
var PointArray = Point.array();
|
||||
var PointArray = Point.array(N);
|
||||
function foo(arr) {
|
||||
var sum = 0;
|
||||
for (var i = 0; i < N; i++) {
|
||||
sum += arr[i].x + arr[i].y + arr[i].z;
|
||||
}
|
||||
}
|
||||
foo(new PointArray(N));
|
||||
foo(new PointArray());
|
||||
|
@ -8,11 +8,11 @@ if (!this.hasOwnProperty("TypedObject"))
|
||||
|
||||
// bug 953111
|
||||
|
||||
var A = TypedObject.uint8.array();
|
||||
var a = new A(0);
|
||||
var A = TypedObject.uint8.array(0);
|
||||
var a = new A();
|
||||
a.forEach(function(val, i) {});
|
||||
|
||||
// bug 951356 (dup, but a dup that is more likely to crash)
|
||||
|
||||
var AA = TypedObject.uint8.array(2147483647).array();
|
||||
var aa = new AA(0);
|
||||
var AA = TypedObject.uint8.array(2147483647).array(0);
|
||||
var aa = new AA();
|
||||
|
@ -11,7 +11,7 @@ setJitCompilerOption("ion.warmup.trigger", 30);
|
||||
var N = 100;
|
||||
var T = TypedObject;
|
||||
var Point = new T.StructType({x: T.uint32, y: T.uint32, z: T.uint32});
|
||||
var PointArray = Point.array();
|
||||
var PointArray = Point.array(N);
|
||||
|
||||
function bar(array, i, x, y, z) {
|
||||
assertEq(array[i].x, x);
|
||||
@ -20,7 +20,7 @@ function bar(array, i, x, y, z) {
|
||||
}
|
||||
|
||||
function foo() {
|
||||
var array = new PointArray(N);
|
||||
var array = new PointArray();
|
||||
for (var i = 0; i < N; i++) {
|
||||
array[i].x = i + 0;
|
||||
array[i].y = i + 1;
|
||||
|
@ -6,14 +6,14 @@ if (!this.hasOwnProperty("TypedObject"))
|
||||
|
||||
var {StructType, uint32, storage} = TypedObject;
|
||||
var S = new StructType({f: uint32, g: uint32});
|
||||
var A = S.array();
|
||||
var A = S.array(10);
|
||||
|
||||
function readFrom(a) {
|
||||
return a[2].f + a[2].g;
|
||||
}
|
||||
|
||||
function main(variant) {
|
||||
var a = new A(10);
|
||||
var a = new A();
|
||||
a[2].f = 22;
|
||||
a[2].g = 44;
|
||||
|
||||
|
@ -14,11 +14,6 @@ var Unit = new StructType(({ f : Object, } ));
|
||||
assertThrowsInstanceOf(() => new Unit(buffer), TypeError,
|
||||
"Able to instantiate opaque type atop buffer");
|
||||
|
||||
var Units = new ArrayType(Unit);
|
||||
var Units = new ArrayType(Unit, 2);
|
||||
assertThrowsInstanceOf(() => new Units(buffer), TypeError,
|
||||
"Able to instantiate opaque type atop buffer");
|
||||
|
||||
var Units2 = Units.dimension(2);
|
||||
assertThrowsInstanceOf(() => new Units2(buffer), TypeError,
|
||||
"Able to instantiate opaque type atop buffer");
|
||||
|
||||
|
@ -0,0 +1,28 @@
|
||||
// Debugger should be notified of scripts created with cloneAndExecuteScript.
|
||||
|
||||
var g = newGlobal();
|
||||
var g2 = newGlobal();
|
||||
var dbg = new Debugger(g, g2);
|
||||
var log = '';
|
||||
|
||||
dbg.onNewScript = function (evalScript) {
|
||||
log += 'e';
|
||||
|
||||
dbg.onNewScript = function (clonedScript) {
|
||||
log += 'c';
|
||||
clonedScript.setBreakpoint(0, {
|
||||
hit(frame) {
|
||||
log += 'b';
|
||||
assertEq(frame.script, clonedScript);
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
dbg.onDebuggerStatement = function (frame) {
|
||||
log += 'd';
|
||||
};
|
||||
|
||||
assertEq(log, '');
|
||||
g.cloneAndExecuteScript("debugger; // nee", g2);
|
||||
assertEq(log, 'ecbd');
|
@ -0,0 +1,28 @@
|
||||
// Debugger should be notified of scripts created with ExecuteInGlobalAndReturnScope.
|
||||
|
||||
var g = newGlobal();
|
||||
var g2 = newGlobal();
|
||||
var dbg = new Debugger(g, g2);
|
||||
var log = '';
|
||||
|
||||
dbg.onNewScript = function (evalScript) {
|
||||
log += 'e';
|
||||
|
||||
dbg.onNewScript = function (clonedScript) {
|
||||
log += 'c';
|
||||
clonedScript.setBreakpoint(0, {
|
||||
hit(frame) {
|
||||
log += 'b';
|
||||
assertEq(frame.script, clonedScript);
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
dbg.onDebuggerStatement = function (frame) {
|
||||
log += 'd';
|
||||
};
|
||||
|
||||
assertEq(log, '');
|
||||
var evalScope = g.evalReturningScope("debugger; // nee", g2);
|
||||
assertEq(log, 'ecbd');
|
@ -8,8 +8,7 @@ var uint32 = TypedObject.uint32;
|
||||
var ObjectType = TypedObject.Object;
|
||||
function runTests() {
|
||||
(function DimensionLinkedToUndimension() {
|
||||
var UintsA = uint32.array();
|
||||
var FiveUintsA = UintsA.dimension(5);
|
||||
var FiveUintsA = uint32.array(5);
|
||||
var FiveUintsB = uint32.array(5);
|
||||
assertEq(true,
|
||||
FiveUintsA.equivalent(FiveUintsB)
|
||||
@ -17,7 +16,7 @@ function runTests() {
|
||||
})();
|
||||
(function PrototypeHierarchy() {
|
||||
schedulegc(3);
|
||||
var Uint8s = uint8.array();
|
||||
var Uint8s = uint8.array(5);
|
||||
})();
|
||||
}
|
||||
|
||||
|
@ -29,14 +29,14 @@ if (!this.TypedObject) {
|
||||
}
|
||||
|
||||
var T = TypedObject;
|
||||
var AT = new T.ArrayType(T.int32);
|
||||
var AT = new T.ArrayType(T.int32, 100);
|
||||
|
||||
function check(v) {
|
||||
return v.map(x => x+1);
|
||||
}
|
||||
|
||||
function test() {
|
||||
var w1 = AT.build(100, x => x+1);
|
||||
var w1 = AT.build(x => x+1);
|
||||
var w2 = Array.build(100, x => x+1);
|
||||
w2.map = w1.map;
|
||||
var a = [ w1, w2 ];
|
||||
|
@ -25,14 +25,14 @@ if (!this.TypedObject) {
|
||||
}
|
||||
|
||||
var T = TypedObject;
|
||||
var AT = new T.ArrayType(T.int32);
|
||||
var AT = new T.ArrayType(T.int32, 100);
|
||||
|
||||
function check(v) {
|
||||
return v.map(x => x+1);
|
||||
}
|
||||
|
||||
function test() {
|
||||
var w = new AT(100);
|
||||
var w = new AT();
|
||||
for ( var i=0 ; i < 1000 ; i++ )
|
||||
w = check(w);
|
||||
return w;
|
||||
|
@ -23,10 +23,10 @@ if (!this.TypedObject) {
|
||||
}
|
||||
|
||||
var T = TypedObject;
|
||||
var AT = new T.ArrayType(T.uint32);
|
||||
var AT = new T.ArrayType(T.uint32, 100);
|
||||
|
||||
function check() {
|
||||
return AT.build(100, x => x+1);
|
||||
return AT.build(x => x+1);
|
||||
}
|
||||
|
||||
function test() {
|
||||
|
@ -21,9 +21,8 @@ if (!this.TypedObject) {
|
||||
}
|
||||
|
||||
var T = TypedObject;
|
||||
var AT = new T.ArrayType(T.int32);
|
||||
var IT = AT.dimension(100);
|
||||
var ix = AT.build(100, x => x == 0 ? 99 : x-1); // [99, 0, 1, ..., 98]
|
||||
var IT = new T.ArrayType(T.int32, 100);
|
||||
var ix = IT.build(x => x == 0 ? 99 : x-1); // [99, 0, 1, ..., 98]
|
||||
|
||||
// This is a left-rotate by one place
|
||||
function check(v) {
|
||||
@ -31,7 +30,7 @@ function check(v) {
|
||||
}
|
||||
|
||||
function test() {
|
||||
var w = AT.build(100, x => x);
|
||||
var w = IT.build(x => x);
|
||||
for ( var i=0 ; i < 77 ; i++ )
|
||||
w = check(w);
|
||||
return w;
|
||||
|
@ -27,7 +27,7 @@ function check(v) {
|
||||
|
||||
function test() {
|
||||
var AT = new T.ArrayType(T.Any,10);
|
||||
var v = new AT(10);
|
||||
var v = new AT();
|
||||
for ( var i=0 ; i < 1000 ; i++ )
|
||||
check(v);
|
||||
return check(v);
|
||||
|
@ -26,8 +26,8 @@ function check(v) {
|
||||
}
|
||||
|
||||
function test() {
|
||||
var AT = new T.ArrayType(T.int32,10);
|
||||
var v = new AT(10);
|
||||
var AT = new T.ArrayType(T.int32, 10);
|
||||
var v = new AT();
|
||||
for ( var i=0 ; i < 1000 ; i++ )
|
||||
check(v);
|
||||
return check(v);
|
||||
|
@ -29,7 +29,7 @@ function check(v) {
|
||||
function test() {
|
||||
var AT = new T.ArrayType(T.int32,10);
|
||||
var v = new Object; // Not actually a typed object
|
||||
var w = new AT(10); // Actually a typed object
|
||||
var w = new AT(); // Actually a typed object
|
||||
var a = [v,w];
|
||||
for ( var i=0 ; i < 1000 ; i++ )
|
||||
try { check(a[i%2]); } catch (e) {}
|
||||
|
@ -17,7 +17,7 @@ function test() {
|
||||
matrix[i][0] = i;
|
||||
|
||||
var Point = new StructType({x: uint32, y: uint32});
|
||||
var Points = Point.array();
|
||||
var Points = Point.array(L);
|
||||
|
||||
assertParallelExecSucceeds(
|
||||
// FIXME Bug 983692 -- no where to pass `m` to
|
||||
|
@ -10,7 +10,7 @@ var { uint8, uint32 } = TypedObject;
|
||||
function test() {
|
||||
var L = minItemsTestingThreshold;
|
||||
var Uints = uint32.array(L);
|
||||
var Uint8s = uint8.array();
|
||||
var Uint8s = uint8.array(L);
|
||||
|
||||
var uint32s = new Uints();
|
||||
|
||||
|
@ -11,8 +11,8 @@ var { ArrayType, StructType, uint32 } = TypedObject;
|
||||
function test() {
|
||||
var L = minItemsTestingThreshold;
|
||||
var Point = new StructType({x: uint32, y: uint32});
|
||||
var Points = Point.array();
|
||||
var points = new Points(L);
|
||||
var Points = Point.array(L);
|
||||
var points = new Points();
|
||||
for (var i = 0; i < L; i++)
|
||||
points[i].x = i;
|
||||
|
||||
|
@ -6,7 +6,7 @@ if (!this.hasOwnProperty("TypedObject"))
|
||||
|
||||
var { ArrayType, StructType, uint32 } = TypedObject;
|
||||
var Point = new StructType({x: uint32, y: uint32});
|
||||
var Points = Point.array();
|
||||
var Points = Point.array(0);
|
||||
var points = new Points();
|
||||
points.mapPar(function() {});
|
||||
|
||||
|
@ -8607,7 +8607,7 @@ static bool
|
||||
GetTemplateObjectForClassHook(JSContext *cx, JSNative hook, CallArgs &args,
|
||||
MutableHandleObject templateObject)
|
||||
{
|
||||
if (hook == TypedObject::constructSized) {
|
||||
if (hook == TypedObject::construct) {
|
||||
Rooted<TypeDescr *> descr(cx, &args.callee().as<TypeDescr>());
|
||||
JSObject *obj = TypedObject::createZeroed(cx, descr, 1, gc::TenuredHeap);
|
||||
if (!obj)
|
||||
|
@ -5097,16 +5097,6 @@ CodeGenerator::visitTypedObjectProto(LTypedObjectProto *lir)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CodeGenerator::visitTypedObjectUnsizedLength(LTypedObjectUnsizedLength *lir)
|
||||
{
|
||||
Register obj = ToRegister(lir->object());
|
||||
Register out = ToRegister(lir->output());
|
||||
|
||||
masm.load32(Address(obj, OutlineTypedObject::offsetOfUnsizedLength()), out);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CodeGenerator::visitTypedObjectElements(LTypedObjectElements *lir)
|
||||
{
|
||||
|
@ -186,7 +186,6 @@ class CodeGenerator : public CodeGeneratorSpecific
|
||||
bool visitTypedObjectElements(LTypedObjectElements *lir);
|
||||
bool visitSetTypedObjectOffset(LSetTypedObjectOffset *lir);
|
||||
bool visitTypedObjectProto(LTypedObjectProto *ins);
|
||||
bool visitTypedObjectUnsizedLength(LTypedObjectUnsizedLength *ins);
|
||||
bool visitStringLength(LStringLength *lir);
|
||||
bool visitInitializedLength(LInitializedLength *lir);
|
||||
bool visitSetInitializedLength(LSetInitializedLength *lir);
|
||||
|
@ -7235,8 +7235,6 @@ IonBuilder::getElemTryTypedObject(bool *emitted, MDefinition *obj, MDefinition *
|
||||
if (elemPrediction.isUseless())
|
||||
return true;
|
||||
|
||||
MOZ_ASSERT(TypeDescr::isSized(elemPrediction.kind()));
|
||||
|
||||
int32_t elemSize;
|
||||
if (!elemPrediction.hasKnownSize(&elemSize))
|
||||
return true;
|
||||
@ -7247,7 +7245,7 @@ IonBuilder::getElemTryTypedObject(bool *emitted, MDefinition *obj, MDefinition *
|
||||
return true;
|
||||
|
||||
case type::Struct:
|
||||
case type::SizedArray:
|
||||
case type::Array:
|
||||
return getElemTryComplexElemOfTypedObject(emitted,
|
||||
obj,
|
||||
index,
|
||||
@ -7268,9 +7266,6 @@ IonBuilder::getElemTryTypedObject(bool *emitted, MDefinition *obj, MDefinition *
|
||||
index,
|
||||
objPrediction,
|
||||
elemPrediction);
|
||||
|
||||
case type::UnsizedArray:
|
||||
MOZ_CRASH("Unsized arrays cannot be element types");
|
||||
}
|
||||
|
||||
MOZ_CRASH("Bad kind");
|
||||
@ -7304,12 +7299,6 @@ IonBuilder::checkTypedObjectIndexInBounds(int32_t elemSize,
|
||||
types::TypeObjectKey *globalType = types::TypeObjectKey::get(&script()->global());
|
||||
if (globalType->hasFlags(constraints(), types::OBJECT_FLAG_TYPED_OBJECT_NEUTERED))
|
||||
return false;
|
||||
} else if (objPrediction.kind() == type::UnsizedArray) {
|
||||
// Note: unsized arrays will have their length set to zero if they are
|
||||
// neutered, so we don't need to make sure that no neutering has
|
||||
// occurred which affects this object.
|
||||
length = MTypedObjectUnsizedLength::New(alloc(), obj);
|
||||
current->add(length->toInstruction());
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@ -8202,8 +8191,6 @@ IonBuilder::setElemTryTypedObject(bool *emitted, MDefinition *obj,
|
||||
if (elemPrediction.isUseless())
|
||||
return true;
|
||||
|
||||
MOZ_ASSERT(TypeDescr::isSized(elemPrediction.kind()));
|
||||
|
||||
int32_t elemSize;
|
||||
if (!elemPrediction.hasKnownSize(&elemSize))
|
||||
return true;
|
||||
@ -8227,8 +8214,7 @@ IonBuilder::setElemTryTypedObject(bool *emitted, MDefinition *obj,
|
||||
elemSize);
|
||||
|
||||
case type::Struct:
|
||||
case type::SizedArray:
|
||||
case type::UnsizedArray:
|
||||
case type::Array:
|
||||
// Not yet optimized.
|
||||
return true;
|
||||
}
|
||||
@ -8720,8 +8706,6 @@ IonBuilder::jsop_length_fastPath()
|
||||
if (prediction.hasKnownArrayLength(&sizedLength)) {
|
||||
obj->setImplicitlyUsedUnchecked();
|
||||
length = MConstant::New(alloc(), Int32Value(sizedLength));
|
||||
} else if (prediction.kind() == type::UnsizedArray) {
|
||||
length = MTypedObjectUnsizedLength::New(alloc(), obj);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@ -9449,7 +9433,7 @@ IonBuilder::getPropTryTypedObject(bool *emitted,
|
||||
return true;
|
||||
|
||||
case type::Struct:
|
||||
case type::SizedArray:
|
||||
case type::Array:
|
||||
return getPropTryComplexPropOfTypedObject(emitted,
|
||||
obj,
|
||||
fieldOffset,
|
||||
@ -9470,9 +9454,6 @@ IonBuilder::getPropTryTypedObject(bool *emitted,
|
||||
fieldOffset,
|
||||
fieldPrediction,
|
||||
resultTypes);
|
||||
|
||||
case type::UnsizedArray:
|
||||
MOZ_CRASH("Field of unsized array type");
|
||||
}
|
||||
|
||||
MOZ_CRASH("Bad kind");
|
||||
@ -10166,8 +10147,7 @@ IonBuilder::setPropTryTypedObject(bool *emitted, MDefinition *obj,
|
||||
value, fieldPrediction);
|
||||
|
||||
case type::Struct:
|
||||
case type::SizedArray:
|
||||
case type::UnsizedArray:
|
||||
case type::Array:
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -777,7 +777,7 @@ class IonBuilder
|
||||
InliningStatus inlineSetTypedObjectOffset(CallInfo &callInfo);
|
||||
bool elementAccessIsTypedObjectArrayOfScalarType(MDefinition* obj, MDefinition* id,
|
||||
ScalarTypeDescr::Type *arrayType);
|
||||
InliningStatus inlineConstructTypedObject(CallInfo &callInfo, SizedTypeDescr *target);
|
||||
InliningStatus inlineConstructTypedObject(CallInfo &callInfo, TypeDescr *target);
|
||||
|
||||
// Utility intrinsics.
|
||||
InliningStatus inlineIsCallable(CallInfo &callInfo);
|
||||
|
@ -4231,20 +4231,6 @@ class LTypedObjectProto : public LCallInstructionHelper<1, 1, 1>
|
||||
}
|
||||
};
|
||||
|
||||
// Load an unsized typed object's length.
|
||||
class LTypedObjectUnsizedLength : public LInstructionHelper<1, 1, 0>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(TypedObjectUnsizedLength)
|
||||
|
||||
explicit LTypedObjectUnsizedLength(const LAllocation &object) {
|
||||
setOperand(0, object);
|
||||
}
|
||||
const LAllocation *object() {
|
||||
return getOperand(0);
|
||||
}
|
||||
};
|
||||
|
||||
// Load a typed object's elements vector.
|
||||
class LTypedObjectElements : public LInstructionHelper<1, 1, 0>
|
||||
{
|
||||
|
@ -284,7 +284,6 @@
|
||||
_(TypedArrayLength) \
|
||||
_(TypedArrayElements) \
|
||||
_(TypedObjectProto) \
|
||||
_(TypedObjectUnsizedLength) \
|
||||
_(TypedObjectElements) \
|
||||
_(SetTypedObjectOffset) \
|
||||
_(StringLength) \
|
||||
|
@ -2522,13 +2522,6 @@ LIRGenerator::visitTypedObjectProto(MTypedObjectProto *ins)
|
||||
ins);
|
||||
}
|
||||
|
||||
bool
|
||||
LIRGenerator::visitTypedObjectUnsizedLength(MTypedObjectUnsizedLength *ins)
|
||||
{
|
||||
MOZ_ASSERT(ins->type() == MIRType_Int32);
|
||||
return define(new(alloc()) LTypedObjectUnsizedLength(useRegisterAtStart(ins->object())), ins);
|
||||
}
|
||||
|
||||
bool
|
||||
LIRGenerator::visitTypedObjectElements(MTypedObjectElements *ins)
|
||||
{
|
||||
|
@ -192,7 +192,6 @@ class LIRGenerator : public LIRGeneratorSpecific
|
||||
bool visitTypedObjectElements(MTypedObjectElements *ins);
|
||||
bool visitSetTypedObjectOffset(MSetTypedObjectOffset *ins);
|
||||
bool visitTypedObjectProto(MTypedObjectProto *ins);
|
||||
bool visitTypedObjectUnsizedLength(MTypedObjectUnsizedLength *ins);
|
||||
bool visitInitializedLength(MInitializedLength *ins);
|
||||
bool visitSetInitializedLength(MSetInitializedLength *ins);
|
||||
bool visitNot(MNot *ins);
|
||||
|
@ -219,12 +219,7 @@ IonBuilder::inlineNativeCall(CallInfo &callInfo, JSFunction *target)
|
||||
return inlineHasClass(callInfo,
|
||||
&ScalarTypeDescr::class_, &ReferenceTypeDescr::class_);
|
||||
if (native == intrinsic_TypeDescrIsArrayType)
|
||||
return inlineHasClass(callInfo,
|
||||
&SizedArrayTypeDescr::class_, &UnsizedArrayTypeDescr::class_);
|
||||
if (native == intrinsic_TypeDescrIsSizedArrayType)
|
||||
return inlineHasClass(callInfo, &SizedArrayTypeDescr::class_);
|
||||
if (native == intrinsic_TypeDescrIsUnsizedArrayType)
|
||||
return inlineHasClass(callInfo, &UnsizedArrayTypeDescr::class_);
|
||||
return inlineHasClass(callInfo, &ArrayTypeDescr::class_);
|
||||
if (native == intrinsic_SetTypedObjectOffset)
|
||||
return inlineSetTypedObjectOffset(callInfo);
|
||||
|
||||
@ -286,8 +281,8 @@ IonBuilder::inlineNonFunctionCall(CallInfo &callInfo, JSObject *target)
|
||||
// Inline a call to a non-function object, invoking the object's call or
|
||||
// construct hook.
|
||||
|
||||
if (callInfo.constructing() && target->constructHook() == TypedObject::constructSized)
|
||||
return inlineConstructTypedObject(callInfo, &target->as<SizedTypeDescr>());
|
||||
if (callInfo.constructing() && target->constructHook() == TypedObject::construct)
|
||||
return inlineConstructTypedObject(callInfo, &target->as<TypeDescr>());
|
||||
|
||||
return InliningStatus_NotInlined;
|
||||
}
|
||||
@ -1652,7 +1647,6 @@ IonBuilder::elementAccessIsTypedObjectArrayOfScalarType(MDefinition* obj, MDefin
|
||||
if (elemPrediction.isUseless() || elemPrediction.kind() != type::Scalar)
|
||||
return false;
|
||||
|
||||
MOZ_ASSERT(type::isSized(elemPrediction.kind()));
|
||||
*arrayType = elemPrediction.scalarType();
|
||||
return true;
|
||||
}
|
||||
@ -2519,7 +2513,7 @@ IonBuilder::inlineIsConstructing(CallInfo &callInfo)
|
||||
}
|
||||
|
||||
IonBuilder::InliningStatus
|
||||
IonBuilder::inlineConstructTypedObject(CallInfo &callInfo, SizedTypeDescr *descr)
|
||||
IonBuilder::inlineConstructTypedObject(CallInfo &callInfo, TypeDescr *descr)
|
||||
{
|
||||
// Only inline default constructors for now.
|
||||
if (callInfo.argc() != 0)
|
||||
|
@ -2807,36 +2807,6 @@ class MTypedObjectProto
|
||||
}
|
||||
};
|
||||
|
||||
class MTypedObjectUnsizedLength
|
||||
: public MUnaryInstruction,
|
||||
public SingleObjectPolicy::Data
|
||||
{
|
||||
private:
|
||||
explicit MTypedObjectUnsizedLength(MDefinition *object)
|
||||
: MUnaryInstruction(object)
|
||||
{
|
||||
setResultType(MIRType_Int32);
|
||||
setMovable();
|
||||
}
|
||||
|
||||
public:
|
||||
INSTRUCTION_HEADER(TypedObjectUnsizedLength)
|
||||
|
||||
static MTypedObjectUnsizedLength *New(TempAllocator &alloc, MDefinition *object) {
|
||||
return new(alloc) MTypedObjectUnsizedLength(object);
|
||||
}
|
||||
|
||||
MDefinition *object() const {
|
||||
return getOperand(0);
|
||||
}
|
||||
bool congruentTo(const MDefinition *ins) const {
|
||||
return congruentIfOperandsEqual(ins);
|
||||
}
|
||||
AliasSet getAliasSet() const {
|
||||
return AliasSet::Load(AliasSet::ObjectFields);
|
||||
}
|
||||
};
|
||||
|
||||
// Creates a new derived type object. At runtime, this is just a call
|
||||
// to `BinaryBlock::createDerived()`. That is, the MIR itself does not
|
||||
// compile to particularly optimized code. However, using a distinct
|
||||
|
@ -163,7 +163,6 @@ namespace jit {
|
||||
_(TypedArrayLength) \
|
||||
_(TypedArrayElements) \
|
||||
_(TypedObjectProto) \
|
||||
_(TypedObjectUnsizedLength) \
|
||||
_(TypedObjectElements) \
|
||||
_(SetTypedObjectOffset) \
|
||||
_(InitializedLength) \
|
||||
|
@ -249,7 +249,6 @@ class ParallelSafetyVisitor : public MDefinitionVisitor
|
||||
SAFE_OP(TypedArrayLength)
|
||||
SAFE_OP(TypedArrayElements)
|
||||
SAFE_OP(TypedObjectProto)
|
||||
SAFE_OP(TypedObjectUnsizedLength)
|
||||
SAFE_OP(TypedObjectElements)
|
||||
SAFE_OP(SetTypedObjectOffset)
|
||||
SAFE_OP(InitializedLength)
|
||||
|
@ -1113,7 +1113,7 @@ RNewDerivedTypedObject::RNewDerivedTypedObject(CompactBufferReader &reader)
|
||||
bool
|
||||
RNewDerivedTypedObject::recover(JSContext *cx, SnapshotIterator &iter) const
|
||||
{
|
||||
Rooted<SizedTypeDescr *> descr(cx, &iter.read().toObject().as<SizedTypeDescr>());
|
||||
Rooted<TypeDescr *> descr(cx, &iter.read().toObject().as<TypeDescr>());
|
||||
Rooted<TypedObject *> owner(cx, &iter.read().toObject().as<TypedObject>());
|
||||
int32_t offset = iter.read().toInt32();
|
||||
|
||||
|
@ -123,24 +123,13 @@ TypedObjectPrediction::ofArrayKind() const
|
||||
case type::Struct:
|
||||
return false;
|
||||
|
||||
case type::SizedArray:
|
||||
case type::UnsizedArray:
|
||||
case type::Array:
|
||||
return true;
|
||||
}
|
||||
|
||||
MOZ_CRASH("Bad kind");
|
||||
}
|
||||
|
||||
static bool
|
||||
DescrHasKnownSize(const TypeDescr &descr, int32_t *out)
|
||||
{
|
||||
if (!descr.is<SizedTypeDescr>())
|
||||
return false;
|
||||
|
||||
*out = descr.as<SizedTypeDescr>().size();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TypedObjectPrediction::hasKnownSize(int32_t *out) const
|
||||
{
|
||||
@ -150,7 +139,8 @@ TypedObjectPrediction::hasKnownSize(int32_t *out) const
|
||||
break;
|
||||
|
||||
case TypedObjectPrediction::Descr:
|
||||
return DescrHasKnownSize(descr(), out);
|
||||
*out = descr().size();
|
||||
return true;
|
||||
|
||||
case TypedObjectPrediction::Prefix:
|
||||
// We only know a prefix of the struct fields, hence we do not
|
||||
@ -233,8 +223,8 @@ TypedObjectPrediction::hasKnownArrayLength(int32_t *length) const
|
||||
case TypedObjectPrediction::Descr:
|
||||
// In later patches, this condition will always be true
|
||||
// so long as this represents an array
|
||||
if (descr().is<SizedArrayTypeDescr>()) {
|
||||
*length = descr().as<SizedArrayTypeDescr>().length();
|
||||
if (descr().is<ArrayTypeDescr>()) {
|
||||
*length = descr().as<ArrayTypeDescr>().length();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -245,13 +235,6 @@ TypedObjectPrediction::hasKnownArrayLength(int32_t *length) const
|
||||
MOZ_CRASH("Bad prediction kind");
|
||||
}
|
||||
|
||||
static TypeDescr &
|
||||
DescrArrayElementType(const TypeDescr &descr) {
|
||||
return (descr.is<SizedArrayTypeDescr>()
|
||||
? descr.as<SizedArrayTypeDescr>().elementType()
|
||||
: descr.as<UnsizedArrayTypeDescr>().elementType());
|
||||
}
|
||||
|
||||
TypedObjectPrediction
|
||||
TypedObjectPrediction::arrayElementType() const
|
||||
{
|
||||
@ -262,7 +245,7 @@ TypedObjectPrediction::arrayElementType() const
|
||||
break;
|
||||
|
||||
case TypedObjectPrediction::Descr:
|
||||
return TypedObjectPrediction(DescrArrayElementType(descr()));
|
||||
return TypedObjectPrediction(descr().as<ArrayTypeDescr>().elementType());
|
||||
|
||||
case TypedObjectPrediction::Prefix:
|
||||
break; // Prefixes are always structs, never arrays
|
||||
|
@ -1014,9 +1014,9 @@ JSObject *
|
||||
CreateDerivedTypedObj(JSContext *cx, HandleObject descr,
|
||||
HandleObject owner, int32_t offset)
|
||||
{
|
||||
MOZ_ASSERT(descr->is<SizedTypeDescr>());
|
||||
MOZ_ASSERT(descr->is<TypeDescr>());
|
||||
MOZ_ASSERT(owner->is<TypedObject>());
|
||||
Rooted<SizedTypeDescr*> descr1(cx, &descr->as<SizedTypeDescr>());
|
||||
Rooted<TypeDescr*> descr1(cx, &descr->as<TypeDescr>());
|
||||
Rooted<TypedObject*> owner1(cx, &owner->as<TypedObject>());
|
||||
return OutlineTypedObject::createDerived(cx, descr1, owner1, offset);
|
||||
}
|
||||
|
@ -838,6 +838,12 @@ MacroAssemblerMIPS::ma_sw(Imm32 imm, Address address)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPS::ma_sw(Register data, BaseIndex &address)
|
||||
{
|
||||
ma_store(data, address, SizeWord);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPS::ma_pop(Register r)
|
||||
{
|
||||
@ -2535,6 +2541,19 @@ MacroAssemblerMIPSCompat::branchTestValue(Condition cond, const Address &valaddr
|
||||
}
|
||||
|
||||
// unboxing code
|
||||
void
|
||||
MacroAssemblerMIPSCompat::unboxNonDouble(const ValueOperand &operand, Register dest)
|
||||
{
|
||||
if (operand.payloadReg() != dest)
|
||||
ma_move(dest, operand.payloadReg());
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPSCompat::unboxNonDouble(const Address &src, Register dest)
|
||||
{
|
||||
ma_lw(dest, Address(src.base, src.offset + PAYLOAD_OFFSET));
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPSCompat::unboxInt32(const ValueOperand &operand, Register dest)
|
||||
{
|
||||
|
@ -216,6 +216,7 @@ class MacroAssemblerMIPS : public Assembler
|
||||
|
||||
void ma_sw(Register data, Address address);
|
||||
void ma_sw(Imm32 imm, Address address);
|
||||
void ma_sw(Register data, BaseIndex &address);
|
||||
|
||||
void ma_pop(Register r);
|
||||
void ma_push(Register r);
|
||||
@ -549,6 +550,8 @@ class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS
|
||||
Label *label);
|
||||
|
||||
// unboxing code
|
||||
void unboxNonDouble(const ValueOperand &operand, Register dest);
|
||||
void unboxNonDouble(const Address &src, Register dest);
|
||||
void unboxInt32(const ValueOperand &operand, Register dest);
|
||||
void unboxInt32(const Address &src, Register dest);
|
||||
void unboxBoolean(const ValueOperand &operand, Register dest);
|
||||
|
@ -4753,6 +4753,9 @@ JS::CloneAndExecuteScript(JSContext *cx, HandleObject obj, HandleScript scriptAr
|
||||
script = CloneScript(cx, NullPtr(), NullPtr(), script);
|
||||
if (!script)
|
||||
return false;
|
||||
|
||||
Rooted<GlobalObject *> global(cx, script->compileAndGo() ? &script->global() : nullptr);
|
||||
js::Debugger::onNewScript(cx, script, global);
|
||||
}
|
||||
return ExecuteScript(cx, obj, script, nullptr);
|
||||
}
|
||||
|
@ -996,8 +996,6 @@ bool intrinsic_ObjectIsOpaqueTypedObject(JSContext *cx, unsigned argc, Value *vp
|
||||
bool intrinsic_ObjectIsTypeDescr(JSContext *cx, unsigned argc, Value *vp);
|
||||
bool intrinsic_TypeDescrIsSimpleType(JSContext *cx, unsigned argc, Value *vp);
|
||||
bool intrinsic_TypeDescrIsArrayType(JSContext *cx, unsigned argc, Value *vp);
|
||||
bool intrinsic_TypeDescrIsUnsizedArrayType(JSContext *cx, unsigned argc, Value *vp);
|
||||
bool intrinsic_TypeDescrIsSizedArrayType(JSContext *cx, unsigned argc, Value *vp);
|
||||
|
||||
class AutoLockForExclusiveAccess
|
||||
{
|
||||
|
@ -1452,24 +1452,33 @@ CharsToNumber(ThreadSafeContext *cx, const CharT *chars, size_t length, double *
|
||||
const CharT *end = chars + length;
|
||||
const CharT *bp = SkipSpace(chars, end);
|
||||
|
||||
/* ECMA doesn't allow signed hex numbers (bug 273467). */
|
||||
if (end - bp >= 2 && bp[0] == '0' && (bp[1] == 'x' || bp[1] == 'X')) {
|
||||
/*
|
||||
* It's probably a hex number. Accept if there's at least one hex
|
||||
* digit after the 0x, and if no non-whitespace characters follow all
|
||||
* the hex digits.
|
||||
*/
|
||||
const CharT *endptr;
|
||||
double d;
|
||||
if (!GetPrefixInteger(cx, bp + 2, end, 16, &endptr, &d) ||
|
||||
endptr == bp + 2 ||
|
||||
SkipSpace(endptr, end) != end)
|
||||
{
|
||||
*result = GenericNaN();
|
||||
} else {
|
||||
*result = d;
|
||||
/* ECMA doesn't allow signed non-decimal numbers (bug 273467). */
|
||||
if (end - bp >= 2 && bp[0] == '0') {
|
||||
int radix = 0;
|
||||
if (bp[1] == 'b' || bp[1] == 'B')
|
||||
radix = 2;
|
||||
else if (bp[1] == 'o' || bp[1] == 'O')
|
||||
radix = 8;
|
||||
else if (bp[1] == 'x' || bp[1] == 'X')
|
||||
radix = 16;
|
||||
|
||||
if (radix != 0) {
|
||||
/*
|
||||
* It's probably a non-decimal number. Accept if there's at least one digit after
|
||||
* the 0b|0o|0x, and if no non-whitespace characters follow all the digits.
|
||||
*/
|
||||
const CharT *endptr;
|
||||
double d;
|
||||
if (!GetPrefixInteger(cx, bp + 2, end, radix, &endptr, &d) ||
|
||||
endptr == bp + 2 ||
|
||||
SkipSpace(endptr, end) != end)
|
||||
{
|
||||
*result = GenericNaN();
|
||||
} else {
|
||||
*result = d;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
|
26
js/src/tests/ecma_6/Number/ToNumber.js
Normal file
26
js/src/tests/ecma_6/Number/ToNumber.js
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* https://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
assertEq(Number("0b11"), 3);
|
||||
assertEq(Number("0B11"), 3);
|
||||
assertEq(Number(" 0b11 "), 3);
|
||||
assertEq(Number("0b12"), NaN);
|
||||
assertEq(Number("-0b11"), NaN);
|
||||
assertEq(+"0b11", 3);
|
||||
|
||||
assertEq(Number("0o66"), 54);
|
||||
assertEq(Number("0O66"), 54);
|
||||
assertEq(Number(" 0o66 "), 54);
|
||||
assertEq(Number("0o88"), NaN);
|
||||
assertEq(Number("-0o66"), NaN);
|
||||
assertEq(+"0o66", 54);
|
||||
|
||||
if(typeof getSelfHostedValue === "function"){
|
||||
assertEq(getSelfHostedValue("ToNumber")("0b11"), 3);
|
||||
assertEq(getSelfHostedValue("ToNumber")("0o66"), 54);
|
||||
}
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(true, true);
|
@ -1,15 +0,0 @@
|
||||
// |reftest| skip-if(!this.hasOwnProperty("TypedObject")||(Android))
|
||||
var BUGNUMBER = 914137;
|
||||
var summary = 'Fuzz bug';
|
||||
|
||||
function test() {
|
||||
var A = new TypedObject.ArrayType(TypedObject.uint8, 2147483647);
|
||||
var a = new A();
|
||||
assertEq(arguments[5], a);
|
||||
}
|
||||
|
||||
print(BUGNUMBER + ": " + summary);
|
||||
assertThrows(test);
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(true, true);
|
||||
print("Tests complete");
|
@ -7,9 +7,9 @@ var StructType = TypedObject.StructType;
|
||||
var float32 = TypedObject.float32;
|
||||
|
||||
function runTests() {
|
||||
var Point = new ArrayType(float32).dimension(3);
|
||||
var Point = new ArrayType(float32, 3);
|
||||
var Line = new StructType({from: Point, to: Point});
|
||||
var Lines = new ArrayType(Line).dimension(3);
|
||||
var Lines = new ArrayType(Line, 3);
|
||||
|
||||
var lines = new Lines([
|
||||
{from: [1, 2, 3], to: [4, 5, 6]},
|
||||
|
@ -28,14 +28,14 @@ function runTests() {
|
||||
assertThrows(function() new ArrayType(""));
|
||||
assertThrows(function() new ArrayType(5));
|
||||
assertThrows(function() new ArrayType(uint8).dimension(-1));
|
||||
var A = new ArrayType(uint8).dimension(10);
|
||||
assertEq(A.__proto__.__proto__, ArrayType.prototype);
|
||||
var A = new ArrayType(uint8, 10);
|
||||
//assertEq(A.__proto__.__proto__, ArrayType.prototype);
|
||||
assertEq(A.length, 10);
|
||||
assertEq(A.elementType, uint8);
|
||||
assertEq(A.byteLength, 10);
|
||||
assertEq(A.toSource(), "new ArrayType(uint8).dimension(10)");
|
||||
assertEq(A.toSource(), "new ArrayType(uint8, 10)");
|
||||
|
||||
assertEq(A.prototype.__proto__.__proto__, ArrayType.prototype.prototype);
|
||||
//assertEq(A.prototype.__proto__.__proto__, ArrayType.prototype.prototype);
|
||||
|
||||
var a = new A();
|
||||
assertEq(a.__proto__, A.prototype);
|
||||
@ -74,8 +74,8 @@ function runTests() {
|
||||
// Length different
|
||||
assertThrows(function() new A([0, 1, 0, 1, 0, 1, 0, 1, 0]));
|
||||
|
||||
var Vec3 = new ArrayType(float32).dimension(3);
|
||||
var Sprite = new ArrayType(Vec3).dimension(3); // say for position, velocity, and direction
|
||||
var Vec3 = new ArrayType(float32, 3);
|
||||
var Sprite = new ArrayType(Vec3, 3); // say for position, velocity, and direction
|
||||
assertEq(Sprite.elementType, Vec3);
|
||||
assertEq(Sprite.elementType.elementType, float32);
|
||||
|
||||
@ -96,7 +96,7 @@ function runTests() {
|
||||
assertEq(Number.isNaN(mario[1][1]), true);
|
||||
|
||||
// ok this is just for kicks
|
||||
var AllSprites = new ArrayType(Sprite).dimension(65536);
|
||||
var AllSprites = new ArrayType(Sprite, 65536);
|
||||
var as = new AllSprites();
|
||||
assertEq(as.length, 65536);
|
||||
|
||||
|
@ -1,25 +0,0 @@
|
||||
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
|
||||
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/licenses/publicdomain/
|
||||
*/
|
||||
|
||||
var BUGNUMBER = 922115;
|
||||
var summary = 'check we cannot create handles to unsized arrays';
|
||||
|
||||
var T = TypedObject;
|
||||
|
||||
function runTests() {
|
||||
var Line = new T.StructType({from: T.uint8, to: T.uint8});
|
||||
var Lines = Line.array();
|
||||
assertThrowsInstanceOf(function() Lines.handle(), TypeError,
|
||||
"was able to create handle to unsized array");
|
||||
|
||||
reportCompare(true, true);
|
||||
print("Tests complete");
|
||||
}
|
||||
|
||||
runTests();
|
||||
|
||||
|
@ -21,31 +21,14 @@ var float64 = TypedObject.float64;
|
||||
|
||||
var objectType = TypedObject.objectType;
|
||||
|
||||
function filterOddsFromVariable() {
|
||||
function filterOdds() {
|
||||
var length = 100;
|
||||
var Uint32s = uint32.array();
|
||||
var uint32s = new Uint32s(100);
|
||||
for (var i = 0; i < length; i++)
|
||||
uint32s[i] = i;
|
||||
|
||||
var odds = uint32s.filter(i => (i % 2) != 0);
|
||||
assertEq(true, objectType(odds) == Uint32s);
|
||||
assertEq(true, Uint32s.variable);
|
||||
assertEq(50, odds.length);
|
||||
for (var i = 0, j = 1; j < length; i++, j += 2)
|
||||
assertEq(odds[i], j);
|
||||
}
|
||||
|
||||
function filterOddsFromSized() {
|
||||
var length = 100;
|
||||
var Uint32s = uint32.array(100);
|
||||
var Uint32s = new ArrayType(uint32, 100);
|
||||
var uint32s = new Uint32s();
|
||||
for (var i = 0; i < length; i++)
|
||||
uint32s[i] = i;
|
||||
|
||||
var odds = uint32s.filter(i => (i % 2) != 0);
|
||||
assertEq(true, objectType(odds) == Uint32s.unsized);
|
||||
assertEq(true, objectType(odds).variable);
|
||||
assertEq(50, odds.length);
|
||||
for (var i = 0, j = 1; j < length; i++, j += 2)
|
||||
assertEq(odds[i], j);
|
||||
@ -54,8 +37,7 @@ function filterOddsFromSized() {
|
||||
function runTests() {
|
||||
print(BUGNUMBER + ": " + summary);
|
||||
|
||||
filterOddsFromVariable();
|
||||
filterOddsFromSized();
|
||||
filterOdds();
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(true, true);
|
||||
|
@ -27,7 +27,7 @@ function TestValues(type, values) {
|
||||
compare(struct.f, values[i]);
|
||||
}
|
||||
|
||||
var Array = new ArrayType(type).dimension(1);
|
||||
var Array = new ArrayType(type, 1);
|
||||
for (var i = 0; i < values.length; i++) {
|
||||
var array = new Array();
|
||||
array[0] = values[i].input;
|
||||
|
@ -39,16 +39,7 @@ function TestStructFields(RefType) {
|
||||
|
||||
function TestArrayElements(RefType) {
|
||||
var rabbit = {};
|
||||
var S1 = new ArrayType(RefType).dimension(1);
|
||||
var s1 = new S1([rabbit]);
|
||||
assertCanReach(s1, rabbit);
|
||||
s1[0] = null;
|
||||
assertCannotReach(s1, rabbit);
|
||||
}
|
||||
|
||||
function TestUnsizedArrayElements(RefType) {
|
||||
var rabbit = {};
|
||||
var S1 = new ArrayType(RefType);
|
||||
var S1 = new ArrayType(RefType, 1);
|
||||
var s1 = new S1([rabbit]);
|
||||
assertCanReach(s1, rabbit);
|
||||
s1[0] = null;
|
||||
@ -58,7 +49,7 @@ function TestUnsizedArrayElements(RefType) {
|
||||
function TestStructInArray(RefType) {
|
||||
var rabbit = {};
|
||||
var S2 = new StructType({f: RefType, g: RefType});
|
||||
var S1 = new ArrayType(S2).dimension(1);
|
||||
var S1 = new ArrayType(S2, 1);
|
||||
var s1 = new S1([{f: rabbit, g: {}}]);
|
||||
assertCanReach(s1, rabbit);
|
||||
s1[0].f = null;
|
||||
@ -91,9 +82,6 @@ function runTests()
|
||||
TestArrayElements(Object);
|
||||
TestArrayElements(Any);
|
||||
|
||||
TestUnsizedArrayElements(Object);
|
||||
TestUnsizedArrayElements(Any);
|
||||
|
||||
TestStructInArray(Object);
|
||||
TestStructInArray(Any);
|
||||
|
||||
|
@ -39,9 +39,9 @@ function runTests() {
|
||||
|
||||
{type: new StructType({a: uint8, b: uint8, c: uint16}), size: 4, alignment: 2},
|
||||
|
||||
{type: new ArrayType(uint8).dimension(32), size: 32, alignment: 1},
|
||||
{type: new ArrayType(uint16).dimension(16), size: 32, alignment: 2},
|
||||
{type: new ArrayType(uint32).dimension(8), size: 32, alignment: 4},
|
||||
{type: new ArrayType(uint8, 32), size: 32, alignment: 1},
|
||||
{type: new ArrayType(uint16, 16), size: 32, alignment: 2},
|
||||
{type: new ArrayType(uint32, 8), size: 32, alignment: 4},
|
||||
];
|
||||
|
||||
for (var i = 0; i < typesAndAlignments.length; i++) {
|
||||
|
@ -21,7 +21,6 @@ function runTests() {
|
||||
assertEq(S.__proto__, StructType.prototype);
|
||||
assertEq(S.prototype.__proto__, StructType.prototype.prototype);
|
||||
assertEq(S.toSource(), "new StructType({x: int32, y: uint8, z: float64})");
|
||||
assertEq(S.variable, false);
|
||||
assertEq(S.byteLength, 16);
|
||||
assertEq(S.byteAlignment, 8);
|
||||
var fieldNames = Object.getOwnPropertyNames(S.fieldTypes);
|
||||
|
@ -1,54 +0,0 @@
|
||||
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
|
||||
var BUGNUMBER = 922115;
|
||||
var summary = 'TypedObjects ArrayType implementation';
|
||||
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/licenses/publicdomain/
|
||||
*/
|
||||
|
||||
var { ArrayType, StructType, uint8, float32, uint32 } = TypedObject;
|
||||
var ObjectType = TypedObject.Object;
|
||||
|
||||
function runTests() {
|
||||
print(BUGNUMBER + ": " + summary);
|
||||
|
||||
(function SimpleArrayOfTwoObjects() {
|
||||
print("SimpleArrayOfTwoObjects");
|
||||
var Objects = new ArrayType(ObjectType);
|
||||
var objects2 = new Objects([{f: "Hello"},
|
||||
{f: "World"}]);
|
||||
assertEq(objects2[0].f, "Hello");
|
||||
assertEq(objects2[1].f, "World");
|
||||
assertEq(objects2.length, 2);
|
||||
})();
|
||||
|
||||
(function EmbedUnsizedArraysBad() {
|
||||
print("EmbedUnsizedArraysBad");
|
||||
var Objects = new ArrayType(ObjectType);
|
||||
assertThrows(() => new ArrayType(Objects));
|
||||
assertThrows(() => new StructType({f: Objects}));
|
||||
})();
|
||||
|
||||
(function MultipleSizes() {
|
||||
print("MultipleSizes");
|
||||
var Uints = new ArrayType(uint32);
|
||||
var Point = new StructType({values: new ArrayType(uint32).dimension(3)});
|
||||
|
||||
var uints = new Uints([0, 1, 2]);
|
||||
var point = new Point({values: uints});
|
||||
|
||||
assertEq(uints.length, point.values.length);
|
||||
for (var i = 0; i < uints.length; i++) {
|
||||
assertEq(uints[i], i);
|
||||
assertEq(uints[i], point.values[i]);
|
||||
}
|
||||
})();
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(true, true);
|
||||
print("Tests complete");
|
||||
}
|
||||
|
||||
runTests();
|
||||
|
@ -1,47 +0,0 @@
|
||||
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
|
||||
var BUGNUMBER = 922115;
|
||||
var summary = 'TypedObjects ArrayType implementation';
|
||||
|
||||
var ArrayType = TypedObject.ArrayType;
|
||||
var StructType = TypedObject.StructType;
|
||||
var uint8 = TypedObject.uint8;
|
||||
var float32 = TypedObject.float32;
|
||||
var uint32 = TypedObject.uint32;
|
||||
var ObjectType = TypedObject.Object;
|
||||
|
||||
function runTests() {
|
||||
(function DimensionLinkedToUndimension() {
|
||||
var UintsA = uint32.array();
|
||||
var FiveUintsA = UintsA.dimension(5);
|
||||
var FiveUintsB = uint32.array(5);
|
||||
|
||||
assertEq(true, FiveUintsA.equivalent(FiveUintsB));
|
||||
assertEq(true, FiveUintsA.unsized === UintsA);
|
||||
assertEq(true, FiveUintsB.unsized !== UintsA);
|
||||
})();
|
||||
|
||||
(function PrototypeHierarchy() {
|
||||
var Uint8s = uint8.array();
|
||||
assertEq(Uint8s.prototype.__proto__, ArrayType.prototype.prototype);
|
||||
Uint8s.prototype.sum = function() {
|
||||
var r = 0;
|
||||
for (var i = 0; i < this.length; i++)
|
||||
r = uint8(r + this[i]);
|
||||
return r;
|
||||
};
|
||||
|
||||
var FiveUint8s = Uint8s.dimension(5);
|
||||
assertEq(FiveUint8s.__proto__, Uint8s);
|
||||
|
||||
var fiveUint8s = new FiveUint8s([128, 128, 128, 128, 128]);
|
||||
assertEq(128, fiveUint8s.sum());
|
||||
})();
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(true, true);
|
||||
|
||||
print("Tests complete");
|
||||
}
|
||||
|
||||
runTests();
|
||||
|
@ -1,23 +0,0 @@
|
||||
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
|
||||
var BUGNUMBER = 922115;
|
||||
var summary = 'cannot embed unsized array in a struct';
|
||||
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/licenses/publicdomain/
|
||||
*/
|
||||
|
||||
var T = TypedObject;
|
||||
|
||||
function runTests() {
|
||||
print(BUGNUMBER + ": " + summary);
|
||||
|
||||
var Uints = T.uint32.array();
|
||||
assertThrowsInstanceOf(() => { new T.StructType({f: Uints}) }, TypeError);
|
||||
assertThrowsInstanceOf(() => { Uints.array() }, TypeError);
|
||||
|
||||
reportCompare(true, true);
|
||||
print("Tests complete");
|
||||
}
|
||||
|
||||
runTests();
|
@ -4832,8 +4832,11 @@ DebuggerArguments_getArg(JSContext *cx, unsigned argc, Value *vp)
|
||||
RootedScript script(cx);
|
||||
if (unsigned(i) < frame.numActualArgs()) {
|
||||
script = frame.script();
|
||||
if (!script->ensureHasAnalyzedArgsUsage(cx))
|
||||
return false;
|
||||
{
|
||||
AutoCompartment ac(cx, script->compartment());
|
||||
if (!script->ensureHasAnalyzedArgsUsage(cx))
|
||||
return false;
|
||||
}
|
||||
if (unsigned(i) < frame.numFormalArgs() && script->formalIsAliased(i)) {
|
||||
for (AliasedFormalIter fi(script); ; fi++) {
|
||||
if (fi.frameIndex() == unsigned(i)) {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user