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:
2022-12-22 10:41:52 +08:00
parent a7ea204c19
commit c1eaf73bd6
180 changed files with 4252 additions and 2875 deletions
+20 -14
View File
@@ -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):
-4
View File
@@ -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
View File
@@ -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
-5
View File
@@ -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)
+1 -1
View File
@@ -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);
+8 -7
View File
@@ -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);
}
+14 -3
View File
@@ -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());
}
+1
View File
@@ -223,6 +223,7 @@ class ModuleObject : public NativeObject
static void finalize(js::FreeOp* fop, JSObject* obj);
bool hasScript() const;
bool hasImportBindings() const;
FunctionDeclarationVector* functionDeclarations();
};
-2
View File
@@ -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),
-51
View File
@@ -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
View File
@@ -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
-5
View File
@@ -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[];
+113 -1
View File
@@ -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_;
+33 -9
View File
@@ -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()) {
+7 -1
View File
@@ -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);
-39
View File
@@ -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 -1
View File
@@ -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;');
+3 -1
View File
@@ -1,5 +1,7 @@
// |jit-test| --no-ion
load(libdir + 'oomTest.js');
if (!('oomTest' in this))
quit();
var g = newGlobal();
oomTest(function() {
Debugger(g);
+3 -1
View File
@@ -1,2 +1,4 @@
load(libdir + 'oomTest.js');
if (!('oomTest' in this))
quit();
oomTest((function(x) { assertEq(x + y + ex, 25); }));
+1 -3
View File
@@ -1,6 +1,4 @@
load(libdir + 'oomTest.js');
if (helperThreadCount() === 0)
if (!('oomTest' in this) || helperThreadCount() === 0)
quit(0);
var lfGlobal = newGlobal();
+3 -1
View File
@@ -1,2 +1,4 @@
load(libdir + 'oomTest.js');
if (!('oomTest' in this))
quit();
oomTest(() => getBacktrace({args: oomTest[load+1], locals: true, thisprops: true}));
+4
View File
@@ -0,0 +1,4 @@
if (!('oomTest' in this))
quit();
oomTest(() => parseModule('import v from "mod";'));
+18
View File
@@ -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) {
+3 -1
View File
@@ -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}));
+3 -1
View File
@@ -1,2 +1,4 @@
load(libdir + 'oomTest.js');
if (!('oomTest' in this))
quit();
oomTest(newGlobal);
+3 -1
View File
@@ -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() {}"));
+3 -1
View File
@@ -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));
+3 -1
View File
@@ -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();
+2 -1
View File
@@ -1,5 +1,6 @@
// |jit-test| slow;
load(libdir + "oomTest.js");
if (!('oomTest' in this))
quit();
enableSPSProfiling();
var lfGlobal = newGlobal();
+5 -9
View File
@@ -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);
+20 -5
View File
@@ -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 {
+5 -5
View File
@@ -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());
+1 -1
View File
@@ -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.
+2 -2
View File
@@ -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)
{
+1
View File
@@ -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);
+6 -3
View File
@@ -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();
+1 -1
View File
@@ -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),
+1 -1
View File
@@ -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"
+18 -15
View File
@@ -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));
+1 -1
View File
@@ -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.
+3 -3
View File
@@ -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();
+44
View File
@@ -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)
{
+1
View File
@@ -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);
+105 -3
View File
@@ -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)
{
+203 -100
View File
@@ -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);
+16 -18
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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/**']
]
-83
View File
@@ -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
+15 -3
View File
@@ -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
View File
@@ -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
+142 -39
View File
@@ -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)))
+16 -6
View File
@@ -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.
+23 -38
View File
@@ -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:
+7 -2
View File
@@ -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": [
-91
View File
@@ -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"
}
}
}
-86
View File
@@ -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