Merge inbound to m-c a=merge

This commit is contained in:
Wes Kocher 2014-11-07 17:48:37 -08:00
commit a2b32b5515
123 changed files with 870 additions and 1293 deletions

View File

@ -254,7 +254,7 @@ IPCAccessibilityActive()
#ifdef MOZ_B2G
return false;
#else
return XRE_GetProcessType() != GeckoProcessType_Default;
return XRE_GetProcessType() == GeckoProcessType_Content;
#endif
}

View File

@ -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

View File

@ -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)

View File

@ -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);

View File

@ -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]

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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);

View File

@ -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 });

View File

@ -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);

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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 });

View File

@ -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);

View File

@ -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)

View File

@ -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;

View File

@ -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);

View File

@ -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;
};

View File

@ -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;

View File

@ -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.

View File

@ -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;
}

View File

@ -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));

View File

@ -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)
{

View File

@ -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; }

View File

@ -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);

View File

@ -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;

View File

@ -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();

View File

@ -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',
]

View File

@ -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

View File

@ -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()));

View File

@ -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()",

View File

@ -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);

View File

@ -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

View File

@ -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];

View File

@ -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,

View File

@ -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

View File

@ -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());

View File

@ -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);

View File

@ -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");
}

View File

@ -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());

View File

@ -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();

View File

@ -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;

View File

@ -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;

View File

@ -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");

View File

@ -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');

View File

@ -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');

View File

@ -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);
})();
}

View File

@ -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 ];

View File

@ -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;

View File

@ -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() {

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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) {}

View File

@ -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

View File

@ -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();

View File

@ -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;

View File

@ -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() {});

View File

@ -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)

View File

@ -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)
{

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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>
{

View File

@ -284,7 +284,6 @@
_(TypedArrayLength) \
_(TypedArrayElements) \
_(TypedObjectProto) \
_(TypedObjectUnsizedLength) \
_(TypedObjectElements) \
_(SetTypedObjectOffset) \
_(StringLength) \

View File

@ -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)
{

View File

@ -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);

View File

@ -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)

View File

@ -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

View File

@ -163,7 +163,6 @@ namespace jit {
_(TypedArrayLength) \
_(TypedArrayElements) \
_(TypedObjectProto) \
_(TypedObjectUnsizedLength) \
_(TypedObjectElements) \
_(SetTypedObjectOffset) \
_(InitializedLength) \

View File

@ -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)

View File

@ -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();

View File

@ -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

View File

@ -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);
}

View File

@ -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)
{

View File

@ -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);

View File

@ -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);
}

View File

@ -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
{

View File

@ -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;
}
/*

View 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);

View File

@ -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");

View File

@ -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]},

View File

@ -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);

View File

@ -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();

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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++) {

View File

@ -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);

View File

@ -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();

View File

@ -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();

View File

@ -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();

View File

@ -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