mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 13:23:07 +00:00
import changes from `dev' branch of rmottola/Arctic-Fox:
- bug 1162519 - use winrm for mach clobber on Windows. r=gps (707dfeb728)
- No bug: Make ./mach clobber work on windows without winrm.exe. r=me (bb55cb7a1d)
- Bug 1176642 - Import proper mozinfo package; r=me (f5baa80864)
- Bug 1216171 - Fix MozbuildObject.bindir to import the correct mozinfo, r=jmaher (58df60341e)
- Bug 1216575 - [mozbuild] Remove if statement that sets bindir to resource dir on osx, r=spohl (079d7483c8)
- Bug 1190474 - Allow test-specific timeouts to be specified in cppunittest.ini, r=chmanchester (86d5ffa97c)
- Bug 1181867 - move -runtime flag to runtests.py so it gets set in automation; r=jland,ahalberstadt (939efb386c)
- Bug 1185761 - [mochitest] Allow boolean values to --keep-open for overriding the default, r=ted (b7d1c99778)
- Bug 1156425 - Allow Android test jobs to run for up to 75 minutes; r=ryanvm (9930c4f8e9)
- Bug 1171303 - Set pref extensions.autoupdate.enabled to false to avoid testOfflinePage failures; r=mfinkle (400ed217a5)
- Bug 1179981 - A new test harness for robocop; r=jmaher (9c6b066733)
- Bug 999450 - Add find-test-chunk command in mach to discover the chunk for a mochitest on a platform. r=chmanchester (b9e5b64fc6)
- Bug 1140441 - Add substring matching option to |mach mach-debug-commands|, r=gps (4ad5b5362e)
- Bug 1090276 - Support mach cppunittest on Android; r=dminor (a5dc185c03)
- Bug 1181261 - Merge configs from testing/config/mozharness into mozharness proper, r=chmanchester (9d2a45b3de)
- Bug 1217144: Allow for cppunittest to be run locally on OSX. r=erahm (f470637d77)
- Bug 1205144 - Remove 'REMOVED' commands from output of mach-commands and mach-debug-commands. r=gps DONTBUILD (19a8e3b0bf)
- Bug 1203627 - Change search order for finding android emulator; r=ahal (ca1b0eb350)
- Bug 1199377 - Fetch host-utils for Android tests when needed; r=jmaher (c276a035af)
- Bug 1211407 - Make |mach mochitest| use the adb under `out/host/*/bin` if no --adbpath specified. r=ahal (e8acae4e41)
- Bug 1122590 - Make |mach mochitest| properly detect devtools tests (and other subsuites), r=chmanchester, DONTBUILD, a=NPOTB (5034e6aac6)
- Bug 938994 - Move build/mobile/robocop into mobile/android/tests/browser/robocop. r=gbrown (f386204b05)
- Bug 1208002: Optimize creation of RegExpMatch result for 'str.match', r=bhackett (b8dccae77a)
- Bug 1214548 - GenerateLcovInfo: Check that getOrCreateScript does not OOM. r=bhackett (9bbd59a94e)
- Bug 1155937 - Fix comment in IonBuilder::getPropTryInnerize. r=bz (a8a05ec18f)
- Bug 1213146 - IonMonkey: MIPS: Modify the last two args of Assembler::bind to generic type. r=arai (54123a5c20)
- Bug 1220505 - IonMonkey: MIPS64: Fix workaround for Loongson3 in Assembler::bind. r=huangwenjun06 (fff27fcfeb)
- Bug 1220939 - IonMonkey: MIPS: Check oom() before using editSrc() and Label::use(). r=jolesen (a2a25baf45)
- Bug 1205167 - IonMonkey: MIPS64: Fix typo in Assembler-mips64. r=nbp (b339f0475b)
- Bug 1217873 - IonMonkey: MIPS: Move BailoutStack to architecture dependent. r=arai f=nbp (cd6a703e71)
- Bug 1217873 - IonMonkey: MIPS: Move visitOutOfLineBailout to architecture dependent. r=arai f=nbp (4fc456d837)
- Bug 1217873 - IonMonkey: MIPS64: Simplify BailoutStack for MIPS64. r=lth (baafdfefeb)
- Bug 1090957 - IonMonkey: MIPS64: Implement atomics in MacroAssembler. r=lth (64df89560f)
- Bug 1219157 - IonMonkey: MIPS64: Delete CodeOffsetLabel::fixup(). r=jolesen (20a4bb8de4)
- Bug 1219125 - IonMonkey: MIPS64: Fix profiler/test-bug1026485.js failure in debug mode. r=arai (701dca2337)
- Bug 1213532 - IonMonkey: MIPS32: Fix call FloatRegistersMIPSShared::GetName recursive. r=arai (96cb12e849)
- Bug 1213532 - IonMonkey: MIPS32: Rename BaseFloatRegisters to FloatRegistersMIPSShared. r=arai (d0bbaaad17)
- Bug 1066642 - IonMonkey: MIPS32: Do not allocate odd FP registers on Loongson CPU-s. r=arai (fe0e2e6f0a)
- Bug 1215420 - IonMonkey: MIPS32: Fix FloatRegister::encoding. r=nbp (03534b7eb6)
- Bug 1129813 - special-case "while" and "for" line notes; r=jimb (000e7e8bea)
- Bug 1139235 - don't set line for literal case expressions; r=fitzgen (b317b4c427)
- Bug 1220766 - Don't assume ListIterator's next slot contains an int32 r=shu (65b563b78b)
- Bug 1224222 - Guard against setters on Array.prototype in self-hosted Module code. r=jonco (5ac5b48c5b)
- Bug 1219044 - Take account of the fact that module import bindings may be null if we have hit OOM r=terrence (27b1e057ad)
- Bug 1219408 - Throw error if module loader attempts to evaluate an uninstantiated module r=shu (b89af38208)
- clean up double definition (92c2e6c4d2)
- remove, since 1170372 has long since landed and no trace can be found in FF/TFF (e417a4dc58)
- Bug 1215430 - Inline the guts of the shared method implementing |new RegExp(...)| and |RegExp.prototype.compile| into each separate method, for clarity. r=efaust (5be0d360f2)
- Bug 1215430 - Refactor RegExp code to be more spec-like in its ordering of things, and eliminate the confusing statefulness of RegExpObjectBuilder. r=efaust (fe24ae119d)
- Bug 1209001 - Add test code for OOM handling in parseModule() r=terrence (c36cc5e5c1)
- Bug 978802 - Crash in argumentsOptimizationFailed() if we run out of memory r=jandem (de1bb00bd7)
- Bug 1212128 - Annotate oomInGetJumpLabelForBranch with allow-oom. (rs=terrence) (72304c3b03)
- Bug 1212469 - Make oomTest() into a shell function r=nbp (6c19395033)
- various cleanups (d12627b23f)
- Bug 1216260 - Replace mozMatchesSelector with matches in add-on SDK. r=matteo (7457c563b6)
- Bug 1216269 - Fix tab-firefox.js typo in tab attach method. r=zer0 (a59f126ec8)
- var-let (d81c53a0ce)
- Bug 1139100 - Apply proper checking for command existence; r=ahal (5d0f1fc75d)
- Bug 1176620 - Refactor how mach command metadata is stored; r=ahal (aa6dc7c786)
- Bug 1176620 - Pass fewer arguments into MethodHandler; r=ahal (fa64eef7ab)
- Bug 1176620 - Eliminate MethodHandler; r=ahal (04130c8e62)
- Bug 1177476 - Fix require_conditions regression in mach, r=gps (30c6400900)
- Bug 1208320 - Allow FileFinder to find dot files; r=glandium (639f2695a0)
- Bug 1210329 - Remove support for line endings munging in the preprocessor. r=gps (cbb01fa96e)
- Bug 1211957 - Add the repackage step at the end of a faster build on Mac. r=gps (48fb11101a)
- Bug 1210687 - Use install manifests for jar.mn files in FasterMake backend. r=gps (cb0b4e2c92)
- Bug 1215238 - Mention the included filepath in pre-processed js sources with #includes. r=glandium (3b3590e287)
- Bug 1209839 - Remove the -E option to the preprocessor. r=gps (63c60f15cd)
- Bug 1215526 - part 3 - make preprocessor.preprocessor report all included files; r=glandium (c4949756ff)
- bit of Bug 1207708 - Part 2 (2a87bac13f)
- some var fixes (35b7ffd9bd)
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
import datetime
|
||||
import glob
|
||||
import time
|
||||
import re
|
||||
@@ -122,8 +123,11 @@ class RemoteAutomation(Automation):
|
||||
if self._devicemanager.fileExists(traces):
|
||||
try:
|
||||
t = self._devicemanager.pullFile(traces)
|
||||
print "Contents of %s:" % traces
|
||||
print t
|
||||
if t:
|
||||
stripped = t.strip()
|
||||
if len(stripped) > 0:
|
||||
print "Contents of %s:" % traces
|
||||
print t
|
||||
# Once reported, delete traces
|
||||
self.deleteANRs()
|
||||
except DMError:
|
||||
@@ -238,10 +242,10 @@ class RemoteAutomation(Automation):
|
||||
self.procName = cmd[0].split('/')[-1]
|
||||
if cmd[0] == 'am' and cmd[1] in RemoteAutomation._specialAmCommands:
|
||||
self.procName = app
|
||||
print "Robocop process name: "+self.procName
|
||||
|
||||
# Setting timeout at 1 hour since on a remote device this takes much longer
|
||||
self.timeout = 3600
|
||||
# Setting timeout at 1 hour since on a remote device this takes much longer.
|
||||
# Temporarily increased to 75 minutes because no more chunks can be created.
|
||||
self.timeout = 4500
|
||||
# The benefit of the following sleep is unclear; it was formerly 15 seconds
|
||||
time.sleep(1)
|
||||
|
||||
@@ -316,19 +320,22 @@ class RemoteAutomation(Automation):
|
||||
def wait(self, timeout = None, noOutputTimeout = None):
|
||||
timer = 0
|
||||
noOutputTimer = 0
|
||||
interval = 20
|
||||
|
||||
interval = 10
|
||||
if timeout == None:
|
||||
timeout = self.timeout
|
||||
|
||||
status = 0
|
||||
while (self.dm.getTopActivity() == self.procName):
|
||||
# retrieve log updates every 60 seconds
|
||||
if timer % 60 == 0:
|
||||
top = self.procName
|
||||
slowLog = False
|
||||
while (top == self.procName):
|
||||
# Get log updates on each interval, but if it is taking
|
||||
# too long, only do it every 60 seconds
|
||||
if (not slowLog) or (timer % 60 == 0):
|
||||
startRead = datetime.datetime.now()
|
||||
messages = self.read_stdout()
|
||||
if (datetime.datetime.now() - startRead) > datetime.timedelta(seconds=5):
|
||||
slowLog = True
|
||||
if messages:
|
||||
noOutputTimer = 0
|
||||
|
||||
time.sleep(interval)
|
||||
timer += interval
|
||||
noOutputTimer += interval
|
||||
@@ -338,10 +345,9 @@ class RemoteAutomation(Automation):
|
||||
if (noOutputTimeout and noOutputTimer > noOutputTimeout):
|
||||
status = 2
|
||||
break
|
||||
|
||||
top = self.dm.getTopActivity()
|
||||
# Flush anything added to stdout during the sleep
|
||||
self.read_stdout()
|
||||
|
||||
return status
|
||||
|
||||
def kill(self, stagedShutdown = False):
|
||||
|
||||
@@ -26,10 +26,6 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
|
||||
'mobile/sutagent/android/ffxcp',
|
||||
'mobile/sutagent/android/fencp',
|
||||
]
|
||||
if not CONFIG['MOZ_B2GDROID']:
|
||||
TEST_DIRS += [
|
||||
'mobile/robocop',
|
||||
]
|
||||
|
||||
for var in ('GRE_MILESTONE', 'MOZ_APP_VERSION', 'MOZ_APP_BASENAME',
|
||||
'MOZ_APP_VENDOR', 'MOZ_APP_ID', 'MAR_CHANNEL_ID',
|
||||
|
||||
+6
-58
@@ -27,10 +27,6 @@
|
||||
# - PYTHON, the path to the python executable
|
||||
# - ACDEFINES, which contains a set of -Dvar=name to be used during
|
||||
# preprocessing
|
||||
# - MOZ_CHROME_FILE_FORMAT, which defines whether to use file copies or
|
||||
# symbolic links
|
||||
# - JAR_MN_TARGETS, which defines the targets to use for jar manifest
|
||||
# processing, see further below
|
||||
# - INSTALL_MANIFESTS, which defines the list of base directories handled
|
||||
# by install manifests, see further below
|
||||
# - MANIFEST_TARGETS, which defines the file paths of chrome manifests, see
|
||||
@@ -42,7 +38,6 @@
|
||||
|
||||
# Targets to be triggered for a default build
|
||||
default: $(addprefix install-,$(INSTALL_MANIFESTS))
|
||||
default: $(addprefix jar-,$(JAR_MN_TARGETS))
|
||||
|
||||
# Explicit files to be built for a default build
|
||||
default: $(addprefix $(TOPOBJDIR)/,$(MANIFEST_TARGETS))
|
||||
@@ -53,6 +48,12 @@ default: $(TOPOBJDIR)/dist/bin/webapprt/webapprt.ini
|
||||
# Targets from the recursive make backend to be built for a default build
|
||||
default: $(TOPOBJDIR)/config/makefiles/xpidl/xpidl
|
||||
|
||||
ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
|
||||
# Mac builds require to copy things in dist/bin/*.app
|
||||
default:
|
||||
$(MAKE) -C $(TOPOBJDIR)/$(MOZ_BUILD_APP)/app repackage
|
||||
endif
|
||||
|
||||
.PHONY: FORCE
|
||||
|
||||
# Extra define to trigger some workarounds. We should strive to limit the
|
||||
@@ -95,52 +96,6 @@ $(addprefix install-,$(INSTALL_MANIFESTS)): install-%: $(TOPOBJDIR)/config/build
|
||||
$(MOZ_DEBUG_DEFINES) \
|
||||
install_$(subst /,_,$*)
|
||||
|
||||
# Install files from jar manifests. Ideally, they would be using install
|
||||
# manifests, but the code to read jar manifests and emit appropriate
|
||||
# install manifests is not there yet.
|
||||
# Things missing:
|
||||
# - DEFINES from config/config.mk
|
||||
# - L10N
|
||||
# - -e when USE_EXTENSION_MANIFEST is set in moz.build
|
||||
#
|
||||
# The list given in JAR_MN_TARGETS corresponds to the list of `jar-%` targets
|
||||
# to be processed, with the `jar-` prefix stripped.
|
||||
# The Makefile is expected to specify the source jar manifest as a dependency
|
||||
# to each target. There is no expectation that the `jar-%` target name matches
|
||||
# the source file name in any way. For example:
|
||||
# JAR_MN_TARGETS = foo
|
||||
# jar-foo: /path/to/some/jar.mn
|
||||
# Additionally, extra defines can be specified for the processing of the jar
|
||||
# manifest by settig the `defines` variable specifically for the given target.
|
||||
# For example:
|
||||
# jar-foo: defines = -Dqux=foo
|
||||
# The default base path where files are going to be installed is `dist/bin`.
|
||||
# It is possible to use a different path by setting the `install_target`
|
||||
# variable. For example:
|
||||
# jar-foo: install_target = dist/bin/foo
|
||||
# When processing jar manifests, relative paths given inside a jar manifest
|
||||
# can be resolved from an object directory. The default path for that object
|
||||
# directory is the translation of the jar manifest directory path from the
|
||||
# source directory to the object directory. That is, for
|
||||
# $(TOPSRCDIR)/path/to/jar.mn, the default would be $(TOPOBJDIR)/path/to.
|
||||
# In case a different path must be used for the object directory, the `objdir`
|
||||
# variable can be set. For example:
|
||||
# jar-foo: objdir=/some/other/path
|
||||
jar-%: objdir ?= $(dir $(patsubst $(TOPSRCDIR)%,$(TOPOBJDIR)%,$<))
|
||||
jar-%: install_target ?= dist/bin
|
||||
jar-%:
|
||||
cd $(objdir) && \
|
||||
$(PYTHON) -m mozbuild.action.jar_maker \
|
||||
-j $(TOPOBJDIR)/$(install_target)/chrome \
|
||||
-t $(TOPSRCDIR) \
|
||||
-f $(MOZ_CHROME_FILE_FORMAT) \
|
||||
-c $(dir $<)/en-US \
|
||||
-DAB_CD=en-US \
|
||||
$(defines) \
|
||||
$(ACDEFINES) \
|
||||
$(MOZ_DEBUG_DEFINES) \
|
||||
$<
|
||||
|
||||
# Create some chrome manifests
|
||||
# This rule is forced to run every time because it may be updating files that
|
||||
# already exit.
|
||||
@@ -159,13 +114,6 @@ $(addprefix $(TOPOBJDIR)/,$(MANIFEST_TARGETS)): FORCE
|
||||
# Below is a set of additional dependencies and variables used to build things
|
||||
# that are not supported by data in moz.build.
|
||||
|
||||
# GENERATED_FILES are not supported yet, and even if they were, the
|
||||
# dependencies are missing information.
|
||||
$(foreach p,linux osx windows,jar-browser-themes-$(p)-jar.mn): \
|
||||
jar-browser-themes-%-jar.mn: \
|
||||
$(TOPOBJDIR)/browser/themes/%/tab-selected-end.svg \
|
||||
$(TOPOBJDIR)/browser/themes/%/tab-selected-start.svg
|
||||
|
||||
# Files to build with the recursive backend and simply copy
|
||||
$(TOPOBJDIR)/dist/bin/greprefs.js: $(TOPOBJDIR)/modules/libpref/greprefs.js
|
||||
$(TOPOBJDIR)/dist/bin/platform.ini: $(TOPOBJDIR)/toolkit/xre/platform.ini
|
||||
|
||||
@@ -1128,11 +1128,6 @@ ifneq (,$(DIST_SUBDIR)$(XPI_NAME))
|
||||
PREF_DIR = defaults/preferences
|
||||
endif
|
||||
|
||||
# on win32, pref files need CRLF line endings... see bug 206029
|
||||
ifeq (WINNT,$(OS_ARCH))
|
||||
PREF_PPFLAGS += --line-endings=crlf
|
||||
endif
|
||||
|
||||
ifneq ($(PREF_JS_EXPORTS),)
|
||||
ifndef NO_DIST_INSTALL
|
||||
PREF_JS_EXPORTS_PATH := $(FINAL_TARGET)/$(PREF_DIR)
|
||||
|
||||
@@ -101,7 +101,7 @@ function CreateListIterator(array) {
|
||||
ThrowTypeError(JSMSG_INCOMPATIBLE_METHOD, "next", "method", ToString(this));
|
||||
|
||||
let array = UnsafeGetObjectFromReservedSlot(this, ITERATOR_SLOT_TARGET);
|
||||
let index = UnsafeGetInt32FromReservedSlot(this, ITERATOR_SLOT_NEXT_INDEX);
|
||||
let index = UnsafeGetReservedSlot(this, ITERATOR_SLOT_NEXT_INDEX);
|
||||
|
||||
if (index >= ToLength(array.length)) {
|
||||
UnsafeSetReservedSlot(this, ITERATOR_SLOT_NEXT_INDEX, 1/0);
|
||||
|
||||
@@ -18,23 +18,24 @@ function ModuleGetExportedNames(exportStarSet = [])
|
||||
return [];
|
||||
|
||||
// Step 3
|
||||
exportStarSet.push(module);
|
||||
_DefineDataProperty(exportStarSet, exportStarSet.length, module);
|
||||
|
||||
// Step 4
|
||||
let exportedNames = [];
|
||||
let namesCount = 0;
|
||||
|
||||
// Step 5
|
||||
let localExportEntries = module.localExportEntries;
|
||||
for (let i = 0; i < localExportEntries.length; i++) {
|
||||
let e = localExportEntries[i];
|
||||
exportedNames.push(e.exportName);
|
||||
_DefineDataProperty(exportedNames, namesCount++, e.exportName);
|
||||
}
|
||||
|
||||
// Step 6
|
||||
let indirectExportEntries = module.indirectExportEntries;
|
||||
for (let i = 0; i < indirectExportEntries.length; i++) {
|
||||
let e = indirectExportEntries[i];
|
||||
exportedNames.push(e.exportName);
|
||||
_DefineDataProperty(exportedNames, namesCount++, e.exportName);
|
||||
}
|
||||
|
||||
// Step 7
|
||||
@@ -46,7 +47,7 @@ function ModuleGetExportedNames(exportStarSet = [])
|
||||
for (let j = 0; j < starNames.length; j++) {
|
||||
let n = starNames[j];
|
||||
if (n !== "default" && !(n in exportedNames))
|
||||
exportedNames.push(n);
|
||||
_DefineDataProperty(exportedNames, namesCount++, n);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,7 +73,7 @@ function ModuleResolveExport(exportName, resolveSet = [], exportStarSet = [])
|
||||
}
|
||||
|
||||
// Step 3
|
||||
resolveSet.push({module: module, exportName: exportName});
|
||||
_DefineDataProperty(resolveSet, resolveSet.length, {module: module, exportName: exportName});
|
||||
|
||||
// Step 4
|
||||
let localExportEntries = module.localExportEntries;
|
||||
@@ -107,7 +108,7 @@ function ModuleResolveExport(exportName, resolveSet = [], exportStarSet = [])
|
||||
return null;
|
||||
|
||||
// Step 8
|
||||
exportStarSet.push(module);
|
||||
_DefineDataProperty(exportStarSet, exportStarSet.length, module);
|
||||
|
||||
// Step 9
|
||||
let starResolution = null;
|
||||
@@ -153,7 +154,7 @@ function GetModuleNamespace(module)
|
||||
if (resolution === null)
|
||||
ThrowSyntaxError(JSMSG_MISSING_NAMESPACE_EXPORT);
|
||||
if (resolution !== "ambiguous")
|
||||
unambiguousNames.push(name);
|
||||
_DefineDataProperty(unambiguousNames, unambiguousNames.length, name);
|
||||
}
|
||||
namespace = ModuleNamespaceCreate(module, unambiguousNames);
|
||||
}
|
||||
|
||||
@@ -574,7 +574,7 @@ ModuleObject::create(ExclusiveContext* cx, HandleObject enclosingStaticScope)
|
||||
ModuleObject::finalize(js::FreeOp* fop, JSObject* obj)
|
||||
{
|
||||
ModuleObject* self = &obj->as<ModuleObject>();
|
||||
if (!self->getReservedSlot(ImportBindingsSlot).isUndefined())
|
||||
if (self->hasImportBindings())
|
||||
fop->delete_(&self->importBindings());
|
||||
if (IndirectBindingMap* bindings = self->namespaceBindings())
|
||||
fop->delete_(bindings);
|
||||
@@ -592,6 +592,13 @@ ModuleObject::environment() const
|
||||
return &value.toObject().as<ModuleEnvironmentObject>();
|
||||
}
|
||||
|
||||
bool
|
||||
ModuleObject::hasImportBindings() const
|
||||
{
|
||||
// Import bindings may not be present if we hit OOM in initialization.
|
||||
return !getReservedSlot(ImportBindingsSlot).isUndefined();
|
||||
}
|
||||
|
||||
IndirectBindingMap&
|
||||
ModuleObject::importBindings()
|
||||
{
|
||||
@@ -719,7 +726,8 @@ ModuleObject::trace(JSTracer* trc, JSObject* obj)
|
||||
module.setReservedSlot(ScriptSlot, PrivateValue(script));
|
||||
}
|
||||
|
||||
TraceBindings(trc, module.importBindings());
|
||||
if (module.hasImportBindings())
|
||||
TraceBindings(trc, module.importBindings());
|
||||
if (IndirectBindingMap* bindings = module.namespaceBindings())
|
||||
TraceBindings(trc, *bindings);
|
||||
|
||||
@@ -785,7 +793,10 @@ ModuleObject::evaluate(JSContext* cx, HandleModuleObject self, MutableHandleValu
|
||||
{
|
||||
RootedScript script(cx, self->script());
|
||||
RootedModuleEnvironmentObject scope(cx, self->environment());
|
||||
MOZ_ASSERT(scope);
|
||||
if (!scope) {
|
||||
JS_ReportError(cx, "Module declarations have not yet been instantiated");
|
||||
return false;
|
||||
}
|
||||
|
||||
return Execute(cx, script, *scope, rval.address());
|
||||
}
|
||||
|
||||
@@ -223,6 +223,7 @@ class ModuleObject : public NativeObject
|
||||
static void finalize(js::FreeOp* fop, JSObject* obj);
|
||||
|
||||
bool hasScript() const;
|
||||
bool hasImportBindings() const;
|
||||
FunctionDeclarationVector* functionDeclarations();
|
||||
};
|
||||
|
||||
|
||||
@@ -1005,8 +1005,6 @@ static const JSFunctionSpec object_static_methods[] = {
|
||||
JS_FN("setPrototypeOf", obj_setPrototypeOf, 2, 0),
|
||||
JS_FN("getOwnPropertyDescriptor", obj_getOwnPropertyDescriptor,2, 0),
|
||||
JS_FN("keys", obj_keys, 1, 0),
|
||||
JS_SELF_HOSTED_FN("values", "ObjectValues", 1, JSPROP_DEFINE_LATE),
|
||||
JS_SELF_HOSTED_FN("entries", "ObjectEntries", 1, JSPROP_DEFINE_LATE),
|
||||
JS_FN("is", obj_is, 2, 0),
|
||||
JS_FN("defineProperty", obj_defineProperty, 3, 0),
|
||||
JS_FN("defineProperties", obj_defineProperties, 2, 0),
|
||||
|
||||
@@ -134,54 +134,3 @@ function ObjectLookupGetter(name) {
|
||||
} while (object !== null);
|
||||
}
|
||||
|
||||
// Draft proposal http://tc39.github.io/proposal-object-values-entries/#Object.values
|
||||
function ObjectValues(O) {
|
||||
// Until https://bugzilla.mozilla.org/show_bug.cgi?id=1170372 implemented
|
||||
var attrs = ATTR_CONFIGURABLE | ATTR_ENUMERABLE | ATTR_WRITABLE;
|
||||
|
||||
// Steps 1-2.
|
||||
var object = ToObject(O);
|
||||
|
||||
// Steps 3-4.
|
||||
// EnumerableOwnProperties is inlined here.
|
||||
var keys = OwnPropertyKeys(object, JSITER_OWNONLY | JSITER_HIDDEN);
|
||||
var values = [];
|
||||
var valuesCount = 0;
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
var key = keys[i];
|
||||
if (!callFunction(std_Object_propertyIsEnumerable, object, key))
|
||||
continue;
|
||||
|
||||
var value = object[key];
|
||||
_DefineDataProperty(values, valuesCount++, value, attrs);
|
||||
}
|
||||
|
||||
// Step 5.
|
||||
return values;
|
||||
}
|
||||
|
||||
// Draft proposal http://tc39.github.io/proposal-object-values-entries/#Object.entries
|
||||
function ObjectEntries(O) {
|
||||
// Until https://bugzilla.mozilla.org/show_bug.cgi?id=1170372 implemented
|
||||
var attrs = ATTR_CONFIGURABLE | ATTR_ENUMERABLE | ATTR_WRITABLE;
|
||||
|
||||
// Steps 1-2.
|
||||
var object = ToObject(O);
|
||||
|
||||
// Steps 3-4.
|
||||
// EnumerableOwnProperties is inlined here.
|
||||
var keys = OwnPropertyKeys(object, JSITER_OWNONLY | JSITER_HIDDEN);
|
||||
var entries = [];
|
||||
var entriesCount = 0;
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
var key = keys[i];
|
||||
if (!callFunction(std_Object_propertyIsEnumerable, object, key))
|
||||
continue;
|
||||
|
||||
var value = object[key];
|
||||
_DefineDataProperty(entries, entriesCount++, [key, value], attrs);
|
||||
}
|
||||
|
||||
// Step 5.
|
||||
return entries;
|
||||
}
|
||||
|
||||
+161
-168
@@ -140,11 +140,13 @@ js::ExecuteRegExpLegacy(JSContext* cx, RegExpStatics* res, RegExpObject& reobj,
|
||||
return CreateRegExpMatchResult(cx, input, matches, rval);
|
||||
}
|
||||
|
||||
/* ES6 draft rc4 21.2.3.2.2. */
|
||||
bool
|
||||
RegExpInitialize(JSContext* cx, RegExpObjectBuilder& builder,
|
||||
HandleValue patternValue, HandleValue flagsValue,
|
||||
RegExpStaticsUse staticsUse, MutableHandleObject result)
|
||||
/*
|
||||
* ES6 21.2.3.2.2. Because this function only ever returns |obj| in the spec,
|
||||
* provided by the user, we omit it and just return the usual success/failure.
|
||||
*/
|
||||
static bool
|
||||
RegExpInitialize(JSContext* cx, Handle<RegExpObject*> obj, HandleValue patternValue,
|
||||
HandleValue flagsValue, RegExpStaticsUse staticsUse)
|
||||
{
|
||||
RootedAtom pattern(cx);
|
||||
if (patternValue.isUndefined()) {
|
||||
@@ -183,148 +185,10 @@ RegExpInitialize(JSContext* cx, RegExpObjectBuilder& builder,
|
||||
}
|
||||
|
||||
/* Steps 11-15. */
|
||||
RootedObject reobj(cx, builder.build(pattern, flags));
|
||||
if (!reobj)
|
||||
if (!InitializeRegExp(cx, obj, pattern, flags))
|
||||
return false;
|
||||
|
||||
/* Step 16. */
|
||||
result.set(reobj);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* ES6 draft rc4 21.2.3.1 steps 5-10.
|
||||
* ES6 draft rc4 B.2.5.1 steps 3-5.
|
||||
* Compile a new |RegExpShared| for the |RegExpObject|.
|
||||
*/
|
||||
static bool
|
||||
CompileRegExpObject(JSContext* cx, RegExpObjectBuilder& builder, const CallArgs& args,
|
||||
RegExpCreationMode creationMode, bool patternIsRegExp=false)
|
||||
{
|
||||
if (args.length() == 0) {
|
||||
/*
|
||||
* 21.2.3.1 step 10.
|
||||
* B.2.5.1 step 5.
|
||||
*/
|
||||
RegExpStatics* res = cx->global()->getRegExpStatics(cx);
|
||||
if (!res)
|
||||
return false;
|
||||
|
||||
RootedAtom empty(cx, cx->runtime()->emptyString);
|
||||
RegExpObject* reobj = builder.build(empty, res->getFlags());
|
||||
if (!reobj)
|
||||
return false;
|
||||
|
||||
args.rval().setObject(*reobj);
|
||||
return true;
|
||||
}
|
||||
|
||||
RootedValue patternValue(cx, args.get(0));
|
||||
|
||||
/*
|
||||
* 21.2.3.1 step 5
|
||||
* B.2.5.1 step 3.
|
||||
*/
|
||||
ESClassValue cls;
|
||||
if (!GetClassOfValue(cx, patternValue, &cls))
|
||||
return false;
|
||||
if (cls == ESClass_RegExp) {
|
||||
/*
|
||||
* B.2.5.1 step 3.a.
|
||||
*/
|
||||
if (args.hasDefined(1) && creationMode == CreateForCompile) {
|
||||
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_NEWREGEXP_FLAGGED);
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Beware, patternObj may be a (transparent) proxy to a RegExp, so only
|
||||
* use generic (proxyable) operations on patternObj that do not assume
|
||||
* patternObj.is<RegExpObject>().
|
||||
*/
|
||||
RootedObject patternObj(cx, &patternValue.toObject());
|
||||
|
||||
RootedAtom sourceAtom(cx);
|
||||
RegExpFlag flags;
|
||||
{
|
||||
/*
|
||||
* 21.2.3.1 step 5.a.
|
||||
* B.2.5.1 step 3.a.
|
||||
* Extract the 'source' from patternObj; do not reuse the
|
||||
* RegExpShared since it may be from a different compartment.
|
||||
*/
|
||||
RegExpGuard g(cx);
|
||||
if (!RegExpToShared(cx, patternObj, &g))
|
||||
return false;
|
||||
sourceAtom = g->getSource();
|
||||
|
||||
if (args.hasDefined(1)) {
|
||||
/* 21.2.3.1 step 5.c. */
|
||||
flags = RegExpFlag(0);
|
||||
RootedString flagStr(cx, ToString<CanGC>(cx, args[1]));
|
||||
if (!flagStr)
|
||||
return false;
|
||||
if (!ParseRegExpFlags(cx, flagStr, &flags))
|
||||
return false;
|
||||
} else {
|
||||
/*
|
||||
* 21.2.3.1 step 5.b.
|
||||
* B.2.5.1 step 3.c.
|
||||
*/
|
||||
flags = g->getFlags();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 21.2.3.1 steps 8-10.
|
||||
* B.2.5.1 step 5.
|
||||
*/
|
||||
RegExpObject* reobj = builder.build(sourceAtom, flags);
|
||||
if (!reobj)
|
||||
return false;
|
||||
|
||||
args.rval().setObject(*reobj);
|
||||
return true;
|
||||
}
|
||||
|
||||
RootedValue P(cx);
|
||||
RootedValue F(cx);
|
||||
/* 21.2.3.1 step 6. */
|
||||
if (patternIsRegExp) {
|
||||
MOZ_ASSERT(creationMode == CreateForConstruct);
|
||||
RootedObject patternObj(cx, &patternValue.toObject());
|
||||
|
||||
/* 21.2.3.1 steps 6.a-b. */
|
||||
if (!GetProperty(cx, patternObj, patternObj, cx->names().source, &P))
|
||||
return false;
|
||||
|
||||
/* 21.2.3.1 step 6.c. */
|
||||
if (!args.hasDefined(1)) {
|
||||
/* 21.2.3.1 steps 6.c.i-ii. */
|
||||
if (!GetProperty(cx, patternObj, patternObj, cx->names().flags, &F))
|
||||
return false;
|
||||
} else {
|
||||
/* 21.2.3.1 steps 6.d. */
|
||||
F = args[1];
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* 21.2.3.1 steps 7.a-b.
|
||||
* B.2.5.1 steps 4.a-b.
|
||||
*/
|
||||
P = patternValue;
|
||||
F = args.get(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* 21.2.3.1 steps 8-10.
|
||||
* B.2.5.1 step 5.
|
||||
*/
|
||||
RootedObject reobj(cx);
|
||||
if (!RegExpInitialize(cx, builder, P, F, UseRegExpStatics, &reobj))
|
||||
return false;
|
||||
|
||||
args.rval().setObject(*reobj);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -366,15 +230,61 @@ js::IsRegExp(JSContext* cx, HandleValue value, bool* result)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ES6 draft rc4 B.2.5.1. */
|
||||
/* ES6 B.2.5.1. */
|
||||
MOZ_ALWAYS_INLINE bool
|
||||
regexp_compile_impl(JSContext* cx, const CallArgs& args)
|
||||
{
|
||||
MOZ_ASSERT(IsRegExpObject(args.thisv()));
|
||||
|
||||
/* Steps 3-5. */
|
||||
RegExpObjectBuilder builder(cx, &args.thisv().toObject().as<RegExpObject>());
|
||||
return CompileRegExpObject(cx, builder, args, CreateForCompile);
|
||||
Rooted<RegExpObject*> regexp(cx, &args.thisv().toObject().as<RegExpObject>());
|
||||
|
||||
// Step 3.
|
||||
RootedValue patternValue(cx, args.get(0));
|
||||
ESClassValue cls;
|
||||
if (!GetClassOfValue(cx, patternValue, &cls))
|
||||
return false;
|
||||
if (cls == ESClass_RegExp) {
|
||||
// Step 3a.
|
||||
if (args.hasDefined(1)) {
|
||||
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_NEWREGEXP_FLAGGED);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Beware! |patternObj| might be a proxy into another compartment, so
|
||||
// don't assume |patternObj.is<RegExpObject>()|. For the same reason,
|
||||
// don't reuse the RegExpShared below.
|
||||
RootedObject patternObj(cx, &patternValue.toObject());
|
||||
|
||||
RootedAtom sourceAtom(cx);
|
||||
RegExpFlag flags;
|
||||
{
|
||||
// Step 3b.
|
||||
RegExpGuard g(cx);
|
||||
if (!RegExpToShared(cx, patternObj, &g))
|
||||
return false;
|
||||
|
||||
sourceAtom = g->getSource();
|
||||
flags = g->getFlags();
|
||||
}
|
||||
|
||||
// Step 5.
|
||||
if (!InitializeRegExp(cx, regexp, sourceAtom, flags))
|
||||
return false;
|
||||
|
||||
args.rval().setObject(*regexp);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Step 4.
|
||||
RootedValue P(cx, patternValue);
|
||||
RootedValue F(cx, args.get(1));
|
||||
|
||||
// Step 5.
|
||||
if (!RegExpInitialize(cx, regexp, P, F, UseRegExpStatics))
|
||||
return false;
|
||||
|
||||
args.rval().setObject(*regexp);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
@@ -386,29 +296,32 @@ regexp_compile(JSContext* cx, unsigned argc, Value* vp)
|
||||
return CallNonGenericMethod<IsRegExpObject, regexp_compile_impl>(cx, args);
|
||||
}
|
||||
|
||||
/* ES6 draft rc4 21.2.3.1. */
|
||||
/* ES6 21.2.3.1. */
|
||||
bool
|
||||
js::regexp_construct(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
/* Steps 1-2. */
|
||||
// Steps 1-2.
|
||||
bool patternIsRegExp;
|
||||
if (!IsRegExp(cx, args.get(0), &patternIsRegExp))
|
||||
return false;
|
||||
|
||||
/* Step 4. */
|
||||
if (!args.isConstructing()) {
|
||||
/* Step 4.b. */
|
||||
if (args.isConstructing()) {
|
||||
// XXX Step 3!
|
||||
} else {
|
||||
// XXX Step 4a
|
||||
|
||||
// Step 4b.
|
||||
if (patternIsRegExp && !args.hasDefined(1)) {
|
||||
RootedObject patternObj(cx, &args[0].toObject());
|
||||
|
||||
/* Steps 4.b.i-ii. */
|
||||
// Steps 4b.i-ii.
|
||||
RootedValue patternConstructor(cx);
|
||||
if (!GetProperty(cx, patternObj, patternObj, cx->names().constructor, &patternConstructor))
|
||||
return false;
|
||||
|
||||
/* Step 4.b.iii. */
|
||||
// Step 4b.iii.
|
||||
if (patternConstructor.isObject() && patternConstructor.toObject() == args.callee()) {
|
||||
args.rval().set(args[0]);
|
||||
return true;
|
||||
@@ -416,9 +329,91 @@ js::regexp_construct(JSContext* cx, unsigned argc, Value* vp)
|
||||
}
|
||||
}
|
||||
|
||||
/* Steps 5-10. */
|
||||
RegExpObjectBuilder builder(cx);
|
||||
return CompileRegExpObject(cx, builder, args, CreateForConstruct, patternIsRegExp);
|
||||
RootedValue patternValue(cx, args.get(0));
|
||||
|
||||
// Step 5.
|
||||
ESClassValue cls;
|
||||
if (!GetClassOfValue(cx, patternValue, &cls))
|
||||
return false;
|
||||
if (cls == ESClass_RegExp) {
|
||||
// Beware! |patternObj| might be a proxy into another compartment, so
|
||||
// don't assume |patternObj.is<RegExpObject>()|. For the same reason,
|
||||
// don't reuse the RegExpShared below.
|
||||
RootedObject patternObj(cx, &patternValue.toObject());
|
||||
|
||||
RootedAtom sourceAtom(cx);
|
||||
RegExpFlag flags;
|
||||
{
|
||||
// Step 5.a.
|
||||
RegExpGuard g(cx);
|
||||
if (!RegExpToShared(cx, patternObj, &g))
|
||||
return false;
|
||||
sourceAtom = g->getSource();
|
||||
|
||||
if (!args.hasDefined(1)) {
|
||||
// Step 5b.
|
||||
flags = g->getFlags();
|
||||
} else {
|
||||
// Step 5c.
|
||||
// XXX We shouldn't be converting to string yet! This must
|
||||
// come *after* the .constructor access in step 8.
|
||||
flags = RegExpFlag(0);
|
||||
RootedString flagStr(cx, ToString<CanGC>(cx, args[1]));
|
||||
if (!flagStr)
|
||||
return false;
|
||||
if (!ParseRegExpFlags(cx, flagStr, &flags))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Steps 8-9.
|
||||
// XXX Note bug in step 5c, with respect to step 8.
|
||||
Rooted<RegExpObject*> regexp(cx, RegExpAlloc(cx));
|
||||
if (!regexp)
|
||||
return false;
|
||||
|
||||
// Step 10.
|
||||
if (!InitializeRegExp(cx, regexp, sourceAtom, flags))
|
||||
return false;
|
||||
|
||||
args.rval().setObject(*regexp);
|
||||
return true;
|
||||
}
|
||||
|
||||
RootedValue P(cx);
|
||||
RootedValue F(cx);
|
||||
|
||||
// Step 6.
|
||||
if (patternIsRegExp) {
|
||||
RootedObject patternObj(cx, &patternValue.toObject());
|
||||
|
||||
// Steps 6a-b.
|
||||
if (!GetProperty(cx, patternObj, patternObj, cx->names().source, &P))
|
||||
return false;
|
||||
|
||||
// Steps 6c-d.
|
||||
F = args.get(1);
|
||||
if (F.isUndefined()) {
|
||||
if (!GetProperty(cx, patternObj, patternObj, cx->names().flags, &F))
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// Steps 7a-b.
|
||||
P = patternValue;
|
||||
F = args.get(1);
|
||||
}
|
||||
|
||||
// Steps 8-9.
|
||||
Rooted<RegExpObject*> regexp(cx, RegExpAlloc(cx));
|
||||
if (!regexp)
|
||||
return false;
|
||||
|
||||
// Step 10.
|
||||
if (!RegExpInitialize(cx, regexp, P, F, UseRegExpStatics))
|
||||
return false;
|
||||
|
||||
args.rval().setObject(*regexp);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -434,12 +429,14 @@ js::regexp_construct_no_statics(JSContext* cx, unsigned argc, Value* vp)
|
||||
/* Steps 1-6 are not required since pattern is always string. */
|
||||
|
||||
/* Steps 7-10. */
|
||||
RegExpObjectBuilder builder(cx);
|
||||
RootedObject reobj(cx);
|
||||
if (!RegExpInitialize(cx, builder, args[0], args.get(1), DontUseRegExpStatics, &reobj))
|
||||
Rooted<RegExpObject*> regexp(cx, RegExpAlloc(cx));
|
||||
if (!regexp)
|
||||
return false;
|
||||
|
||||
args.rval().setObject(*reobj);
|
||||
if (!RegExpInitialize(cx, regexp, args[0], args.get(1), DontUseRegExpStatics))
|
||||
return false;
|
||||
|
||||
args.rval().setObject(*regexp);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -703,12 +700,8 @@ js::CreateRegExpPrototype(JSContext* cx, JSProtoKey key)
|
||||
return nullptr;
|
||||
proto->NativeObject::setPrivate(nullptr);
|
||||
|
||||
HandlePropertyName empty = cx->names().empty;
|
||||
RegExpObjectBuilder builder(cx, proto);
|
||||
if (!builder.build(empty, RegExpFlag(0)))
|
||||
return nullptr;
|
||||
|
||||
return proto;
|
||||
RootedAtom source(cx, cx->names().empty);
|
||||
return InitializeRegExp(cx, proto, source, RegExpFlag(0));
|
||||
}
|
||||
|
||||
static bool
|
||||
|
||||
@@ -26,9 +26,6 @@ enum RegExpStaticsUpdate { UpdateRegExpStatics, DontUpdateRegExpStatics };
|
||||
// Whether RegExp statics should be used to create a RegExp instance.
|
||||
enum RegExpStaticsUse { UseRegExpStatics, DontUseRegExpStatics };
|
||||
|
||||
// This enum is used to indicate whether 'CompileRegExpObject' is called from 'regexp_compile'.
|
||||
enum RegExpCreationMode { CreateForCompile, CreateForConstruct };
|
||||
|
||||
RegExpRunStatus
|
||||
ExecuteRegExp(JSContext* cx, HandleObject regexp, HandleString string,
|
||||
MatchPairs* matches, RegExpStaticsUpdate staticsUpdate);
|
||||
@@ -99,8 +96,6 @@ IsRegExp(JSContext* cx, HandleValue value, bool* result);
|
||||
// RegExp ClassSpec members used in RegExpObject.cpp.
|
||||
extern bool
|
||||
regexp_construct(JSContext* cx, unsigned argc, Value* vp);
|
||||
extern JSObject*
|
||||
CreateRegExpPrototype(JSContext* cx, JSProtoKey key);
|
||||
extern const JSPropertySpec regexp_static_props[];
|
||||
extern const JSPropertySpec regexp_properties[];
|
||||
extern const JSFunctionSpec regexp_methods[];
|
||||
|
||||
@@ -53,6 +53,25 @@ static bool fuzzingSafe = false;
|
||||
// OOM conditions.
|
||||
static bool disableOOMFunctions = false;
|
||||
|
||||
static bool
|
||||
EnvVarIsDefined(const char* name)
|
||||
{
|
||||
const char* value = getenv(name);
|
||||
return value && *value;
|
||||
}
|
||||
|
||||
#if defined(DEBUG) || defined(JS_OOM_BREAKPOINT)
|
||||
static bool
|
||||
EnvVarAsInt(const char* name, int* valueOut)
|
||||
{
|
||||
if (!EnvVarIsDefined(name))
|
||||
return false;
|
||||
|
||||
*valueOut = atoi(getenv(name));
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool
|
||||
GetBuildConfiguration(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
@@ -1062,6 +1081,93 @@ ResetOOMFailure(JSContext* cx, unsigned argc, Value* vp)
|
||||
OOM_maxAllocations = UINT32_MAX;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
OOMTest(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
if (args.length() != 1 || !args[0].isObject() || !args[0].toObject().is<JSFunction>()) {
|
||||
JS_ReportError(cx, "oomTest() takes a single function argument.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (disableOOMFunctions) {
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
}
|
||||
|
||||
RootedFunction function(cx, &args[0].toObject().as<JSFunction>());
|
||||
|
||||
bool verbose = EnvVarIsDefined("OOM_VERBOSE");
|
||||
|
||||
unsigned threadStart = oom::THREAD_TYPE_MAIN;
|
||||
unsigned threadEnd = oom::THREAD_TYPE_MAX;
|
||||
|
||||
// Test a single thread type if specified by the OOM_THREAD environment variable.
|
||||
int threadOption = 0;
|
||||
if (EnvVarAsInt("OOM_THREAD", &threadOption)) {
|
||||
if (threadOption < oom::THREAD_TYPE_MAIN || threadOption > oom::THREAD_TYPE_MAX) {
|
||||
JS_ReportError(cx, "OOM_THREAD value out of range.");
|
||||
return false;
|
||||
}
|
||||
|
||||
threadStart = threadOption;
|
||||
threadEnd = threadOption + 1;
|
||||
}
|
||||
|
||||
JS_SetGCZeal(cx, 0, JS_DEFAULT_ZEAL_FREQ);
|
||||
|
||||
for (unsigned thread = threadStart; thread < threadEnd; thread++) {
|
||||
if (verbose)
|
||||
fprintf(stderr, "thread %d\n", thread);
|
||||
|
||||
HelperThreadState().waitForAllThreads();
|
||||
js::oom::targetThread = thread;
|
||||
|
||||
unsigned allocation = 1;
|
||||
bool handledOOM;
|
||||
do {
|
||||
if (verbose)
|
||||
fprintf(stderr, " allocation %d\n", allocation);
|
||||
|
||||
MOZ_ASSERT(!cx->isExceptionPending());
|
||||
MOZ_ASSERT(!cx->runtime()->hadOutOfMemory);
|
||||
|
||||
OOM_maxAllocations = OOM_counter + allocation;
|
||||
OOM_failAlways = false;
|
||||
|
||||
RootedValue result(cx);
|
||||
bool ok = JS_CallFunction(cx, cx->global(), function,
|
||||
HandleValueArray::empty(), &result);
|
||||
|
||||
handledOOM = OOM_counter >= OOM_maxAllocations;
|
||||
OOM_maxAllocations = UINT32_MAX;
|
||||
|
||||
MOZ_ASSERT_IF(ok, !cx->isExceptionPending());
|
||||
MOZ_ASSERT_IF(!ok, cx->isExceptionPending());
|
||||
|
||||
// Note that it is possible that the function throws an exception
|
||||
// unconnected to OOM, in which case we ignore it. More correct
|
||||
// would be to have the caller pass some kind of exception
|
||||
// specification and to check the exception against it.
|
||||
|
||||
cx->clearPendingException();
|
||||
cx->runtime()->hadOutOfMemory = false;
|
||||
|
||||
allocation++;
|
||||
} while (handledOOM);
|
||||
|
||||
if (verbose) {
|
||||
fprintf(stderr, " finished after %d allocations\n", allocation - 2);
|
||||
}
|
||||
}
|
||||
|
||||
js::oom::targetThread = js::oom::THREAD_TYPE_NONE;
|
||||
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
static const js::Class FakePromiseClass = {
|
||||
@@ -3034,6 +3140,12 @@ static const JSFunctionSpecWithHelp TestingFunctions[] = {
|
||||
"resetOOMFailure()",
|
||||
" Remove the allocation failure scheduled by either oomAfterAllocations() or\n"
|
||||
" oomAtAllocation() and return whether any allocation had been caused to fail."),
|
||||
|
||||
JS_FN_HELP("oomTest", OOMTest, 0, 0,
|
||||
"oomTest(function)",
|
||||
" Test that the passed function behaves correctly under OOM conditions by\n"
|
||||
" repeatedly executing it and simulating allocation failure at successive\n"
|
||||
" allocations until the function completes without seeing a failure."),
|
||||
#endif
|
||||
|
||||
JS_FN_HELP("makeFakePromise", MakeFakePromise, 0, 0,
|
||||
@@ -3432,7 +3544,7 @@ js::DefineTestingFunctions(JSContext* cx, HandleObject obj, bool fuzzingSafe_,
|
||||
bool disableOOMFunctions_)
|
||||
{
|
||||
fuzzingSafe = fuzzingSafe_;
|
||||
if (getenv("MOZ_FUZZING_SAFE") && getenv("MOZ_FUZZING_SAFE")[0] != '0')
|
||||
if (EnvVarIsDefined("MOZ_FUZZING_SAFE"))
|
||||
fuzzingSafe = true;
|
||||
|
||||
disableOOMFunctions = disableOOMFunctions_;
|
||||
|
||||
@@ -3191,7 +3191,11 @@ BytecodeEmitter::emitSwitch(ParseNode* pn)
|
||||
/* Emit code for evaluating cases and jumping to case statements. */
|
||||
for (ParseNode* caseNode = cases->pn_head; caseNode; caseNode = caseNode->pn_next) {
|
||||
ParseNode* caseValue = caseNode->pn_left;
|
||||
if (caseValue && !emitTree(caseValue))
|
||||
// If the expression is a literal, suppress line number
|
||||
// emission so that debugging works more naturally.
|
||||
if (caseValue &&
|
||||
!emitTree(caseValue, caseValue->isLiteral() ? SUPPRESS_LINENOTE :
|
||||
EMIT_LINENOTE))
|
||||
return false;
|
||||
if (!beforeCases) {
|
||||
/* prevCaseOffset is the previous JSOP_CASE's bytecode offset. */
|
||||
@@ -5770,14 +5774,17 @@ BytecodeEmitter::emitCStyleFor(ParseNode* pn, ptrdiff_t top)
|
||||
bool
|
||||
BytecodeEmitter::emitFor(ParseNode* pn, ptrdiff_t top)
|
||||
{
|
||||
if (pn->pn_left->isKind(PNK_FORHEAD))
|
||||
return emitCStyleFor(pn, top);
|
||||
|
||||
if (!updateLineNumberNotes(pn->pn_pos.begin))
|
||||
return false;
|
||||
|
||||
if (pn->pn_left->isKind(PNK_FORIN))
|
||||
return emitForIn(pn, top);
|
||||
|
||||
if (pn->pn_left->isKind(PNK_FOROF))
|
||||
return emitForOf(StmtType::FOR_OF_LOOP, pn, top);
|
||||
|
||||
MOZ_ASSERT(pn->pn_left->isKind(PNK_FORHEAD));
|
||||
return emitCStyleFor(pn, top);
|
||||
MOZ_ASSERT(pn->pn_left->isKind(PNK_FOROF));
|
||||
return emitForOf(StmtType::FOR_OF_LOOP, pn, top);
|
||||
}
|
||||
|
||||
MOZ_NEVER_INLINE bool
|
||||
@@ -6021,6 +6028,20 @@ BytecodeEmitter::emitWhile(ParseNode* pn, ptrdiff_t top)
|
||||
* . . .
|
||||
* N N*(ifeq-fail; goto); ifeq-pass goto; N*ifne-pass; ifne-fail
|
||||
*/
|
||||
|
||||
// If we have a single-line while, like "while (x) ;", we want to
|
||||
// emit the line note before the initial goto, so that the
|
||||
// debugger sees a single entry point. This way, if there is a
|
||||
// breakpoint on the line, it will only fire once; and "next"ing
|
||||
// will skip the whole loop. However, for the multi-line case we
|
||||
// want to emit the line note after the initial goto, so that
|
||||
// "cont" stops on each iteration -- but without a stop before the
|
||||
// first iteration.
|
||||
if (parser->tokenStream.srcCoords.lineNum(pn->pn_pos.begin) ==
|
||||
parser->tokenStream.srcCoords.lineNum(pn->pn_pos.end) &&
|
||||
!updateSourceCoordNotes(pn->pn_pos.begin))
|
||||
return false;
|
||||
|
||||
LoopStmtInfo stmtInfo(cx);
|
||||
pushLoopStatement(&stmtInfo, StmtType::WHILE_LOOP, top);
|
||||
|
||||
@@ -7552,7 +7573,7 @@ BytecodeEmitter::emitClass(ParseNode* pn)
|
||||
}
|
||||
|
||||
bool
|
||||
BytecodeEmitter::emitTree(ParseNode* pn)
|
||||
BytecodeEmitter::emitTree(ParseNode* pn, EmitLineNumberNote emitLineNote)
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
|
||||
@@ -7562,8 +7583,11 @@ BytecodeEmitter::emitTree(ParseNode* pn)
|
||||
ptrdiff_t top = offset();
|
||||
pn->pn_offset = top;
|
||||
|
||||
/* Emit notes to tell the current bytecode's source line number. */
|
||||
if (!updateLineNumberNotes(pn->pn_pos.begin))
|
||||
/* Emit notes to tell the current bytecode's source line number.
|
||||
However, a couple trees require special treatment; see the
|
||||
relevant emitter functions for details. */
|
||||
if (emitLineNote == EMIT_LINENOTE && pn->getKind() != PNK_WHILE && pn->getKind() != PNK_FOR &&
|
||||
!updateLineNumberNotes(pn->pn_pos.begin))
|
||||
return false;
|
||||
|
||||
switch (pn->getKind()) {
|
||||
|
||||
@@ -336,8 +336,14 @@ struct BytecodeEmitter
|
||||
|
||||
void setJumpOffsetAt(ptrdiff_t off);
|
||||
|
||||
// Control whether emitTree emits a line number note.
|
||||
enum EmitLineNumberNote {
|
||||
EMIT_LINENOTE,
|
||||
SUPPRESS_LINENOTE
|
||||
};
|
||||
|
||||
// Emit code for the tree rooted at pn.
|
||||
bool emitTree(ParseNode* pn);
|
||||
bool emitTree(ParseNode* pn, EmitLineNumberNote emitLineNote = EMIT_LINENOTE);
|
||||
|
||||
// Emit function code for the tree rooted at body.
|
||||
bool emitFunctionScript(ParseNode* body);
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
// Function to test OOM handling by repeatedly calling a function and failing
|
||||
// successive allocations.
|
||||
|
||||
if (!("oomAtAllocation" in this && "resetOOMFailure" in this && "oomThreadTypes" in this))
|
||||
quit();
|
||||
|
||||
if ("gczeal" in this)
|
||||
gczeal(0);
|
||||
|
||||
const verbose = ("os" in this) && os.getenv("OOM_VERBOSE");
|
||||
|
||||
// Test out of memory handing by calling a function f() while causing successive
|
||||
// memory allocations to fail. Repeat until f() finishes without reaching the
|
||||
// failing allocation.
|
||||
function oomTest(f) {
|
||||
for (let thread = 1; thread < oomThreadTypes(); thread++) {
|
||||
if (verbose)
|
||||
print("testing thread " + thread);
|
||||
|
||||
var i = 1;
|
||||
var more;
|
||||
do {
|
||||
if (verbose)
|
||||
print("fail at " + i);
|
||||
try {
|
||||
oomAtAllocation(i, thread);
|
||||
f();
|
||||
more = resetOOMFailure();
|
||||
} catch (e) {
|
||||
// Ignore exceptions.
|
||||
more = resetOOMFailure();
|
||||
}
|
||||
i++;
|
||||
} while(more);
|
||||
|
||||
if (verbose)
|
||||
print("finished after " + (i - 2) + " failures");
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// |jit-test| allow-oom
|
||||
// |jit-test| allow-oom; allow-unhandlable-oom
|
||||
gcparam("maxBytes", gcparam("gcBytes") + 4*1024);
|
||||
var max = 400;
|
||||
function f(b) {
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
iter = getSelfHostedValue("CreateListIterator")([]);
|
||||
iter.next();
|
||||
iter.next();
|
||||
@@ -0,0 +1,7 @@
|
||||
oomTest(() => {
|
||||
var g = newGlobal();
|
||||
g.eval("\
|
||||
function f(){}; \
|
||||
getLcovInfo(); \
|
||||
");
|
||||
});
|
||||
@@ -0,0 +1,46 @@
|
||||
// Test how stepping interacts with switch statements.
|
||||
|
||||
var g = newGlobal();
|
||||
|
||||
g.eval('function bob() { return "bob"; }');
|
||||
|
||||
// Stepping into a sparse switch should not stop on literal cases.
|
||||
evaluate(`function lit(x) { // 1
|
||||
debugger; // 2
|
||||
switch(x) { // 3
|
||||
case "nope": // 4
|
||||
break; // 5
|
||||
case "bob": // 6
|
||||
break; // 7
|
||||
} // 8
|
||||
}`, {lineNumber: 1, global: g});
|
||||
|
||||
// Stepping into a sparse switch should stop on non-literal cases.
|
||||
evaluate(`function nonlit(x) { // 1
|
||||
debugger; // 2
|
||||
switch(x) { // 3
|
||||
case bob(): // 4
|
||||
break; // 5
|
||||
} // 6
|
||||
}`, {lineNumber: 1, global: g});
|
||||
|
||||
var dbg = Debugger(g);
|
||||
var badStep = false;
|
||||
|
||||
function test(s, okLine) {
|
||||
dbg.onDebuggerStatement = function(frame) {
|
||||
frame.onStep = function() {
|
||||
let thisLine = this.script.getOffsetLocation(this.offset).lineNumber;
|
||||
// The stop at line 3 is the switch.
|
||||
if (thisLine > 3) {
|
||||
assertEq(thisLine, okLine)
|
||||
frame.onStep = undefined;
|
||||
}
|
||||
};
|
||||
};
|
||||
g.eval(s);
|
||||
}
|
||||
|
||||
test("lit('bob');", 7);
|
||||
|
||||
test("nonlit('bob');", 4);
|
||||
@@ -0,0 +1,24 @@
|
||||
// A "while" or a "for" loop should have a single entry point.
|
||||
|
||||
var g = newGlobal();
|
||||
var dbg = new Debugger(g);
|
||||
|
||||
dbg.onDebuggerStatement = function(frame) {
|
||||
var s = frame.eval('f').return.script;
|
||||
|
||||
// There should be just a single entry point for the first line of
|
||||
// the function. See below to understand the "+2".
|
||||
assertEq(s.getLineOffsets(g.line0 + 2).length, 1);
|
||||
};
|
||||
|
||||
|
||||
function test(code) {
|
||||
g.eval('var line0 = Error().lineNumber;\n' +
|
||||
'function f() {\n' + // line0 + 1
|
||||
code + '\n' + // line0 + 2 -- see above
|
||||
'}\n' +
|
||||
'debugger;');
|
||||
}
|
||||
|
||||
test('while (false)\n;');
|
||||
test('for (;false;)\n;');
|
||||
@@ -1,5 +1,7 @@
|
||||
// |jit-test| --no-ion
|
||||
load(libdir + 'oomTest.js');
|
||||
if (!('oomTest' in this))
|
||||
quit();
|
||||
|
||||
var g = newGlobal();
|
||||
oomTest(function() {
|
||||
Debugger(g);
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
load(libdir + 'oomTest.js');
|
||||
if (!('oomTest' in this))
|
||||
quit();
|
||||
|
||||
oomTest((function(x) { assertEq(x + y + ex, 25); }));
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
load(libdir + 'oomTest.js');
|
||||
|
||||
if (helperThreadCount() === 0)
|
||||
if (!('oomTest' in this) || helperThreadCount() === 0)
|
||||
quit(0);
|
||||
|
||||
var lfGlobal = newGlobal();
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
load(libdir + 'oomTest.js');
|
||||
if (!('oomTest' in this))
|
||||
quit();
|
||||
|
||||
oomTest(() => getBacktrace({args: oomTest[load+1], locals: true, thisprops: true}));
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
if (!('oomTest' in this))
|
||||
quit();
|
||||
|
||||
oomTest(() => parseModule('import v from "mod";'));
|
||||
@@ -0,0 +1,18 @@
|
||||
if (!('oomTest' in this))
|
||||
quit();
|
||||
|
||||
oomTest(() => {
|
||||
try {
|
||||
var max = 400;
|
||||
function f(b) {
|
||||
if (b) {
|
||||
f(b - 1);
|
||||
} else {
|
||||
g = {};
|
||||
}
|
||||
g.apply(null, arguments);
|
||||
}
|
||||
f(max - 1);
|
||||
} catch(exc0) {}
|
||||
f();
|
||||
});
|
||||
@@ -1,4 +1,5 @@
|
||||
load(libdir + 'oomTest.js');
|
||||
if (!('oomTest' in this))
|
||||
quit();
|
||||
|
||||
function arrayProtoOutOfRange() {
|
||||
function f(obj) {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
load(libdir + 'oomTest.js');
|
||||
if (!('oomTest' in this))
|
||||
quit();
|
||||
|
||||
var g = newGlobal();
|
||||
oomTest(() => Debugger(g));
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
load(libdir + 'oomTest.js');
|
||||
if (!('oomTest' in this))
|
||||
quit();
|
||||
|
||||
oomTest(() => {
|
||||
let x = 0;
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
load(libdir + 'oomTest.js');
|
||||
if (!('oomTest' in this))
|
||||
quit();
|
||||
|
||||
oomTest(() => getBacktrace({args: true, locals: true, thisprops: true}));
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// |jit-test| --no-threads
|
||||
load(libdir + 'oomTest.js');
|
||||
// |jit-test| allow-oom; allow-unhandlable-oom; --no-threads
|
||||
if (!('oomTest' in this))
|
||||
quit();
|
||||
|
||||
oomTest(() => getBacktrace({thisprops: gc() && delete addDebuggee.enabled}));
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
load(libdir + 'oomTest.js');
|
||||
if (!('oomTest' in this))
|
||||
quit();
|
||||
|
||||
oomTest(newGlobal);
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
load(libdir + 'oomTest.js');
|
||||
if (!('oomTest' in this))
|
||||
quit();
|
||||
|
||||
function parseAsmJS() {
|
||||
eval(`function m(stdlib)
|
||||
{
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
load(libdir + 'oomTest.js');
|
||||
if (!('oomTest' in this))
|
||||
quit();
|
||||
|
||||
oomTest(() => eval("function f() {}"));
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
load(libdir + 'oomTest.js');
|
||||
if (!('oomTest' in this))
|
||||
quit();
|
||||
|
||||
oomTest(() => assertEq("foobar\xff5baz\u1200".search(/bar\u0178\d/i), 3));
|
||||
oomTest(() => assertEq((/(?!(?!(?!6)[\Wc]))/i).test(), false));
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
load(libdir + 'oomTest.js');
|
||||
if (!('oomTest' in this))
|
||||
quit();
|
||||
|
||||
oomTest(function () {
|
||||
eval(`var wm = new WeakMap();
|
||||
wm.set({}, 'FOO').get(false);`);
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
if (!('oomTest' in this))
|
||||
quit();
|
||||
|
||||
oomTest(() => parseModule('import v from "mod";'));
|
||||
fullcompartmentchecks(true);
|
||||
@@ -0,0 +1,2 @@
|
||||
// |jit-test| error: Error
|
||||
parseModule("").evaluation();
|
||||
@@ -1,5 +1,6 @@
|
||||
// |jit-test| slow;
|
||||
load(libdir + "oomTest.js");
|
||||
if (!('oomTest' in this))
|
||||
quit();
|
||||
|
||||
enableSPSProfiling();
|
||||
var lfGlobal = newGlobal();
|
||||
|
||||
@@ -11883,6 +11883,11 @@ IonBuilder::getPropTryInnerize(bool* emitted, MDefinition* obj, PropertyName* na
|
||||
{
|
||||
// See the comment in tryInnerizeWindow for how this works.
|
||||
|
||||
// Note that it's important that we do this _before_ we'd try to
|
||||
// do the optimizations below on obj normally, since some of those
|
||||
// optimizations have fallback paths that are slower than the path
|
||||
// we'd produce here.
|
||||
|
||||
MOZ_ASSERT(*emitted == false);
|
||||
|
||||
MDefinition* inner = tryInnerizeWindow(obj);
|
||||
@@ -11890,15 +11895,6 @@ IonBuilder::getPropTryInnerize(bool* emitted, MDefinition* obj, PropertyName* na
|
||||
return true;
|
||||
|
||||
if (!forceInlineCaches()) {
|
||||
// Note: the Baseline ICs don't know about this optimization, so it's
|
||||
// possible the global property's HeapTypeSet has not been initialized
|
||||
// yet. In this case we'll fall back to getPropTryCache for now.
|
||||
|
||||
// Note that it's important that we do this _before_ we'd try to
|
||||
// do the optimizations below on obj normally, since some of those
|
||||
// optimizations have fallback paths that are slower than the path
|
||||
// we'd produce here.
|
||||
|
||||
trackOptimizationAttempt(TrackedStrategy::GetProp_Constant);
|
||||
if (!getPropTryConstant(emitted, inner, NameToId(name), types) || *emitted)
|
||||
return *emitted;
|
||||
|
||||
@@ -1298,6 +1298,10 @@ AssemblerMIPSShared::bind(Label* label, BufferOffset boff)
|
||||
// A used label holds a link to branch that uses it.
|
||||
BufferOffset b(label);
|
||||
do {
|
||||
// Even a 0 offset may be invalid if we're out of memory.
|
||||
if (oom())
|
||||
return;
|
||||
|
||||
Instruction* inst = editSrc(b);
|
||||
|
||||
// Second word holds a pointer to the next branch in label's chain.
|
||||
@@ -1313,7 +1317,7 @@ AssemblerMIPSShared::bind(Label* label, BufferOffset boff)
|
||||
void
|
||||
AssemblerMIPSShared::retarget(Label* label, Label* target)
|
||||
{
|
||||
if (label->used()) {
|
||||
if (label->used() && !oom()) {
|
||||
if (target->bound()) {
|
||||
bind(label, BufferOffset(target));
|
||||
} else if (target->used()) {
|
||||
|
||||
@@ -1030,7 +1030,7 @@ class AssemblerMIPSShared : public AssemblerShared
|
||||
|
||||
// label operations
|
||||
void bind(Label* label, BufferOffset boff = BufferOffset());
|
||||
virtual void bind(InstImm* inst, uint32_t branch, uint32_t target) = 0;
|
||||
virtual void bind(InstImm* inst, uintptr_t branch, uintptr_t target) = 0;
|
||||
virtual void Bind(uint8_t* rawCode, AbsoluteLabel* label, const void* address) = 0;
|
||||
uint32_t currentOffset() {
|
||||
return nextOffset().getOffset();
|
||||
|
||||
@@ -4,10 +4,7 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "jit/mips-shared/Bailouts-mips-shared.h"
|
||||
|
||||
#include "jscntxt.h"
|
||||
#include "jscompartment.h"
|
||||
#include "jit/Bailouts.h"
|
||||
|
||||
using namespace js;
|
||||
using namespace js::jit;
|
||||
|
||||
@@ -198,16 +198,6 @@ CodeGeneratorMIPSShared::bailout(LSnapshot* snapshot)
|
||||
bailoutFrom(&label, snapshot);
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorMIPSShared::visitOutOfLineBailout(OutOfLineBailout* ool)
|
||||
{
|
||||
// Push snapshotOffset and make sure stack is aligned.
|
||||
masm.subPtr(Imm32(2 * sizeof(void*)), StackPointer);
|
||||
masm.storePtr(ImmWord(ool->snapshot()->snapshotOffset()), Address(StackPointer, 0));
|
||||
|
||||
masm.jump(&deoptLabel_);
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorMIPSShared::visitMinMaxD(LMinMaxD* ins)
|
||||
{
|
||||
|
||||
@@ -175,7 +175,7 @@ class CodeGeneratorMIPSShared : public CodeGeneratorShared
|
||||
virtual void visitTruncateFToInt32(LTruncateFToInt32* ins);
|
||||
|
||||
// Out of line visitors.
|
||||
void visitOutOfLineBailout(OutOfLineBailout* ool);
|
||||
virtual void visitOutOfLineBailout(OutOfLineBailout* ool) = 0;
|
||||
protected:
|
||||
virtual ValueOperand ToOutValue(LInstruction* ins) = 0;
|
||||
void memoryBarrier(MemoryBarrierBits barrier);
|
||||
|
||||
@@ -47,15 +47,25 @@ class FloatRegisters : public FloatRegistersMIPSShared
|
||||
public:
|
||||
static const char* GetName(uint32_t i) {
|
||||
MOZ_ASSERT(i < Total);
|
||||
return GetName(Code(i % 32));
|
||||
return FloatRegistersMIPSShared::GetName(Code(i % 32));
|
||||
}
|
||||
|
||||
static Code FromName(const char* name);
|
||||
|
||||
static const uint32_t Total = 64;
|
||||
static const uint32_t TotalDouble = 16;
|
||||
static const uint32_t RegisterIdLimit = 32;
|
||||
// Workarounds: On Loongson CPU-s the odd FP registers behave differently
|
||||
// in fp-32 mode than standard MIPS.
|
||||
#if defined(_MIPS_ARCH_LOONGSON3A)
|
||||
static const uint32_t TotalSingle = 16;
|
||||
static const uint32_t Allocatable = 28;
|
||||
static const SetType AllSingleMask = 0x55555555ULL;
|
||||
#else
|
||||
static const uint32_t TotalSingle = 32;
|
||||
static const uint32_t Allocatable = 42;
|
||||
static const SetType AllSingleMask = (1ULL << 32) - 1;
|
||||
#endif
|
||||
// When saving all registers we only need to do is save double registers.
|
||||
static const uint32_t TotalPhys = 16;
|
||||
|
||||
@@ -63,7 +73,7 @@ class FloatRegisters : public FloatRegistersMIPSShared
|
||||
"SetType should be large enough to enumerate all registers.");
|
||||
|
||||
static const SetType AllDoubleMask = 0x55555555ULL << 32;
|
||||
static const SetType AllMask = AllDoubleMask | ((1ULL << 32) - 1);
|
||||
static const SetType AllMask = AllDoubleMask | AllSingleMask;
|
||||
|
||||
static const SetType NonVolatileDoubleMask =
|
||||
((1ULL << FloatRegisters::f20) |
|
||||
@@ -165,7 +175,7 @@ class FloatRegister : public FloatRegisterMIPSShared
|
||||
}
|
||||
Encoding encoding() const {
|
||||
MOZ_ASSERT(!isInvalid());
|
||||
return Code(code_ | (kind_ << 5));
|
||||
return Encoding(code_);
|
||||
}
|
||||
uint32_t id() const {
|
||||
return code_;
|
||||
@@ -178,10 +188,15 @@ class FloatRegister : public FloatRegisterMIPSShared
|
||||
// This is similar to FromCode except for double registers on O32.
|
||||
static FloatRegister FromIndex(uint32_t index, RegType kind) {
|
||||
#if defined(USES_O32_ABI)
|
||||
// Only even FP registers are avaiable for Loongson on O32.
|
||||
# if defined(_MIPS_ARCH_LOONGSON3A)
|
||||
return FloatRegister(index * 2, kind);
|
||||
# else
|
||||
if (kind == Double)
|
||||
return FloatRegister(index * 2, RegType(kind));
|
||||
return FloatRegister(index * 2, kind);
|
||||
# endif
|
||||
#endif
|
||||
return FloatRegister(index, RegType(kind));
|
||||
return FloatRegister(index, kind);
|
||||
}
|
||||
|
||||
bool volatile_() const {
|
||||
|
||||
@@ -82,21 +82,21 @@ const Register ABIArgGenerator::NonReturn_VolatileReg1 = a1;
|
||||
uint32_t
|
||||
js::jit::RT(FloatRegister r)
|
||||
{
|
||||
MOZ_ASSERT(r.id() < FloatRegisters::TotalSingle);
|
||||
MOZ_ASSERT(r.id() < FloatRegisters::RegisterIdLimit);
|
||||
return r.id() << RTShift;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
js::jit::RD(FloatRegister r)
|
||||
{
|
||||
MOZ_ASSERT(r.id() < FloatRegisters::TotalSingle);
|
||||
MOZ_ASSERT(r.id() < FloatRegisters::RegisterIdLimit);
|
||||
return r.id() << RDShift;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
js::jit::SA(FloatRegister r)
|
||||
{
|
||||
MOZ_ASSERT(r.id() < FloatRegisters::TotalSingle);
|
||||
MOZ_ASSERT(r.id() < FloatRegisters::RegisterIdLimit);
|
||||
return r.id() << SAShift;
|
||||
}
|
||||
|
||||
@@ -261,7 +261,7 @@ Assembler::Bind(uint8_t* rawCode, AbsoluteLabel* label, const void* address)
|
||||
}
|
||||
|
||||
void
|
||||
Assembler::bind(InstImm* inst, uint32_t branch, uint32_t target)
|
||||
Assembler::bind(InstImm* inst, uintptr_t branch, uintptr_t target)
|
||||
{
|
||||
int32_t offset = target - branch;
|
||||
InstImm inst_bgezal = InstImm(op_regimm, zero, rt_bgezal, BOffImm16(0));
|
||||
@@ -321,7 +321,7 @@ void
|
||||
Assembler::bind(RepatchLabel* label)
|
||||
{
|
||||
BufferOffset dest = nextOffset();
|
||||
if (label->used()) {
|
||||
if (label->used() && !oom()) {
|
||||
// If the label has a use, then change this use to refer to
|
||||
// the bound label;
|
||||
BufferOffset b(label->offset());
|
||||
|
||||
@@ -129,7 +129,7 @@ class Assembler : public AssemblerMIPSShared
|
||||
static void TraceJumpRelocations(JSTracer* trc, JitCode* code, CompactBufferReader& reader);
|
||||
static void TraceDataRelocations(JSTracer* trc, JitCode* code, CompactBufferReader& reader);
|
||||
|
||||
void bind(InstImm* inst, uint32_t branch, uint32_t target);
|
||||
void bind(InstImm* inst, uintptr_t branch, uintptr_t target);
|
||||
|
||||
// Copy the assembly code to the given buffer, and perform any pending
|
||||
// relocations relying on the target address.
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "jit/mips32/Bailouts-mips32.h"
|
||||
|
||||
#include "jscntxt.h"
|
||||
#include "jscompartment.h"
|
||||
|
||||
#include "jit/mips-shared/Bailouts-mips-shared.h"
|
||||
|
||||
using namespace js;
|
||||
using namespace js::jit;
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef jit_mips_shared_Bailouts_mips_shared_h
|
||||
#define jit_mips_shared_Bailouts_mips_shared_h
|
||||
#ifndef jit_mips32_Bailouts_mips32_h
|
||||
#define jit_mips32_Bailouts_mips32_h
|
||||
|
||||
#include "jit/Bailouts.h"
|
||||
#include "jit/JitCompartment.h"
|
||||
@@ -74,4 +74,4 @@ class BailoutStack
|
||||
} // namespace jit
|
||||
} // namespace js
|
||||
|
||||
#endif /* jit_mips_shared_Bailouts_mips_shared_h */
|
||||
#endif /* jit_mips32_Bailouts_mips32_h */
|
||||
@@ -46,6 +46,16 @@ class js::jit::OutOfLineTableSwitch : public OutOfLineCodeBase<CodeGeneratorMIPS
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
CodeGeneratorMIPS::visitOutOfLineBailout(OutOfLineBailout* ool)
|
||||
{
|
||||
// Push snapshotOffset and make sure stack is aligned.
|
||||
masm.subPtr(Imm32(2 * sizeof(void*)), StackPointer);
|
||||
masm.storePtr(ImmWord(ool->snapshot()->snapshotOffset()), Address(StackPointer, 0));
|
||||
|
||||
masm.jump(&deoptLabel_);
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorMIPS::visitOutOfLineTableSwitch(OutOfLineTableSwitch* ool)
|
||||
{
|
||||
|
||||
@@ -40,6 +40,7 @@ class CodeGeneratorMIPS : public CodeGeneratorMIPSShared
|
||||
virtual void visitCompareBitwiseAndBranch(LCompareBitwiseAndBranch* lir);
|
||||
|
||||
// Out of line visitors.
|
||||
void visitOutOfLineBailout(OutOfLineBailout* ool);
|
||||
void visitOutOfLineTableSwitch(OutOfLineTableSwitch* ool);
|
||||
protected:
|
||||
ValueOperand ToValue(LInstruction* ins, size_t pos);
|
||||
|
||||
@@ -596,7 +596,8 @@ MacroAssemblerMIPS::ma_bal(Label* label, DelaySlotFill delaySlotFill)
|
||||
|
||||
BufferOffset bo = writeInst(getBranchCode(BranchIsCall).encode());
|
||||
writeInst(nextInChain);
|
||||
label->use(bo.getOffset());
|
||||
if (!oom())
|
||||
label->use(bo.getOffset());
|
||||
// Leave space for long jump.
|
||||
as_nop();
|
||||
if (delaySlotFill == FillDelaySlot)
|
||||
@@ -655,7 +656,8 @@ MacroAssemblerMIPS::branchWithCode(InstImm code, Label* label, JumpKind jumpKind
|
||||
code.setBOffImm16(BOffImm16(4));
|
||||
BufferOffset bo = writeInst(code.encode());
|
||||
writeInst(nextInChain);
|
||||
label->use(bo.getOffset());
|
||||
if (!oom())
|
||||
label->use(bo.getOffset());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -666,7 +668,8 @@ MacroAssemblerMIPS::branchWithCode(InstImm code, Label* label, JumpKind jumpKind
|
||||
|
||||
BufferOffset bo = writeInst(code.encode());
|
||||
writeInst(nextInChain);
|
||||
label->use(bo.getOffset());
|
||||
if (!oom())
|
||||
label->use(bo.getOffset());
|
||||
// Leave space for potential long jump.
|
||||
as_nop();
|
||||
as_nop();
|
||||
|
||||
@@ -727,7 +727,7 @@ MipsDebugger::printAllRegsIncludingFPU()
|
||||
|
||||
printf("\n\n");
|
||||
// f0, f1, f2, ... f31.
|
||||
for (uint32_t i = 0; i < FloatRegisters::TotalSingle; i++) {
|
||||
for (uint32_t i = 0; i < FloatRegisters::RegisterIdLimit; i++) {
|
||||
if (i & 0x1) {
|
||||
printf("%3s: 0x%08x\tflt: %-8.4g\n",
|
||||
FloatRegisters::GetName(i),
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include "jit/JitFrames.h"
|
||||
#include "jit/JitSpewer.h"
|
||||
#include "jit/Linker.h"
|
||||
#include "jit/mips-shared/Bailouts-mips-shared.h"
|
||||
#include "jit/mips32/Bailouts-mips32.h"
|
||||
#include "jit/mips32/SharedICHelpers-mips32.h"
|
||||
#ifdef JS_ION_PERF
|
||||
# include "jit/PerfSpewer.h"
|
||||
|
||||
@@ -256,7 +256,7 @@ Assembler::Bind(uint8_t* rawCode, AbsoluteLabel* label, const void* address)
|
||||
}
|
||||
|
||||
void
|
||||
Assembler::bind(InstImm* inst, uint64_t branch, uint64_t target)
|
||||
Assembler::bind(InstImm* inst, uintptr_t branch, uintptr_t target)
|
||||
{
|
||||
int64_t offset = target - branch;
|
||||
InstImm inst_bgezal = InstImm(op_regimm, zero, rt_bgezal, BOffImm16(0));
|
||||
@@ -281,18 +281,21 @@ Assembler::bind(InstImm* inst, uint64_t branch, uint64_t target)
|
||||
}
|
||||
|
||||
if (BOffImm16::IsInRange(offset)) {
|
||||
bool conditional = (inst[0].encode() != inst_bgezal.encode() &&
|
||||
inst[0].encode() != inst_beq.encode());
|
||||
|
||||
inst[0].setBOffImm16(BOffImm16(offset));
|
||||
inst[1].makeNop();
|
||||
|
||||
// Don't skip trailing nops can imporve performance
|
||||
// on Loongson3 platform.
|
||||
#ifndef _MIPS_ARCH_LOONGSON3A
|
||||
bool conditional = (inst[0].encode() != inst_bgezal.encode() &&
|
||||
inst[0].encode() != inst_beq.encode());
|
||||
|
||||
// Skip the trailing nops in conditional branches.
|
||||
// FIXME: On Loongson3 platform, the branch degrade performance.
|
||||
if (0 && conditional) {
|
||||
if (conditional) {
|
||||
inst[2] = InstImm(op_regimm, zero, rt_bgez, BOffImm16(5 * sizeof(uint32_t))).encode();
|
||||
// There are 4 nops after this
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -317,7 +320,7 @@ void
|
||||
Assembler::bind(RepatchLabel* label)
|
||||
{
|
||||
BufferOffset dest = nextOffset();
|
||||
if (label->used()) {
|
||||
if (label->used() && !oom()) {
|
||||
// If the label has a use, then change this use to refer to
|
||||
// the bound label;
|
||||
BufferOffset b(label->offset());
|
||||
@@ -368,10 +371,10 @@ uint64_t
|
||||
Assembler::ExtractLoad64Value(Instruction* inst0)
|
||||
{
|
||||
InstImm* i0 = (InstImm*) inst0;
|
||||
InstImm* i1 = (InstImm*) inst0->next();
|
||||
InstReg* i2 = (InstReg*) inst1->next();
|
||||
InstImm* i3 = (InstImm*) inst2->next();
|
||||
InstImm* i5 = (InstImm*) inst3->next()->next();
|
||||
InstImm* i1 = (InstImm*) i0->next();
|
||||
InstReg* i2 = (InstReg*) i1->next();
|
||||
InstImm* i3 = (InstImm*) i2->next();
|
||||
InstImm* i5 = (InstImm*) i3->next()->next();
|
||||
|
||||
MOZ_ASSERT(i0->extractOpcode() == ((uint32_t)op_lui >> OpcodeShift));
|
||||
MOZ_ASSERT(i1->extractOpcode() == ((uint32_t)op_ori >> OpcodeShift));
|
||||
@@ -398,10 +401,10 @@ void
|
||||
Assembler::UpdateLoad64Value(Instruction* inst0, uint64_t value)
|
||||
{
|
||||
InstImm* i0 = (InstImm*) inst0;
|
||||
InstImm* i1 = (InstImm*) inst0->next();
|
||||
InstReg* i2 = (InstReg*) inst1->next();
|
||||
InstImm* i3 = (InstImm*) inst2->next();
|
||||
InstImm* i5 = (InstImm*) inst3->next()->next();
|
||||
InstImm* i1 = (InstImm*) i0->next();
|
||||
InstReg* i2 = (InstReg*) i1->next();
|
||||
InstImm* i3 = (InstImm*) i2->next();
|
||||
InstImm* i5 = (InstImm*) i3->next()->next();
|
||||
|
||||
MOZ_ASSERT(i0->extractOpcode() == ((uint32_t)op_lui >> OpcodeShift));
|
||||
MOZ_ASSERT(i1->extractOpcode() == ((uint32_t)op_ori >> OpcodeShift));
|
||||
|
||||
@@ -131,7 +131,7 @@ class Assembler : public AssemblerMIPSShared
|
||||
static void TraceJumpRelocations(JSTracer* trc, JitCode* code, CompactBufferReader& reader);
|
||||
static void TraceDataRelocations(JSTracer* trc, JitCode* code, CompactBufferReader& reader);
|
||||
|
||||
void bind(InstImm* inst, uint64_t branch, uint64_t target);
|
||||
void bind(InstImm* inst, uintptr_t branch, uintptr_t target);
|
||||
|
||||
// Copy the assembly code to the given buffer, and perform any pending
|
||||
// relocations relying on the target address.
|
||||
|
||||
@@ -4,17 +4,17 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "jit/mips64/Bailouts-mips64.h"
|
||||
|
||||
#include "jscntxt.h"
|
||||
#include "jscompartment.h"
|
||||
|
||||
#include "jit/mips-shared/Bailouts-mips-shared.h"
|
||||
|
||||
using namespace js;
|
||||
using namespace js::jit;
|
||||
|
||||
BailoutFrameInfo::BailoutFrameInfo(const JitActivationIterator& activations,
|
||||
BailoutStack* bailout)
|
||||
: machine_(bailout->machine())
|
||||
: machine_(bailout->machineState())
|
||||
{
|
||||
uint8_t* sp = bailout->parentStackPointer();
|
||||
framePointer_ = sp + bailout->frameSize();
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sts=4 et sw=4 tw=99:
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef jit_mips64_Bailouts_mips64_h
|
||||
#define jit_mips64_Bailouts_mips64_h
|
||||
|
||||
#include "jit/Bailouts.h"
|
||||
#include "jit/JitCompartment.h"
|
||||
|
||||
namespace js {
|
||||
namespace jit {
|
||||
|
||||
class BailoutStack
|
||||
{
|
||||
RegisterDump::FPUArray fpregs_;
|
||||
RegisterDump::GPRArray regs_;
|
||||
uintptr_t frameSize_;
|
||||
uintptr_t snapshotOffset_;
|
||||
|
||||
public:
|
||||
MachineState machineState() {
|
||||
return MachineState::FromBailout(regs_, fpregs_);
|
||||
}
|
||||
uint32_t snapshotOffset() const {
|
||||
return snapshotOffset_;
|
||||
}
|
||||
uint32_t frameSize() const {
|
||||
return frameSize_;
|
||||
}
|
||||
uint8_t* parentStackPointer() {
|
||||
return (uint8_t*)this + sizeof(BailoutStack);
|
||||
}
|
||||
static size_t offsetOfFrameSize() {
|
||||
return offsetof(BailoutStack, frameSize_);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace jit
|
||||
} // namespace js
|
||||
|
||||
#endif /* jit_mips64_Bailouts_mips64_h */
|
||||
@@ -46,6 +46,14 @@ class js::jit::OutOfLineTableSwitch : public OutOfLineCodeBase<CodeGeneratorMIPS
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
CodeGeneratorMIPS64::visitOutOfLineBailout(OutOfLineBailout* ool)
|
||||
{
|
||||
masm.push(ImmWord(ool->snapshot()->snapshotOffset()));
|
||||
|
||||
masm.jump(&deoptLabel_);
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorMIPS64::visitOutOfLineTableSwitch(OutOfLineTableSwitch* ool)
|
||||
{
|
||||
|
||||
@@ -46,6 +46,7 @@ class CodeGeneratorMIPS64 : public CodeGeneratorMIPSShared
|
||||
virtual void visitCompareBitwiseAndBranch(LCompareBitwiseAndBranch* lir);
|
||||
|
||||
// Out of line visitors.
|
||||
void visitOutOfLineBailout(OutOfLineBailout* ool);
|
||||
void visitOutOfLineTableSwitch(OutOfLineTableSwitch* ool);
|
||||
protected:
|
||||
ValueOperand ToValue(LInstruction* ins, size_t pos);
|
||||
|
||||
@@ -703,7 +703,8 @@ MacroAssemblerMIPS64::ma_bal(Label* label, DelaySlotFill delaySlotFill)
|
||||
|
||||
BufferOffset bo = writeInst(getBranchCode(BranchIsCall).encode());
|
||||
writeInst(nextInChain);
|
||||
label->use(bo.getOffset());
|
||||
if (!oom())
|
||||
label->use(bo.getOffset());
|
||||
// Leave space for long jump.
|
||||
as_nop();
|
||||
as_nop();
|
||||
@@ -765,7 +766,8 @@ MacroAssemblerMIPS64::branchWithCode(InstImm code, Label* label, JumpKind jumpKi
|
||||
code.setBOffImm16(BOffImm16(4));
|
||||
BufferOffset bo = writeInst(code.encode());
|
||||
writeInst(nextInChain);
|
||||
label->use(bo.getOffset());
|
||||
if (!oom())
|
||||
label->use(bo.getOffset());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -777,7 +779,8 @@ MacroAssemblerMIPS64::branchWithCode(InstImm code, Label* label, JumpKind jumpKi
|
||||
|
||||
BufferOffset bo = writeInst(code.encode());
|
||||
writeInst(nextInChain);
|
||||
label->use(bo.getOffset());
|
||||
if (!oom())
|
||||
label->use(bo.getOffset());
|
||||
// Leave space for potential long jump.
|
||||
as_nop();
|
||||
as_nop();
|
||||
@@ -2526,6 +2529,105 @@ MacroAssemblerMIPS64Compat::handleFailureWithHandlerTail(void* handler)
|
||||
jump(a1);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void
|
||||
MacroAssemblerMIPS64Compat::compareExchangeToTypedIntArray(Scalar::Type arrayType, const T& mem,
|
||||
Register oldval, Register newval,
|
||||
Register temp, Register valueTemp,
|
||||
Register offsetTemp, Register maskTemp,
|
||||
AnyRegister output)
|
||||
{
|
||||
switch (arrayType) {
|
||||
case Scalar::Int8:
|
||||
compareExchange8SignExtend(mem, oldval, newval, valueTemp, offsetTemp, maskTemp, output.gpr());
|
||||
break;
|
||||
case Scalar::Uint8:
|
||||
compareExchange8ZeroExtend(mem, oldval, newval, valueTemp, offsetTemp, maskTemp, output.gpr());
|
||||
break;
|
||||
case Scalar::Uint8Clamped:
|
||||
compareExchange8ZeroExtend(mem, oldval, newval, valueTemp, offsetTemp, maskTemp, output.gpr());
|
||||
break;
|
||||
case Scalar::Int16:
|
||||
compareExchange16SignExtend(mem, oldval, newval, valueTemp, offsetTemp, maskTemp, output.gpr());
|
||||
break;
|
||||
case Scalar::Uint16:
|
||||
compareExchange16ZeroExtend(mem, oldval, newval, valueTemp, offsetTemp, maskTemp, output.gpr());
|
||||
break;
|
||||
case Scalar::Int32:
|
||||
compareExchange32(mem, oldval, newval, valueTemp, offsetTemp, maskTemp, output.gpr());
|
||||
break;
|
||||
case Scalar::Uint32:
|
||||
// At the moment, the code in MCallOptimize.cpp requires the output
|
||||
// type to be double for uint32 arrays. See bug 1077305.
|
||||
MOZ_ASSERT(output.isFloat());
|
||||
compareExchange32(mem, oldval, newval, valueTemp, offsetTemp, maskTemp, temp);
|
||||
convertUInt32ToDouble(temp, output.fpu());
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("Invalid typed array type");
|
||||
}
|
||||
}
|
||||
|
||||
template void
|
||||
MacroAssemblerMIPS64Compat::compareExchangeToTypedIntArray(Scalar::Type arrayType, const Address& mem,
|
||||
Register oldval, Register newval, Register temp,
|
||||
Register valueTemp, Register offsetTemp, Register maskTemp,
|
||||
AnyRegister output);
|
||||
template void
|
||||
MacroAssemblerMIPS64Compat::compareExchangeToTypedIntArray(Scalar::Type arrayType, const BaseIndex& mem,
|
||||
Register oldval, Register newval, Register temp,
|
||||
Register valueTemp, Register offsetTemp, Register maskTemp,
|
||||
AnyRegister output);
|
||||
|
||||
template<typename T>
|
||||
void
|
||||
MacroAssemblerMIPS64Compat::atomicExchangeToTypedIntArray(Scalar::Type arrayType, const T& mem,
|
||||
Register value, Register temp, Register valueTemp,
|
||||
Register offsetTemp, Register maskTemp,
|
||||
AnyRegister output)
|
||||
{
|
||||
switch (arrayType) {
|
||||
case Scalar::Int8:
|
||||
atomicExchange8SignExtend(mem, value, valueTemp, offsetTemp, maskTemp, output.gpr());
|
||||
break;
|
||||
case Scalar::Uint8:
|
||||
atomicExchange8ZeroExtend(mem, value, valueTemp, offsetTemp, maskTemp, output.gpr());
|
||||
break;
|
||||
case Scalar::Uint8Clamped:
|
||||
atomicExchange8ZeroExtend(mem, value, valueTemp, offsetTemp, maskTemp, output.gpr());
|
||||
break;
|
||||
case Scalar::Int16:
|
||||
atomicExchange16SignExtend(mem, value, valueTemp, offsetTemp, maskTemp, output.gpr());
|
||||
break;
|
||||
case Scalar::Uint16:
|
||||
atomicExchange16ZeroExtend(mem, value, valueTemp, offsetTemp, maskTemp, output.gpr());
|
||||
break;
|
||||
case Scalar::Int32:
|
||||
atomicExchange32(mem, value, valueTemp, offsetTemp, maskTemp, output.gpr());
|
||||
break;
|
||||
case Scalar::Uint32:
|
||||
// At the moment, the code in MCallOptimize.cpp requires the output
|
||||
// type to be double for uint32 arrays. See bug 1077305.
|
||||
MOZ_ASSERT(output.isFloat());
|
||||
atomicExchange32(mem, value, valueTemp, offsetTemp, maskTemp, temp);
|
||||
convertUInt32ToDouble(temp, output.fpu());
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("Invalid typed array type");
|
||||
}
|
||||
}
|
||||
|
||||
template void
|
||||
MacroAssemblerMIPS64Compat::atomicExchangeToTypedIntArray(Scalar::Type arrayType, const Address& mem,
|
||||
Register value, Register temp, Register valueTemp,
|
||||
Register offsetTemp, Register maskTemp,
|
||||
AnyRegister output);
|
||||
template void
|
||||
MacroAssemblerMIPS64Compat::atomicExchangeToTypedIntArray(Scalar::Type arrayType, const BaseIndex& mem,
|
||||
Register value, Register temp, Register valueTemp,
|
||||
Register offsetTemp, Register maskTemp,
|
||||
AnyRegister output);
|
||||
|
||||
CodeOffsetLabel
|
||||
MacroAssemblerMIPS64Compat::toggledJump(Label* label)
|
||||
{
|
||||
|
||||
@@ -772,219 +772,322 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64
|
||||
// The following functions are exposed for use in platform-shared code.
|
||||
|
||||
template<typename T>
|
||||
void compareExchange8SignExtend(const T& mem, Register oldval, Register newval, Register output)
|
||||
void compareExchange8SignExtend(const T& mem, Register oldval, Register newval, Register valueTemp,
|
||||
Register offsetTemp, Register maskTemp, Register output)
|
||||
{
|
||||
MOZ_CRASH("NYI");
|
||||
compareExchange(1, true, mem, oldval, newval, valueTemp, offsetTemp, maskTemp, output);
|
||||
}
|
||||
template<typename T>
|
||||
void compareExchange8ZeroExtend(const T& mem, Register oldval, Register newval, Register output)
|
||||
void compareExchange8ZeroExtend(const T& mem, Register oldval, Register newval, Register valueTemp,
|
||||
Register offsetTemp, Register maskTemp, Register output)
|
||||
{
|
||||
MOZ_CRASH("NYI");
|
||||
compareExchange(1, false, mem, oldval, newval, valueTemp, offsetTemp, maskTemp, output);
|
||||
}
|
||||
template<typename T>
|
||||
void compareExchange16SignExtend(const T& mem, Register oldval, Register newval, Register output)
|
||||
void compareExchange16SignExtend(const T& mem, Register oldval, Register newval, Register valueTemp,
|
||||
Register offsetTemp, Register maskTemp, Register output)
|
||||
{
|
||||
MOZ_CRASH("NYI");
|
||||
compareExchange(2, true, mem, oldval, newval, valueTemp, offsetTemp, maskTemp, output);
|
||||
}
|
||||
template<typename T>
|
||||
void compareExchange16ZeroExtend(const T& mem, Register oldval, Register newval, Register output)
|
||||
void compareExchange16ZeroExtend(const T& mem, Register oldval, Register newval, Register valueTemp,
|
||||
Register offsetTemp, Register maskTemp, Register output)
|
||||
{
|
||||
MOZ_CRASH("NYI");
|
||||
compareExchange(2, false, mem, oldval, newval, valueTemp, offsetTemp, maskTemp, output);
|
||||
}
|
||||
template<typename T>
|
||||
void compareExchange32(const T& mem, Register oldval, Register newval, Register output)
|
||||
void compareExchange32(const T& mem, Register oldval, Register newval, Register valueTemp,
|
||||
Register offsetTemp, Register maskTemp, Register output)
|
||||
{
|
||||
MOZ_CRASH("NYI");
|
||||
compareExchange(4, false, mem, oldval, newval, valueTemp, offsetTemp, maskTemp, output);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void atomicExchange8SignExtend(const T& mem, Register value, Register output)
|
||||
void atomicExchange8SignExtend(const T& mem, Register value, Register valueTemp,
|
||||
Register offsetTemp, Register maskTemp, Register output)
|
||||
{
|
||||
MOZ_CRASH("NYI");
|
||||
atomicExchange(1, true, mem, value, valueTemp, offsetTemp, maskTemp, output);
|
||||
}
|
||||
template<typename T>
|
||||
void atomicExchange8ZeroExtend(const T& mem, Register value, Register output)
|
||||
void atomicExchange8ZeroExtend(const T& mem, Register value, Register valueTemp,
|
||||
Register offsetTemp, Register maskTemp, Register output)
|
||||
{
|
||||
MOZ_CRASH("NYI");
|
||||
atomicExchange(1, false, mem, value, valueTemp, offsetTemp, maskTemp, output);
|
||||
}
|
||||
template<typename T>
|
||||
void atomicExchange16SignExtend(const T& mem, Register value, Register output)
|
||||
void atomicExchange16SignExtend(const T& mem, Register value, Register valueTemp,
|
||||
Register offsetTemp, Register maskTemp, Register output)
|
||||
{
|
||||
MOZ_CRASH("NYI");
|
||||
atomicExchange(2, true, mem, value, valueTemp, offsetTemp, maskTemp, output);
|
||||
}
|
||||
template<typename T>
|
||||
void atomicExchange16ZeroExtend(const T& mem, Register value, Register output)
|
||||
void atomicExchange16ZeroExtend(const T& mem, Register value, Register valueTemp,
|
||||
Register offsetTemp, Register maskTemp, Register output)
|
||||
{
|
||||
MOZ_CRASH("NYI");
|
||||
atomicExchange(2, false, mem, value, valueTemp, offsetTemp, maskTemp, output);
|
||||
}
|
||||
template<typename T>
|
||||
void atomicExchange32(const T& mem, Register value, Register output)
|
||||
void atomicExchange32(const T& mem, Register value, Register valueTemp,
|
||||
Register offsetTemp, Register maskTemp, Register output)
|
||||
{
|
||||
MOZ_CRASH("NYI");
|
||||
atomicExchange(4, false, mem, value, valueTemp, offsetTemp, maskTemp, output);
|
||||
}
|
||||
|
||||
template<typename T, typename S>
|
||||
void atomicFetchAdd8SignExtend(const S& value, const T& mem, Register temp, Register output) {
|
||||
MOZ_CRASH("NYI");
|
||||
void atomicFetchAdd8SignExtend(const S& value, const T& mem, Register flagTemp,
|
||||
Register valueTemp, Register offsetTemp, Register maskTemp, Register output)
|
||||
{
|
||||
atomicFetchOp(1, true, AtomicFetchAddOp, value, mem, flagTemp, valueTemp, offsetTemp, maskTemp, output);
|
||||
}
|
||||
template<typename T, typename S>
|
||||
void atomicFetchAdd8ZeroExtend(const S& value, const T& mem, Register temp, Register output) {
|
||||
MOZ_CRASH("NYI");
|
||||
void atomicFetchAdd8ZeroExtend(const S& value, const T& mem, Register flagTemp,
|
||||
Register valueTemp, Register offsetTemp, Register maskTemp, Register output)
|
||||
{
|
||||
atomicFetchOp(1, false, AtomicFetchAddOp, value, mem, flagTemp, valueTemp, offsetTemp, maskTemp, output);
|
||||
}
|
||||
template<typename T, typename S>
|
||||
void atomicFetchAdd16SignExtend(const S& value, const T& mem, Register temp, Register output) {
|
||||
MOZ_CRASH("NYI");
|
||||
void atomicFetchAdd16SignExtend(const S& value, const T& mem, Register flagTemp,
|
||||
Register valueTemp, Register offsetTemp, Register maskTemp, Register output)
|
||||
{
|
||||
atomicFetchOp(2, true, AtomicFetchAddOp, value, mem, flagTemp, valueTemp, offsetTemp, maskTemp, output);
|
||||
}
|
||||
template<typename T, typename S>
|
||||
void atomicFetchAdd16ZeroExtend(const S& value, const T& mem, Register temp, Register output) {
|
||||
MOZ_CRASH("NYI");
|
||||
void atomicFetchAdd16ZeroExtend(const S& value, const T& mem, Register flagTemp,
|
||||
Register valueTemp, Register offsetTemp, Register maskTemp, Register output)
|
||||
{
|
||||
atomicFetchOp(2, false, AtomicFetchAddOp, value, mem, flagTemp, valueTemp, offsetTemp, maskTemp, output);
|
||||
}
|
||||
template<typename T, typename S>
|
||||
void atomicFetchAdd32(const S& value, const T& mem, Register temp, Register output) {
|
||||
MOZ_CRASH("NYI");
|
||||
void atomicFetchAdd32(const S& value, const T& mem, Register flagTemp,
|
||||
Register valueTemp, Register offsetTemp, Register maskTemp, Register output)
|
||||
{
|
||||
atomicFetchOp(4, false, AtomicFetchAddOp, value, mem, flagTemp, valueTemp, offsetTemp, maskTemp, output);
|
||||
}
|
||||
template <typename T, typename S>
|
||||
void atomicAdd8(const T& value, const S& mem) {
|
||||
MOZ_CRASH("NYI");
|
||||
void atomicAdd8(const T& value, const S& mem, Register flagTemp,
|
||||
Register valueTemp, Register offsetTemp, Register maskTemp)
|
||||
{
|
||||
atomicEffectOp(1, AtomicFetchAddOp, value, mem, flagTemp, valueTemp, offsetTemp, maskTemp);
|
||||
}
|
||||
template <typename T, typename S>
|
||||
void atomicAdd16(const T& value, const S& mem) {
|
||||
MOZ_CRASH("NYI");
|
||||
void atomicAdd16(const T& value, const S& mem, Register flagTemp,
|
||||
Register valueTemp, Register offsetTemp, Register maskTemp)
|
||||
{
|
||||
atomicEffectOp(2, AtomicFetchAddOp, value, mem, flagTemp, valueTemp, offsetTemp, maskTemp);
|
||||
}
|
||||
template <typename T, typename S>
|
||||
void atomicAdd32(const T& value, const S& mem) {
|
||||
MOZ_CRASH("NYI");
|
||||
void atomicAdd32(const T& value, const S& mem, Register flagTemp,
|
||||
Register valueTemp, Register offsetTemp, Register maskTemp)
|
||||
{
|
||||
atomicEffectOp(4, AtomicFetchAddOp, value, mem, flagTemp, valueTemp, offsetTemp, maskTemp);
|
||||
}
|
||||
|
||||
template<typename T, typename S>
|
||||
void atomicFetchSub8SignExtend(const S& value, const T& mem, Register temp, Register output) {
|
||||
MOZ_CRASH("NYI");
|
||||
void atomicFetchSub8SignExtend(const S& value, const T& mem, Register flagTemp,
|
||||
Register valueTemp, Register offsetTemp, Register maskTemp, Register output)
|
||||
{
|
||||
atomicFetchOp(1, true, AtomicFetchSubOp, value, mem, flagTemp, valueTemp, offsetTemp, maskTemp, output);
|
||||
}
|
||||
template<typename T, typename S>
|
||||
void atomicFetchSub8ZeroExtend(const S& value, const T& mem, Register temp, Register output) {
|
||||
MOZ_CRASH("NYI");
|
||||
void atomicFetchSub8ZeroExtend(const S& value, const T& mem, Register flagTemp,
|
||||
Register valueTemp, Register offsetTemp, Register maskTemp, Register output)
|
||||
{
|
||||
atomicFetchOp(1, false, AtomicFetchSubOp, value, mem, flagTemp, valueTemp, offsetTemp, maskTemp, output);
|
||||
}
|
||||
template<typename T, typename S>
|
||||
void atomicFetchSub16SignExtend(const S& value, const T& mem, Register temp, Register output) {
|
||||
MOZ_CRASH("NYI");
|
||||
void atomicFetchSub16SignExtend(const S& value, const T& mem, Register flagTemp,
|
||||
Register valueTemp, Register offsetTemp, Register maskTemp, Register output)
|
||||
{
|
||||
atomicFetchOp(2, true, AtomicFetchSubOp, value, mem, flagTemp, valueTemp, offsetTemp, maskTemp, output);
|
||||
}
|
||||
template<typename T, typename S>
|
||||
void atomicFetchSub16ZeroExtend(const S& value, const T& mem, Register temp, Register output) {
|
||||
MOZ_CRASH("NYI");
|
||||
void atomicFetchSub16ZeroExtend(const S& value, const T& mem, Register flagTemp,
|
||||
Register valueTemp, Register offsetTemp, Register maskTemp, Register output)
|
||||
{
|
||||
atomicFetchOp(2, false, AtomicFetchSubOp, value, mem, flagTemp, valueTemp, offsetTemp, maskTemp, output);
|
||||
}
|
||||
template<typename T, typename S>
|
||||
void atomicFetchSub32(const S& value, const T& mem, Register temp, Register output) {
|
||||
MOZ_CRASH("NYI");
|
||||
void atomicFetchSub32(const S& value, const T& mem, Register flagTemp,
|
||||
Register valueTemp, Register offsetTemp, Register maskTemp, Register output)
|
||||
{
|
||||
atomicFetchOp(4, false, AtomicFetchSubOp, value, mem, flagTemp, valueTemp, offsetTemp, maskTemp, output);
|
||||
}
|
||||
template <typename T, typename S> void atomicSub8(const T& value, const S& mem) {
|
||||
MOZ_CRASH("NYI");
|
||||
template <typename T, typename S>
|
||||
void atomicSub8(const T& value, const S& mem, Register flagTemp,
|
||||
Register valueTemp, Register offsetTemp, Register maskTemp)
|
||||
{
|
||||
atomicEffectOp(1, AtomicFetchSubOp, value, mem, flagTemp, valueTemp, offsetTemp, maskTemp);
|
||||
}
|
||||
template <typename T, typename S> void atomicSub16(const T& value, const S& mem) {
|
||||
MOZ_CRASH("NYI");
|
||||
template <typename T, typename S>
|
||||
void atomicSub16(const T& value, const S& mem, Register flagTemp,
|
||||
Register valueTemp, Register offsetTemp, Register maskTemp)
|
||||
{
|
||||
atomicEffectOp(2, AtomicFetchSubOp, value, mem, flagTemp, valueTemp, offsetTemp, maskTemp);
|
||||
}
|
||||
template <typename T, typename S> void atomicSub32(const T& value, const S& mem) {
|
||||
MOZ_CRASH("NYI");
|
||||
template <typename T, typename S>
|
||||
void atomicSub32(const T& value, const S& mem, Register flagTemp,
|
||||
Register valueTemp, Register offsetTemp, Register maskTemp)
|
||||
{
|
||||
atomicEffectOp(4, AtomicFetchSubOp, value, mem, flagTemp, valueTemp, offsetTemp, maskTemp);
|
||||
}
|
||||
|
||||
template<typename T, typename S>
|
||||
void atomicFetchAnd8SignExtend(const S& value, const T& mem, Register temp, Register output) {
|
||||
MOZ_CRASH("NYI");
|
||||
void atomicFetchAnd8SignExtend(const S& value, const T& mem, Register flagTemp,
|
||||
Register valueTemp, Register offsetTemp, Register maskTemp, Register output)
|
||||
{
|
||||
atomicFetchOp(1, true, AtomicFetchAndOp, value, mem, flagTemp, valueTemp, offsetTemp, maskTemp, output);
|
||||
}
|
||||
template<typename T, typename S>
|
||||
void atomicFetchAnd8ZeroExtend(const S& value, const T& mem, Register temp, Register output) {
|
||||
MOZ_CRASH("NYI");
|
||||
void atomicFetchAnd8ZeroExtend(const S& value, const T& mem, Register flagTemp,
|
||||
Register valueTemp, Register offsetTemp, Register maskTemp, Register output)
|
||||
{
|
||||
atomicFetchOp(1, false, AtomicFetchAndOp, value, mem, flagTemp, valueTemp, offsetTemp, maskTemp, output);
|
||||
}
|
||||
template<typename T, typename S>
|
||||
void atomicFetchAnd16SignExtend(const S& value, const T& mem, Register temp, Register output) {
|
||||
MOZ_CRASH("NYI");
|
||||
void atomicFetchAnd16SignExtend(const S& value, const T& mem, Register flagTemp,
|
||||
Register valueTemp, Register offsetTemp, Register maskTemp, Register output)
|
||||
{
|
||||
atomicFetchOp(2, true, AtomicFetchAndOp, value, mem, flagTemp, valueTemp, offsetTemp, maskTemp, output);
|
||||
}
|
||||
template<typename T, typename S>
|
||||
void atomicFetchAnd16ZeroExtend(const S& value, const T& mem, Register temp, Register output) {
|
||||
MOZ_CRASH("NYI");
|
||||
void atomicFetchAnd16ZeroExtend(const S& value, const T& mem, Register flagTemp,
|
||||
Register valueTemp, Register offsetTemp, Register maskTemp, Register output)
|
||||
{
|
||||
atomicFetchOp(2, false, AtomicFetchAndOp, value, mem, flagTemp, valueTemp, offsetTemp, maskTemp, output);
|
||||
}
|
||||
template<typename T, typename S>
|
||||
void atomicFetchAnd32(const S& value, const T& mem, Register temp, Register output) {
|
||||
MOZ_CRASH("NYI");
|
||||
void atomicFetchAnd32(const S& value, const T& mem, Register flagTemp,
|
||||
Register valueTemp, Register offsetTemp, Register maskTemp, Register output)
|
||||
{
|
||||
atomicFetchOp(4, false, AtomicFetchAndOp, value, mem, flagTemp, valueTemp, offsetTemp, maskTemp, output);
|
||||
}
|
||||
template <typename T, typename S>
|
||||
void atomicAnd8(const T& value, const S& mem) {
|
||||
MOZ_CRASH("NYI");
|
||||
void atomicAnd8(const T& value, const S& mem, Register flagTemp,
|
||||
Register valueTemp, Register offsetTemp, Register maskTemp)
|
||||
{
|
||||
atomicEffectOp(1, AtomicFetchAndOp, value, mem, flagTemp, valueTemp, offsetTemp, maskTemp);
|
||||
}
|
||||
template <typename T, typename S>
|
||||
void atomicAnd16(const T& value, const S& mem) {
|
||||
MOZ_CRASH("NYI");
|
||||
void atomicAnd16(const T& value, const S& mem, Register flagTemp,
|
||||
Register valueTemp, Register offsetTemp, Register maskTemp)
|
||||
{
|
||||
atomicEffectOp(2, AtomicFetchAndOp, value, mem, flagTemp, valueTemp, offsetTemp, maskTemp);
|
||||
}
|
||||
template <typename T, typename S>
|
||||
void atomicAnd32(const T& value, const S& mem) {
|
||||
MOZ_CRASH("NYI");
|
||||
void atomicAnd32(const T& value, const S& mem, Register flagTemp,
|
||||
Register valueTemp, Register offsetTemp, Register maskTemp)
|
||||
{
|
||||
atomicEffectOp(4, AtomicFetchAndOp, value, mem, flagTemp, valueTemp, offsetTemp, maskTemp);
|
||||
}
|
||||
|
||||
template<typename T, typename S>
|
||||
void atomicFetchOr8SignExtend(const S& value, const T& mem, Register temp, Register output) {
|
||||
MOZ_CRASH("NYI");
|
||||
void atomicFetchOr8SignExtend(const S& value, const T& mem, Register flagTemp,
|
||||
Register valueTemp, Register offsetTemp, Register maskTemp, Register output)
|
||||
{
|
||||
atomicFetchOp(1, true, AtomicFetchOrOp, value, mem, flagTemp, valueTemp, offsetTemp, maskTemp, output);
|
||||
}
|
||||
template<typename T, typename S>
|
||||
void atomicFetchOr8ZeroExtend(const S& value, const T& mem, Register temp, Register output) {
|
||||
MOZ_CRASH("NYI");
|
||||
void atomicFetchOr8ZeroExtend(const S& value, const T& mem, Register flagTemp,
|
||||
Register valueTemp, Register offsetTemp, Register maskTemp, Register output)
|
||||
{
|
||||
atomicFetchOp(1, false, AtomicFetchOrOp, value, mem, flagTemp, valueTemp, offsetTemp, maskTemp, output);
|
||||
}
|
||||
template<typename T, typename S>
|
||||
void atomicFetchOr16SignExtend(const S& value, const T& mem, Register temp, Register output) {
|
||||
MOZ_CRASH("NYI");
|
||||
void atomicFetchOr16SignExtend(const S& value, const T& mem, Register flagTemp,
|
||||
Register valueTemp, Register offsetTemp, Register maskTemp, Register output)
|
||||
{
|
||||
atomicFetchOp(2, true, AtomicFetchOrOp, value, mem, flagTemp, valueTemp, offsetTemp, maskTemp, output);
|
||||
}
|
||||
template<typename T, typename S>
|
||||
void atomicFetchOr16ZeroExtend(const S& value, const T& mem, Register temp, Register output) {
|
||||
MOZ_CRASH("NYI");
|
||||
void atomicFetchOr16ZeroExtend(const S& value, const T& mem, Register flagTemp,
|
||||
Register valueTemp, Register offsetTemp, Register maskTemp, Register output)
|
||||
{
|
||||
atomicFetchOp(2, false, AtomicFetchOrOp, value, mem, flagTemp, valueTemp, offsetTemp, maskTemp, output);
|
||||
}
|
||||
template<typename T, typename S>
|
||||
void atomicFetchOr32(const S& value, const T& mem, Register temp, Register output) {
|
||||
MOZ_CRASH("NYI");
|
||||
void atomicFetchOr32(const S& value, const T& mem, Register flagTemp,
|
||||
Register valueTemp, Register offsetTemp, Register maskTemp, Register output)
|
||||
{
|
||||
atomicFetchOp(4, false, AtomicFetchOrOp, value, mem, flagTemp, valueTemp, offsetTemp, maskTemp, output);
|
||||
}
|
||||
template <typename T, typename S>
|
||||
void atomicOr8(const T& value, const S& mem) {
|
||||
MOZ_CRASH("NYI");
|
||||
void atomicOr8(const T& value, const S& mem, Register flagTemp,
|
||||
Register valueTemp, Register offsetTemp, Register maskTemp)
|
||||
{
|
||||
atomicEffectOp(1, AtomicFetchOrOp, value, mem, flagTemp, valueTemp, offsetTemp, maskTemp);
|
||||
}
|
||||
template <typename T, typename S>
|
||||
void atomicOr16(const T& value, const S& mem) {
|
||||
MOZ_CRASH("NYI");
|
||||
void atomicOr16(const T& value, const S& mem, Register flagTemp,
|
||||
Register valueTemp, Register offsetTemp, Register maskTemp)
|
||||
{
|
||||
atomicEffectOp(2, AtomicFetchOrOp, value, mem, flagTemp, valueTemp, offsetTemp, maskTemp);
|
||||
}
|
||||
template <typename T, typename S>
|
||||
void atomicOr32(const T& value, const S& mem) {
|
||||
MOZ_CRASH("NYI");
|
||||
void atomicOr32(const T& value, const S& mem, Register flagTemp,
|
||||
Register valueTemp, Register offsetTemp, Register maskTemp)
|
||||
{
|
||||
atomicEffectOp(4, AtomicFetchOrOp, value, mem, flagTemp, valueTemp, offsetTemp, maskTemp);
|
||||
}
|
||||
|
||||
template<typename T, typename S>
|
||||
void atomicFetchXor8SignExtend(const S& value, const T& mem, Register temp, Register output) {
|
||||
MOZ_CRASH("NYI");
|
||||
void atomicFetchXor8SignExtend(const S& value, const T& mem, Register flagTemp,
|
||||
Register valueTemp, Register offsetTemp, Register maskTemp, Register output)
|
||||
{
|
||||
atomicFetchOp(1, true, AtomicFetchXorOp, value, mem, flagTemp, valueTemp, offsetTemp, maskTemp, output);
|
||||
}
|
||||
template<typename T, typename S>
|
||||
void atomicFetchXor8ZeroExtend(const S& value, const T& mem, Register temp, Register output) {
|
||||
MOZ_CRASH("NYI");
|
||||
void atomicFetchXor8ZeroExtend(const S& value, const T& mem, Register flagTemp,
|
||||
Register valueTemp, Register offsetTemp, Register maskTemp, Register output)
|
||||
{
|
||||
atomicFetchOp(1, false, AtomicFetchXorOp, value, mem, flagTemp, valueTemp, offsetTemp, maskTemp, output);
|
||||
}
|
||||
template<typename T, typename S>
|
||||
void atomicFetchXor16SignExtend(const S& value, const T& mem, Register temp, Register output) {
|
||||
MOZ_CRASH("NYI");
|
||||
void atomicFetchXor16SignExtend(const S& value, const T& mem, Register flagTemp,
|
||||
Register valueTemp, Register offsetTemp, Register maskTemp, Register output)
|
||||
{
|
||||
atomicFetchOp(2, true, AtomicFetchXorOp, value, mem, flagTemp, valueTemp, offsetTemp, maskTemp, output);
|
||||
}
|
||||
template<typename T, typename S>
|
||||
void atomicFetchXor16ZeroExtend(const S& value, const T& mem, Register temp, Register output) {
|
||||
MOZ_CRASH("NYI");
|
||||
void atomicFetchXor16ZeroExtend(const S& value, const T& mem, Register flagTemp,
|
||||
Register valueTemp, Register offsetTemp, Register maskTemp, Register output)
|
||||
{
|
||||
atomicFetchOp(2, false, AtomicFetchXorOp, value, mem, flagTemp, valueTemp, offsetTemp, maskTemp, output);
|
||||
}
|
||||
template<typename T, typename S>
|
||||
void atomicFetchXor32(const S& value, const T& mem, Register temp, Register output) {
|
||||
MOZ_CRASH("NYI");
|
||||
void atomicFetchXor32(const S& value, const T& mem, Register flagTemp,
|
||||
Register valueTemp, Register offsetTemp, Register maskTemp, Register output)
|
||||
{
|
||||
atomicFetchOp(4, false, AtomicFetchXorOp, value, mem, flagTemp, valueTemp, offsetTemp, maskTemp, output);
|
||||
}
|
||||
template <typename T, typename S>
|
||||
void atomicXor8(const T& value, const S& mem) {
|
||||
MOZ_CRASH("NYI");
|
||||
void atomicXor8(const T& value, const S& mem, Register flagTemp,
|
||||
Register valueTemp, Register offsetTemp, Register maskTemp)
|
||||
{
|
||||
atomicEffectOp(1, AtomicFetchXorOp, value, mem, flagTemp, valueTemp, offsetTemp, maskTemp);
|
||||
}
|
||||
template <typename T, typename S>
|
||||
void atomicXor16(const T& value, const S& mem) {
|
||||
MOZ_CRASH("NYI");
|
||||
void atomicXor16(const T& value, const S& mem, Register flagTemp,
|
||||
Register valueTemp, Register offsetTemp, Register maskTemp)
|
||||
{
|
||||
atomicEffectOp(2, AtomicFetchXorOp, value, mem, flagTemp, valueTemp, offsetTemp, maskTemp);
|
||||
}
|
||||
template <typename T, typename S>
|
||||
void atomicXor32(const T& value, const S& mem) {
|
||||
MOZ_CRASH("NYI");
|
||||
void atomicXor32(const T& value, const S& mem, Register flagTemp,
|
||||
Register valueTemp, Register offsetTemp, Register maskTemp)
|
||||
{
|
||||
atomicEffectOp(4, AtomicFetchXorOp, value, mem, flagTemp, valueTemp, offsetTemp, maskTemp);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void compareExchangeToTypedIntArray(Scalar::Type arrayType, const T& mem, Register oldval, Register newval,
|
||||
Register temp, Register valueTemp, Register offsetTemp, Register maskTemp,
|
||||
AnyRegister output);
|
||||
|
||||
template<typename T>
|
||||
void atomicExchangeToTypedIntArray(Scalar::Type arrayType, const T& mem, Register value,
|
||||
Register temp, Register valueTemp, Register offsetTemp, Register maskTemp,
|
||||
AnyRegister output);
|
||||
|
||||
void add32(Register src, Register dest);
|
||||
void add32(Imm32 imm, Register dest);
|
||||
void add32(Imm32 imm, const Address& dest);
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include "jit/JitFrames.h"
|
||||
#include "jit/JitSpewer.h"
|
||||
#include "jit/Linker.h"
|
||||
#include "jit/mips-shared/Bailouts-mips-shared.h"
|
||||
#include "jit/mips64/Bailouts-mips64.h"
|
||||
#include "jit/mips64/SharedICHelpers-mips64.h"
|
||||
#ifdef JS_ION_PERF
|
||||
# include "jit/PerfSpewer.h"
|
||||
@@ -554,10 +554,8 @@ JitRuntime::generateArgumentsRectifier(JSContext* cx, void** returnAddrOut)
|
||||
AutoFlushICache afc("ArgumentsRectifier");
|
||||
JitCode* code = linker.newCode<NoGC>(cx, OTHER_CODE);
|
||||
|
||||
CodeOffsetLabel returnLabel(returnOffset);
|
||||
returnLabel.fixup(&masm);
|
||||
if (returnAddrOut)
|
||||
*returnAddrOut = (void*) (code->raw() + returnLabel.offset());
|
||||
*returnAddrOut = (void*) (code->raw() + returnOffset);
|
||||
|
||||
#ifdef JS_ION_PERF
|
||||
writePerfSpewerJitCodeProfile(code, "ArgumentsRectifier");
|
||||
@@ -575,20 +573,14 @@ JitRuntime::generateArgumentsRectifier(JSContext* cx, void** returnAddrOut)
|
||||
* (See: JitRuntime::generateBailoutHandler).
|
||||
*/
|
||||
static void
|
||||
PushBailoutFrame(MacroAssembler& masm, uint32_t frameClass, Register spArg)
|
||||
PushBailoutFrame(MacroAssembler& masm, Register spArg)
|
||||
{
|
||||
// Make sure that alignment is proper.
|
||||
masm.checkStackAlignment();
|
||||
|
||||
// Push registers such that we can access them from [base + code].
|
||||
masm.PushRegsInMask(AllRegs);
|
||||
|
||||
// Push the frameSize_ or tableOffset_ stored in ra
|
||||
// Push the frameSize_ stored in ra
|
||||
// See: CodeGeneratorMIPS64::generateOutOfLineCode()
|
||||
masm.push(ra);
|
||||
|
||||
// Push frame class to stack
|
||||
masm.push(ImmWord(frameClass));
|
||||
// Push registers such that we can access them from [base + code].
|
||||
masm.PushRegsInMask(AllRegs);
|
||||
|
||||
// Put pointer to BailoutStack as first argument to the Bailout()
|
||||
masm.movePtr(StackPointer, spArg);
|
||||
@@ -597,12 +589,11 @@ PushBailoutFrame(MacroAssembler& masm, uint32_t frameClass, Register spArg)
|
||||
static void
|
||||
GenerateBailoutThunk(JSContext* cx, MacroAssembler& masm, uint32_t frameClass)
|
||||
{
|
||||
PushBailoutFrame(masm, frameClass, a0);
|
||||
PushBailoutFrame(masm, a0);
|
||||
|
||||
// Put pointer to BailoutInfo
|
||||
static const uint32_t sizeOfBailoutInfo = sizeof(uintptr_t) * 2;
|
||||
masm.subPtr(Imm32(sizeOfBailoutInfo), StackPointer);
|
||||
masm.storePtr(ImmPtr(nullptr), Address(StackPointer, 0));
|
||||
masm.movePtr(StackPointer, a1);
|
||||
|
||||
masm.setupAlignedABICall();
|
||||
@@ -613,6 +604,13 @@ GenerateBailoutThunk(JSContext* cx, MacroAssembler& masm, uint32_t frameClass)
|
||||
// Get BailoutInfo pointer
|
||||
masm.loadPtr(Address(StackPointer, 0), a2);
|
||||
|
||||
// Stack is:
|
||||
// [frame]
|
||||
// snapshotOffset
|
||||
// frameSize
|
||||
// [bailoutFrame]
|
||||
// [bailoutInfo]
|
||||
//
|
||||
// Remove both the bailout frame and the topmost Ion frame's stack.
|
||||
// Load frameSize from stack
|
||||
masm.loadPtr(Address(StackPointer,
|
||||
@@ -1197,7 +1195,7 @@ JitRuntime::generateProfilerExitFrameTailStub(JSContext* cx)
|
||||
{
|
||||
// scratch2 := StackPointer + Descriptor.size*1 + JitFrameLayout::Size();
|
||||
masm.as_daddu(scratch2, StackPointer, scratch1);
|
||||
masm.add32(Imm32(JitFrameLayout::Size()), scratch2);
|
||||
masm.addPtr(Imm32(JitFrameLayout::Size()), scratch2);
|
||||
masm.loadPtr(Address(scratch2, RectifierFrameLayout::offsetOfDescriptor()), scratch3);
|
||||
masm.ma_dsrl(scratch1, scratch3, Imm32(FRAMESIZE_SHIFT));
|
||||
masm.and32(Imm32((1 << FRAMETYPE_BITS) - 1), scratch3);
|
||||
@@ -1218,7 +1216,7 @@ JitRuntime::generateProfilerExitFrameTailStub(JSContext* cx)
|
||||
|
||||
// scratch3 := RectFrame + Rect-Descriptor.Size + RectifierFrameLayout::Size()
|
||||
masm.as_daddu(scratch3, scratch2, scratch1);
|
||||
masm.add32(Imm32(RectifierFrameLayout::Size()), scratch3);
|
||||
masm.addPtr(Imm32(RectifierFrameLayout::Size()), scratch3);
|
||||
masm.storePtr(scratch3, lastProfilingFrame);
|
||||
masm.ret();
|
||||
|
||||
|
||||
+2
-1
@@ -2039,7 +2039,8 @@ GenerateLcovInfo(JSContext* cx, JSCompartment* comp, GenericPrinter& out)
|
||||
|
||||
// Queue the script in the list of script associated to the
|
||||
// current source.
|
||||
if (!queue.append(fun.getOrCreateScript(cx)))
|
||||
JSScript* childScript = fun.getOrCreateScript(cx);
|
||||
if (!childScript || !queue.append(childScript))
|
||||
return false;
|
||||
}
|
||||
} while (!queue.empty());
|
||||
|
||||
+4
-10
@@ -4098,17 +4098,11 @@ JSScript::argumentsOptimizationFailed(JSContext* cx, HandleScript script)
|
||||
continue;
|
||||
AbstractFramePtr frame = i.abstractFramePtr();
|
||||
if (frame.isFunctionFrame() && frame.script() == script) {
|
||||
/* We crash on OOM since cleaning up here would be complicated. */
|
||||
AutoEnterOOMUnsafeRegion oomUnsafe;
|
||||
ArgumentsObject* argsobj = ArgumentsObject::createExpected(cx, frame);
|
||||
if (!argsobj) {
|
||||
/*
|
||||
* We can't leave stack frames with script->needsArgsObj but no
|
||||
* arguments object. It is, however, safe to leave frames with
|
||||
* an arguments object but !script->needsArgsObj.
|
||||
*/
|
||||
script->needsArgsObj_ = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!argsobj)
|
||||
oomUnsafe.crash("JSScript::argumentsOptimizationFailed");
|
||||
SetFrameArgumentsObject(cx, frame, script, argsobj);
|
||||
}
|
||||
}
|
||||
|
||||
+28
-13
@@ -2382,23 +2382,38 @@ BuildFlatMatchArray(JSContext* cx, HandleString textstr, const FlatMatch& fm,
|
||||
return true;
|
||||
}
|
||||
|
||||
/* For this non-global match, produce a RegExp.exec-style array. */
|
||||
RootedObject obj(cx, NewDenseEmptyArray(cx));
|
||||
if (!obj)
|
||||
/* Get the templateObject that defines the shape and type of the output object */
|
||||
JSObject* templateObject = cx->compartment()->regExps.getOrCreateMatchResultTemplateObject(cx);
|
||||
if (!templateObject)
|
||||
return false;
|
||||
|
||||
RootedValue patternVal(cx, StringValue(fm.pattern()));
|
||||
RootedValue matchVal(cx, Int32Value(fm.match()));
|
||||
RootedValue textVal(cx, StringValue(textstr));
|
||||
|
||||
if (!DefineElement(cx, obj, 0, patternVal) ||
|
||||
!DefineProperty(cx, obj, cx->names().index, matchVal) ||
|
||||
!DefineProperty(cx, obj, cx->names().input, textVal))
|
||||
{
|
||||
RootedArrayObject arr(cx, NewDenseFullyAllocatedArrayWithTemplate(cx, 1, templateObject));
|
||||
if (!arr)
|
||||
return false;
|
||||
}
|
||||
|
||||
args->rval().setObject(*obj);
|
||||
/* Store a Value for each pair. */
|
||||
arr->setDenseInitializedLength(1);
|
||||
arr->initDenseElement(0, StringValue(fm.pattern()));
|
||||
|
||||
/* Set the |index| property. (TemplateObject positions it in slot 0) */
|
||||
arr->setSlot(0, Int32Value(fm.match()));
|
||||
|
||||
/* Set the |input| property. (TemplateObject positions it in slot 1) */
|
||||
arr->setSlot(1, StringValue(textstr));
|
||||
|
||||
#ifdef DEBUG
|
||||
RootedValue test(cx);
|
||||
RootedId id(cx, NameToId(cx->names().index));
|
||||
if (!NativeGetProperty(cx, arr, id, &test))
|
||||
return false;
|
||||
MOZ_ASSERT(test == arr->getSlot(0));
|
||||
id = NameToId(cx->names().input);
|
||||
if (!NativeGetProperty(cx, arr, id, &test))
|
||||
return false;
|
||||
MOZ_ASSERT(test == arr->getSlot(1));
|
||||
#endif
|
||||
|
||||
args->rval().setObject(*arr);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
+54
-88
@@ -40,96 +40,24 @@ JS_STATIC_ASSERT(GlobalFlag == JSREG_GLOB);
|
||||
JS_STATIC_ASSERT(MultilineFlag == JSREG_MULTILINE);
|
||||
JS_STATIC_ASSERT(StickyFlag == JSREG_STICKY);
|
||||
|
||||
/* RegExpObjectBuilder */
|
||||
|
||||
RegExpObjectBuilder::RegExpObjectBuilder(ExclusiveContext* cx, RegExpObject* reobj)
|
||||
: cx(cx), reobj_(cx, reobj)
|
||||
{}
|
||||
|
||||
bool
|
||||
RegExpObjectBuilder::getOrCreate()
|
||||
RegExpObject*
|
||||
js::RegExpAlloc(ExclusiveContext* cx)
|
||||
{
|
||||
if (reobj_)
|
||||
return true;
|
||||
|
||||
// Note: RegExp objects are always allocated in the tenured heap. This is
|
||||
// not strictly required, but simplifies embedding them in jitcode.
|
||||
reobj_ = NewBuiltinClassInstance<RegExpObject>(cx, TenuredObject);
|
||||
if (!reobj_)
|
||||
return false;
|
||||
reobj_->initPrivate(nullptr);
|
||||
RegExpObject* regexp = NewBuiltinClassInstance<RegExpObject>(cx, TenuredObject);
|
||||
if (!regexp)
|
||||
return nullptr;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
RegExpObjectBuilder::getOrCreateClone(HandleObjectGroup group)
|
||||
{
|
||||
MOZ_ASSERT(!reobj_);
|
||||
MOZ_ASSERT(group->clasp() == &RegExpObject::class_);
|
||||
|
||||
// Note: RegExp objects are always allocated in the tenured heap. This is
|
||||
// not strictly required, but simplifies embedding them in jitcode.
|
||||
reobj_ = NewObjectWithGroup<RegExpObject>(cx->asJSContext(), group, TenuredObject);
|
||||
if (!reobj_)
|
||||
return false;
|
||||
reobj_->initPrivate(nullptr);
|
||||
|
||||
return true;
|
||||
regexp->initPrivate(nullptr);
|
||||
return regexp;
|
||||
}
|
||||
|
||||
RegExpObject*
|
||||
RegExpObjectBuilder::build(HandleAtom source, RegExpShared& shared)
|
||||
js::InitializeRegExp(ExclusiveContext* cx, Handle<RegExpObject*> regexp, HandleAtom source,
|
||||
RegExpFlag flags)
|
||||
{
|
||||
if (!getOrCreate())
|
||||
return nullptr;
|
||||
|
||||
if (!reobj_->init(cx, source, shared.getFlags()))
|
||||
return nullptr;
|
||||
|
||||
reobj_->setShared(shared);
|
||||
return reobj_;
|
||||
}
|
||||
|
||||
RegExpObject*
|
||||
RegExpObjectBuilder::build(HandleAtom source, RegExpFlag flags)
|
||||
{
|
||||
if (!getOrCreate())
|
||||
return nullptr;
|
||||
|
||||
return reobj_->init(cx, source, flags) ? reobj_.get() : nullptr;
|
||||
}
|
||||
|
||||
RegExpObject*
|
||||
RegExpObjectBuilder::clone(Handle<RegExpObject*> other)
|
||||
{
|
||||
RootedObjectGroup group(cx, other->group());
|
||||
if (!getOrCreateClone(group))
|
||||
return nullptr;
|
||||
|
||||
/*
|
||||
* Check that the RegExpShared for the original is okay to use in
|
||||
* the clone -- if the |RegExpStatics| provides more flags we'll
|
||||
* need a different |RegExpShared|.
|
||||
*/
|
||||
RegExpStatics* res = other->getProto()->global().getRegExpStatics(cx);
|
||||
if (!res)
|
||||
return nullptr;
|
||||
|
||||
RegExpFlag origFlags = other->getFlags();
|
||||
RegExpFlag staticsFlags = res->getFlags();
|
||||
if ((origFlags & staticsFlags) != staticsFlags) {
|
||||
RegExpFlag newFlags = RegExpFlag(origFlags | staticsFlags);
|
||||
Rooted<JSAtom*> source(cx, other->getSource());
|
||||
return build(source, newFlags);
|
||||
}
|
||||
|
||||
RegExpGuard g(cx);
|
||||
if (!other->getShared(cx->asJSContext(), &g))
|
||||
return nullptr;
|
||||
|
||||
Rooted<JSAtom*> source(cx, other->getSource());
|
||||
return build(source, *g);
|
||||
return regexp->init(cx, source, flags) ? regexp : nullptr;
|
||||
}
|
||||
|
||||
/* MatchPairs */
|
||||
@@ -292,8 +220,11 @@ RegExpObject::createNoStatics(ExclusiveContext* cx, HandleAtom source, RegExpFla
|
||||
if (!irregexp::ParsePatternSyntax(*tokenStream, alloc, source))
|
||||
return nullptr;
|
||||
|
||||
RegExpObjectBuilder builder(cx);
|
||||
return builder.build(source, flags);
|
||||
Rooted<RegExpObject*> regexp(cx, RegExpAlloc(cx));
|
||||
if (!regexp)
|
||||
return nullptr;
|
||||
|
||||
return InitializeRegExp(cx, regexp, source, flags);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -945,11 +876,46 @@ RegExpCompartment::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf)
|
||||
JSObject*
|
||||
js::CloneRegExpObject(JSContext* cx, JSObject* obj_)
|
||||
{
|
||||
RegExpObjectBuilder builder(cx);
|
||||
Rooted<RegExpObject*> regex(cx, &obj_->as<RegExpObject>());
|
||||
JSObject* res = builder.clone(regex);
|
||||
MOZ_ASSERT_IF(res, res->group() == regex->group());
|
||||
return res;
|
||||
|
||||
// Check that the RegExpShared for |regex| is okay to reuse in the clone.
|
||||
// If the |RegExpStatics| provides additional flags, we'll need a new
|
||||
// |RegExpShared|.
|
||||
RegExpStatics* currentStatics = regex->getProto()->global().getRegExpStatics(cx);
|
||||
if (!currentStatics)
|
||||
return nullptr;
|
||||
|
||||
Rooted<JSAtom*> source(cx, regex->getSource());
|
||||
|
||||
RegExpFlag origFlags = regex->getFlags();
|
||||
RegExpFlag staticsFlags = currentStatics->getFlags();
|
||||
if ((origFlags & staticsFlags) != staticsFlags) {
|
||||
Rooted<RegExpObject*> clone(cx, RegExpAlloc(cx));
|
||||
if (!clone)
|
||||
return nullptr;
|
||||
|
||||
return InitializeRegExp(cx, clone, source, RegExpFlag(origFlags | staticsFlags));
|
||||
}
|
||||
|
||||
// Otherwise, the clone can use |regexp|'s RegExpShared.
|
||||
RootedObjectGroup group(cx, regex->group());
|
||||
|
||||
// Note: RegExp objects are always allocated in the tenured heap. This is
|
||||
// not strictly required, but it simplifies embedding them in jitcode.
|
||||
Rooted<RegExpObject*> clone(cx, NewObjectWithGroup<RegExpObject>(cx, group, TenuredObject));
|
||||
if (!clone)
|
||||
return nullptr;
|
||||
clone->initPrivate(nullptr);
|
||||
|
||||
RegExpGuard g(cx);
|
||||
if (!regex->getShared(cx, &g))
|
||||
return nullptr;
|
||||
|
||||
if (!InitializeRegExp(cx, clone, source, g->getFlags()))
|
||||
return nullptr;
|
||||
|
||||
clone->setShared(*g.re());
|
||||
return clone;
|
||||
}
|
||||
|
||||
static bool
|
||||
|
||||
+13
-20
@@ -63,28 +63,19 @@ enum RegExpRunStatus
|
||||
RegExpRunStatus_Success_NotFound
|
||||
};
|
||||
|
||||
class RegExpObjectBuilder
|
||||
{
|
||||
ExclusiveContext* cx;
|
||||
Rooted<RegExpObject*> reobj_;
|
||||
extern RegExpObject*
|
||||
RegExpAlloc(ExclusiveContext* cx);
|
||||
|
||||
bool getOrCreate();
|
||||
bool getOrCreateClone(HandleObjectGroup group);
|
||||
extern RegExpObject*
|
||||
InitializeRegExp(ExclusiveContext* cx, Handle<RegExpObject*> regexp, HandleAtom source,
|
||||
RegExpFlag flags);
|
||||
|
||||
public:
|
||||
explicit RegExpObjectBuilder(ExclusiveContext* cx, RegExpObject* reobj = nullptr);
|
||||
// |regexp| is under-typed because this function's used in the JIT.
|
||||
extern JSObject*
|
||||
CloneRegExpObject(JSContext* cx, JSObject* regexp);
|
||||
|
||||
RegExpObject* reobj() { return reobj_; }
|
||||
|
||||
RegExpObject* build(HandleAtom source, RegExpFlag flags);
|
||||
RegExpObject* build(HandleAtom source, RegExpShared& shared);
|
||||
|
||||
/* Perform a VM-internal clone. */
|
||||
RegExpObject* clone(Handle<RegExpObject*> other);
|
||||
};
|
||||
|
||||
JSObject*
|
||||
CloneRegExpObject(JSContext* cx, JSObject* obj);
|
||||
extern JSObject*
|
||||
CreateRegExpPrototype(JSContext* cx, JSProtoKey key);
|
||||
|
||||
/*
|
||||
* A RegExpShared is the compiled representation of a regexp. A RegExpShared is
|
||||
@@ -457,7 +448,9 @@ class RegExpObject : public NativeObject
|
||||
static void trace(JSTracer* trc, JSObject* obj);
|
||||
|
||||
private:
|
||||
friend class RegExpObjectBuilder;
|
||||
friend RegExpObject*
|
||||
InitializeRegExp(ExclusiveContext* cx, Handle<RegExpObject*> regexp, HandleAtom source,
|
||||
RegExpFlag flags);
|
||||
|
||||
bool init(ExclusiveContext* cx, HandleAtom source, RegExpFlag flags);
|
||||
|
||||
|
||||
@@ -6,17 +6,15 @@
|
||||
|
||||
DEFINES['ANDROID_PACKAGE_NAME'] = CONFIG['ANDROID_PACKAGE_NAME']
|
||||
|
||||
base = '/mobile/android/tests/browser/robocop/'
|
||||
|
||||
ANDROID_APK_NAME = 'robocop-debug'
|
||||
ANDROID_APK_PACKAGE = 'org.mozilla.roboexample.test'
|
||||
ANDROID_ASSETS_DIRS += [base + 'assets']
|
||||
ANDROID_ASSETS_DIRS += ['assets']
|
||||
|
||||
TEST_HARNESS_FILES.testing.mochitest += [
|
||||
base + 'robocop.ini',
|
||||
base + 'robocop_autophone.ini',
|
||||
'robocop.ini',
|
||||
'robocop_autophone.ini',
|
||||
]
|
||||
TEST_HARNESS_FILES.testing.mochitest.tests.robocop += [base + x for x in [
|
||||
TEST_HARNESS_FILES.testing.mochitest.tests.robocop += [
|
||||
'*.html',
|
||||
'*.jpg',
|
||||
'*.mp4',
|
||||
@@ -25,8 +23,7 @@ TEST_HARNESS_FILES.testing.mochitest.tests.robocop += [base + x for x in [
|
||||
'*.swf',
|
||||
'*.webm',
|
||||
'*.xml',
|
||||
'reader_mode_pages/**', # The ** preserves directory structure.
|
||||
'robocop*.js',
|
||||
'test*.js',
|
||||
]]
|
||||
# The ** below preserves directory structure.
|
||||
TEST_HARNESS_FILES.testing.mochitest.tests.robocop.reader_mode_pages += [base + 'reader_mode_pages/**']
|
||||
]
|
||||
@@ -44,86 +44,3 @@ class UnrecognizedArgumentError(MachError):
|
||||
|
||||
self.command = command
|
||||
self.arguments = arguments
|
||||
|
||||
|
||||
class MethodHandler(object):
|
||||
"""Describes a Python method that implements a mach command.
|
||||
|
||||
Instances of these are produced by mach when it processes classes
|
||||
defining mach commands.
|
||||
"""
|
||||
__slots__ = (
|
||||
# The Python class providing the command. This is the class type not
|
||||
# an instance of the class. Mach will instantiate a new instance of
|
||||
# the class if the command is executed.
|
||||
'cls',
|
||||
|
||||
# Whether the __init__ method of the class should receive a mach
|
||||
# context instance. This should only affect the mach driver and how
|
||||
# it instantiates classes.
|
||||
'pass_context',
|
||||
|
||||
# The name of the method providing the command. In other words, this
|
||||
# is the str name of the attribute on the class type corresponding to
|
||||
# the name of the function.
|
||||
'method',
|
||||
|
||||
# The name of the command.
|
||||
'name',
|
||||
|
||||
# String category this command belongs to.
|
||||
'category',
|
||||
|
||||
# Description of the purpose of this command.
|
||||
'description',
|
||||
|
||||
# Docstring associated with command.
|
||||
'docstring',
|
||||
|
||||
# Functions used to 'skip' commands if they don't meet the conditions
|
||||
# in a given context.
|
||||
'conditions',
|
||||
|
||||
# argparse.ArgumentParser instance to use as the basis for command
|
||||
# arguments.
|
||||
'_parser',
|
||||
'parser',
|
||||
|
||||
# Arguments added to this command's parser. This is a 2-tuple of
|
||||
# positional and named arguments, respectively.
|
||||
'arguments',
|
||||
|
||||
# Argument groups added to this command's parser.
|
||||
'argument_group_names',
|
||||
|
||||
# Dict of string to MethodHandler defining sub commands for this
|
||||
# command.
|
||||
'subcommand_handlers',
|
||||
)
|
||||
|
||||
def __init__(self, cls, method, name, category=None, description=None,
|
||||
docstring=None, conditions=None, parser=None, arguments=None,
|
||||
argument_group_names=None, pass_context=False,
|
||||
subcommand_handlers=None):
|
||||
|
||||
self.cls = cls
|
||||
self.method = method
|
||||
self.name = name
|
||||
self.category = category
|
||||
self.description = description
|
||||
self.docstring = docstring
|
||||
self.conditions = conditions or []
|
||||
self.arguments = arguments or []
|
||||
self.argument_group_names = argument_group_names or []
|
||||
self.pass_context = pass_context
|
||||
self.subcommand_handlers = subcommand_handlers or {}
|
||||
self._parser = parser
|
||||
|
||||
@property
|
||||
def parser(self):
|
||||
# creating cli parsers at command dispatch time can potentially be
|
||||
# expensive, make it possible to lazy load them.
|
||||
if callable(self._parser):
|
||||
self._parser = self._parser()
|
||||
return self._parser
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ from __future__ import absolute_import, print_function, unicode_literals
|
||||
from mach.decorators import (
|
||||
CommandProvider,
|
||||
Command,
|
||||
CommandArgument,
|
||||
)
|
||||
|
||||
|
||||
@@ -15,18 +16,29 @@ class BuiltinCommands(object):
|
||||
def __init__(self, context):
|
||||
self.context = context
|
||||
|
||||
@property
|
||||
def command_keys(self):
|
||||
# NOTE 'REMOVED' is a function in testing/mochitest/mach_commands.py
|
||||
return (k for k, v in self.context.commands.command_handlers.items()
|
||||
if not v.conditions or v.conditions[0].__name__ != 'REMOVED')
|
||||
|
||||
@Command('mach-commands', category='misc',
|
||||
description='List all mach commands.')
|
||||
def commands(self):
|
||||
print("\n".join(self.context.commands.command_handlers.keys()))
|
||||
print("\n".join(self.command_keys))
|
||||
|
||||
@Command('mach-debug-commands', category='misc',
|
||||
description='Show info about available mach commands.')
|
||||
def debug_commands(self):
|
||||
@CommandArgument('match', metavar='MATCH', default=None, nargs='?',
|
||||
help='Only display commands containing given substring.')
|
||||
def debug_commands(self, match=None):
|
||||
import inspect
|
||||
|
||||
handlers = self.context.commands.command_handlers
|
||||
for command in sorted(handlers.keys()):
|
||||
for command in sorted(self.command_keys):
|
||||
if match and match not in command:
|
||||
continue
|
||||
|
||||
handler = handlers[command]
|
||||
cls = handler.cls
|
||||
method = getattr(cls, getattr(handler, 'method'))
|
||||
|
||||
+134
-63
@@ -9,15 +9,90 @@ import collections
|
||||
import inspect
|
||||
import types
|
||||
|
||||
from .base import (
|
||||
MachError,
|
||||
MethodHandler
|
||||
)
|
||||
|
||||
from .base import MachError
|
||||
from .config import ConfigProvider
|
||||
from .registrar import Registrar
|
||||
|
||||
|
||||
class _MachCommand(object):
|
||||
"""Container for mach command metadata.
|
||||
|
||||
Mach commands contain lots of attributes. This class exists to capture them
|
||||
in a sane way so tuples, etc aren't used instead.
|
||||
"""
|
||||
__slots__ = (
|
||||
# Content from decorator arguments to define the command.
|
||||
'name',
|
||||
'subcommand',
|
||||
'category',
|
||||
'description',
|
||||
'conditions',
|
||||
'_parser',
|
||||
'arguments',
|
||||
'argument_group_names',
|
||||
|
||||
# Describes how dispatch is performed.
|
||||
|
||||
# The Python class providing the command. This is the class type not
|
||||
# an instance of the class. Mach will instantiate a new instance of
|
||||
# the class if the command is executed.
|
||||
'cls',
|
||||
|
||||
# Whether the __init__ method of the class should receive a mach
|
||||
# context instance. This should only affect the mach driver and how
|
||||
# it instantiates classes.
|
||||
'pass_context',
|
||||
|
||||
# The name of the method providing the command. In other words, this
|
||||
# is the str name of the attribute on the class type corresponding to
|
||||
# the name of the function.
|
||||
'method',
|
||||
|
||||
# Dict of string to _MachCommand defining sub-commands for this
|
||||
# command.
|
||||
'subcommand_handlers',
|
||||
)
|
||||
|
||||
def __init__(self, name=None, subcommand=None, category=None,
|
||||
description=None, conditions=None, parser=None):
|
||||
self.name = name
|
||||
self.subcommand = subcommand
|
||||
self.category = category
|
||||
self.description = description
|
||||
self.conditions = conditions or []
|
||||
self._parser = parser
|
||||
self.arguments = []
|
||||
self.argument_group_names = []
|
||||
|
||||
self.cls = None
|
||||
self.pass_context = None
|
||||
self.method = None
|
||||
self.subcommand_handlers = {}
|
||||
|
||||
@property
|
||||
def parser(self):
|
||||
# Creating CLI parsers at command dispatch time can be expensive. Make
|
||||
# it possible to lazy load them by using functions.
|
||||
if callable(self._parser):
|
||||
self._parser = self._parser()
|
||||
|
||||
return self._parser
|
||||
|
||||
@property
|
||||
def docstring(self):
|
||||
return self.cls.__dict__[self.method].__doc__
|
||||
|
||||
def __ior__(self, other):
|
||||
if not isinstance(other, _MachCommand):
|
||||
raise ValueError('can only operate on _MachCommand instances')
|
||||
|
||||
for a in self.__slots__:
|
||||
if not getattr(self, a):
|
||||
setattr(self, a, getattr(other, a))
|
||||
|
||||
return self
|
||||
|
||||
|
||||
def CommandProvider(cls):
|
||||
"""Class decorator to denote that it provides subcommands for Mach.
|
||||
|
||||
@@ -47,6 +122,8 @@ def CommandProvider(cls):
|
||||
if len(spec.args) == 2:
|
||||
pass_context = True
|
||||
|
||||
seen_commands = set()
|
||||
|
||||
# We scan __dict__ because we only care about the classes own attributes,
|
||||
# not inherited ones. If we did inherited attributes, we could potentially
|
||||
# define commands multiple times. We also sort keys so commands defined in
|
||||
@@ -57,40 +134,37 @@ def CommandProvider(cls):
|
||||
if not isinstance(value, types.FunctionType):
|
||||
continue
|
||||
|
||||
command_name, category, description, conditions, parser = getattr(
|
||||
value, '_mach_command', (None, None, None, None, None))
|
||||
|
||||
if command_name is None:
|
||||
command = getattr(value, '_mach_command', None)
|
||||
if not command:
|
||||
continue
|
||||
|
||||
if conditions is None and Registrar.require_conditions:
|
||||
# Ignore subcommands for now: we handle them later.
|
||||
if command.subcommand:
|
||||
continue
|
||||
|
||||
seen_commands.add(command.name)
|
||||
|
||||
if not command.conditions and Registrar.require_conditions:
|
||||
continue
|
||||
|
||||
msg = 'Mach command \'%s\' implemented incorrectly. ' + \
|
||||
'Conditions argument must take a list ' + \
|
||||
'of functions. Found %s instead.'
|
||||
|
||||
conditions = conditions or []
|
||||
if not isinstance(conditions, collections.Iterable):
|
||||
msg = msg % (command_name, type(conditions))
|
||||
if not isinstance(command.conditions, collections.Iterable):
|
||||
msg = msg % (command.name, type(command.conditions))
|
||||
raise MachError(msg)
|
||||
|
||||
for c in conditions:
|
||||
for c in command.conditions:
|
||||
if not hasattr(c, '__call__'):
|
||||
msg = msg % (command_name, type(c))
|
||||
msg = msg % (command.name, type(c))
|
||||
raise MachError(msg)
|
||||
|
||||
arguments = getattr(value, '_mach_command_args', None)
|
||||
command.cls = cls
|
||||
command.method = attr
|
||||
command.pass_context = pass_context
|
||||
|
||||
argument_group_names = getattr(value, '_mach_command_arg_group_names', None)
|
||||
|
||||
handler = MethodHandler(cls, attr, command_name, category=category,
|
||||
description=description, docstring=value.__doc__,
|
||||
conditions=conditions, parser=parser,
|
||||
arguments=arguments, argument_group_names=argument_group_names,
|
||||
pass_context=pass_context)
|
||||
|
||||
Registrar.register_command_handler(handler)
|
||||
Registrar.register_command_handler(command)
|
||||
|
||||
# Now do another pass to get sub-commands. We do this in two passes so
|
||||
# we can check the parent command existence without having to hold
|
||||
@@ -101,32 +175,33 @@ def CommandProvider(cls):
|
||||
if not isinstance(value, types.FunctionType):
|
||||
continue
|
||||
|
||||
command, subcommand, description = getattr(value, '_mach_subcommand',
|
||||
(None, None, None))
|
||||
|
||||
command = getattr(value, '_mach_command', None)
|
||||
if not command:
|
||||
continue
|
||||
|
||||
if command not in Registrar.command_handlers:
|
||||
# It is a regular command.
|
||||
if not command.subcommand:
|
||||
continue
|
||||
|
||||
if command.name not in seen_commands:
|
||||
raise MachError('Command referenced by sub-command does not '
|
||||
'exist: %s' % command)
|
||||
'exist: %s' % command.name)
|
||||
|
||||
arguments = getattr(value, '_mach_command_args', None)
|
||||
argument_group_names = getattr(value, '_mach_command_arg_group_names', None)
|
||||
if command.name not in Registrar.command_handlers:
|
||||
continue
|
||||
|
||||
handler = MethodHandler(cls, attr, subcommand, description=description,
|
||||
docstring=value.__doc__,
|
||||
arguments=arguments, argument_group_names=argument_group_names,
|
||||
pass_context=pass_context)
|
||||
parent = Registrar.command_handlers[command]
|
||||
command.cls = cls
|
||||
command.method = attr
|
||||
command.pass_context = pass_context
|
||||
parent = Registrar.command_handlers[command.name]
|
||||
|
||||
if parent.parser:
|
||||
if parent._parser:
|
||||
raise MachError('cannot declare sub commands against a command '
|
||||
'that has a parser installed: %s' % command)
|
||||
if subcommand in parent.subcommand_handlers:
|
||||
raise MachError('sub-command already defined: %s' % subcommand)
|
||||
if command.subcommand in parent.subcommand_handlers:
|
||||
raise MachError('sub-command already defined: %s' % command.subcommand)
|
||||
|
||||
parent.subcommand_handlers[subcommand] = handler
|
||||
parent.subcommand_handlers[command.subcommand] = command
|
||||
|
||||
return cls
|
||||
|
||||
@@ -152,17 +227,14 @@ class Command(object):
|
||||
def foo(self):
|
||||
pass
|
||||
"""
|
||||
def __init__(self, name, category=None, description=None, conditions=None,
|
||||
parser=None):
|
||||
self._name = name
|
||||
self._category = category
|
||||
self._description = description
|
||||
self._conditions = conditions
|
||||
self._parser = parser
|
||||
def __init__(self, name, **kwargs):
|
||||
self._mach_command = _MachCommand(name=name, **kwargs)
|
||||
|
||||
def __call__(self, func):
|
||||
func._mach_command = (self._name, self._category, self._description,
|
||||
self._conditions, self._parser)
|
||||
if not hasattr(func, '_mach_command'):
|
||||
func._mach_command = _MachCommand()
|
||||
|
||||
func._mach_command |= self._mach_command
|
||||
|
||||
return func
|
||||
|
||||
@@ -184,13 +256,14 @@ class SubCommand(object):
|
||||
description -- A textual description for this sub command.
|
||||
"""
|
||||
def __init__(self, command, subcommand, description=None):
|
||||
self._command = command
|
||||
self._subcommand = subcommand
|
||||
self._description = description
|
||||
self._mach_command = _MachCommand(name=command, subcommand=subcommand,
|
||||
description=description)
|
||||
|
||||
def __call__(self, func):
|
||||
func._mach_subcommand = (self._command, self._subcommand,
|
||||
self._description)
|
||||
if not hasattr(func, '_mach_command'):
|
||||
func._mach_command = _MachCommand()
|
||||
|
||||
func._mach_command |= self._mach_command
|
||||
|
||||
return func
|
||||
|
||||
@@ -217,11 +290,10 @@ class CommandArgument(object):
|
||||
self._command_args = (args, kwargs)
|
||||
|
||||
def __call__(self, func):
|
||||
command_args = getattr(func, '_mach_command_args', [])
|
||||
if not hasattr(func, '_mach_command'):
|
||||
func._mach_command = _MachCommand()
|
||||
|
||||
command_args.insert(0, self._command_args)
|
||||
|
||||
func._mach_command_args = command_args
|
||||
func._mach_command.arguments.insert(0, self._command_args)
|
||||
|
||||
return func
|
||||
|
||||
@@ -250,11 +322,10 @@ class CommandArgumentGroup(object):
|
||||
self._group_name = group_name
|
||||
|
||||
def __call__(self, func):
|
||||
command_arg_group_names = getattr(func, '_mach_command_arg_group_names', [])
|
||||
if not hasattr(func, '_mach_command'):
|
||||
func._mach_command = _MachCommand()
|
||||
|
||||
command_arg_group_names.insert(0, self._group_name)
|
||||
|
||||
func._mach_command_arg_group_names = command_arg_group_names
|
||||
func._mach_command.argument_group_names.insert(0, self._group_name)
|
||||
|
||||
return func
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
from __future__ import absolute_import, unicode_literals, print_function
|
||||
|
||||
from mozbuild.backend.common import CommonBackend
|
||||
from mozbuild.frontend.data import (
|
||||
@@ -16,12 +16,29 @@ from mozbuild.frontend.data import (
|
||||
Resources,
|
||||
VariablePassthru,
|
||||
)
|
||||
from mozbuild.jar import JarManifestParser
|
||||
from mozbuild.makeutil import Makefile
|
||||
from mozbuild.preprocessor import Preprocessor
|
||||
from mozbuild.util import OrderedDefaultDict
|
||||
from mozpack.manifests import InstallManifest
|
||||
import mozpack.path as mozpath
|
||||
from collections import OrderedDict
|
||||
from itertools import chain
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
class OverwriteInstallManifest(InstallManifest):
|
||||
def _add_entry(self, dest, entry):
|
||||
# Because of bug 1210703, we can't let the default behavior of
|
||||
# InstallManifest._add_entry, which is to error out.
|
||||
# To match the current behavior of the recursive make libs tier, we
|
||||
# keep the last one given, but still warn about it.
|
||||
if dest in self._dests:
|
||||
print('Warning: Item already in manifest: %s' % dest,
|
||||
file=sys.stderr)
|
||||
|
||||
self._dests[dest] = entry
|
||||
|
||||
|
||||
class FasterMakeBackend(CommonBackend):
|
||||
@@ -30,17 +47,19 @@ class FasterMakeBackend(CommonBackend):
|
||||
|
||||
self._seen_directories = set()
|
||||
self._defines = dict()
|
||||
self._jar_manifests = OrderedDict()
|
||||
|
||||
self._manifest_entries = OrderedDefaultDict(list)
|
||||
|
||||
self._install_manifests = OrderedDefaultDict(InstallManifest)
|
||||
self._install_manifests = OrderedDefaultDict(OverwriteInstallManifest)
|
||||
|
||||
def _add_preprocess(self, obj, path, dest, **kwargs):
|
||||
target = mozpath.basename(path)
|
||||
# This matches what PP_TARGETS do in config/rules.
|
||||
if target.endswith('.in'):
|
||||
target = target[:-3]
|
||||
self._dependencies = OrderedDefaultDict(list)
|
||||
|
||||
def _add_preprocess(self, obj, path, dest, target=None, **kwargs):
|
||||
if target is None:
|
||||
target = mozpath.basename(path)
|
||||
# This matches what PP_TARGETS do in config/rules.
|
||||
if target.endswith('.in'):
|
||||
target = target[:-3]
|
||||
depfile = mozpath.join(
|
||||
self.environment.topobjdir, 'faster', '.deps',
|
||||
mozpath.join(obj.install_target, dest, target).replace('/', '_'))
|
||||
@@ -66,12 +85,7 @@ class FasterMakeBackend(CommonBackend):
|
||||
|
||||
elif isinstance(obj, JARManifest) and \
|
||||
obj.install_target.startswith('dist/bin'):
|
||||
defines = self._defines.get(obj.objdir, [])
|
||||
if defines:
|
||||
defines = list(defines.get_defines())
|
||||
self._jar_manifests[obj.path] = (obj.objdir,
|
||||
obj.install_target,
|
||||
defines)
|
||||
self._consume_jar_manifest(obj, defines)
|
||||
|
||||
elif isinstance(obj, VariablePassthru) and \
|
||||
obj.install_target.startswith('dist/bin'):
|
||||
@@ -174,6 +188,113 @@ class FasterMakeBackend(CommonBackend):
|
||||
self._seen_directories.add(obj.objdir)
|
||||
return True
|
||||
|
||||
def _consume_jar_manifest(self, obj, defines):
|
||||
# Ideally, this would all be handled somehow in the emitter, but
|
||||
# this would require all the magic surrounding l10n and addons in
|
||||
# the recursive make backend to die, which is not going to happen
|
||||
# any time soon enough.
|
||||
# Notably missing:
|
||||
# - DEFINES from config/config.mk
|
||||
# - L10n support
|
||||
# - The equivalent of -e when USE_EXTENSION_MANIFEST is set in
|
||||
# moz.build, but it doesn't matter in dist/bin.
|
||||
pp = Preprocessor()
|
||||
pp.context.update(defines)
|
||||
pp.context.update(self.environment.defines)
|
||||
pp.context.update(
|
||||
AB_CD='en-US',
|
||||
BUILD_FASTER=1,
|
||||
)
|
||||
pp.out = JarManifestParser()
|
||||
pp.do_include(obj.path)
|
||||
|
||||
for jarinfo in pp.out:
|
||||
install_target = obj.install_target
|
||||
# Bug 1150417 added some gross hacks, which we don't try to
|
||||
# support generically. Fortunately, the hacks don't define more
|
||||
# than chrome manifest entries, so just assume we don't get
|
||||
# any installation entries.
|
||||
if jarinfo.name.startswith('../'):
|
||||
assert not jarinfo.entries
|
||||
|
||||
base = mozpath.join('chrome', jarinfo.name)
|
||||
|
||||
for e in jarinfo.entries:
|
||||
if e.is_locale:
|
||||
src = mozpath.join(
|
||||
jarinfo.relativesrcdir or mozpath.dirname(obj.path),
|
||||
'en-US',
|
||||
e.source)
|
||||
elif e.source.startswith('/'):
|
||||
src = mozpath.join(self.environment.topsrcdir,
|
||||
e.source[1:])
|
||||
else:
|
||||
src = mozpath.join(mozpath.dirname(obj.path), e.source)
|
||||
|
||||
if '*' in e.source:
|
||||
if e.preprocess:
|
||||
raise Exception('%s: Wildcards are not supported with '
|
||||
'preprocessing' % obj.path)
|
||||
def _prefix(s):
|
||||
for p in s.split('/'):
|
||||
if '*' not in p:
|
||||
yield p + '/'
|
||||
prefix = ''.join(_prefix(src))
|
||||
|
||||
self._install_manifests[obj.install_target] \
|
||||
.add_pattern_symlink(
|
||||
prefix,
|
||||
src[len(prefix):],
|
||||
mozpath.join(base, e.output))
|
||||
continue
|
||||
|
||||
if not os.path.exists(src):
|
||||
if e.is_locale:
|
||||
raise Exception(
|
||||
'%s: Cannot find %s' % (obj.path, e.source))
|
||||
if e.source.startswith('/'):
|
||||
src = mozpath.join(self.environment.topobjdir,
|
||||
e.source[1:])
|
||||
else:
|
||||
# This actually gets awkward if the jar.mn is not
|
||||
# in the same directory as the moz.build declaring
|
||||
# it, but it's how it works in the recursive make,
|
||||
# not that anything relies on that, but it's simpler.
|
||||
src = mozpath.join(obj.objdir, e.source)
|
||||
self._dependencies['install-%s' % obj.install_target] \
|
||||
.append(mozpath.relpath(
|
||||
src, self.environment.topobjdir))
|
||||
|
||||
if e.preprocess:
|
||||
kwargs = {}
|
||||
if src.endswith('.css'):
|
||||
kwargs['marker'] = '%'
|
||||
self._add_preprocess(
|
||||
obj,
|
||||
src,
|
||||
mozpath.join(base, mozpath.dirname(e.output)),
|
||||
mozpath.basename(e.output),
|
||||
defines=defines,
|
||||
**kwargs)
|
||||
else:
|
||||
self._install_manifests[obj.install_target].add_symlink(
|
||||
src,
|
||||
mozpath.join(base, e.output))
|
||||
|
||||
manifest = mozpath.normpath(mozpath.join(obj.install_target, base))
|
||||
manifest += '.manifest'
|
||||
for m in jarinfo.chrome_manifests:
|
||||
self._manifest_entries[manifest].append(
|
||||
m.replace('%', jarinfo.name + '/'))
|
||||
|
||||
# ../ special cased for bug 1150417 again.
|
||||
if not jarinfo.name.startswith('../'):
|
||||
manifest = mozpath.normpath(mozpath.join(obj.install_target,
|
||||
'chrome.manifest'))
|
||||
entry = 'manifest %s.manifest' % base
|
||||
if entry not in self._manifest_entries[manifest]:
|
||||
self._manifest_entries[manifest].append(entry)
|
||||
|
||||
def consume_finished(self):
|
||||
mk = Makefile()
|
||||
# Add the default rule at the very beginning.
|
||||
@@ -185,34 +306,11 @@ class FasterMakeBackend(CommonBackend):
|
||||
for var in (
|
||||
'PYTHON',
|
||||
'ACDEFINES',
|
||||
'MOZ_CHROME_FILE_FORMAT',
|
||||
'MOZ_BUILD_APP',
|
||||
'MOZ_WIDGET_TOOLKIT',
|
||||
):
|
||||
mk.add_statement('%s = %s' % (var, self.environment.substs[var]))
|
||||
|
||||
# Add all necessary information for jar manifest processing
|
||||
jar_mn_targets = []
|
||||
|
||||
for path, (objdir, install_target, defines) in \
|
||||
self._jar_manifests.iteritems():
|
||||
rel_manifest = mozpath.relpath(path, self.environment.topsrcdir)
|
||||
target = rel_manifest.replace('/', '-')
|
||||
assert target not in jar_mn_targets
|
||||
jar_mn_targets.append(target)
|
||||
target = 'jar-%s' % target
|
||||
mk.create_rule([target]).add_dependencies([path])
|
||||
if objdir != mozpath.join(self.environment.topobjdir,
|
||||
mozpath.dirname(rel_manifest)):
|
||||
mk.create_rule([target]).add_dependencies(
|
||||
['objdir = %s' % objdir])
|
||||
if install_target != 'dist/bin':
|
||||
mk.create_rule([target]).add_dependencies(
|
||||
['install_target = %s' % install_target])
|
||||
if defines:
|
||||
mk.create_rule([target]).add_dependencies(
|
||||
['defines = %s' % ' '.join(defines)])
|
||||
|
||||
mk.add_statement('JAR_MN_TARGETS = %s' % ' '.join(jar_mn_targets))
|
||||
|
||||
# Add information for chrome manifest generation
|
||||
manifest_targets = []
|
||||
|
||||
@@ -228,6 +326,11 @@ class FasterMakeBackend(CommonBackend):
|
||||
mk.add_statement('INSTALL_MANIFESTS = %s'
|
||||
% ' '.join(self._install_manifests.keys()))
|
||||
|
||||
# Add dependencies we infered:
|
||||
for target, deps in self._dependencies.iteritems():
|
||||
mk.create_rule([target]).add_dependencies(
|
||||
'$(TOPOBJDIR)/%s' % d for d in deps)
|
||||
|
||||
mk.add_statement('include $(TOPSRCDIR)/config/faster/rules.mk')
|
||||
|
||||
for base, install_manifest in self._install_manifests.iteritems():
|
||||
|
||||
@@ -605,19 +605,23 @@ class RecursiveMakeBackend(CommonBackend):
|
||||
backend_file.write('DIST_FILES += %s\n' % f)
|
||||
|
||||
elif isinstance(obj, AndroidResDirs):
|
||||
# Order matters.
|
||||
for p in obj.paths:
|
||||
backend_file.write('ANDROID_RES_DIRS += %s\n' % p.full_path)
|
||||
|
||||
elif isinstance(obj, AndroidAssetsDirs):
|
||||
# Order matters.
|
||||
for p in obj.paths:
|
||||
backend_file.write('ANDROID_ASSETS_DIRS += %s\n' % p.full_path)
|
||||
|
||||
elif isinstance(obj, AndroidExtraResDirs):
|
||||
for p in obj.paths:
|
||||
backend_file.write('ANDROID_EXTRA_RES_DIRS += %s\n' % p.full_path)
|
||||
# Order does not matter.
|
||||
for p in sorted(set(p.full_path for p in obj.paths)):
|
||||
backend_file.write('ANDROID_EXTRA_RES_DIRS += %s\n' % p)
|
||||
|
||||
elif isinstance(obj, AndroidExtraPackages):
|
||||
for p in obj.packages:
|
||||
# Order does not matter.
|
||||
for p in sorted(set(obj.packages)):
|
||||
backend_file.write('ANDROID_EXTRA_PACKAGES += %s\n' % p)
|
||||
|
||||
else:
|
||||
@@ -1256,7 +1260,7 @@ INSTALL_TARGETS += %(prefix)s
|
||||
(target, ' '.join(mozpath.join('generated', f) for f in jar.generated_sources)))
|
||||
if jar.extra_jars:
|
||||
backend_file.write('%s_EXTRA_JARS := %s\n' %
|
||||
(target, ' '.join(jar.extra_jars)))
|
||||
(target, ' '.join(sorted(set(jar.extra_jars)))))
|
||||
if jar.javac_flags:
|
||||
backend_file.write('%s_JAVAC_FLAGS := %s\n' %
|
||||
(target, ' '.join(jar.javac_flags)))
|
||||
|
||||
@@ -278,9 +278,6 @@ class MozbuildObject(ProcessExecutionMixin):
|
||||
|
||||
@property
|
||||
def bindir(self):
|
||||
import mozinfo
|
||||
if mozinfo.os == "mac":
|
||||
return os.path.join(self.topobjdir, 'dist', self.substs['MOZ_MACBUNDLE_NAME'], 'Contents', 'Resources')
|
||||
return os.path.join(self.topobjdir, 'dist', 'bin')
|
||||
|
||||
@property
|
||||
@@ -313,12 +310,25 @@ class MozbuildObject(ProcessExecutionMixin):
|
||||
return False
|
||||
return Clobberer(self.topsrcdir, self.topobjdir).clobber_needed()
|
||||
|
||||
def have_winrm(self):
|
||||
# `winrm -h` should print 'winrm version ...' and exit 1
|
||||
try:
|
||||
p = subprocess.Popen(['winrm.exe', '-h'],
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT)
|
||||
return p.wait() == 1 and p.stdout.read().startswith('winrm')
|
||||
except:
|
||||
return False
|
||||
|
||||
def remove_objdir(self):
|
||||
"""Remove the entire object directory."""
|
||||
|
||||
# We use mozfile because it is faster than shutil.rmtree().
|
||||
# mozfile doesn't like unicode arguments (bug 818783).
|
||||
rmtree(self.topobjdir.encode('utf-8'))
|
||||
if sys.platform.startswith('win') and self.have_winrm():
|
||||
subprocess.check_call(['winrm', '-rf', self.topobjdir])
|
||||
else:
|
||||
# We use mozfile because it is faster than shutil.rmtree().
|
||||
# mozfile doesn't like unicode arguments (bug 818783).
|
||||
rmtree(self.topobjdir.encode('utf-8'))
|
||||
|
||||
def get_binary_path(self, what='app', validate_exists=True, where='default'):
|
||||
"""Obtain the path to a compiled binary for this build configuration.
|
||||
|
||||
@@ -274,7 +274,7 @@ class Preprocessor:
|
||||
self.key = MSG
|
||||
RuntimeError.__init__(self, (self.file, self.line, self.key, context))
|
||||
|
||||
def __init__(self, line_endings='\n', defines=None, marker='#'):
|
||||
def __init__(self, defines=None, marker='#'):
|
||||
self.context = Context()
|
||||
for k,v in {'FILE': '',
|
||||
'LINE': 0,
|
||||
@@ -288,7 +288,6 @@ class Preprocessor:
|
||||
# 2: #else found
|
||||
self.ifStates = []
|
||||
self.checkLineNumbers = False
|
||||
self.writtenLines = 0
|
||||
self.filters = []
|
||||
self.cmds = {}
|
||||
for cmd, level in {'define': 0,
|
||||
@@ -311,7 +310,6 @@ class Preprocessor:
|
||||
self.cmds[cmd] = (level, getattr(self, 'do_' + cmd))
|
||||
self.out = sys.stdout
|
||||
self.setMarker(marker)
|
||||
self.LE = line_endings
|
||||
self.varsubst = re.compile('@(?P<VAR>\w+)@', re.U)
|
||||
self.includes = set()
|
||||
self.silenceMissingDirectiveWarnings = False
|
||||
@@ -325,12 +323,6 @@ class Preprocessor:
|
||||
sys.stderr.write('{0}: WARNING: no useful preprocessor directives found\n'.format(file))
|
||||
pass
|
||||
|
||||
def setLineEndings(self, aLE):
|
||||
"""
|
||||
Set the line endings to be used for output.
|
||||
"""
|
||||
self.LE = {'cr': '\x0D', 'lf': '\x0A', 'crlf': '\x0D\x0A'}[aLE]
|
||||
|
||||
def setMarker(self, aMarker):
|
||||
"""
|
||||
Set the marker to be used for processing directives.
|
||||
@@ -373,7 +365,6 @@ class Preprocessor:
|
||||
rv = Preprocessor()
|
||||
rv.context.update(self.context)
|
||||
rv.setMarker(self.marker)
|
||||
rv.LE = self.LE
|
||||
rv.out = self.out
|
||||
return rv
|
||||
|
||||
@@ -411,6 +402,11 @@ class Preprocessor:
|
||||
aLine = f[1](aLine)
|
||||
return aLine
|
||||
|
||||
def noteLineInfo(self):
|
||||
# Record the current line and file. Called once before transitioning
|
||||
# into or out of an included file and after writing each line.
|
||||
self.line_info = self.context['FILE'], self.context['LINE']
|
||||
|
||||
def write(self, aLine):
|
||||
"""
|
||||
Internal method for handling output.
|
||||
@@ -418,20 +414,19 @@ class Preprocessor:
|
||||
if not self.out:
|
||||
return
|
||||
|
||||
next_line, next_file = self.context['LINE'], self.context['FILE']
|
||||
if self.checkLineNumbers:
|
||||
self.writtenLines += 1
|
||||
ln = self.context['LINE']
|
||||
if self.writtenLines != ln:
|
||||
self.out.write('//@line {line} "{file}"{le}'.format(line=ln,
|
||||
file=self.context['FILE'],
|
||||
le=self.LE))
|
||||
self.writtenLines = ln
|
||||
expected_file, expected_line = self.line_info
|
||||
expected_line += 1
|
||||
if (expected_line != next_line or
|
||||
expected_file and expected_file != next_file):
|
||||
self.out.write('//@line {line} "{file}"\n'.format(line=next_line,
|
||||
file=next_file))
|
||||
self.noteLineInfo()
|
||||
|
||||
filteredLine = self.applyFilters(aLine)
|
||||
if filteredLine != aLine:
|
||||
self.actionLevel = 2
|
||||
# ensure our line ending. Only need to handle \n, as we're reading
|
||||
# with universal line ending support, at least for files.
|
||||
filteredLine = re.sub('\n', self.LE, filteredLine)
|
||||
self.out.write(filteredLine)
|
||||
|
||||
def handleCommandLine(self, args, defaultToStdin = False):
|
||||
@@ -490,9 +485,6 @@ class Preprocessor:
|
||||
def getCommandLineParser(self, unescapeDefines = False):
|
||||
escapedValue = re.compile('".*"$')
|
||||
numberValue = re.compile('\d+$')
|
||||
def handleE(option, opt, value, parser):
|
||||
for k,v in os.environ.iteritems():
|
||||
self.context[k] = v
|
||||
def handleD(option, opt, value, parser):
|
||||
vals = value.split('=', 1)
|
||||
if len(vals) == 1:
|
||||
@@ -507,8 +499,6 @@ class Preprocessor:
|
||||
del self.context[value]
|
||||
def handleF(option, opt, value, parser):
|
||||
self.do_filter(value)
|
||||
def handleLE(option, opt, value, parser):
|
||||
self.setLineEndings(value)
|
||||
def handleMarker(option, opt, value, parser):
|
||||
self.setMarker(value)
|
||||
def handleSilenceDirectiveWarnings(option, opt, value, parse):
|
||||
@@ -516,8 +506,6 @@ class Preprocessor:
|
||||
p = OptionParser()
|
||||
p.add_option('-I', action='append', type="string", default = [],
|
||||
metavar="FILENAME", help='Include file')
|
||||
p.add_option('-E', action='callback', callback=handleE,
|
||||
help='Import the environment into the defined variables')
|
||||
p.add_option('-D', action='callback', callback=handleD, type="string",
|
||||
metavar="VAR[=VAL]", help='Define a variable')
|
||||
p.add_option('-U', action='callback', callback=handleU, type="string",
|
||||
@@ -529,9 +517,6 @@ class Preprocessor:
|
||||
'instead of stdout')
|
||||
p.add_option('--depend', type="string", default=None, metavar="FILENAME",
|
||||
help='Generate dependencies in the given file')
|
||||
p.add_option('--line-endings', action='callback', callback=handleLE,
|
||||
type="string", metavar="[cr|lr|crlf]",
|
||||
help='Use the specified line endings [Default: OS dependent]')
|
||||
p.add_option('--marker', action='callback', callback=handleMarker,
|
||||
type="string",
|
||||
help='Use the specified marker instead of #')
|
||||
@@ -563,7 +548,6 @@ class Preprocessor:
|
||||
self.actionLevel = 2
|
||||
elif self.disableLevel == 0 and not self.comment.match(aLine):
|
||||
self.write(aLine)
|
||||
pass
|
||||
|
||||
# Instruction handlers
|
||||
# These are named do_'instruction name' and take one argument
|
||||
@@ -688,7 +672,7 @@ class Preprocessor:
|
||||
lst.append('\n') # add back the newline
|
||||
self.write(reduce(lambda x, y: x+y, lst, ''))
|
||||
def do_literal(self, args):
|
||||
self.write(args + self.LE)
|
||||
self.write(args + '\n')
|
||||
def do_filter(self, args):
|
||||
filters = [f for f in args.split(' ') if hasattr(self, 'filter_' + f)]
|
||||
if len(filters) == 0:
|
||||
@@ -752,7 +736,6 @@ class Preprocessor:
|
||||
Files should be opened, and will be closed after processing.
|
||||
"""
|
||||
isName = type(args) == str or type(args) == unicode
|
||||
oldWrittenLines = self.writtenLines
|
||||
oldCheckLineNumbers = self.checkLineNumbers
|
||||
self.checkLineNumbers = False
|
||||
if isName:
|
||||
@@ -772,6 +755,8 @@ class Preprocessor:
|
||||
oldFile = self.context['FILE']
|
||||
oldLine = self.context['LINE']
|
||||
oldDir = self.context['DIRECTORY']
|
||||
self.noteLineInfo()
|
||||
|
||||
if args.isatty():
|
||||
# we're stdin, use '-' and '' for file and dir
|
||||
self.context['FILE'] = '-'
|
||||
@@ -782,15 +767,15 @@ class Preprocessor:
|
||||
self.context['FILE'] = abspath
|
||||
self.context['DIRECTORY'] = os.path.dirname(abspath)
|
||||
self.context['LINE'] = 0
|
||||
self.writtenLines = 0
|
||||
|
||||
for l in args:
|
||||
self.context['LINE'] += 1
|
||||
self.handleLine(l)
|
||||
if isName:
|
||||
args.close()
|
||||
|
||||
self.context['FILE'] = oldFile
|
||||
self.checkLineNumbers = oldCheckLineNumbers
|
||||
self.writtenLines = oldWrittenLines
|
||||
self.context['LINE'] = oldLine
|
||||
self.context['DIRECTORY'] = oldDir
|
||||
def do_includesubst(self, args):
|
||||
@@ -802,13 +787,13 @@ class Preprocessor:
|
||||
|
||||
def preprocess(includes=[sys.stdin], defines={},
|
||||
output = sys.stdout,
|
||||
line_endings='\n', marker='#'):
|
||||
pp = Preprocessor(line_endings=line_endings,
|
||||
defines=defines,
|
||||
marker='#'):
|
||||
pp = Preprocessor(defines=defines,
|
||||
marker=marker)
|
||||
for f in includes:
|
||||
with open(f, 'rU') as input:
|
||||
pp.processFile(input=input, output=output)
|
||||
return pp.includes
|
||||
|
||||
|
||||
# Keep this module independently executable.
|
||||
|
||||
@@ -440,12 +440,6 @@ class TestPreprocessor(unittest.TestCase):
|
||||
'#endif',
|
||||
])
|
||||
|
||||
def test_lineEndings(self):
|
||||
with MockedOpen({'f': 'first\n#literal second\n'}):
|
||||
self.pp.setLineEndings('cr')
|
||||
self.pp.do_include('f')
|
||||
self.assertEqual(self.pp.out.getvalue(), "first\rsecond\r")
|
||||
|
||||
def test_filterDefine(self):
|
||||
self.do_include_pass([
|
||||
'#filter substitution',
|
||||
@@ -562,6 +556,56 @@ class TestPreprocessor(unittest.TestCase):
|
||||
self.pp.do_include('f')
|
||||
self.assertEqual(self.pp.out.getvalue(), 'foobarbaz\nbarfoobaz\n')
|
||||
|
||||
def test_include_line(self):
|
||||
files = {
|
||||
'test.js': '\n'.join([
|
||||
'#define foo foobarbaz',
|
||||
'#include @inc@',
|
||||
'@bar@',
|
||||
'',
|
||||
]),
|
||||
'bar.js': '\n'.join([
|
||||
'#define bar barfoobaz',
|
||||
'@foo@',
|
||||
'',
|
||||
]),
|
||||
'foo.js': '\n'.join([
|
||||
'bazfoobar',
|
||||
'#include bar.js',
|
||||
'bazbarfoo',
|
||||
'',
|
||||
]),
|
||||
'baz.js': 'baz\n',
|
||||
'f.js': '\n'.join([
|
||||
'#include foo.js',
|
||||
'#filter substitution',
|
||||
'#define inc bar.js',
|
||||
'#include test.js',
|
||||
'#include baz.js',
|
||||
'fin',
|
||||
'',
|
||||
]),
|
||||
}
|
||||
|
||||
with MockedOpen(files):
|
||||
self.pp.do_include('f.js')
|
||||
self.assertEqual(self.pp.out.getvalue(),
|
||||
('//@line 1 "CWD/foo.js"\n'
|
||||
'bazfoobar\n'
|
||||
'//@line 2 "CWD/bar.js"\n'
|
||||
'@foo@\n'
|
||||
'//@line 3 "CWD/foo.js"\n'
|
||||
'bazbarfoo\n'
|
||||
'//@line 2 "CWD/bar.js"\n'
|
||||
'foobarbaz\n'
|
||||
'//@line 3 "CWD/test.js"\n'
|
||||
'barfoobaz\n'
|
||||
'//@line 1 "CWD/baz.js"\n'
|
||||
'baz\n'
|
||||
'//@line 6 "CWD/f.js"\n'
|
||||
'fin\n').replace('CWD/',
|
||||
os.getcwd() + os.path.sep))
|
||||
|
||||
def test_include_missing_file(self):
|
||||
with MockedOpen({'f': '#include foo\n'}):
|
||||
with self.assertRaises(Preprocessor.Error) as e:
|
||||
|
||||
@@ -817,7 +817,8 @@ class FileFinder(BaseFinder):
|
||||
'''
|
||||
Helper to get appropriate BaseFile instances from the file system.
|
||||
'''
|
||||
def __init__(self, base, find_executables=True, ignore=(), **kargs):
|
||||
def __init__(self, base, find_executables=True, ignore=(),
|
||||
find_dotfiles=False, **kargs):
|
||||
'''
|
||||
Create a FileFinder for files under the given base directory.
|
||||
|
||||
@@ -832,6 +833,7 @@ class FileFinder(BaseFinder):
|
||||
an entry corresponds to a file, that particular file will be ignored.
|
||||
'''
|
||||
BaseFinder.__init__(self, base, **kargs)
|
||||
self.find_dotfiles = find_dotfiles
|
||||
self.find_executables = find_executables
|
||||
self.ignore = ignore
|
||||
|
||||
@@ -866,7 +868,10 @@ class FileFinder(BaseFinder):
|
||||
# inode ordering.
|
||||
for p in sorted(os.listdir(os.path.join(self.base, path))):
|
||||
if p.startswith('.'):
|
||||
continue
|
||||
if p in ('.', '..'):
|
||||
continue
|
||||
if not self.find_dotfiles:
|
||||
continue
|
||||
for p_, f in self._find(mozpath.join(path, p)):
|
||||
yield p_, f
|
||||
|
||||
|
||||
@@ -973,6 +973,21 @@ class TestFileFinder(MatchTestTemplate, TestWithTmpDir):
|
||||
self.do_check('**', ['foo/bar', 'foo/baz', 'foo/quxz', 'bar'])
|
||||
self.do_check('foo/**', ['foo/bar', 'foo/baz', 'foo/quxz'])
|
||||
|
||||
def test_dotfiles(self):
|
||||
"""Finder can find files beginning with . is configured."""
|
||||
self.prepare_match_test(with_dotfiles=True)
|
||||
self.finder = FileFinder(self.tmpdir, find_dotfiles=True)
|
||||
self.do_check('**', ['bar', 'foo/.foo', 'foo/.bar/foo',
|
||||
'foo/bar', 'foo/baz', 'foo/qux/1', 'foo/qux/bar',
|
||||
'foo/qux/2/test', 'foo/qux/2/test2'])
|
||||
|
||||
def test_dotfiles_plus_ignore(self):
|
||||
self.prepare_match_test(with_dotfiles=True)
|
||||
self.finder = FileFinder(self.tmpdir, find_dotfiles=True,
|
||||
ignore=['foo/.bar/**'])
|
||||
self.do_check('foo/**', ['foo/.foo', 'foo/bar', 'foo/baz',
|
||||
'foo/qux/1', 'foo/qux/bar', 'foo/qux/2/test', 'foo/qux/2/test2'])
|
||||
|
||||
|
||||
class TestJarFinder(MatchTestTemplate, TestWithTmpDir):
|
||||
def add(self, path):
|
||||
|
||||
@@ -1,105 +0,0 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
config = {
|
||||
"suite_definitions": {
|
||||
"mochitest": {
|
||||
"run_filename": "runtestsremote.py",
|
||||
"testsdir": "mochitest",
|
||||
"options": ["--autorun", "--close-when-done", "--dm_trans=adb",
|
||||
"--console-level=INFO", "--app=%(app)s", "--remote-webserver=%(remote_webserver)s",
|
||||
"--xre-path=%(xre_path)s", "--utility-path=%(utility_path)s",
|
||||
"--http-port=%(http_port)s", "--ssl-port=%(ssl_port)s",
|
||||
"--certificate-path=%(certs_path)s", "--symbols-path=%(symbols_path)s",
|
||||
"--quiet", "--log-raw=%(raw_log_file)s",
|
||||
"--total-chunks=16",
|
||||
"--run-only-tests=android23.json",
|
||||
],
|
||||
},
|
||||
"mochitest-gl": {
|
||||
"run_filename": "runtestsremote.py",
|
||||
"testsdir": "mochitest",
|
||||
"options": ["--autorun", "--close-when-done", "--dm_trans=adb",
|
||||
"--console-level=INFO", "--app=%(app)s", "--remote-webserver=%(remote_webserver)s",
|
||||
"--xre-path=%(xre_path)s", "--utility-path=%(utility_path)s",
|
||||
"--http-port=%(http_port)s", "--ssl-port=%(ssl_port)s",
|
||||
"--certificate-path=%(certs_path)s", "--symbols-path=%(symbols_path)s",
|
||||
"--quiet", "--log-raw=%(raw_log_file)s",
|
||||
"--total-chunks=2",
|
||||
"--test-manifest=gl.json",
|
||||
],
|
||||
},
|
||||
"robocop": {
|
||||
"run_filename": "runtestsremote.py",
|
||||
"testsdir": "mochitest",
|
||||
"options": ["--autorun", "--close-when-done", "--dm_trans=adb",
|
||||
"--console-level=INFO", "--app=%(app)s", "--remote-webserver=%(remote_webserver)s",
|
||||
"--xre-path=%(xre_path)s", "--utility-path=%(utility_path)s",
|
||||
"--http-port=%(http_port)s", "--ssl-port=%(ssl_port)s",
|
||||
"--certificate-path=%(certs_path)s", "--symbols-path=%(symbols_path)s",
|
||||
"--quiet", "--log-raw=%(raw_log_file)s",
|
||||
"--total-chunks=4",
|
||||
"--robocop-path=../..",
|
||||
"--robocop-ids=fennec_ids.txt",
|
||||
"--robocop=robocop.ini",
|
||||
],
|
||||
},
|
||||
"reftest": {
|
||||
"run_filename": "remotereftest.py",
|
||||
"testsdir": "reftest",
|
||||
"options": [ "--app=%(app)s", "--ignore-window-size",
|
||||
"--dm_trans=adb",
|
||||
"--bootstrap",
|
||||
"--remote-webserver=%(remote_webserver)s", "--xre-path=%(xre_path)s",
|
||||
"--utility-path=%(utility_path)s", "--http-port=%(http_port)s",
|
||||
"--ssl-port=%(ssl_port)s", "--httpd-path", "%(modules_dir)s",
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
"--total-chunks=16",
|
||||
"tests/layout/reftests/reftest.list",
|
||||
],
|
||||
},
|
||||
"crashtest": {
|
||||
"run_filename": "remotereftest.py",
|
||||
"testsdir": "reftest",
|
||||
"options": [ "--app=%(app)s", "--ignore-window-size",
|
||||
"--dm_trans=adb",
|
||||
"--bootstrap",
|
||||
"--remote-webserver=%(remote_webserver)s", "--xre-path=%(xre_path)s",
|
||||
"--utility-path=%(utility_path)s", "--http-port=%(http_port)s",
|
||||
"--ssl-port=%(ssl_port)s", "--httpd-path", "%(modules_dir)s",
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
"--total-chunks=2",
|
||||
"tests/testing/crashtest/crashtests.list",
|
||||
],
|
||||
},
|
||||
"jsreftest": {
|
||||
"run_filename": "remotereftest.py",
|
||||
"testsdir": "reftest",
|
||||
"options": [ "--app=%(app)s", "--ignore-window-size",
|
||||
"--dm_trans=adb",
|
||||
"--bootstrap",
|
||||
"--remote-webserver=%(remote_webserver)s", "--xre-path=%(xre_path)s",
|
||||
"--utility-path=%(utility_path)s", "--http-port=%(http_port)s",
|
||||
"--ssl-port=%(ssl_port)s", "--httpd-path", "%(modules_dir)s",
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
"../jsreftest/tests/jstests.list",
|
||||
"--total-chunks=6",
|
||||
"--extra-profile-file=jsreftest/tests/user.js",
|
||||
],
|
||||
},
|
||||
"xpcshell": {
|
||||
"run_filename": "remotexpcshelltests.py",
|
||||
"testsdir": "xpcshell",
|
||||
"options": [
|
||||
"--dm_trans=adb",
|
||||
"--xre-path=%(xre_path)s", "--testing-modules-dir=%(modules_dir)s",
|
||||
"--apk=%(installer_path)s", "--no-logfiles",
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
"--manifest=tests/xpcshell.ini",
|
||||
"--log-raw=%(raw_log_file)s",
|
||||
"--total-chunks=3",
|
||||
],
|
||||
},
|
||||
}, # end suite_definitions
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
config = {
|
||||
"suite_definitions": {
|
||||
"mochitest": {
|
||||
"run_filename": "runtestsremote.py",
|
||||
"testsdir": "mochitest",
|
||||
"options": ["--dm_trans=sut", "--app=%(app)s", "--remote-webserver=%(remote_webserver)s",
|
||||
"--xre-path=%(xre_path)s", "--utility-path=%(utility_path)s",
|
||||
"--deviceIP=%(device_ip)s", "--devicePort=%(device_port)s",
|
||||
"--http-port=%(http_port)s", "--ssl-port=%(ssl_port)s",
|
||||
"--certificate-path=%(certs_path)s", "--symbols-path=%(symbols_path)s",
|
||||
"--quiet", "--log-raw=%(raw_log_file)s",
|
||||
"--total-chunks=16",
|
||||
"--run-only-tests=android23.json",
|
||||
],
|
||||
},
|
||||
"mochitest-gl": {
|
||||
"run_filename": "runtestsremote.py",
|
||||
"testsdir": "mochitest",
|
||||
"options": ["--dm_trans=sut", "--app=%(app)s", "--remote-webserver=%(remote_webserver)s",
|
||||
"--xre-path=%(xre_path)s", "--utility-path=%(utility_path)s",
|
||||
"--deviceIP=%(device_ip)s", "--devicePort=%(device_port)s",
|
||||
"--http-port=%(http_port)s", "--ssl-port=%(ssl_port)s",
|
||||
"--certificate-path=%(certs_path)s", "--symbols-path=%(symbols_path)s",
|
||||
"--quiet", "--log-raw=%(raw_log_file)s",
|
||||
"--total-chunks=4", "--subsuite=webgl",
|
||||
],
|
||||
},
|
||||
"robocop": {
|
||||
"run_filename": "runtestsremote.py",
|
||||
"testsdir": "mochitest",
|
||||
"options": ["--dm_trans=sut", "--app=%(app)s", "--remote-webserver=%(remote_webserver)s",
|
||||
"--xre-path=%(xre_path)s", "--utility-path=%(utility_path)s",
|
||||
"--deviceIP=%(device_ip)s", "--devicePort=%(device_port)s",
|
||||
"--http-port=%(http_port)s", "--ssl-port=%(ssl_port)s",
|
||||
"--certificate-path=%(certs_path)s", "--symbols-path=%(symbols_path)s",
|
||||
"--quiet", "--log-raw=%(raw_log_file)s",
|
||||
"--total-chunks=4",
|
||||
"--robocop-apk=../../robocop.apk",
|
||||
"--robocop-ids=fennec_ids.txt",
|
||||
"--robocop-ini=robocop.ini",
|
||||
],
|
||||
},
|
||||
"reftest": {
|
||||
"run_filename": "remotereftest.py",
|
||||
"testsdir": "reftest",
|
||||
"options": [ "--app=%(app)s", "--ignore-window-size",
|
||||
"--bootstrap",
|
||||
"--remote-webserver=%(remote_webserver)s", "--xre-path=%(xre_path)s",
|
||||
"--utility-path=%(utility_path)s", "--deviceIP=%(device_ip)s",
|
||||
"--devicePort=%(device_port)s", "--http-port=%(http_port)s",
|
||||
"--ssl-port=%(ssl_port)s", "--httpd-path", "%(modules_dir)s",
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
"--total-chunks=16",
|
||||
"tests/layout/reftests/reftest.list",
|
||||
],
|
||||
},
|
||||
"crashtest": {
|
||||
"run_filename": "remotereftest.py",
|
||||
"testsdir": "reftest",
|
||||
"options": [ "--app=%(app)s", "--ignore-window-size",
|
||||
"--bootstrap",
|
||||
"--remote-webserver=%(remote_webserver)s", "--xre-path=%(xre_path)s",
|
||||
"--utility-path=%(utility_path)s", "--deviceIP=%(device_ip)s",
|
||||
"--devicePort=%(device_port)s", "--http-port=%(http_port)s",
|
||||
"--ssl-port=%(ssl_port)s", "--httpd-path", "%(modules_dir)s",
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
"--total-chunks=2",
|
||||
"tests/testing/crashtest/crashtests.list",
|
||||
],
|
||||
},
|
||||
"jsreftest": {
|
||||
"run_filename": "remotereftest.py",
|
||||
"testsdir": "reftest",
|
||||
"options": [ "--app=%(app)s", "--ignore-window-size",
|
||||
"--bootstrap",
|
||||
"--remote-webserver=%(remote_webserver)s", "--xre-path=%(xre_path)s",
|
||||
"--utility-path=%(utility_path)s", "--deviceIP=%(device_ip)s",
|
||||
"--devicePort=%(device_port)s", "--http-port=%(http_port)s",
|
||||
"--ssl-port=%(ssl_port)s", "--httpd-path", "%(modules_dir)s",
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
"../jsreftest/tests/jstests.list",
|
||||
"--total-chunks=6",
|
||||
"--extra-profile-file=jsreftest/tests/user.js",
|
||||
],
|
||||
},
|
||||
"xpcshell": {
|
||||
"run_filename": "remotexpcshelltests.py",
|
||||
"testsdir": "xpcshell",
|
||||
"options": ["--deviceIP=%(device_ip)s", "--devicePort=%(device_port)s",
|
||||
"--xre-path=%(xre_path)s", "--testing-modules-dir=%(modules_dir)s",
|
||||
"--apk=%(installer_path)s", "--no-logfiles",
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
"--manifest=tests/xpcshell.ini",
|
||||
"--log-raw=%(raw_log_file)s",
|
||||
"--total-chunks=3",
|
||||
],
|
||||
},
|
||||
}, # end suite_definitions
|
||||
}
|
||||
@@ -1,138 +0,0 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
config = {
|
||||
"suite_definitions": {
|
||||
"cppunittest": {
|
||||
"options": [
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
"--xre-path=tests/bin",
|
||||
"--dm_trans=sut",
|
||||
"--deviceIP=%(device_ip)s",
|
||||
"--localBinDir=../tests/bin",
|
||||
"--apk=%(apk_path)s",
|
||||
"--skip-manifest=../tests/cppunittests/android_cppunittest_manifest.txt"
|
||||
],
|
||||
"run_filename": "remotecppunittests.py",
|
||||
"testsdir": "cppunittest"
|
||||
},
|
||||
"crashtest": {
|
||||
"options": [
|
||||
"--deviceIP=%(device_ip)s",
|
||||
"--xre-path=../hostutils/xre",
|
||||
"--utility-path=../hostutils/bin",
|
||||
"--app=%(app_name)s",
|
||||
"--ignore-window-size",
|
||||
"--bootstrap",
|
||||
"--http-port=%(http_port)s",
|
||||
"--ssl-port=%(ssl_port)s",
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
"reftest/tests/testing/crashtest/crashtests.list"
|
||||
],
|
||||
"run_filename": "remotereftest.py",
|
||||
"testsdir": "reftest"
|
||||
},
|
||||
"jittest": {
|
||||
"options": [
|
||||
"bin/js",
|
||||
"--remote",
|
||||
"-j",
|
||||
"1",
|
||||
"--deviceTransport=sut",
|
||||
"--deviceIP=%(device_ip)s",
|
||||
"--localLib=../tests/bin",
|
||||
"--no-slow",
|
||||
"--no-progress",
|
||||
"--format=automation",
|
||||
"--jitflags=all"
|
||||
],
|
||||
"run_filename": "jit_test.py",
|
||||
"testsdir": "jit-test/jit-test"
|
||||
},
|
||||
"jsreftest": {
|
||||
"options": [
|
||||
"--deviceIP=%(device_ip)s",
|
||||
"--xre-path=../hostutils/xre",
|
||||
"--utility-path=../hostutils/bin",
|
||||
"--app=%(app_name)s",
|
||||
"--ignore-window-size",
|
||||
"--bootstrap",
|
||||
"--extra-profile-file=jsreftest/tests/user.js",
|
||||
"jsreftest/tests/jstests.list",
|
||||
"--http-port=%(http_port)s",
|
||||
"--ssl-port=%(ssl_port)s",
|
||||
"--symbols-path=%(symbols_path)s"
|
||||
],
|
||||
"run_filename": "remotereftest.py",
|
||||
"testsdir": "reftest"
|
||||
},
|
||||
"mochitest": {
|
||||
"options": [
|
||||
"--dm_trans=sut",
|
||||
"--deviceIP=%(device_ip)s",
|
||||
"--xre-path=../hostutils/xre",
|
||||
"--utility-path=../hostutils/bin",
|
||||
"--certificate-path=certs",
|
||||
"--app=%(app_name)s",
|
||||
"--http-port=%(http_port)s",
|
||||
"--ssl-port=%(ssl_port)s",
|
||||
"--run-only-tests=android.json",
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
"--quiet",
|
||||
"--log-raw=%(raw_log_file)s"
|
||||
],
|
||||
"run_filename": "runtestsremote.py",
|
||||
"testsdir": "mochitest"
|
||||
},
|
||||
"reftest": {
|
||||
"options": [
|
||||
"--deviceIP=%(device_ip)s",
|
||||
"--xre-path=../hostutils/xre",
|
||||
"--utility-path=../hostutils/bin",
|
||||
"--app=%(app_name)s",
|
||||
"--ignore-window-size",
|
||||
"--bootstrap",
|
||||
"--http-port=%(http_port)s",
|
||||
"--ssl-port=%(ssl_port)s",
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
"reftest/tests/layout/reftests/reftest.list"
|
||||
],
|
||||
"run_filename": "remotereftest.py",
|
||||
"testsdir": "reftest"
|
||||
},
|
||||
"robocop": {
|
||||
"options": [
|
||||
"--dm_trans=sut",
|
||||
"--deviceIP=%(device_ip)s",
|
||||
"--xre-path=../hostutils/xre",
|
||||
"--utility-path=../hostutils/bin",
|
||||
"--certificate-path=certs",
|
||||
"--app=%(app_name)s",
|
||||
"--console-level=INFO",
|
||||
"--http-port=%(http_port)s",
|
||||
"--ssl-port=%(ssl_port)s",
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
"--robocop-ini=mochitest/robocop.ini"
|
||||
],
|
||||
"run_filename": "runtestsremote.py",
|
||||
"testsdir": "mochitest"
|
||||
},
|
||||
"xpcshell": {
|
||||
"options": [
|
||||
"--deviceIP=%(device_ip)s",
|
||||
"--xre-path=../hostutils/xre",
|
||||
"--manifest=xpcshell/tests/xpcshell.ini",
|
||||
"--build-info-json=xpcshell/mozinfo.json",
|
||||
"--testing-modules-dir=modules",
|
||||
"--local-lib-dir=../fennec",
|
||||
"--apk=../%(apk_name)s",
|
||||
"--no-logfiles",
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
"--log-raw=%(raw_log_file)s"
|
||||
],
|
||||
"run_filename": "remotexpcshelltests.py",
|
||||
"testsdir": "xpcshell"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
config = {
|
||||
"suite_definitions": {
|
||||
"mochitest": {
|
||||
"run_filename": "runtestsremote.py",
|
||||
"options": ["--dm_trans=sut", "--app=%(app)s", "--remote-webserver=%(remote_webserver)s",
|
||||
"--xre-path=%(xre_path)s", "--utility-path=%(utility_path)s",
|
||||
"--deviceIP=%(device_ip)s", "--devicePort=%(device_port)s",
|
||||
"--http-port=%(http_port)s", "--ssl-port=%(ssl_port)s",
|
||||
"--certificate-path=%(certs_path)s", "--symbols-path=%(symbols_path)s",
|
||||
"--quiet", "--log-raw=%(raw_log_file)s",
|
||||
],
|
||||
},
|
||||
"reftest": {
|
||||
"run_filename": "remotereftest.py",
|
||||
"options": [ "--app=%(app)s", "--ignore-window-size",
|
||||
"--bootstrap",
|
||||
"--remote-webserver=%(remote_webserver)s", "--xre-path=%(xre_path)s",
|
||||
"--utility-path=%(utility_path)s", "--deviceIP=%(device_ip)s",
|
||||
"--devicePort=%(device_port)s", "--http-port=%(http_port)s",
|
||||
"--ssl-port=%(ssl_port)s", "--httpd-path", "%(modules_dir)s",
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
],
|
||||
},
|
||||
"xpcshell": {
|
||||
"run_filename": "remotexpcshelltests.py",
|
||||
"options": ["--deviceIP=%(device_ip)s", "--devicePort=%(device_port)s",
|
||||
"--xre-path=%(xre_path)s", "--testing-modules-dir=%(modules_dir)s",
|
||||
"--apk=%(installer_path)s", "--no-logfiles",
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
"--manifest=tests/xpcshell.ini",
|
||||
"--log-raw=%(raw_log_file)s",
|
||||
],
|
||||
},
|
||||
}, # end suite_definitions
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
config = {
|
||||
"suite_definitions": {
|
||||
"mochitest": {
|
||||
"options": [
|
||||
"%(test_manifest)s",
|
||||
"--total-chunks=%(total_chunks)s",
|
||||
"--this-chunk=%(this_chunk)s",
|
||||
"--profile=%(gaia_profile)s",
|
||||
"--app=%(application)s",
|
||||
"--desktop",
|
||||
"--utility-path=%(utility_path)s",
|
||||
"--certificate-path=%(cert_path)s",
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
"--browser-arg=%(browser_arg)s",
|
||||
"--quiet",
|
||||
"--log-raw=%(raw_log_file)s"
|
||||
],
|
||||
"run_filename": "runtestsb2g.py",
|
||||
"testsdir": "mochitest"
|
||||
},
|
||||
"reftest": {
|
||||
"options": [
|
||||
"--desktop",
|
||||
"--profile=%(gaia_profile)s",
|
||||
"--appname=%(application)s",
|
||||
"--total-chunks=%(total_chunks)s",
|
||||
"--this-chunk=%(this_chunk)s",
|
||||
"--browser-arg=%(browser_arg)s",
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
"%(test_manifest)s"
|
||||
],
|
||||
"run_filename": "runreftestsb2g.py",
|
||||
"testsdir": "reftest"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,141 +0,0 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
config = {
|
||||
"suite_definitions": {
|
||||
"cppunittest": {
|
||||
"options": [
|
||||
"--dm_trans=adb",
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
"--xre-path=%(xre_path)s",
|
||||
"--addEnv",
|
||||
"LD_LIBRARY_PATH=/vendor/lib:/system/lib:/system/b2g",
|
||||
"--with-b2g-emulator=%(b2gpath)s",
|
||||
"--skip-manifest=b2g_cppunittest_manifest.txt",
|
||||
"."
|
||||
],
|
||||
"run_filename": "remotecppunittests.py",
|
||||
"testsdir": "cppunittest"
|
||||
},
|
||||
"crashtest": {
|
||||
"options": [
|
||||
"--adbpath=%(adbpath)s",
|
||||
"--b2gpath=%(b2gpath)s",
|
||||
"--emulator=%(emulator)s",
|
||||
"--emulator-res=800x1000",
|
||||
"--logdir=%(logcat_dir)s",
|
||||
"--remote-webserver=%(remote_webserver)s",
|
||||
"--ignore-window-size",
|
||||
"--xre-path=%(xre_path)s",
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
"--busybox=%(busybox)s",
|
||||
"--total-chunks=%(total_chunks)s",
|
||||
"--this-chunk=%(this_chunk)s",
|
||||
"tests/testing/crashtest/crashtests.list"
|
||||
],
|
||||
"run_filename": "runreftestb2g.py",
|
||||
"testsdir": "reftest"
|
||||
},
|
||||
"jsreftest": {
|
||||
"options": [
|
||||
"--adbpath=%(adbpath)s",
|
||||
"--b2gpath=%(b2gpath)s",
|
||||
"--emulator=%(emulator)s",
|
||||
"--emulator-res=800x1000",
|
||||
"--logdir=%(logcat_dir)s",
|
||||
"--remote-webserver=%(remote_webserver)s",
|
||||
"--ignore-window-size",
|
||||
"--xre-path=%(xre_path)s",
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
"--busybox=%(busybox)s",
|
||||
"--total-chunks=%(total_chunks)s",
|
||||
"--this-chunk=%(this_chunk)s",
|
||||
"--extra-profile-file=jsreftest/tests/user.js",
|
||||
"jsreftest/tests/jstests.list"
|
||||
],
|
||||
"run_filename": "remotereftest.py",
|
||||
"testsdir": "reftest"
|
||||
},
|
||||
"mochitest": {
|
||||
"options": [
|
||||
"--adbpath=%(adbpath)s",
|
||||
"--b2gpath=%(b2gpath)s",
|
||||
"--emulator=%(emulator)s",
|
||||
"--logdir=%(logcat_dir)s",
|
||||
"--remote-webserver=%(remote_webserver)s",
|
||||
"%(test_manifest)s",
|
||||
"--xre-path=%(xre_path)s",
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
"--busybox=%(busybox)s",
|
||||
"--total-chunks=%(total_chunks)s",
|
||||
"--this-chunk=%(this_chunk)s",
|
||||
"--quiet",
|
||||
"--log-raw=%(raw_log_file)s",
|
||||
"--certificate-path=%(certificate_path)s",
|
||||
"%(test_path)s"
|
||||
],
|
||||
"run_filename": "runtestsb2g.py",
|
||||
"testsdir": "mochitest"
|
||||
},
|
||||
"mochitest-chrome": {
|
||||
"options": [
|
||||
"--adbpath=%(adbpath)s",
|
||||
"--b2gpath=%(b2gpath)s",
|
||||
"--emulator=%(emulator)s",
|
||||
"--logdir=%(logcat_dir)s",
|
||||
"--remote-webserver=%(remote_webserver)s",
|
||||
"--xre-path=%(xre_path)s",
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
"--busybox=%(busybox)s",
|
||||
"--total-chunks=%(total_chunks)s",
|
||||
"--this-chunk=%(this_chunk)s",
|
||||
"--quiet",
|
||||
"--chrome",
|
||||
"--log-raw=%(raw_log_file)s",
|
||||
"--certificate-path=%(certificate_path)s",
|
||||
"%(test_path)s"
|
||||
],
|
||||
"run_filename": "runtestsb2g.py",
|
||||
"testsdir": "mochitest"
|
||||
},
|
||||
"reftest": {
|
||||
"options": [
|
||||
"--adbpath=%(adbpath)s",
|
||||
"--b2gpath=%(b2gpath)s",
|
||||
"--emulator=%(emulator)s",
|
||||
"--emulator-res=800x1000",
|
||||
"--logdir=%(logcat_dir)s",
|
||||
"--remote-webserver=%(remote_webserver)s",
|
||||
"--ignore-window-size",
|
||||
"--xre-path=%(xre_path)s",
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
"--busybox=%(busybox)s",
|
||||
"--total-chunks=%(total_chunks)s",
|
||||
"--this-chunk=%(this_chunk)s",
|
||||
"--enable-oop",
|
||||
"tests/layout/reftests/reftest.list"
|
||||
],
|
||||
"run_filename": "runreftestsb2g.py",
|
||||
"testsdir": "reftest"
|
||||
},
|
||||
"xpcshell": {
|
||||
"options": [
|
||||
"--adbpath=%(adbpath)s",
|
||||
"--b2gpath=%(b2gpath)s",
|
||||
"--emulator=%(emulator)s",
|
||||
"--logdir=%(logcat_dir)s",
|
||||
"--manifest=tests/xpcshell.ini",
|
||||
"--use-device-libs",
|
||||
"--testing-modules-dir=%(modules_dir)s",
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
"--busybox=%(busybox)s",
|
||||
"--total-chunks=%(total_chunks)s",
|
||||
"--this-chunk=%(this_chunk)s",
|
||||
"--log-raw=%(raw_log_file)s"
|
||||
],
|
||||
"run_filename": "runtestsb2g.py",
|
||||
"testsdir": "xpcshell"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,10 @@
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
# XXX Bug 1181261 - Please update config in testing/mozharness/config
|
||||
# instead. This file is still needed for mulet mochitests, but should
|
||||
# be removed once bug 1188330 is finished.
|
||||
|
||||
config = {
|
||||
"suite_definitions": {
|
||||
"cppunittest": {
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
# This is used by mozharness' mulet_unittest.py
|
||||
|
||||
# XXX Bug 1181261 - Please update config in testing/mozharness/config
|
||||
# instead. This file is still needed for mulet reftests, but should
|
||||
# be removed once bug 1188330 is finished.
|
||||
|
||||
config = {
|
||||
# testsuite options
|
||||
"reftest_options": [
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
config = {
|
||||
"suite_definitions": {
|
||||
"cppunittest": {
|
||||
"options": [
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
"--xre-path=%(abs_app_dir)s"
|
||||
],
|
||||
"run_filename": "runcppunittests.py",
|
||||
"testsdir": "cppunittest"
|
||||
},
|
||||
"jittest": {
|
||||
"options": [
|
||||
"tests/bin/js",
|
||||
"--no-slow",
|
||||
"--no-progress",
|
||||
"--format=automation",
|
||||
"--jitflags=all"
|
||||
],
|
||||
"run_filename": "jit_test.py",
|
||||
"testsdir": "jit-test/jit-test"
|
||||
},
|
||||
"mochitest": {
|
||||
"options": [
|
||||
"--appname=%(binary_path)s",
|
||||
"--utility-path=tests/bin",
|
||||
"--extra-profile-file=tests/bin/plugins",
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
"--certificate-path=tests/certs",
|
||||
"--quiet",
|
||||
"--log-raw=%(raw_log_file)s"
|
||||
],
|
||||
"run_filename": "runtests.py",
|
||||
"testsdir": "mochitest"
|
||||
},
|
||||
"mozbase": {
|
||||
"options": [
|
||||
"-b",
|
||||
"%(binary_path)s"
|
||||
],
|
||||
"run_filename": "test.py",
|
||||
"testsdir": "mozbase"
|
||||
},
|
||||
"mozmill": {
|
||||
"options": [
|
||||
"--binary=%(binary_path)s",
|
||||
"--symbols-path=%(symbols_path)s"
|
||||
],
|
||||
"run_filename": "runtestlist.py",
|
||||
"testsdir": "mozmill"
|
||||
},
|
||||
"reftest": {
|
||||
"options": [
|
||||
"--appname=%(binary_path)s",
|
||||
"--utility-path=tests/bin",
|
||||
"--extra-profile-file=tests/bin/plugins",
|
||||
"--symbols-path=%(symbols_path)s"
|
||||
],
|
||||
"run_filename": "runreftest.py",
|
||||
"testsdir": "reftest"
|
||||
},
|
||||
"webapprt": {
|
||||
"options": [
|
||||
"--app=%(app_path)s",
|
||||
"--utility-path=tests/bin",
|
||||
"--extra-profile-file=tests/bin/plugins",
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
"--certificate-path=tests/certs",
|
||||
"--autorun",
|
||||
"--close-when-done",
|
||||
"--console-level=INFO",
|
||||
"--testing-modules-dir=tests/modules",
|
||||
"--quiet"
|
||||
],
|
||||
"run_filename": "runtests.py",
|
||||
"testsdir": "mochitest"
|
||||
},
|
||||
"xpcshell": {
|
||||
"options": [
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
"--test-plugin-path=%(test_plugin_path)s",
|
||||
"--log-raw=%(raw_log_file)s"
|
||||
],
|
||||
"run_filename": "runxpcshelltests.py",
|
||||
"testsdir": "xpcshell"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
config = {
|
||||
"suite_definitions": {
|
||||
"gaiatest_desktop": {
|
||||
"options": [
|
||||
"--restart",
|
||||
"--timeout=%(timeout)s",
|
||||
"--type=%(type)s",
|
||||
"--testvars=%(testvars)s",
|
||||
"--profile=%(profile)s",
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
"--gecko-log=%(gecko_log)s",
|
||||
"--xml-output=%(xml_output)s",
|
||||
"--html-output=%(html_output)s",
|
||||
"--log-raw=%(raw_log_file)s",
|
||||
"--binary=%(binary)s",
|
||||
"--address=%(address)s",
|
||||
"--total-chunks=%(total_chunks)s",
|
||||
"--this-chunk=%(this_chunk)s"
|
||||
],
|
||||
"run_filename": "",
|
||||
"testsdir": ""
|
||||
},
|
||||
"gaiatest_emulator": {
|
||||
"options": [
|
||||
"--restart",
|
||||
"--timeout=%(timeout)s",
|
||||
"--type=%(type)s",
|
||||
"--testvars=%(testvars)s",
|
||||
"--profile=%(profile)s",
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
"--xml-output=%(xml_output)s",
|
||||
"--html-output=%(html_output)s",
|
||||
"--log-raw=%(raw_log_file)s",
|
||||
"--logcat-dir=%(logcat_dir)s",
|
||||
"--emulator=%(emulator)s",
|
||||
"--homedir=%(homedir)s"
|
||||
],
|
||||
"run_filename": "",
|
||||
"testsdir": ""
|
||||
},
|
||||
"marionette_desktop": {
|
||||
"options": [
|
||||
"--type=%(type)s",
|
||||
"--log-raw=%(raw_log_file)s",
|
||||
"--binary=%(binary)s",
|
||||
"--address=%(address)s",
|
||||
"--symbols-path=%(symbols_path)s"
|
||||
],
|
||||
"run_filename": "",
|
||||
"testsdir": ""
|
||||
},
|
||||
"marionette_emulator": {
|
||||
"options": [
|
||||
"--type=%(type)s",
|
||||
"--log-raw=%(raw_log_file)s",
|
||||
"--logcat-dir=%(logcat_dir)s",
|
||||
"--emulator=%(emulator)s",
|
||||
"--homedir=%(homedir)s",
|
||||
"--symbols-path=%(symbols_path)s"
|
||||
],
|
||||
"run_filename": "",
|
||||
"testsdir": ""
|
||||
},
|
||||
"webapi_desktop": {
|
||||
"options": [],
|
||||
"run_filename": "",
|
||||
"testsdir": ""
|
||||
},
|
||||
"webapi_emulator": {
|
||||
"options": [
|
||||
"--type=%(type)s",
|
||||
"--log-raw=%(raw_log_file)s",
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
"--logcat-dir=%(logcat_dir)s",
|
||||
"--emulator=%(emulator)s",
|
||||
"--homedir=%(homedir)s"
|
||||
],
|
||||
"run_filename": "",
|
||||
"testsdir": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
config = {
|
||||
"reftest_options": [
|
||||
"--appname=%(binary_path)s", "--utility-path=tests/bin",
|
||||
"--extra-profile-file=tests/bin/plugins", "--symbols-path=%(symbols_path)s"
|
||||
],
|
||||
"mochitest_options": [
|
||||
"--appname=%(binary_path)s", "--utility-path=tests/bin",
|
||||
"--extra-profile-file=tests/bin/plugins", "--symbols-path=%(symbols_path)s",
|
||||
"--certificate-path=tests/certs", "--setpref=webgl.force-enabled=true",
|
||||
"--quiet", "--log-raw=%(raw_log_file)s"
|
||||
],
|
||||
"webapprt_options": [
|
||||
"--app=%(app_path)s", "--utility-path=tests/bin",
|
||||
"--extra-profile-file=tests/bin/plugins", "--symbols-path=%(symbols_path)s",
|
||||
"--certificate-path=tests/certs", "--autorun", "--close-when-done",
|
||||
"--console-level=INFO", "--testing-modules-dir=tests/modules",
|
||||
"--quiet"
|
||||
],
|
||||
"xpcshell_options": [
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
"--test-plugin-path=%(test_plugin_path)s"
|
||||
],
|
||||
"cppunittest_options": [
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
"--xre-path=%(abs_app_dir)s"
|
||||
],
|
||||
"jittest_options": [
|
||||
"tests/bin/js",
|
||||
"--no-slow",
|
||||
"--no-progress",
|
||||
"--format=automation",
|
||||
"--jitflags=all"
|
||||
],
|
||||
"mozbase_options": [
|
||||
"-b", "%(binary_path)s"
|
||||
],
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
# Because this list exposes new surface to our interface to try, and could
|
||||
# easily produce unexpected results if misused, this should only include
|
||||
# arguments likely to work with multiple harnesses, and will have unintended
|
||||
# effects if conflicts with TryParser are introduced.
|
||||
config = {
|
||||
'--tag': {
|
||||
'action': 'append',
|
||||
'dest': 'tags',
|
||||
'default': None,
|
||||
},
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
config = {
|
||||
"options": [
|
||||
"--prefs-root=%(test_path)s/prefs",
|
||||
"--processes=1",
|
||||
"--config=%(test_path)s/wptrunner.ini",
|
||||
"--ca-cert-path=%(test_path)s/certs/cacert.pem",
|
||||
"--host-key-path=%(test_path)s/certs/web-platform.test.key",
|
||||
"--host-cert-path=%(test_path)s/certs/web-platform.test.pem",
|
||||
"--certutil-binary=%(test_install_path)s/bin/certutil",
|
||||
],
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
config = {
|
||||
"suite_definitions": {
|
||||
"cppunittest": {
|
||||
"options": [
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
"--xre-path=%(abs_app_dir)s"
|
||||
],
|
||||
"run_filename": "runcppunittests.py",
|
||||
"testsdir": "cppunittest"
|
||||
},
|
||||
"jittest": {
|
||||
"options": [
|
||||
"tests/bin/js",
|
||||
"--no-slow",
|
||||
"--no-progress",
|
||||
"--format=automation",
|
||||
"--jitflags=all"
|
||||
],
|
||||
"run_filename": "jit_test.py",
|
||||
"testsdir": "jit-test/jit-test"
|
||||
},
|
||||
"mochitest": {
|
||||
"options": [
|
||||
"--appname=%(binary_path)s",
|
||||
"--utility-path=tests/bin",
|
||||
"--extra-profile-file=tests/bin/plugins",
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
"--certificate-path=tests/certs",
|
||||
"--quiet",
|
||||
"--log-raw=%(raw_log_file)s"
|
||||
],
|
||||
"run_filename": "runtests.py",
|
||||
"testsdir": "mochitest"
|
||||
},
|
||||
"mozbase": {
|
||||
"options": [
|
||||
"-b",
|
||||
"%(binary_path)s"
|
||||
],
|
||||
"run_filename": "test.py",
|
||||
"testsdir": "mozbase"
|
||||
},
|
||||
"mozmill": {
|
||||
"options": [
|
||||
"--binary=%(binary_path)s",
|
||||
"--symbols-path=%(symbols_path)s"
|
||||
],
|
||||
"run_filename": "runtestlist.py",
|
||||
"testsdir": "mozmill"
|
||||
},
|
||||
"reftest": {
|
||||
"options": [
|
||||
"--appname=%(binary_path)s",
|
||||
"--utility-path=tests/bin",
|
||||
"--extra-profile-file=tests/bin/plugins",
|
||||
"--symbols-path=%(symbols_path)s"
|
||||
],
|
||||
"run_filename": "runreftest.py",
|
||||
"testsdir": "reftest"
|
||||
},
|
||||
"webapprt": {
|
||||
"options": [
|
||||
"--app=%(app_path)s",
|
||||
"--utility-path=tests/bin",
|
||||
"--extra-profile-file=tests/bin/plugins",
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
"--certificate-path=tests/certs",
|
||||
"--autorun",
|
||||
"--close-when-done",
|
||||
"--console-level=INFO",
|
||||
"--testing-modules-dir=tests/modules",
|
||||
"--quiet"
|
||||
],
|
||||
"run_filename": "runtests.py",
|
||||
"testsdir": "mochitest"
|
||||
},
|
||||
"xpcshell": {
|
||||
"options": [
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
"--test-plugin-path=%(test_plugin_path)s",
|
||||
"--log-raw=%(raw_log_file)s"
|
||||
],
|
||||
"run_filename": "runxpcshelltests.py",
|
||||
"testsdir": "xpcshell"
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user