summaryrefslogtreecommitdiffstats
path: root/js/src
diff options
context:
space:
mode:
Diffstat (limited to 'js/src')
-rw-r--r--js/src/Makefile.in11
-rw-r--r--js/src/builtin/Iterator.js41
-rw-r--r--js/src/builtin/Module.js46
-rw-r--r--js/src/builtin/ModuleObject.cpp124
-rw-r--r--js/src/builtin/ModuleObject.h7
-rw-r--r--js/src/builtin/Object.cpp95
-rw-r--r--js/src/builtin/Promise.cpp8
-rw-r--r--js/src/builtin/Promise.h8
-rw-r--r--js/src/builtin/Promise.js69
-rw-r--r--js/src/builtin/RegExp.cpp34
-rw-r--r--js/src/builtin/RegExp.h2
-rw-r--r--js/src/builtin/RegExp.js140
-rw-r--r--js/src/builtin/SelfHostingDefines.h8
-rw-r--r--js/src/builtin/String.js27
-rw-r--r--js/src/builtin/TestingFunctions.cpp12
-rw-r--r--js/src/builtin/TypedObject.cpp1
-rw-r--r--js/src/ctypes/CTypes.cpp4
-rw-r--r--js/src/ctypes/libffi/src/x86/win32.S28
-rw-r--r--js/src/frontend/TokenStream.cpp2
-rw-r--r--js/src/gc/Marking.cpp7
-rw-r--r--js/src/gc/Memory.cpp17
-rw-r--r--js/src/gc/RootMarking.cpp1
-rw-r--r--js/src/irregexp/NativeRegExpMacroAssembler.cpp8
-rw-r--r--js/src/irregexp/NativeRegExpMacroAssembler.h7
-rw-r--r--js/src/irregexp/RegExpAST.cpp8
-rw-r--r--js/src/irregexp/RegExpAST.h33
-rw-r--r--js/src/irregexp/RegExpBytecode.h23
-rw-r--r--js/src/irregexp/RegExpEngine.cpp151
-rw-r--r--js/src/irregexp/RegExpEngine.h31
-rw-r--r--js/src/irregexp/RegExpInterpreter.cpp74
-rw-r--r--js/src/irregexp/RegExpMacroAssembler.cpp17
-rw-r--r--js/src/irregexp/RegExpMacroAssembler.h15
-rw-r--r--js/src/irregexp/RegExpParser.cpp205
-rw-r--r--js/src/irregexp/RegExpParser.h26
-rw-r--r--js/src/jit-test/modules/empty.js1
-rw-r--r--js/src/jit-test/modules/export-circular-nonexisting-binding-1.js4
-rw-r--r--js/src/jit-test/modules/export-circular-nonexisting-binding-2.js1
-rw-r--r--js/src/jit-test/modules/export-star-circular-1.js1
-rw-r--r--js/src/jit-test/modules/export-star-circular-2.js3
-rw-r--r--js/src/jit-test/tests/auto-regress/bug466654.js8
-rw-r--r--js/src/jit-test/tests/auto-regress/bug516897.js6
-rw-r--r--js/src/jit-test/tests/auto-regress/bug537854.js4
-rw-r--r--js/src/jit-test/tests/auto-regress/bug560796.js9
-rw-r--r--js/src/jit-test/tests/auto-regress/bug638735.js1
-rw-r--r--js/src/jit-test/tests/auto-regress/bug639413.js9
-rw-r--r--js/src/jit-test/tests/auto-regress/bug698899.js9
-rw-r--r--js/src/jit-test/tests/auto-regress/bug746397.js10
-rw-r--r--js/src/jit-test/tests/auto-regress/bug769192.js6
-rw-r--r--js/src/jit-test/tests/baseline/bug843444.js8
-rw-r--r--js/src/jit-test/tests/basic/bug1220766.js3
-rw-r--r--js/src/jit-test/tests/basic/bug510437.js13
-rw-r--r--js/src/jit-test/tests/basic/bug605015.js9
-rw-r--r--js/src/jit-test/tests/basic/bug631305.js9
-rw-r--r--js/src/jit-test/tests/basic/bug662562.js6
-rw-r--r--js/src/jit-test/tests/basic/bug690292.js12
-rw-r--r--js/src/jit-test/tests/basic/bug696748.js3
-rw-r--r--js/src/jit-test/tests/basic/bug831846.js3
-rw-r--r--js/src/jit-test/tests/basic/testAssigningWatchedDeletedProperty.js7
-rw-r--r--js/src/jit-test/tests/basic/testBug566556.js9
-rw-r--r--js/src/jit-test/tests/basic/testBug578044.js13
-rw-r--r--js/src/jit-test/tests/basic/testBug584650.js9
-rw-r--r--js/src/jit-test/tests/basic/testBug780288-1.js20
-rw-r--r--js/src/jit-test/tests/basic/testBug780288-2.js20
-rw-r--r--js/src/jit-test/tests/basic/testEvalCalledFromWatchOverSetter.js3
-rw-r--r--js/src/jit-test/tests/basic/testNonStubGetter.js7
-rw-r--r--js/src/jit-test/tests/basic/testSettingWatchPointOnReadOnlyProp.js7
-rw-r--r--js/src/jit-test/tests/basic/testTrueShiftTrue.js16
-rw-r--r--js/src/jit-test/tests/basic/testWatchRecursion.js63
-rw-r--r--js/src/jit-test/tests/ctypes/function-definition.js2
-rw-r--r--js/src/jit-test/tests/gc/bug-900405.js3
-rw-r--r--js/src/jit-test/tests/gc/bug-913261.js5
-rw-r--r--js/src/jit-test/tests/gc/bug-986864.js8
-rw-r--r--js/src/jit-test/tests/ion/bug1063182.js8
-rw-r--r--js/src/jit-test/tests/ion/bug772901.js2
-rw-r--r--js/src/jit-test/tests/ion/bug774257-1.js8
-rw-r--r--js/src/jit-test/tests/ion/bug774257-2.js10
-rw-r--r--js/src/jit-test/tests/ion/bug779631.js9
-rw-r--r--js/src/jit-test/tests/ion/bug783590.js1
-rw-r--r--js/src/jit-test/tests/jaeger/bug550665.js8
-rw-r--r--js/src/jit-test/tests/jaeger/bug557063.js7
-rw-r--r--js/src/jit-test/tests/jaeger/bug588338.js1
-rw-r--r--js/src/jit-test/tests/jaeger/bug625438.js10
-rw-r--r--js/src/jit-test/tests/jaeger/bug630366.js7
-rw-r--r--js/src/jit-test/tests/jaeger/recompile/bug641225.js1
-rw-r--r--js/src/jit-test/tests/modules/bug-1320993.js2
-rw-r--r--js/src/jit-test/tests/modules/export-circular-nonexisting-binding.js3
-rw-r--r--js/src/jit-test/tests/modules/export-star-cannot-rescue-missing-export.js4
-rw-r--r--js/src/jit-test/tests/modules/export-star-circular-dependencies.js6
-rw-r--r--js/src/jit-test/tests/modules/import-namespace.js45
-rw-r--r--js/src/jit-test/tests/pic/fuzz1.js4
-rw-r--r--js/src/jit-test/tests/pic/fuzz3.js3
-rw-r--r--js/src/jit-test/tests/pic/watch1.js7
-rw-r--r--js/src/jit-test/tests/pic/watch1a.js17
-rw-r--r--js/src/jit-test/tests/pic/watch2.js8
-rw-r--r--js/src/jit-test/tests/pic/watch2a.js18
-rw-r--r--js/src/jit-test/tests/pic/watch3.js7
-rw-r--r--js/src/jit-test/tests/pic/watch3a.js19
-rw-r--r--js/src/jit-test/tests/pic/watch3b.js20
-rw-r--r--js/src/jit-test/tests/pic/watch4.js9
-rw-r--r--js/src/jit-test/tests/pic/watch5.js27
-rw-r--r--js/src/jit-test/tests/profiler/bug1140643.js14
-rw-r--r--js/src/jit/BaselineIC.cpp6
-rw-r--r--js/src/jit/InlinableNatives.h1
-rw-r--r--js/src/jit/IonCaches.cpp5
-rw-r--r--js/src/jit/MCallOptimize.cpp2
-rw-r--r--js/src/jit/arm/MacroAssembler-arm.cpp4
-rw-r--r--js/src/js.msg4
-rw-r--r--js/src/jsapi.cpp1
-rw-r--r--js/src/jsapi.h4
-rw-r--r--js/src/jscntxt.cpp1
-rw-r--r--js/src/jscompartment.cpp12
-rw-r--r--js/src/jscompartment.h3
-rw-r--r--js/src/jsexn.cpp19
-rw-r--r--js/src/jsfriendapi.cpp2
-rw-r--r--js/src/jsfriendapi.h24
-rw-r--r--js/src/jsgc.cpp14
-rw-r--r--js/src/jsiter.cpp59
-rw-r--r--js/src/jsiter.h2
-rw-r--r--js/src/jsnativestack.cpp14
-rw-r--r--js/src/jsobj.cpp72
-rw-r--r--js/src/jsobj.h22
-rw-r--r--js/src/jsobjinlines.h6
-rw-r--r--js/src/jsstr.cpp1
-rw-r--r--js/src/jsversion.h1
-rw-r--r--js/src/jswatchpoint.cpp246
-rw-r--r--js/src/jswatchpoint.h90
-rw-r--r--js/src/jswrapper.h7
-rw-r--r--js/src/moz.build9
-rw-r--r--js/src/old-configure.in8
-rw-r--r--js/src/proxy/BaseProxyHandler.cpp14
-rw-r--r--js/src/proxy/Proxy.cpp27
-rw-r--r--js/src/proxy/Proxy.h3
-rw-r--r--js/src/proxy/SecurityWrapper.cpp19
-rw-r--r--js/src/shell/OSObject.cpp5
-rw-r--r--js/src/tests/ecma_5/Array/frozen-dense-array.js19
-rw-r--r--js/src/tests/ecma_5/extensions/watch-array-length.js41
-rw-r--r--js/src/tests/ecma_5/extensions/watch-inherited-property.js38
-rw-r--r--js/src/tests/ecma_5/extensions/watch-replaced-setter.js46
-rw-r--r--js/src/tests/ecma_5/extensions/watch-setter-become-setter.js44
-rw-r--r--js/src/tests/ecma_5/extensions/watch-value-prop-becoming-setter.js43
-rw-r--r--js/src/tests/ecma_5/extensions/watchpoint-deletes-JSPropertyOp-setter.js56
-rw-r--r--js/src/tests/js1_5/Object/regress-362872-01.js41
-rw-r--r--js/src/tests/js1_5/Object/regress-362872-02.js24
-rw-r--r--js/src/tests/js1_5/Regress/regress-127243.js75
-rw-r--r--js/src/tests/js1_5/Regress/regress-213482.js29
-rw-r--r--js/src/tests/js1_5/Regress/regress-240577.js37
-rw-r--r--js/src/tests/js1_5/Regress/regress-355341.js29
-rw-r--r--js/src/tests/js1_5/Regress/regress-355344.js49
-rw-r--r--js/src/tests/js1_5/Regress/regress-361467.js32
-rw-r--r--js/src/tests/js1_5/Regress/regress-361617.js35
-rw-r--r--js/src/tests/js1_5/Regress/regress-385393-06.js28
-rw-r--r--js/src/tests/js1_5/Regress/regress-506567.js45
-rw-r--r--js/src/tests/js1_5/extensions/regress-303277.js19
-rw-r--r--js/src/tests/js1_5/extensions/regress-355339.js32
-rw-r--r--js/src/tests/js1_5/extensions/regress-361346.js22
-rw-r--r--js/src/tests/js1_5/extensions/regress-361360.js32
-rw-r--r--js/src/tests/js1_5/extensions/regress-361552.js27
-rw-r--r--js/src/tests/js1_5/extensions/regress-361558.js19
-rw-r--r--js/src/tests/js1_5/extensions/regress-361571.js38
-rw-r--r--js/src/tests/js1_5/extensions/regress-361856.js35
-rw-r--r--js/src/tests/js1_5/extensions/regress-361964.js54
-rw-r--r--js/src/tests/js1_5/extensions/regress-385134.js38
-rw-r--r--js/src/tests/js1_5/extensions/regress-385393-09.js18
-rw-r--r--js/src/tests/js1_5/extensions/regress-390597.js42
-rw-r--r--js/src/tests/js1_5/extensions/regress-420612.js21
-rw-r--r--js/src/tests/js1_5/extensions/regress-435345-01.js100
-rw-r--r--js/src/tests/js1_5/extensions/regress-454040.js25
-rw-r--r--js/src/tests/js1_5/extensions/regress-454142.js30
-rw-r--r--js/src/tests/js1_5/extensions/regress-455413.js24
-rw-r--r--js/src/tests/js1_5/extensions/regress-465145.js24
-rwxr-xr-xjs/src/tests/js1_5/extensions/regress-472787.js31
-rw-r--r--js/src/tests/js1_5/extensions/regress-488995.js46
-rw-r--r--js/src/tests/js1_6/Regress/regress-476655.js40
-rw-r--r--js/src/tests/js1_6/extensions/regress-457521.js24
-rw-r--r--js/src/tests/js1_6/extensions/regress-479567.js33
-rw-r--r--js/src/tests/js1_7/extensions/regress-453955.js31
-rw-r--r--js/src/tests/js1_7/extensions/regress-473282.js20
-rw-r--r--js/src/tests/js1_7/regress/regress-385133-01.js37
-rw-r--r--js/src/tests/js1_8/extensions/regress-394709.js51
-rw-r--r--js/src/tests/js1_8/extensions/regress-481989.js19
-rw-r--r--js/src/tests/js1_8_1/extensions/regress-452498-193.js34
-rw-r--r--js/src/tests/js1_8_1/extensions/regress-452498-196.js9
-rw-r--r--js/src/tests/js1_8_1/extensions/regress-520572.js41
-rw-r--r--js/src/tests/js1_8_1/regress/regress-452498-160.js5
-rw-r--r--js/src/tests/js1_8_5/extensions/regress-604781-1.js24
-rw-r--r--js/src/tests/js1_8_5/extensions/regress-604781-2.js13
-rw-r--r--js/src/tests/js1_8_5/extensions/regress-627984-1.js16
-rw-r--r--js/src/tests/js1_8_5/extensions/regress-627984-2.js15
-rw-r--r--js/src/tests/js1_8_5/extensions/regress-627984-3.js14
-rw-r--r--js/src/tests/js1_8_5/extensions/regress-627984-4.js15
-rw-r--r--js/src/tests/js1_8_5/extensions/regress-627984-5.js13
-rw-r--r--js/src/tests/js1_8_5/extensions/regress-627984-6.js15
-rw-r--r--js/src/tests/js1_8_5/extensions/regress-627984-7.js9
-rw-r--r--js/src/tests/js1_8_5/extensions/regress-631723.js10
-rw-r--r--js/src/tests/js1_8_5/extensions/regress-636697.js11
-rw-r--r--js/src/tests/js1_8_5/extensions/regress-637985.js8
-rw-r--r--js/src/tests/js1_8_5/extensions/regress-691746.js11
-rw-r--r--js/src/tests/js1_8_5/extensions/watch-undefined-setter.js19
-rw-r--r--js/src/tests/js1_8_5/regress/regress-533876.js23
-rw-r--r--js/src/tests/js1_8_5/regress/regress-548276.js10
-rw-r--r--js/src/tests/js1_8_5/regress/regress-584648.js16
-rw-r--r--js/src/tests/js1_8_5/regress/regress-635195.js8
-rw-r--r--js/src/tests/js1_8_5/regress/regress-636394.js10
-rw-r--r--js/src/vm/CommonPropertyNames.h2
-rw-r--r--js/src/vm/EnvironmentObject.cpp5
-rw-r--r--js/src/vm/GlobalObject.cpp79
-rw-r--r--js/src/vm/GlobalObject.h8
-rw-r--r--js/src/vm/NativeObject-inl.h8
-rw-r--r--js/src/vm/NativeObject.cpp14
-rw-r--r--js/src/vm/RegExpObject.cpp5
-rw-r--r--js/src/vm/RegExpObject.h8
-rw-r--r--js/src/vm/Runtime.cpp1
-rw-r--r--js/src/vm/SelfHosting.cpp56
-rw-r--r--js/src/vm/Shape.h2
-rw-r--r--js/src/vm/Time.cpp12
-rw-r--r--js/src/vm/TypeInference.cpp114
-rw-r--r--js/src/wasm/WasmSignalHandlers.cpp9
217 files changed, 1164 insertions, 3763 deletions
diff --git a/js/src/Makefile.in b/js/src/Makefile.in
index 20678c68c..bc99e62b5 100644
--- a/js/src/Makefile.in
+++ b/js/src/Makefile.in
@@ -138,6 +138,17 @@ distclean::
CFLAGS += $(MOZ_ZLIB_CFLAGS)
+ifeq ($(OS_ARCH),SunOS)
+ifeq ($(TARGET_CPU),sparc)
+
+ifdef GNU_CC
+CFLAGS += -mcpu=v9
+CXXFLAGS += -mcpu=v9
+endif #GNU_CC
+
+endif
+endif
+
$(LIBRARY_NAME).pc: js.pc
cp $^ $@
diff --git a/js/src/builtin/Iterator.js b/js/src/builtin/Iterator.js
index 735eec7a0..e25b76156 100644
--- a/js/src/builtin/Iterator.js
+++ b/js/src/builtin/Iterator.js
@@ -84,44 +84,3 @@ function LegacyIteratorShim() {
function LegacyGeneratorIteratorShim() {
return NewLegacyIterator(ToObject(this), LegacyGeneratorIterator);
}
-
-// 7.4.8 CreateListIterator()
-function CreateListIterator(array) {
- let iterator = NewListIterator();
- UnsafeSetReservedSlot(iterator, ITERATOR_SLOT_TARGET, array);
- UnsafeSetReservedSlot(iterator, ITERATOR_SLOT_NEXT_INDEX, 0);
-
- // 7.4.8.1 ListIterator next()
- // The spec requires that we use a new next function per iterator object.
- let next = function() {
- if (!IsObject(this) || !IsListIterator(this))
- return callFunction(CallListIteratorMethodIfWrapped, this, "ListIteratorNext");
-
- if (ActiveFunction() !== UnsafeGetReservedSlot(this, ITERATOR_SLOT_NEXT_METHOD))
- ThrowTypeError(JSMSG_INCOMPATIBLE_METHOD, "next", "method", ToString(this));
-
- let array = UnsafeGetObjectFromReservedSlot(this, ITERATOR_SLOT_TARGET);
- let index = UnsafeGetReservedSlot(this, ITERATOR_SLOT_NEXT_INDEX);
-
- if (index >= ToLength(array.length)) {
- UnsafeSetReservedSlot(this, ITERATOR_SLOT_NEXT_INDEX, 1/0);
- return { value: undefined, done: true };
- }
-
- UnsafeSetReservedSlot(this, ITERATOR_SLOT_NEXT_INDEX, index + 1);
- return { value: array[index], done: false };
- };
-
- UnsafeSetReservedSlot(iterator, ITERATOR_SLOT_NEXT_METHOD, next);
- iterator.next = next;
-
- iterator[std_iterator] = ListIteratorIdentity;
- return iterator;
-}
-
-function ListIteratorIdentity() {
- if (!IsObject(this) || !IsListIterator(this))
- return callFunction(CallListIteratorMethodIfWrapped, this, "ListIteratorIdentity");
-
- return this;
-}
diff --git a/js/src/builtin/Module.js b/js/src/builtin/Module.js
index 7b70a7fe8..5c3d5e147 100644
--- a/js/src/builtin/Module.js
+++ b/js/src/builtin/Module.js
@@ -65,12 +65,12 @@ function ModuleGetExportedNames(exportStarSet = [])
return exportedNames;
}
-// 15.2.1.16.3 ResolveExport(exportName, resolveSet, exportStarSet)
-function ModuleResolveExport(exportName, resolveSet = [], exportStarSet = [])
+// 15.2.1.16.3 ResolveExport(exportName, resolveSet)
+function ModuleResolveExport(exportName, resolveSet = [])
{
if (!IsObject(this) || !IsModule(this)) {
return callFunction(CallModuleMethodIfWrapped, this, exportName, resolveSet,
- exportStarSet, "ModuleResolveExport");
+ "ModuleResolveExport");
}
// Step 1
@@ -100,38 +100,29 @@ function ModuleResolveExport(exportName, resolveSet = [], exportStarSet = [])
let e = indirectExportEntries[i];
if (exportName === e.exportName) {
let importedModule = CallModuleResolveHook(module, e.moduleRequest,
- MODULE_STATE_INSTANTIATED);
- let indirectResolution = callFunction(importedModule.resolveExport, importedModule,
- e.importName, resolveSet, exportStarSet);
- if (indirectResolution !== null)
- return indirectResolution;
+ MODULE_STATE_PARSED);
+ return callFunction(importedModule.resolveExport, importedModule, e.importName,
+ resolveSet);
}
}
// Step 6
if (exportName === "default") {
// A default export cannot be provided by an export *.
- ThrowSyntaxError(JSMSG_BAD_DEFAULT_EXPORT);
+ return null;
}
// Step 7
- if (callFunction(ArrayIncludes, exportStarSet, module))
- return null;
-
- // Step 8
- _DefineDataProperty(exportStarSet, exportStarSet.length, module);
-
- // Step 9
let starResolution = null;
- // Step 10
+ // Step 8
let starExportEntries = module.starExportEntries;
for (let i = 0; i < starExportEntries.length; i++) {
let e = starExportEntries[i];
let importedModule = CallModuleResolveHook(module, e.moduleRequest,
- MODULE_STATE_INSTANTIATED);
+ MODULE_STATE_PARSED);
let resolution = callFunction(importedModule.resolveExport, importedModule,
- exportName, resolveSet, exportStarSet);
+ exportName, resolveSet);
if (resolution === "ambiguous")
return resolution;
@@ -148,6 +139,7 @@ function ModuleResolveExport(exportName, resolveSet = [], exportStarSet = [])
}
}
+ // Step 9
return starResolution;
}
@@ -213,8 +205,8 @@ function GetModuleEnvironment(module)
function RecordInstantationFailure(module)
{
- // Set the module's environment slot to 'null' to indicate a failed module
- // instantiation.
+ // Set the module's state to 'failed' to indicate a failed module
+ // instantiation and reset the environment slot to 'undefined'.
assert(IsModule(module), "Non-module passed to RecordInstantationFailure");
SetModuleState(module, MODULE_STATE_FAILED);
UnsafeSetReservedSlot(module, MODULE_OBJECT_ENVIRONMENT_SLOT, undefined);
@@ -275,11 +267,13 @@ function ModuleDeclarationInstantiation()
ThrowSyntaxError(JSMSG_MISSING_IMPORT, imp.importName);
if (resolution === "ambiguous")
ThrowSyntaxError(JSMSG_AMBIGUOUS_IMPORT, imp.importName);
+ if (resolution.module.state < MODULE_STATE_INSTANTIATED)
+ ThrowInternalError(JSMSG_BAD_MODULE_STATE);
CreateImportBinding(env, imp.localName, resolution.module, resolution.bindingName);
}
}
- // Step 16.iv
+ // Step 17.a.iii
InstantiateModuleFunctionDeclarations(module);
} catch (e) {
RecordInstantationFailure(module);
@@ -318,11 +312,3 @@ function ModuleEvaluation()
return EvaluateModule(module);
}
_SetCanonicalName(ModuleEvaluation, "ModuleEvaluation");
-
-function ModuleNamespaceEnumerate()
-{
- if (!IsObject(this) || !IsModuleNamespace(this))
- return callFunction(CallModuleMethodIfWrapped, this, "ModuleNamespaceEnumerate");
-
- return CreateListIterator(ModuleNamespaceExports(this));
-}
diff --git a/js/src/builtin/ModuleObject.cpp b/js/src/builtin/ModuleObject.cpp
index 798ef46e1..575bab0b0 100644
--- a/js/src/builtin/ModuleObject.cpp
+++ b/js/src/builtin/ModuleObject.cpp
@@ -147,7 +147,7 @@ DEFINE_GETTER_FUNCTIONS(ExportEntryObject, moduleRequest, ModuleRequestSlot)
DEFINE_GETTER_FUNCTIONS(ExportEntryObject, importName, ImportNameSlot)
DEFINE_GETTER_FUNCTIONS(ExportEntryObject, localName, LocalNameSlot)
-DEFINE_ATOM_ACCESSOR_METHOD(ExportEntryObject, exportName)
+DEFINE_ATOM_OR_NULL_ACCESSOR_METHOD(ExportEntryObject, exportName)
DEFINE_ATOM_OR_NULL_ACCESSOR_METHOD(ExportEntryObject, moduleRequest)
DEFINE_ATOM_OR_NULL_ACCESSOR_METHOD(ExportEntryObject, importName)
DEFINE_ATOM_OR_NULL_ACCESSOR_METHOD(ExportEntryObject, localName)
@@ -289,14 +289,6 @@ ModuleNamespaceObject::create(JSContext* cx, HandleModuleObject module)
if (!object)
return nullptr;
- RootedId funName(cx, INTERNED_STRING_TO_JSID(cx, cx->names().Symbol_iterator_fun));
- RootedFunction enumerateFun(cx);
- enumerateFun = JS::GetSelfHostedFunction(cx, "ModuleNamespaceEnumerate", funName, 0);
- if (!enumerateFun)
- return nullptr;
-
- SetProxyExtra(object, ProxyHandler::EnumerateFunctionSlot, ObjectValue(*enumerateFun));
-
return &object->as<ModuleNamespaceObject>();
}
@@ -338,14 +330,9 @@ ModuleNamespaceObject::addBinding(JSContext* cx, HandleAtom exportedName,
const char ModuleNamespaceObject::ProxyHandler::family = 0;
ModuleNamespaceObject::ProxyHandler::ProxyHandler()
- : BaseProxyHandler(&family, true)
+ : BaseProxyHandler(&family, false)
{}
-JS::Value ModuleNamespaceObject::ProxyHandler::getEnumerateFunction(HandleObject proxy) const
-{
- return GetProxyExtra(proxy, EnumerateFunctionSlot);
-}
-
bool
ModuleNamespaceObject::ProxyHandler::getPrototype(JSContext* cx, HandleObject proxy,
MutableHandleObject protop) const
@@ -358,6 +345,8 @@ bool
ModuleNamespaceObject::ProxyHandler::setPrototype(JSContext* cx, HandleObject proxy,
HandleObject proto, ObjectOpResult& result) const
{
+ if (!proto)
+ return result.succeed();
return result.failCantSetProto();
}
@@ -402,21 +391,12 @@ ModuleNamespaceObject::ProxyHandler::getOwnPropertyDescriptor(JSContext* cx, Han
Rooted<ModuleNamespaceObject*> ns(cx, &proxy->as<ModuleNamespaceObject>());
if (JSID_IS_SYMBOL(id)) {
Rooted<JS::Symbol*> symbol(cx, JSID_TO_SYMBOL(id));
- if (symbol == cx->wellKnownSymbols().iterator) {
- RootedValue enumerateFun(cx, getEnumerateFunction(proxy));
- desc.object().set(proxy);
- desc.setConfigurable(false);
- desc.setEnumerable(false);
- desc.setValue(enumerateFun);
- return true;
- }
-
if (symbol == cx->wellKnownSymbols().toStringTag) {
RootedValue value(cx, StringValue(cx->names().Module));
desc.object().set(proxy);
desc.setWritable(false);
desc.setEnumerable(false);
- desc.setConfigurable(true);
+ desc.setConfigurable(false);
desc.setValue(value);
return true;
}
@@ -458,8 +438,8 @@ ModuleNamespaceObject::ProxyHandler::has(JSContext* cx, HandleObject proxy, Hand
Rooted<ModuleNamespaceObject*> ns(cx, &proxy->as<ModuleNamespaceObject>());
if (JSID_IS_SYMBOL(id)) {
Rooted<JS::Symbol*> symbol(cx, JSID_TO_SYMBOL(id));
- return symbol == cx->wellKnownSymbols().iterator ||
- symbol == cx->wellKnownSymbols().toStringTag;
+ *bp = symbol == cx->wellKnownSymbols().toStringTag;
+ return true;
}
*bp = ns->bindings().has(id);
@@ -473,23 +453,21 @@ ModuleNamespaceObject::ProxyHandler::get(JSContext* cx, HandleObject proxy, Hand
Rooted<ModuleNamespaceObject*> ns(cx, &proxy->as<ModuleNamespaceObject>());
if (JSID_IS_SYMBOL(id)) {
Rooted<JS::Symbol*> symbol(cx, JSID_TO_SYMBOL(id));
- if (symbol == cx->wellKnownSymbols().iterator) {
- vp.set(getEnumerateFunction(proxy));
- return true;
- }
-
if (symbol == cx->wellKnownSymbols().toStringTag) {
vp.setString(cx->names().Module);
return true;
}
- return false;
+ vp.setUndefined();
+ return true;
}
ModuleEnvironmentObject* env;
Shape* shape;
- if (!ns->bindings().lookup(id, &env, &shape))
- return false;
+ if (!ns->bindings().lookup(id, &env, &shape)) {
+ vp.setUndefined();
+ return true;
+ }
RootedValue value(cx, env->getSlot(shape->slot()));
if (value.isMagic(JS_UNINITIALIZED_LEXICAL)) {
@@ -526,7 +504,7 @@ ModuleNamespaceObject::ProxyHandler::ownPropertyKeys(JSContext* cx, HandleObject
Rooted<ModuleNamespaceObject*> ns(cx, &proxy->as<ModuleNamespaceObject>());
RootedObject exports(cx, &ns->exports());
uint32_t count;
- if (!GetLengthProperty(cx, exports, &count) || !props.reserve(props.length() + count))
+ if (!GetLengthProperty(cx, exports, &count) || !props.reserve(props.length() + count + 1))
return false;
Rooted<ValueVector> names(cx, ValueVector(cx));
@@ -536,6 +514,8 @@ ModuleNamespaceObject::ProxyHandler::ownPropertyKeys(JSContext* cx, HandleObject
for (uint32_t i = 0; i < count; i++)
props.infallibleAppend(AtomToId(&names[i].toString()->asAtom()));
+ props.infallibleAppend(SYMBOL_TO_JSID(cx->wellKnownSymbols().toStringTag));
+
return true;
}
@@ -1014,7 +994,7 @@ GlobalObject::initModuleProto(JSContext* cx, Handle<GlobalObject*> global)
static const JSFunctionSpec protoFunctions[] = {
JS_SELF_HOSTED_FN("getExportedNames", "ModuleGetExportedNames", 1, 0),
- JS_SELF_HOSTED_FN("resolveExport", "ModuleResolveExport", 3, 0),
+ JS_SELF_HOSTED_FN("resolveExport", "ModuleResolveExport", 2, 0),
JS_SELF_HOSTED_FN("declarationInstantiation", "ModuleDeclarationInstantiation", 0, 0),
JS_SELF_HOSTED_FN("evaluation", "ModuleEvaluation", 0, 0),
JS_FS_END
@@ -1164,6 +1144,13 @@ ModuleBuilder::processExport(frontend::ParseNode* pn)
bool isDefault = pn->getKind() == PNK_EXPORT_DEFAULT;
ParseNode* kid = isDefault ? pn->pn_left : pn->pn_kid;
+ if (isDefault && pn->pn_right) {
+ // This is an export default containing an expression.
+ RootedAtom localName(cx_, cx_->names().starDefaultStar);
+ RootedAtom exportName(cx_, cx_->names().default_);
+ return appendExportEntry(exportName, localName);
+ }
+
switch (kid->getKind()) {
case PNK_EXPORT_SPEC_LIST:
MOZ_ASSERT(!isDefault);
@@ -1177,53 +1164,46 @@ ModuleBuilder::processExport(frontend::ParseNode* pn)
break;
case PNK_CLASS: {
- const ClassNode& cls = kid->as<ClassNode>();
- MOZ_ASSERT(cls.names());
- RootedAtom localName(cx_, cls.names()->innerBinding()->pn_atom);
- RootedAtom exportName(cx_, isDefault ? cx_->names().default_ : localName.get());
- if (!appendExportEntry(exportName, localName))
- return false;
- break;
+ const ClassNode& cls = kid->as<ClassNode>();
+ MOZ_ASSERT(cls.names());
+ RootedAtom localName(cx_, cls.names()->innerBinding()->pn_atom);
+ RootedAtom exportName(cx_, isDefault ? cx_->names().default_ : localName.get());
+ if (!appendExportEntry(exportName, localName))
+ return false;
+ break;
}
case PNK_VAR:
case PNK_CONST:
case PNK_LET: {
- MOZ_ASSERT(kid->isArity(PN_LIST));
- for (ParseNode* var = kid->pn_head; var; var = var->pn_next) {
- if (var->isKind(PNK_ASSIGN))
- var = var->pn_left;
- MOZ_ASSERT(var->isKind(PNK_NAME));
- RootedAtom localName(cx_, var->pn_atom);
- RootedAtom exportName(cx_, isDefault ? cx_->names().default_ : localName.get());
- if (!appendExportEntry(exportName, localName))
- return false;
- }
- break;
+ MOZ_ASSERT(kid->isArity(PN_LIST));
+ for (ParseNode* var = kid->pn_head; var; var = var->pn_next) {
+ if (var->isKind(PNK_ASSIGN))
+ var = var->pn_left;
+ MOZ_ASSERT(var->isKind(PNK_NAME));
+ RootedAtom localName(cx_, var->pn_atom);
+ RootedAtom exportName(cx_, isDefault ? cx_->names().default_ : localName.get());
+ if (!appendExportEntry(exportName, localName))
+ return false;
+ }
+ break;
}
case PNK_FUNCTION: {
- RootedFunction func(cx_, kid->pn_funbox->function());
- if (!func->isArrow()) {
- RootedAtom localName(cx_, func->explicitName());
- RootedAtom exportName(cx_, isDefault ? cx_->names().default_ : localName.get());
- MOZ_ASSERT_IF(isDefault, localName);
- if (!appendExportEntry(exportName, localName))
- return false;
- break;
- }
- }
-
- MOZ_FALLTHROUGH; // Arrow functions are handled below.
-
- default:
- MOZ_ASSERT(isDefault);
- RootedAtom localName(cx_, cx_->names().starDefaultStar);
- RootedAtom exportName(cx_, cx_->names().default_);
+ RootedFunction func(cx_, kid->pn_funbox->function());
+ MOZ_ASSERT(!func->isArrow());
+ RootedAtom localName(cx_, func->explicitName());
+ RootedAtom exportName(cx_, isDefault ? cx_->names().default_ : localName.get());
+ MOZ_ASSERT_IF(isDefault, localName);
if (!appendExportEntry(exportName, localName))
return false;
break;
+ }
+
+ default:
+ MOZ_CRASH("Unexpected parse node");
}
+
return true;
}
diff --git a/js/src/builtin/ModuleObject.h b/js/src/builtin/ModuleObject.h
index e83520ebe..22db762ac 100644
--- a/js/src/builtin/ModuleObject.h
+++ b/js/src/builtin/ModuleObject.h
@@ -142,15 +142,8 @@ class ModuleNamespaceObject : public ProxyObject
private:
struct ProxyHandler : public BaseProxyHandler
{
- enum
- {
- EnumerateFunctionSlot = 0
- };
-
ProxyHandler();
- JS::Value getEnumerateFunction(HandleObject proxy) const;
-
bool getOwnPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id,
MutableHandle<PropertyDescriptor> desc) const override;
bool defineProperty(JSContext* cx, HandleObject proxy, HandleId id,
diff --git a/js/src/builtin/Object.cpp b/js/src/builtin/Object.cpp
index 56c77f304..bfcc8d20e 100644
--- a/js/src/builtin/Object.cpp
+++ b/js/src/builtin/Object.cpp
@@ -568,97 +568,6 @@ obj_setPrototypeOf(JSContext* cx, unsigned argc, Value* vp)
return true;
}
-#if JS_HAS_OBJ_WATCHPOINT
-
-bool
-js::WatchHandler(JSContext* cx, JSObject* obj_, jsid id_, const JS::Value& old,
- JS::Value* nvp, void* closure)
-{
- RootedObject obj(cx, obj_);
- RootedId id(cx, id_);
-
- /* Avoid recursion on (obj, id) already being watched on cx. */
- AutoResolving resolving(cx, obj, id, AutoResolving::WATCH);
- if (resolving.alreadyStarted())
- return true;
-
- FixedInvokeArgs<3> args(cx);
-
- args[0].set(IdToValue(id));
- args[1].set(old);
- args[2].set(*nvp);
-
- RootedValue callable(cx, ObjectValue(*static_cast<JSObject*>(closure)));
- RootedValue thisv(cx, ObjectValue(*obj));
- RootedValue rv(cx);
- if (!Call(cx, callable, thisv, args, &rv))
- return false;
-
- *nvp = rv;
- return true;
-}
-
-static bool
-obj_watch(JSContext* cx, unsigned argc, Value* vp)
-{
- CallArgs args = CallArgsFromVp(argc, vp);
-
- RootedObject obj(cx, ToObject(cx, args.thisv()));
- if (!obj)
- return false;
-
- if (!GlobalObject::warnOnceAboutWatch(cx, obj))
- return false;
-
- if (args.length() <= 1) {
- ReportMissingArg(cx, args.calleev(), 1);
- return false;
- }
-
- RootedObject callable(cx, ValueToCallable(cx, args[1], args.length() - 2));
- if (!callable)
- return false;
-
- RootedId propid(cx);
- if (!ValueToId<CanGC>(cx, args[0], &propid))
- return false;
-
- if (!WatchProperty(cx, obj, propid, callable))
- return false;
-
- args.rval().setUndefined();
- return true;
-}
-
-static bool
-obj_unwatch(JSContext* cx, unsigned argc, Value* vp)
-{
- CallArgs args = CallArgsFromVp(argc, vp);
-
- RootedObject obj(cx, ToObject(cx, args.thisv()));
- if (!obj)
- return false;
-
- if (!GlobalObject::warnOnceAboutWatch(cx, obj))
- return false;
-
- RootedId id(cx);
- if (args.length() != 0) {
- if (!ValueToId<CanGC>(cx, args[0], &id))
- return false;
- } else {
- id = JSID_VOID;
- }
-
- if (!UnwatchProperty(cx, obj, id))
- return false;
-
- args.rval().setUndefined();
- return true;
-}
-
-#endif /* JS_HAS_OBJ_WATCHPOINT */
-
/* ECMA 15.2.4.5. */
bool
js::obj_hasOwnProperty(JSContext* cx, unsigned argc, Value* vp)
@@ -1290,10 +1199,6 @@ static const JSFunctionSpec object_methods[] = {
JS_FN(js_toString_str, obj_toString, 0,0),
JS_SELF_HOSTED_FN(js_toLocaleString_str, "Object_toLocaleString", 0, 0),
JS_SELF_HOSTED_FN(js_valueOf_str, "Object_valueOf", 0,0),
-#if JS_HAS_OBJ_WATCHPOINT
- JS_FN(js_watch_str, obj_watch, 2,0),
- JS_FN(js_unwatch_str, obj_unwatch, 1,0),
-#endif
JS_FN(js_hasOwnProperty_str, obj_hasOwnProperty, 1,0),
JS_FN(js_isPrototypeOf_str, obj_isPrototypeOf, 1,0),
JS_FN(js_propertyIsEnumerable_str, obj_propertyIsEnumerable, 1,0),
diff --git a/js/src/builtin/Promise.cpp b/js/src/builtin/Promise.cpp
index ec7845e89..1d068f8c6 100644
--- a/js/src/builtin/Promise.cpp
+++ b/js/src/builtin/Promise.cpp
@@ -2006,6 +2006,13 @@ CommonStaticResolveRejectImpl(JSContext* cx, HandleValue thisVal, HandleValue ar
return promise;
}
+MOZ_MUST_USE JSObject*
+js::PromiseResolve(JSContext* cx, HandleObject constructor, HandleValue value)
+{
+ RootedValue C(cx, ObjectValue(*constructor));
+ return CommonStaticResolveRejectImpl(cx, C, value, ResolveMode);
+}
+
/**
* ES2016, 25.4.4.4, Promise.reject.
*/
@@ -2739,6 +2746,7 @@ CreatePromisePrototype(JSContext* cx, JSProtoKey key)
static const JSFunctionSpec promise_methods[] = {
JS_SELF_HOSTED_FN("catch", "Promise_catch", 1, 0),
JS_FN("then", Promise_then, 2, 0),
+ JS_SELF_HOSTED_FN("finally", "Promise_finally", 1, 0),
JS_FS_END
};
diff --git a/js/src/builtin/Promise.h b/js/src/builtin/Promise.h
index c76dc358c..6a6453e46 100644
--- a/js/src/builtin/Promise.h
+++ b/js/src/builtin/Promise.h
@@ -128,6 +128,14 @@ OriginalPromiseThen(JSContext* cx, Handle<PromiseObject*> promise,
HandleValue onFulfilled, HandleValue onRejected,
MutableHandleObject dependent, bool createDependent);
+/**
+ * PromiseResolve ( C, x )
+ *
+ * The abstract operation PromiseResolve, given a constructor and a value,
+ * returns a new promise resolved with that value.
+ */
+MOZ_MUST_USE JSObject*
+PromiseResolve(JSContext* cx, HandleObject constructor, HandleValue value);
MOZ_MUST_USE PromiseObject*
CreatePromiseObjectForAsync(JSContext* cx, HandleValue generatorVal);
diff --git a/js/src/builtin/Promise.js b/js/src/builtin/Promise.js
index 704cbab0b..91a1e1f56 100644
--- a/js/src/builtin/Promise.js
+++ b/js/src/builtin/Promise.js
@@ -14,3 +14,72 @@ function Promise_catch(onRejected) {
// Steps 1-2.
return callContentFunction(this.then, this, undefined, onRejected);
}
+
+// Promise.prototype.finally(onFinally)
+// See https://tc39.es/proposal-promise-finally/
+function Promise_finally(onFinally) {
+ // Step 1.
+ var promise = this;
+
+ // Step 2.
+ if (!IsObject(promise))
+ ThrowTypeError(JSMSG_INCOMPATIBLE_PROTO, "Promise", "finally", "value");
+
+ // Step 3.
+ var C = SpeciesConstructor(promise, GetBuiltinConstructor("Promise"));
+
+ // Step 4.
+ assert(IsConstructor(C), "SpeciesConstructor returns a constructor function");
+
+ // Steps 5-6.
+ var thenFinally, catchFinally;
+ if (!IsCallable(onFinally)) {
+ thenFinally = onFinally;
+ catchFinally = onFinally;
+ } else {
+ // ThenFinally Function.
+ // The parentheses prevent the inferring of a function name.
+ (thenFinally) = function(value) {
+ // Steps 1-2 (implicit).
+
+ // Step 3.
+ var result = onFinally();
+
+ // Steps 4-5 (implicit).
+
+ // Step 6.
+ var promise = PromiseResolve(C, result);
+
+ // Step 7.
+ // FIXME: spec issue - "be equivalent to a function that" is not a defined spec term.
+ // https://github.com/tc39/ecma262/issues/933
+
+ // Step 8.
+ return callContentFunction(promise.then, promise, function() { return value; });
+ };
+
+ // CatchFinally Function.
+ // The parentheses prevent the inferring of a function name.
+ (catchFinally) = function(reason) {
+ // Steps 1-2 (implicit).
+
+ // Step 3.
+ var result = onFinally();
+
+ // Steps 4-5 (implicit).
+
+ // Step 6.
+ var promise = PromiseResolve(C, result);
+
+ // Step 7.
+ // FIXME: spec issue - "be equivalent to a function that" is not a defined spec term.
+ // https://github.com/tc39/ecma262/issues/933
+
+ // Step 8.
+ return callContentFunction(promise.then, promise, function() { throw reason; });
+ };
+ }
+
+ // Step 7.
+ return callContentFunction(promise.then, promise, thenFinally, catchFinally);
+}
diff --git a/js/src/builtin/RegExp.cpp b/js/src/builtin/RegExp.cpp
index 7cf20d23c..55e0c8578 100644
--- a/js/src/builtin/RegExp.cpp
+++ b/js/src/builtin/RegExp.cpp
@@ -178,7 +178,7 @@ CheckPatternSyntax(JSContext* cx, HandleAtom pattern, RegExpFlag flags)
CompileOptions options(cx);
frontend::TokenStream dummyTokenStream(cx, options, nullptr, 0, nullptr);
return irregexp::ParsePatternSyntax(dummyTokenStream, cx->tempLifoAlloc(), pattern,
- flags & UnicodeFlag);
+ flags & UnicodeFlag, flags & DotAllFlag);
}
enum RegExpSharedUse {
@@ -664,6 +664,29 @@ js::regexp_multiline(JSContext* cx, unsigned argc, JS::Value* vp)
return CallNonGenericMethod<IsRegExpInstanceOrPrototype, regexp_multiline_impl>(cx, args);
}
+// ES 2018 dotAll
+MOZ_ALWAYS_INLINE bool
+regexp_dotall_impl(JSContext* cx, const CallArgs& args)
+{
+ MOZ_ASSERT(IsRegExpInstanceOrPrototype(args.thisv()));
+
+ if (!IsRegExpObject(args.thisv())) {
+ args.rval().setUndefined();
+ return true;
+ }
+
+ Rooted<RegExpObject*> reObj(cx, &args.thisv().toObject().as<RegExpObject>());
+ args.rval().setBoolean(reObj->dotall());
+ return true;
+}
+
+bool
+js::regexp_dotall(JSContext* cx, unsigned argc, JS::Value* vp)
+{
+ CallArgs args = CallArgsFromVp(argc, vp);
+ return CallNonGenericMethod<IsRegExpInstanceOrPrototype, regexp_dotall_impl>(cx, args);
+}
+
// ES 2017 draft rev32 21.2.5.10.
MOZ_ALWAYS_INLINE bool
regexp_source_impl(JSContext* cx, const CallArgs& args)
@@ -759,6 +782,7 @@ const JSPropertySpec js::regexp_properties[] = {
JS_PSG("source", regexp_source, 0),
JS_PSG("sticky", regexp_sticky, 0),
JS_PSG("unicode", regexp_unicode, 0),
+ JS_PSG("dotall", regexp_dotall, 0),
JS_PS_END
};
@@ -771,6 +795,7 @@ const JSFunctionSpec js::regexp_methods[] = {
JS_SELF_HOSTED_FN("exec", "RegExp_prototype_Exec", 1,0),
JS_SELF_HOSTED_FN("test", "RegExpTest" , 1,0),
JS_SELF_HOSTED_SYM_FN(match, "RegExpMatch", 1,0),
+ JS_SELF_HOSTED_SYM_FN(matchAll, "RegExpMatchAll", 1, 0),
JS_SELF_HOSTED_SYM_FN(replace, "RegExpReplace", 2,0),
JS_SELF_HOSTED_SYM_FN(search, "RegExpSearch", 1,0),
JS_SELF_HOSTED_SYM_FN(split, "RegExpSplit", 2,0),
@@ -1642,6 +1667,13 @@ js::RegExpPrototypeOptimizableRaw(JSContext* cx, JSObject* proto)
if (unicodeGetter != regexp_unicode)
return false;
+ JSNative dotAllGetter;
+ if (!GetOwnNativeGetterPure(cx, proto, NameToId(cx->names().dotall), &dotAllGetter))
+ return false;
+
+ if (dotAllGetter != regexp_dotall)
+ return false;
+
// Check if @@match, @@search, and exec are own data properties,
// those values should be tested in selfhosted JS.
bool has = false;
diff --git a/js/src/builtin/RegExp.h b/js/src/builtin/RegExp.h
index 4e0ff6948..f808f5146 100644
--- a/js/src/builtin/RegExp.h
+++ b/js/src/builtin/RegExp.h
@@ -153,6 +153,8 @@ extern MOZ_MUST_USE bool
regexp_sticky(JSContext* cx, unsigned argc, JS::Value* vp);
extern MOZ_MUST_USE bool
regexp_unicode(JSContext* cx, unsigned argc, JS::Value* vp);
+extern MOZ_MUST_USE bool
+regexp_dotall(JSContext* cx, unsigned argc, JS::Value* vp);
} /* namespace js */
diff --git a/js/src/builtin/RegExp.js b/js/src/builtin/RegExp.js
index 0b849292c..91212066c 100644
--- a/js/src/builtin/RegExp.js
+++ b/js/src/builtin/RegExp.js
@@ -3,6 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// ES6 draft rev34 (2015/02/20) 21.2.5.3 get RegExp.prototype.flags
+// Updated for ES2018 /s (dotAll)
function RegExpFlagsGetter() {
// Steps 1-2.
var R = this;
@@ -31,6 +32,10 @@ function RegExpFlagsGetter() {
// Steps 16-18.
if (R.sticky)
result += "y";
+
+ // ES2018
+ if (R.dotall)
+ result += "s";
// Step 19.
return result;
@@ -1026,3 +1031,138 @@ function RegExpSpecies() {
return this;
}
_SetCanonicalName(RegExpSpecies, "get [Symbol.species]");
+
+// String.prototype.matchAll proposal.
+//
+// RegExp.prototype [ @@matchAll ] ( string )
+function RegExpMatchAll(string) {
+ // Step 1.
+ var rx = this;
+
+ // Step 2.
+ if (!IsObject(rx))
+ ThrowTypeError(JSMSG_NOT_NONNULL_OBJECT, rx === null ? "null" : typeof rx);
+
+ if (rx.flags === undefined || rx.flags === null)
+ ThrowTypeError(JSMSG_FLAGS_UNDEFINED_OR_NULL);
+
+ // Step 3.
+ var str = ToString(string);
+
+ // Step 4.
+ var C = SpeciesConstructor(rx, GetBuiltinConstructor("RegExp"));
+
+ // Step 5.
+ var flags = ToString(rx.flags);
+
+ // Step 2.b.iii; located here because it needs to check |flags|.
+ if (!callFunction(std_String_includes, flags, "g")) {
+ ThrowTypeError(JSMSG_REQUIRES_GLOBAL_REGEXP, "matchAll");
+ }
+
+ // Step 6.
+ var matcher = new C(rx, flags);
+
+ // Steps 7-8.
+ matcher.lastIndex = ToLength(rx.lastIndex);
+
+ // Steps 9-12.
+ // Note, always global because non-global throws as per
+ // https://github.com/tc39/ecma262/pull/1716
+ var flags = REGEXP_GLOBAL_FLAG |
+ (callFunction(std_String_includes, flags, "u") ? REGEXP_UNICODE_FLAG : 0);
+
+ // Step 13.
+ return CreateRegExpStringIterator(matcher, str, flags);
+}
+
+// String.prototype.matchAll proposal.
+//
+// CreateRegExpStringIterator ( R, S, global, fullUnicode )
+function CreateRegExpStringIterator(regexp, string, flags) {
+ // Step 1.
+ assert(typeof string === "string", "|string| is a string value");
+
+ // Steps 2-3.
+ assert(typeof flags === "number", "|flags| is a number value");
+
+ // Steps 4-9.
+ var iterator = NewRegExpStringIterator();
+ UnsafeSetReservedSlot(iterator, REGEXP_STRING_ITERATOR_REGEXP_SLOT, regexp);
+ UnsafeSetReservedSlot(iterator, REGEXP_STRING_ITERATOR_STRING_SLOT, string);
+ UnsafeSetReservedSlot(iterator, REGEXP_STRING_ITERATOR_FLAGS_SLOT, flags | 0);
+ UnsafeSetReservedSlot(iterator, REGEXP_STRING_ITERATOR_DONE_SLOT, false);
+
+ // Step 10.
+ return iterator;
+}
+
+// String.prototype.matchAll proposal.
+//
+// %RegExpStringIteratorPrototype%.next ( )
+function RegExpStringIteratorNext() {
+ // Steps 1-3.
+ var obj;
+ if (!IsObject(this) || (obj = GuardToRegExpStringIterator(this)) === null) {
+ return callFunction(CallRegExpStringIteratorMethodIfWrapped, this,
+ "RegExpStringIteratorNext");
+ }
+
+ var result = { value: undefined, done: false };
+
+ // Step 4.
+ var done = UnsafeGetReservedSlot(obj, REGEXP_STRING_ITERATOR_DONE_SLOT);
+ if (done) {
+ result.done = true;
+ return result;
+ }
+
+ // Step 5.
+ var regexp = UnsafeGetObjectFromReservedSlot(obj, REGEXP_STRING_ITERATOR_REGEXP_SLOT);
+
+ // Step 6.
+ var string = UnsafeGetStringFromReservedSlot(obj, REGEXP_STRING_ITERATOR_STRING_SLOT);
+
+ // Steps 7-8.
+ var flags = UnsafeGetInt32FromReservedSlot(obj, REGEXP_STRING_ITERATOR_FLAGS_SLOT);
+ var global = !!(flags & REGEXP_GLOBAL_FLAG);
+ var fullUnicode = !!(flags & REGEXP_UNICODE_FLAG);
+
+ // Step 9.
+ var match = RegExpExec(regexp, string, false);
+
+ // Step 10.
+ if (match === null) {
+ // Step 10.a.
+ UnsafeSetReservedSlot(obj, REGEXP_STRING_ITERATOR_DONE_SLOT, true);
+
+ // Step 10.b.
+ result.done = true;
+ return result;
+ }
+
+ // Step 11.a.
+ if (global) {
+ // Step 11.a.i.
+ var matchStr = ToString(match[0]);
+
+ // Step 11.a.ii.
+ if (matchStr.length === 0) {
+ // Step 11.a.ii.1.
+ var thisIndex = ToLength(regexp.lastIndex);
+
+ // Step 11.a.ii.2.
+ var nextIndex = fullUnicode ? AdvanceStringIndex(string, thisIndex) : thisIndex + 1;
+
+ // Step 11.a.ii.3.
+ regexp.lastIndex = nextIndex;
+ }
+ } else {
+ // Step 11.b.i.
+ UnsafeSetReservedSlot(obj, REGEXP_STRING_ITERATOR_DONE_SLOT, true);
+ }
+
+ // Steps 11.a.iii and 11.b.ii.
+ result.value = match;
+ return result;
+}
diff --git a/js/src/builtin/SelfHostingDefines.h b/js/src/builtin/SelfHostingDefines.h
index b57c17269..117ac7ffd 100644
--- a/js/src/builtin/SelfHostingDefines.h
+++ b/js/src/builtin/SelfHostingDefines.h
@@ -71,8 +71,6 @@
// Used for list, i.e. Array and String, iterators.
#define ITERATOR_SLOT_NEXT_INDEX 1
#define ITERATOR_SLOT_ITEM_KIND 2
-// Used for ListIterator.
-#define ITERATOR_SLOT_NEXT_METHOD 2
#define ITEM_KIND_KEY 0
#define ITEM_KIND_VALUE 1
@@ -92,6 +90,12 @@
#define REGEXP_MULTILINE_FLAG 0x04
#define REGEXP_STICKY_FLAG 0x08
#define REGEXP_UNICODE_FLAG 0x10
+#define REGEXP_DOTALL_FLAG 0x20
+
+#define REGEXP_STRING_ITERATOR_REGEXP_SLOT 0
+#define REGEXP_STRING_ITERATOR_STRING_SLOT 1
+#define REGEXP_STRING_ITERATOR_FLAGS_SLOT 2
+#define REGEXP_STRING_ITERATOR_DONE_SLOT 3
#define MODULE_OBJECT_ENVIRONMENT_SLOT 2
diff --git a/js/src/builtin/String.js b/js/src/builtin/String.js
index f830b1aa2..d07ec6127 100644
--- a/js/src/builtin/String.js
+++ b/js/src/builtin/String.js
@@ -63,6 +63,33 @@ function String_generic_match(thisValue, regexp) {
return callFunction(String_match, thisValue, regexp);
}
+// String.prototype.matchAll proposal.
+//
+// String.prototype.matchAll ( regexp )
+function String_matchAll(regexp) {
+ // Step 1.
+ RequireObjectCoercible(this);
+
+ // Step 2.
+ if (regexp !== undefined && regexp !== null) {
+ // Step 2.a.
+ var matcher = GetMethod(regexp, std_matchAll);
+
+ // Step 2.b.
+ if (matcher !== undefined)
+ return callContentFunction(matcher, regexp, this);
+ }
+
+ // Step 3.
+ var string = ToString(this);
+
+ // Step 4.
+ var rx = RegExpCreate(regexp, "g");
+
+ // Step 5.
+ return callContentFunction(GetMethod(rx, std_matchAll), rx, string);
+}
+
/**
* A helper function implementing the logic for both String.prototype.padStart
* and String.prototype.padEnd as described in ES7 Draft March 29, 2016
diff --git a/js/src/builtin/TestingFunctions.cpp b/js/src/builtin/TestingFunctions.cpp
index 992fe2c97..b521e2bb3 100644
--- a/js/src/builtin/TestingFunctions.cpp
+++ b/js/src/builtin/TestingFunctions.cpp
@@ -239,8 +239,11 @@ GetBuildConfiguration(JSContext* cx, unsigned argc, Value* vp)
value = BooleanValue(true);
if (!JS_SetProperty(cx, info, "intl-api", value))
return false;
-
+#ifdef XP_SOLARIS
+ value = BooleanValue(false);
+#else
value = BooleanValue(true);
+#endif
if (!JS_SetProperty(cx, info, "mapped-array-buffer", value))
return false;
@@ -3897,10 +3900,10 @@ ConvertRegExpTreeToObject(JSContext* cx, irregexp::RegExpTree* tree)
return nullptr;
return obj;
}
- if (tree->IsLookahead()) {
- if (!StringProp(cx, obj, "type", "Lookahead"))
+ if (tree->IsLookaround()) {
+ if (!StringProp(cx, obj, "type", "Lookaround"))
return nullptr;
- irregexp::RegExpLookahead* t = tree->AsLookahead();
+ irregexp::RegExpLookaround* t = tree->AsLookaround();
if (!BooleanProp(cx, obj, "is_positive", t->is_positive()))
return nullptr;
if (!TreeProp(cx, obj, "body", t->body()))
@@ -3972,6 +3975,7 @@ ParseRegExp(JSContext* cx, unsigned argc, Value* vp)
flags & MultilineFlag, match_only,
flags & UnicodeFlag, flags & IgnoreCaseFlag,
flags & GlobalFlag, flags & StickyFlag,
+ flags & DotAllFlag,
&data))
{
return false;
diff --git a/js/src/builtin/TypedObject.cpp b/js/src/builtin/TypedObject.cpp
index ff3680774..50bf0b836 100644
--- a/js/src/builtin/TypedObject.cpp
+++ b/js/src/builtin/TypedObject.cpp
@@ -2215,7 +2215,6 @@ const ObjectOps TypedObject::objectOps_ = {
TypedObject::obj_setProperty,
TypedObject::obj_getOwnPropertyDescriptor,
TypedObject::obj_deleteProperty,
- nullptr, nullptr, /* watch/unwatch */
nullptr, /* getElements */
TypedObject::obj_enumerate,
nullptr, /* thisValue */
diff --git a/js/src/ctypes/CTypes.cpp b/js/src/ctypes/CTypes.cpp
index d6adfac2c..aed1114bd 100644
--- a/js/src/ctypes/CTypes.cpp
+++ b/js/src/ctypes/CTypes.cpp
@@ -20,6 +20,10 @@
#include <float.h>
#endif
+#if defined(XP_SOLARIS)
+#include <ieeefp.h>
+#endif
+
#ifdef HAVE_SSIZE_T
#include <sys/types.h>
#endif
diff --git a/js/src/ctypes/libffi/src/x86/win32.S b/js/src/ctypes/libffi/src/x86/win32.S
index daf0e799c..4f702e8b1 100644
--- a/js/src/ctypes/libffi/src/x86/win32.S
+++ b/js/src/ctypes/libffi/src/x86/win32.S
@@ -1158,8 +1158,24 @@ L_ffi_closure_SYSV_inner$stub:
.byte 0x7c /* .sleb128 -4; CIE Data Alignment Factor */
.byte 0x8 /* CIE RA Column */
#ifdef __PIC__
- .byte 0x1 /* .uleb128 0x1; Augmentation size */
- .byte 0x1b /* FDE Encoding (pcrel sdata4) */
+# if defined __sun__ && defined __svr4__
+/* 32-bit Solaris 2/x86 uses datarel encoding for PIC. GNU ld before 2.22
+ doesn't correctly sort .eh_frame_hdr with mixed encodings, so match this. */
+# define FDE_ENCODING 0x30 /* datarel */
+# define FDE_ENCODE(X) X@GOTOFF
+# else
+# define FDE_ENCODING 0x1b /* pcrel sdata4 */
+# if defined HAVE_AS_X86_PCREL
+# define FDE_ENCODE(X) X-.
+# else
+# define FDE_ENCODE(X) X@rel
+# endif
+# endif
+#else
+# define FDE_ENCODING 0 /* absolute */
+# define FDE_ENCODE(X) X
+.byte 0x1 /* .uleb128 0x1; Augmentation size */
+.byte FDE_ENCODING
#endif
.byte 0xc /* DW_CFA_def_cfa CFA = r4 + 4 = 4(%esp) */
.byte 0x4 /* .uleb128 0x4 */
@@ -1176,7 +1192,7 @@ L_ffi_closure_SYSV_inner$stub:
#if defined __PIC__ && defined HAVE_AS_X86_PCREL
.long .LFB1-. /* FDE initial location */
#else
- .long .LFB1
+ .long FDE_ENCODE(.LFB1)
#endif
.long .LFE1-.LFB1 /* FDE address range */
#ifdef __PIC__
@@ -1207,7 +1223,7 @@ L_ffi_closure_SYSV_inner$stub:
#if defined __PIC__ && defined HAVE_AS_X86_PCREL
.long .LFB3-. /* FDE initial location */
#else
- .long .LFB3
+ .long FDE_ENCODE(.LFB3)
#endif
.long .LFE3-.LFB3 /* FDE address range */
#ifdef __PIC__
@@ -1240,7 +1256,7 @@ L_ffi_closure_SYSV_inner$stub:
#if defined __PIC__ && defined HAVE_AS_X86_PCREL
.long .LFB4-. /* FDE initial location */
#else
- .long .LFB4
+ .long FDE_ENCODE(.LFB4)
#endif
.long .LFE4-.LFB4 /* FDE address range */
#ifdef __PIC__
@@ -1278,7 +1294,7 @@ L_ffi_closure_SYSV_inner$stub:
#if defined __PIC__ && defined HAVE_AS_X86_PCREL
.long .LFB5-. /* FDE initial location */
#else
- .long .LFB5
+ .long FDE_ENCODE(.LFB5)
#endif
.long .LFE5-.LFB5 /* FDE address range */
#ifdef __PIC__
diff --git a/js/src/frontend/TokenStream.cpp b/js/src/frontend/TokenStream.cpp
index b8623d545..e07f8df8a 100644
--- a/js/src/frontend/TokenStream.cpp
+++ b/js/src/frontend/TokenStream.cpp
@@ -1843,6 +1843,8 @@ TokenStream::getTokenInternal(TokenKind* ttp, Modifier modifier)
reflags = RegExpFlag(reflags | StickyFlag);
else if (c == 'u' && !(reflags & UnicodeFlag))
reflags = RegExpFlag(reflags | UnicodeFlag);
+ else if (c == 's' && !(reflags & DotAllFlag))
+ reflags = RegExpFlag(reflags | DotAllFlag);
else
break;
getChar();
diff --git a/js/src/gc/Marking.cpp b/js/src/gc/Marking.cpp
index da3ef7d0d..262fc8cbc 100644
--- a/js/src/gc/Marking.cpp
+++ b/js/src/gc/Marking.cpp
@@ -2846,10 +2846,9 @@ struct UnmarkGrayTracer : public JS::CallbackTracer
*
* There is an additional complication for certain kinds of edges that are not
* contained explicitly in the source object itself, such as from a weakmap key
- * to its value, and from an object being watched by a watchpoint to the
- * watchpoint's closure. These "implicit edges" are represented in some other
- * container object, such as the weakmap or the watchpoint itself. In these
- * cases, calling unmark gray on an object won't find all of its children.
+ * to its value. These "implicit edges" are represented in some other
+ * container object, such as the weakmap itself. In these cases, calling unmark
+ * gray on an object won't find all of its children.
*
* Handling these implicit edges has two parts:
* - A special pass enumerating all of the containers that know about the
diff --git a/js/src/gc/Memory.cpp b/js/src/gc/Memory.cpp
index 268e1e489..418984057 100644
--- a/js/src/gc/Memory.cpp
+++ b/js/src/gc/Memory.cpp
@@ -415,8 +415,15 @@ InitMemorySubsystem()
static inline void*
MapMemoryAt(void* desired, size_t length, int prot = PROT_READ | PROT_WRITE,
int flags = MAP_PRIVATE | MAP_ANON, int fd = -1, off_t offset = 0)
+
+// Solaris manages 64-bit address space in a different manner from every other
+// AMD64 operating system, but fortunately the fix is the same one
+// required for every operating system on 64-bit SPARC, Itanium, and ARM.
+// Most people's intuition failed them here and they thought this couldn't
+// possibly be correct on AMD64, but for Solaris/illumos it is.
+
{
-#if defined(__ia64__) || (defined(__sparc64__) && defined(__NetBSD__)) || defined(__aarch64__)
+#if defined(__ia64__) || (defined(__sparc64__) && defined(__NetBSD__)) || defined(__aarch64__) || (defined(__sun) && defined(__x86_64__))
MOZ_ASSERT((0xffff800000000000ULL & (uintptr_t(desired) + length - 1)) == 0);
#endif
void* region = mmap(desired, length, prot, flags, fd, offset);
@@ -466,7 +473,7 @@ MapMemory(size_t length, int prot = PROT_READ | PROT_WRITE,
return nullptr;
}
return region;
-#elif defined(__aarch64__)
+#elif defined(__aarch64__) || (defined(__sun) && defined(__x86_64__))
/*
* There might be similar virtual address issue on arm64 which depends on
* hardware and kernel configurations. But the work around is slightly
@@ -678,7 +685,11 @@ MarkPagesUnused(void* p, size_t size)
return false;
MOZ_ASSERT(OffsetFromAligned(p, pageSize) == 0);
- int result = madvise(p, size, MADV_DONTNEED);
+#ifdef XP_SOLARIS
+ int result = posix_madvise(p, size, POSIX_MADV_DONTNEED);
+#else
+ int result = madvise(p, size, MADV_DONTNEED);
+#endif
return result != -1;
}
diff --git a/js/src/gc/RootMarking.cpp b/js/src/gc/RootMarking.cpp
index f5969bc1f..7d665e8eb 100644
--- a/js/src/gc/RootMarking.cpp
+++ b/js/src/gc/RootMarking.cpp
@@ -14,7 +14,6 @@
#include "jsgc.h"
#include "jsprf.h"
#include "jstypes.h"
-#include "jswatchpoint.h"
#include "builtin/MapObject.h"
#include "frontend/BytecodeCompiler.h"
diff --git a/js/src/irregexp/NativeRegExpMacroAssembler.cpp b/js/src/irregexp/NativeRegExpMacroAssembler.cpp
index 0fb507297..e17eecb9b 100644
--- a/js/src/irregexp/NativeRegExpMacroAssembler.cpp
+++ b/js/src/irregexp/NativeRegExpMacroAssembler.cpp
@@ -582,7 +582,7 @@ NativeRegExpMacroAssembler::CheckAtStart(Label* on_at_start)
}
void
-NativeRegExpMacroAssembler::CheckNotAtStart(Label* on_not_at_start)
+NativeRegExpMacroAssembler::CheckNotAtStart(int cp_offset, Label* on_not_at_start)
{
JitSpew(SPEW_PREFIX "CheckNotAtStart");
@@ -673,7 +673,7 @@ NativeRegExpMacroAssembler::CheckGreedyLoop(Label* on_tos_equals_current_positio
}
void
-NativeRegExpMacroAssembler::CheckNotBackReference(int start_reg, Label* on_no_match)
+NativeRegExpMacroAssembler::CheckNotBackReference(int start_reg, bool read_backward, Label* on_no_match)
{
JitSpew(SPEW_PREFIX "CheckNotBackReference(%d)", start_reg);
@@ -744,8 +744,8 @@ NativeRegExpMacroAssembler::CheckNotBackReference(int start_reg, Label* on_no_ma
}
void
-NativeRegExpMacroAssembler::CheckNotBackReferenceIgnoreCase(int start_reg, Label* on_no_match,
- bool unicode)
+NativeRegExpMacroAssembler::CheckNotBackReferenceIgnoreCase(int start_reg, bool read_backward,
+ Label* on_no_match, bool unicode)
{
JitSpew(SPEW_PREFIX "CheckNotBackReferenceIgnoreCase(%d, %d)", start_reg, unicode);
diff --git a/js/src/irregexp/NativeRegExpMacroAssembler.h b/js/src/irregexp/NativeRegExpMacroAssembler.h
index 7a72e252f..fc582dccf 100644
--- a/js/src/irregexp/NativeRegExpMacroAssembler.h
+++ b/js/src/irregexp/NativeRegExpMacroAssembler.h
@@ -105,9 +105,10 @@ class MOZ_STACK_CLASS NativeRegExpMacroAssembler final : public RegExpMacroAssem
void CheckCharacterGT(char16_t limit, jit::Label* on_greater);
void CheckCharacterLT(char16_t limit, jit::Label* on_less);
void CheckGreedyLoop(jit::Label* on_tos_equals_current_position);
- void CheckNotAtStart(jit::Label* on_not_at_start);
- void CheckNotBackReference(int start_reg, jit::Label* on_no_match);
- void CheckNotBackReferenceIgnoreCase(int start_reg, jit::Label* on_no_match, bool unicode);
+ void CheckNotAtStart(int cp_offset, jit::Label* on_not_at_start);
+ void CheckNotBackReference(int start_reg, bool read_backward, jit::Label* on_no_match);
+ void CheckNotBackReferenceIgnoreCase(int start_reg, bool read_backward,
+ jit::Label* on_no_match, bool unicode);
void CheckNotCharacter(unsigned c, jit::Label* on_not_equal);
void CheckNotCharacterAfterAnd(unsigned c, unsigned and_with, jit::Label* on_not_equal);
void CheckNotCharacterAfterMinusAnd(char16_t c, char16_t minus, char16_t and_with,
diff --git a/js/src/irregexp/RegExpAST.cpp b/js/src/irregexp/RegExpAST.cpp
index 8dfd99057..43867c312 100644
--- a/js/src/irregexp/RegExpAST.cpp
+++ b/js/src/irregexp/RegExpAST.cpp
@@ -250,16 +250,16 @@ RegExpCapture::CaptureRegisters()
}
// ----------------------------------------------------------------------------
-// RegExpLookahead
+// RegExpLookaround
Interval
-RegExpLookahead::CaptureRegisters()
+RegExpLookaround::CaptureRegisters()
{
return body()->CaptureRegisters();
}
bool
-RegExpLookahead::IsAnchoredAtStart()
+RegExpLookaround::IsAnchoredAtStart()
{
- return is_positive() && body()->IsAnchoredAtStart();
+ return is_positive() && type() == LOOKAHEAD && body()->IsAnchoredAtStart();
}
diff --git a/js/src/irregexp/RegExpAST.h b/js/src/irregexp/RegExpAST.h
index 7bda6fc7e..6f59842bc 100644
--- a/js/src/irregexp/RegExpAST.h
+++ b/js/src/irregexp/RegExpAST.h
@@ -360,6 +360,7 @@ class RegExpCapture : public RegExpTree
virtual int min_match() { return body_->min_match(); }
virtual int max_match() { return body_->max_match(); }
RegExpTree* body() { return body_; }
+ void set_body(RegExpTree* body) { body_ = body; }
int index() { return index_; }
static int StartRegister(int index) { return index * 2; }
static int EndRegister(int index) { return index * 2 + 1; }
@@ -369,25 +370,29 @@ class RegExpCapture : public RegExpTree
int index_;
};
-class RegExpLookahead : public RegExpTree
+class RegExpLookaround : public RegExpTree
{
public:
- RegExpLookahead(RegExpTree* body,
- bool is_positive,
- int capture_count,
- int capture_from)
+ enum Type { LOOKAHEAD, LOOKBEHIND };
+
+ RegExpLookaround(RegExpTree* body,
+ bool is_positive,
+ int capture_count,
+ int capture_from,
+ Type type)
: body_(body),
is_positive_(is_positive),
capture_count_(capture_count),
- capture_from_(capture_from)
+ capture_from_(capture_from),
+ type_(type)
{}
virtual void* Accept(RegExpVisitor* visitor, void* data);
virtual RegExpNode* ToNode(RegExpCompiler* compiler,
RegExpNode* on_success);
- virtual RegExpLookahead* AsLookahead();
+ virtual RegExpLookaround* AsLookaround();
virtual Interval CaptureRegisters();
- virtual bool IsLookahead();
+ virtual bool IsLookaround();
virtual bool IsAnchoredAtStart();
virtual int min_match() { return 0; }
virtual int max_match() { return 0; }
@@ -395,12 +400,14 @@ class RegExpLookahead : public RegExpTree
bool is_positive() { return is_positive_; }
int capture_count() { return capture_count_; }
int capture_from() { return capture_from_; }
+ Type type() { return type_; }
private:
RegExpTree* body_;
bool is_positive_;
int capture_count_;
int capture_from_;
+ Type type_;
};
typedef InfallibleVector<RegExpCapture*, 1> RegExpCaptureVector;
@@ -417,8 +424,14 @@ class RegExpBackReference : public RegExpTree
RegExpNode* on_success);
virtual RegExpBackReference* AsBackReference();
virtual bool IsBackReference();
- virtual int min_match() { return 0; }
- virtual int max_match() { return capture_->max_match(); }
+ virtual int min_match() override { return 0; }
+ // The capture may not be completely parsed yet, if the reference occurs
+ // before the capture. In the ordinary case, nothing has been captured yet,
+ // so the back reference must have the length 0. If the back reference is
+ // inside a lookbehind, effectively making it a forward reference, we return
+ virtual int max_match() override {
+ return capture_->body() ? capture_->max_match() : 0;
+ }
int index() { return capture_->index(); }
RegExpCapture* capture() { return capture_; }
private:
diff --git a/js/src/irregexp/RegExpBytecode.h b/js/src/irregexp/RegExpBytecode.h
index f31b78c59..ea3f80b4f 100644
--- a/js/src/irregexp/RegExpBytecode.h
+++ b/js/src/irregexp/RegExpBytecode.h
@@ -82,16 +82,19 @@ V(CHECK_LT, 35, 8) /* bc8 pad8 uc16 addr32 */ \
V(CHECK_GT, 36, 8) /* bc8 pad8 uc16 addr32 */ \
V(CHECK_NOT_BACK_REF, 37, 8) /* bc8 reg_idx24 addr32 */ \
V(CHECK_NOT_BACK_REF_NO_CASE, 38, 8) /* bc8 reg_idx24 addr32 */ \
-V(CHECK_NOT_REGS_EQUAL, 39, 12) /* bc8 regidx24 reg_idx32 addr32 */ \
-V(CHECK_REGISTER_LT, 40, 12) /* bc8 reg_idx24 value32 addr32 */ \
-V(CHECK_REGISTER_GE, 41, 12) /* bc8 reg_idx24 value32 addr32 */ \
-V(CHECK_REGISTER_EQ_POS, 42, 8) /* bc8 reg_idx24 addr32 */ \
-V(CHECK_AT_START, 43, 8) /* bc8 pad24 addr32 */ \
-V(CHECK_NOT_AT_START, 44, 8) /* bc8 pad24 addr32 */ \
-V(CHECK_GREEDY, 45, 8) /* bc8 pad24 addr32 */ \
-V(ADVANCE_CP_AND_GOTO, 46, 8) /* bc8 offset24 addr32 */ \
-V(SET_CURRENT_POSITION_FROM_END, 47, 4) /* bc8 idx24 */ \
-V(CHECK_NOT_BACK_REF_NO_CASE_UNICODE, 48, 8) /* bc8 reg_idx24 addr32 */
+V(CHECK_NOT_BACK_REF_BACKWARD, 39, 8) /* bc8 reg_idx24 addr32 */ \
+V(CHECK_NOT_BACK_REF_NO_CASE_BACKWARD, 40, 8) /* bc8 reg_idx24 addr32 */ \
+V(CHECK_NOT_REGS_EQUAL, 41, 12) /* bc8 regidx24 reg_idx32 addr32 */ \
+V(CHECK_REGISTER_LT, 42, 12) /* bc8 reg_idx24 value32 addr32 */ \
+V(CHECK_REGISTER_GE, 43, 12) /* bc8 reg_idx24 value32 addr32 */ \
+V(CHECK_REGISTER_EQ_POS, 44, 8) /* bc8 reg_idx24 addr32 */ \
+V(CHECK_AT_START, 45, 8) /* bc8 pad24 addr32 */ \
+V(CHECK_NOT_AT_START, 46, 8) /* bc8 pad24 addr32 */ \
+V(CHECK_GREEDY, 47, 8) /* bc8 pad24 addr32 */ \
+V(ADVANCE_CP_AND_GOTO, 48, 8) /* bc8 offset24 addr32 */ \
+V(SET_CURRENT_POSITION_FROM_END, 49, 4) /* bc8 idx24 */ \
+V(CHECK_NOT_BACK_REF_NO_CASE_UNICODE, 50, 8) /* bc8 reg_idx24 addr32 */ \
+V(CHECK_NOT_BACK_REF_NO_CASE_BACKWARD_UNICODE, 51, 8) /* bc8 reg_idx24 addr32 */
#define DECLARE_BYTECODES(name, code, length) \
static const int BC_##name = code;
diff --git a/js/src/irregexp/RegExpEngine.cpp b/js/src/irregexp/RegExpEngine.cpp
index 4d691a5dc..62f94c3e7 100644
--- a/js/src/irregexp/RegExpEngine.cpp
+++ b/js/src/irregexp/RegExpEngine.cpp
@@ -721,6 +721,8 @@ ActionNode::EmptyMatchCheck(int start_register,
int
TextNode::EatsAtLeast(int still_to_find, int budget, bool not_at_start)
{
+ if (read_backward())
+ return 0;
int answer = Length();
if (answer >= still_to_find)
return answer;
@@ -736,8 +738,7 @@ TextNode::EatsAtLeast(int still_to_find, int budget, bool not_at_start)
int
TextNode::GreedyLoopTextLength()
{
- TextElement elm = elements()[elements().length() - 1];
- return elm.cp_offset() + elm.length();
+ return Length();
}
RegExpNode*
@@ -887,6 +888,8 @@ AssertionNode::FillInBMInfo(int offset, int budget, BoyerMooreLookahead* bm, boo
int
BackReferenceNode::EatsAtLeast(int still_to_find, int budget, bool not_at_start)
{
+ if (read_backward())
+ return 0;
if (budget <= 0)
return 0;
return on_success()->EatsAtLeast(still_to_find, budget - 1, not_at_start);
@@ -1578,6 +1581,9 @@ class irregexp::RegExpCompiler
current_expansion_factor_ = value;
}
+ bool read_backward() { return read_backward_; }
+ void set_read_backward(bool value) { read_backward_ = value; }
+
JSContext* cx() const { return cx_; }
LifoAlloc* alloc() const { return alloc_; }
@@ -1595,6 +1601,7 @@ class irregexp::RegExpCompiler
bool unicode_;
bool reg_exp_too_big_;
int current_expansion_factor_;
+ bool read_backward_;
FrequencyCollator frequency_collator_;
JSContext* cx_;
LifoAlloc* alloc_;
@@ -1624,6 +1631,7 @@ RegExpCompiler::RegExpCompiler(JSContext* cx, LifoAlloc* alloc, int capture_coun
unicode_(unicode),
reg_exp_too_big_(false),
current_expansion_factor_(1),
+ read_backward_(false),
frequency_collator_(),
cx_(cx),
alloc_(alloc)
@@ -1747,7 +1755,7 @@ irregexp::CompilePattern(JSContext* cx, RegExpShared* shared, RegExpCompileData*
// at the start of input.
ChoiceNode* first_step_node = alloc.newInfallible<ChoiceNode>(&alloc, 2);
RegExpNode* char_class =
- alloc.newInfallible<TextNode>(alloc.newInfallible<RegExpCharacterClass>('*'), loop_node);
+ alloc.newInfallible<TextNode>(alloc.newInfallible<RegExpCharacterClass>('*'), false, loop_node);
first_step_node->AddAlternative(GuardedAlternative(captured_body));
first_step_node->AddAlternative(GuardedAlternative(char_class));
node = first_step_node;
@@ -1850,19 +1858,19 @@ RegExpAtom::ToNode(RegExpCompiler* compiler, RegExpNode* on_success)
TextElementVector* elms =
compiler->alloc()->newInfallible<TextElementVector>(*compiler->alloc());
elms->append(TextElement::Atom(this));
- return compiler->alloc()->newInfallible<TextNode>(elms, on_success);
+ return compiler->alloc()->newInfallible<TextNode>(elms, compiler->read_backward(), on_success);
}
RegExpNode*
RegExpText::ToNode(RegExpCompiler* compiler, RegExpNode* on_success)
{
- return compiler->alloc()->newInfallible<TextNode>(&elements_, on_success);
+ return compiler->alloc()->newInfallible<TextNode>(&elements_, compiler->read_backward(), on_success);
}
RegExpNode*
RegExpCharacterClass::ToNode(RegExpCompiler* compiler, RegExpNode* on_success)
{
- return compiler->alloc()->newInfallible<TextNode>(this, on_success);
+ return compiler->alloc()->newInfallible<TextNode>(this, compiler->read_backward(), on_success);
}
RegExpNode*
@@ -2003,7 +2011,8 @@ RegExpQuantifier::ToNode(int min,
alternation->AddAlternative(GuardedAlternative(body->ToNode(compiler, answer)));
}
answer = alternation;
- if (not_at_start) alternation->set_not_at_start();
+ if (not_at_start && !compiler->read_backward())
+ alternation->set_not_at_start();
}
return answer;
}
@@ -2015,8 +2024,9 @@ RegExpQuantifier::ToNode(int min,
int reg_ctr = needs_counter
? compiler->AllocateRegister()
: RegExpCompiler::kNoRegister;
- LoopChoiceNode* center = alloc->newInfallible<LoopChoiceNode>(alloc, body->min_match() == 0);
- if (not_at_start)
+ LoopChoiceNode* center = alloc->newInfallible<LoopChoiceNode>(alloc, body->min_match() == 0,
+ compiler->read_backward());
+ if (not_at_start && !compiler->read_backward())
center->set_not_at_start();
RegExpNode* loop_return = needs_counter
? static_cast<RegExpNode*>(ActionNode::IncrementRegister(reg_ctr, center))
@@ -2092,7 +2102,7 @@ RegExpAssertion::ToNode(RegExpCompiler* compiler,
CharacterRange::AddClassEscape(alloc, 'n', newline_ranges);
RegExpCharacterClass* newline_atom = alloc->newInfallible<RegExpCharacterClass>('n');
TextNode* newline_matcher =
- alloc->newInfallible<TextNode>(newline_atom,
+ alloc->newInfallible<TextNode>(newline_atom, false,
ActionNode::PositiveSubmatchSuccess(stack_pointer_register,
position_register,
0, // No captures inside.
@@ -2124,6 +2134,7 @@ RegExpBackReference::ToNode(RegExpCompiler* compiler, RegExpNode* on_success)
{
return compiler->alloc()->newInfallible<BackReferenceNode>(RegExpCapture::StartRegister(index()),
RegExpCapture::EndRegister(index()),
+ compiler->read_backward(),
on_success);
}
@@ -2134,7 +2145,7 @@ RegExpEmpty::ToNode(RegExpCompiler* compiler, RegExpNode* on_success)
}
RegExpNode*
-RegExpLookahead::ToNode(RegExpCompiler* compiler, RegExpNode* on_success)
+RegExpLookaround::ToNode(RegExpCompiler* compiler, RegExpNode* on_success)
{
int stack_pointer_register = compiler->AllocateRegister();
int position_register = compiler->AllocateRegister();
@@ -2145,6 +2156,10 @@ RegExpLookahead::ToNode(RegExpCompiler* compiler, RegExpNode* on_success)
int register_start =
register_of_first_capture + capture_from_ * registers_per_capture;
+ RegExpNode* result;
+ bool was_reading_backward = compiler->read_backward();
+ compiler->set_read_backward(type() == LOOKBEHIND);
+
if (is_positive()) {
RegExpNode* bodyNode =
body()->ToNode(compiler,
@@ -2153,37 +2168,39 @@ RegExpLookahead::ToNode(RegExpCompiler* compiler, RegExpNode* on_success)
register_count,
register_start,
on_success));
- return ActionNode::BeginSubmatch(stack_pointer_register,
+ result = ActionNode::BeginSubmatch(stack_pointer_register,
+ position_register,
+ bodyNode);
+ } else {
+ // We use a ChoiceNode for a negative lookahead because it has most of
+ // the characteristics we need. It has the body of the lookahead as its
+ // first alternative and the expression after the lookahead of the second
+ // alternative. If the first alternative succeeds then the
+ // NegativeSubmatchSuccess will unwind the stack including everything the
+ // choice node set up and backtrack. If the first alternative fails then
+ // the second alternative is tried, which is exactly the desired result
+ // for a negative lookahead. The NegativeLookaheadChoiceNode is a special
+ // ChoiceNode that knows to ignore the first exit when calculating quick
+ // checks.
+ LifoAlloc* alloc = compiler->alloc();
+
+ RegExpNode* success =
+ alloc->newInfallible<NegativeSubmatchSuccess>(alloc,
+ stack_pointer_register,
+ position_register,
+ register_count,
+ register_start);
+ GuardedAlternative body_alt(body()->ToNode(compiler, success));
+
+ ChoiceNode* choice_node =
+ alloc->newInfallible<NegativeLookaheadChoiceNode>(alloc, body_alt, GuardedAlternative(on_success));
+
+ result = ActionNode::BeginSubmatch(stack_pointer_register,
position_register,
- bodyNode);
- }
-
- // We use a ChoiceNode for a negative lookahead because it has most of
- // the characteristics we need. It has the body of the lookahead as its
- // first alternative and the expression after the lookahead of the second
- // alternative. If the first alternative succeeds then the
- // NegativeSubmatchSuccess will unwind the stack including everything the
- // choice node set up and backtrack. If the first alternative fails then
- // the second alternative is tried, which is exactly the desired result
- // for a negative lookahead. The NegativeLookaheadChoiceNode is a special
- // ChoiceNode that knows to ignore the first exit when calculating quick
- // checks.
- LifoAlloc* alloc = compiler->alloc();
-
- RegExpNode* success =
- alloc->newInfallible<NegativeSubmatchSuccess>(alloc,
- stack_pointer_register,
- position_register,
- register_count,
- register_start);
- GuardedAlternative body_alt(body()->ToNode(compiler, success));
-
- ChoiceNode* choice_node =
- alloc->newInfallible<NegativeLookaheadChoiceNode>(alloc, body_alt, GuardedAlternative(on_success));
-
- return ActionNode::BeginSubmatch(stack_pointer_register,
- position_register,
- choice_node);
+ choice_node);
+ }
+ compiler->set_read_backward(was_reading_backward);
+ return result;
}
RegExpNode*
@@ -2198,8 +2215,14 @@ RegExpCapture::ToNode(RegExpTree* body,
RegExpCompiler* compiler,
RegExpNode* on_success)
{
+ MOZ_ASSERT(body);
int start_reg = RegExpCapture::StartRegister(index);
int end_reg = RegExpCapture::EndRegister(index);
+ if (compiler->read_backward()) {
+ // std::swap(start_reg, end_reg);
+ start_reg = RegExpCapture::EndRegister(index);
+ end_reg = RegExpCapture::StartRegister(index);
+ }
RegExpNode* store_end = ActionNode::StorePosition(end_reg, true, on_success);
RegExpNode* body_node = body->ToNode(compiler, store_end);
return ActionNode::StorePosition(start_reg, true, body_node);
@@ -2210,8 +2233,15 @@ RegExpAlternative::ToNode(RegExpCompiler* compiler, RegExpNode* on_success)
{
const RegExpTreeVector& children = nodes();
RegExpNode* current = on_success;
- for (int i = children.length() - 1; i >= 0; i--)
- current = children[i]->ToNode(compiler, current);
+ if (compiler->read_backward()) {
+ for (int i = 0; i < children.length(); i++) {
+ current = children[i]->ToNode(compiler, current);
+ }
+ } else {
+ for (int i = children.length() - 1; i >= 0; i--) {
+ current = children[i]->ToNode(compiler, current);
+ }
+ }
return current;
}
@@ -2764,7 +2794,6 @@ Trace::InvalidateCurrentCharacter()
void
Trace::AdvanceCurrentPositionInTrace(int by, RegExpCompiler* compiler)
{
- MOZ_ASSERT(by > 0);
// We don't have an instruction for shifting the current character register
// down or for using a shifted value for anything so lets just forget that
// we preloaded any characters into it.
@@ -3109,9 +3138,9 @@ AssertionNode::Emit(RegExpCompiler* compiler, Trace* trace)
return;
}
if (trace->at_start() == Trace::UNKNOWN) {
- assembler->CheckNotAtStart(trace->backtrack());
+ assembler->CheckNotAtStart(trace->cp_offset(), trace->backtrack());
Trace at_start_trace = *trace;
- at_start_trace.set_at_start(true);
+ at_start_trace.set_at_start(Trace::TRUE_VALUE);
on_success()->Emit(compiler, &at_start_trace);
return;
}
@@ -3814,9 +3843,10 @@ TextNode::TextEmitPass(RegExpCompiler* compiler,
jit::Label* backtrack = trace->backtrack();
QuickCheckDetails* quick_check = trace->quick_check_performed();
int element_count = elements().length();
+ int backward_offset = read_backward() ? -Length() : 0;
for (int i = preloaded ? 0 : element_count - 1; i >= 0; i--) {
TextElement elm = elements()[i];
- int cp_offset = trace->cp_offset() + elm.cp_offset();
+ int cp_offset = trace->cp_offset() + elm.cp_offset() + backward_offset;
if (elm.text_type() == TextElement::ATOM) {
const CharacterVector& quarks = elm.atom()->data();
for (int j = preloaded ? 0 : quarks.length() - 1; j >= 0; j--) {
@@ -3844,11 +3874,12 @@ TextNode::TextEmitPass(RegExpCompiler* compiler,
break;
}
if (emit_function != nullptr) {
+ bool bounds_check = *checked_up_to < cp_offset + j || read_backward();
bool bound_checked = emit_function(compiler,
quarks[j],
backtrack,
cp_offset + j,
- *checked_up_to < cp_offset + j,
+ bounds_check,
preloaded);
if (bound_checked) UpdateBoundsCheck(cp_offset + j, checked_up_to);
}
@@ -3859,13 +3890,14 @@ TextNode::TextEmitPass(RegExpCompiler* compiler,
if (first_element_checked && i == 0) continue;
if (DeterminedAlready(quick_check, elm.cp_offset())) continue;
RegExpCharacterClass* cc = elm.char_class();
+ bool bounds_check = *checked_up_to < cp_offset || read_backward();
EmitCharClass(alloc(),
assembler,
cc,
ascii,
backtrack,
cp_offset,
- *checked_up_to < cp_offset,
+ bounds_check,
preloaded);
UpdateBoundsCheck(cp_offset, checked_up_to);
}
@@ -3945,8 +3977,11 @@ TextNode::Emit(RegExpCompiler* compiler, Trace* trace)
}
Trace successor_trace(*trace);
- successor_trace.set_at_start(false);
- successor_trace.AdvanceCurrentPositionInTrace(Length(), compiler);
+ // If we advance backward, we may end up at the start.
+ successor_trace.AdvanceCurrentPositionInTrace(
+ read_backward() ? -Length() : Length(), compiler);
+ successor_trace.set_at_start(read_backward() ? Trace::UNKNOWN
+ : Trace::FALSE_VALUE);
RecursionCheck rc(compiler);
on_success()->Emit(compiler, &successor_trace);
}
@@ -4118,6 +4153,8 @@ ChoiceNode::CalculatePreloadCharacters(RegExpCompiler* compiler, int eats_at_lea
RegExpNode*
TextNode::GetSuccessorOfOmnivorousTextNode(RegExpCompiler* compiler)
{
+ if (read_backward()) return NULL;
+
if (elements().length() != 1)
return nullptr;
@@ -4165,7 +4202,7 @@ ChoiceNode::GreedyLoopTextLengthForAlternative(GuardedAlternative* alternative)
SeqRegExpNode* seq_node = static_cast<SeqRegExpNode*>(node);
node = seq_node->on_success();
}
- return length;
+ return read_backward() ? -length : length;
}
// Creates a list of AlternativeGenerations. If the list has a reasonable
@@ -4240,7 +4277,7 @@ ChoiceNode::Emit(RegExpCompiler* compiler, Trace* trace)
jit::Label greedy_loop_label;
Trace counter_backtrack_trace;
counter_backtrack_trace.set_backtrack(&greedy_loop_label);
- if (not_at_start()) counter_backtrack_trace.set_at_start(false);
+ if (not_at_start()) counter_backtrack_trace.set_at_start(Trace::FALSE_VALUE);
if (choice_count > 1 && text_length != kNodeIsTooComplexForGreedyLoops) {
// Here we have special handling for greedy loops containing only text nodes
@@ -4256,7 +4293,7 @@ ChoiceNode::Emit(RegExpCompiler* compiler, Trace* trace)
current_trace = &counter_backtrack_trace;
jit::Label greedy_match_failed;
Trace greedy_match_trace;
- if (not_at_start()) greedy_match_trace.set_at_start(false);
+ if (not_at_start()) greedy_match_trace.set_at_start(Trace::FALSE_VALUE);
greedy_match_trace.set_backtrack(&greedy_match_failed);
jit::Label loop_label;
macro_assembler->Bind(&loop_label);
@@ -4605,11 +4642,14 @@ BackReferenceNode::Emit(RegExpCompiler* compiler, Trace* trace)
MOZ_ASSERT(start_reg_ + 1 == end_reg_);
if (compiler->ignore_case()) {
assembler->CheckNotBackReferenceIgnoreCase(start_reg_,
+ read_backward(),
trace->backtrack(),
compiler->unicode());
} else {
- assembler->CheckNotBackReference(start_reg_, trace->backtrack());
+ assembler->CheckNotBackReference(start_reg_, read_backward(), trace->backtrack());
}
+ // We are going to advance backward, so we may end up at the start.
+ if (read_backward()) trace->set_at_start(Trace::UNKNOWN);
on_success()->Emit(compiler, trace);
}
@@ -4977,7 +5017,6 @@ QuickCheckDetails::Clear()
void
QuickCheckDetails::Advance(int by, bool ascii)
{
- MOZ_ASSERT(by >= 0);
if (by >= characters_) {
Clear();
return;
diff --git a/js/src/irregexp/RegExpEngine.h b/js/src/irregexp/RegExpEngine.h
index 1a8fd4b22..c4409dcca 100644
--- a/js/src/irregexp/RegExpEngine.h
+++ b/js/src/irregexp/RegExpEngine.h
@@ -119,7 +119,7 @@ InterpretCode(JSContext* cx, const uint8_t* byteCode, const CharT* chars, size_t
VISIT(Atom) \
VISIT(Quantifier) \
VISIT(Capture) \
- VISIT(Lookahead) \
+ VISIT(Lookaround) \
VISIT(BackReference) \
VISIT(Empty) \
VISIT(Text)
@@ -763,15 +763,19 @@ class TextNode : public SeqRegExpNode
{
public:
TextNode(TextElementVector* elements,
+ bool read_backward,
RegExpNode* on_success)
: SeqRegExpNode(on_success),
- elements_(elements)
+ elements_(elements),
+ read_backward_(read_backward)
{}
TextNode(RegExpCharacterClass* that,
+ bool read_backward,
RegExpNode* on_success)
: SeqRegExpNode(on_success),
- elements_(alloc()->newInfallible<TextElementVector>(*alloc()))
+ elements_(alloc()->newInfallible<TextElementVector>(*alloc())),
+ read_backward_(read_backward)
{
elements_->append(TextElement::CharClass(that));
}
@@ -784,6 +788,7 @@ class TextNode : public SeqRegExpNode
int characters_filled_in,
bool not_at_start);
TextElementVector& elements() { return *elements_; }
+ bool read_backward() { return read_backward_; }
void MakeCaseIndependent(bool is_ascii, bool unicode);
virtual int GreedyLoopTextLength();
virtual RegExpNode* GetSuccessorOfOmnivorousTextNode(
@@ -814,6 +819,7 @@ class TextNode : public SeqRegExpNode
int* checked_up_to);
int Length();
TextElementVector* elements_;
+ bool read_backward_;
};
class AssertionNode : public SeqRegExpNode
@@ -882,15 +888,18 @@ class BackReferenceNode : public SeqRegExpNode
public:
BackReferenceNode(int start_reg,
int end_reg,
+ bool read_backward,
RegExpNode* on_success)
: SeqRegExpNode(on_success),
start_reg_(start_reg),
- end_reg_(end_reg)
+ end_reg_(end_reg),
+ read_backward_(read_backward)
{}
virtual void Accept(NodeVisitor* visitor);
int start_register() { return start_reg_; }
int end_register() { return end_reg_; }
+ bool read_backward() { return read_backward_; }
virtual void Emit(RegExpCompiler* compiler, Trace* trace);
virtual int EatsAtLeast(int still_to_find,
int recursion_depth,
@@ -909,6 +918,7 @@ class BackReferenceNode : public SeqRegExpNode
private:
int start_reg_;
int end_reg_;
+ bool read_backward_;
};
class EndNode : public RegExpNode
@@ -1053,6 +1063,7 @@ class ChoiceNode : public RegExpNode
void set_being_calculated(bool b) { being_calculated_ = b; }
virtual bool try_to_emit_quick_check_for_alternative(int i) { return true; }
virtual RegExpNode* FilterASCII(int depth, bool ignore_case, bool unicode);
+ virtual bool read_backward() { return false; }
protected:
int GreedyLoopTextLengthForAlternative(GuardedAlternative* alternative);
@@ -1111,11 +1122,13 @@ class NegativeLookaheadChoiceNode : public ChoiceNode
class LoopChoiceNode : public ChoiceNode
{
public:
- explicit LoopChoiceNode(LifoAlloc* alloc, bool body_can_be_zero_length)
+ explicit LoopChoiceNode(LifoAlloc* alloc, bool body_can_be_zero_length,
+ bool read_backward)
: ChoiceNode(alloc, 2),
loop_node_(nullptr),
continue_node_(nullptr),
- body_can_be_zero_length_(body_can_be_zero_length)
+ body_can_be_zero_length_(body_can_be_zero_length),
+ read_backward_(read_backward)
{}
void AddLoopAlternative(GuardedAlternative alt);
@@ -1133,6 +1146,7 @@ class LoopChoiceNode : public ChoiceNode
RegExpNode* loop_node() { return loop_node_; }
RegExpNode* continue_node() { return continue_node_; }
bool body_can_be_zero_length() { return body_can_be_zero_length_; }
+ virtual bool read_backward() { return read_backward_; }
virtual void Accept(NodeVisitor* visitor);
virtual RegExpNode* FilterASCII(int depth, bool ignore_case, bool unicode);
@@ -1147,6 +1161,7 @@ class LoopChoiceNode : public ChoiceNode
RegExpNode* loop_node_;
RegExpNode* continue_node_;
bool body_can_be_zero_length_;
+ bool read_backward_;
};
// Improve the speed that we scan for an initial point where a non-anchored
@@ -1422,8 +1437,8 @@ class Trace
}
TriBool at_start() { return at_start_; }
- void set_at_start(bool at_start) {
- at_start_ = at_start ? TRUE_VALUE : FALSE_VALUE;
+ void set_at_start(TriBool at_start) {
+ at_start_ = at_start;
}
jit::Label* backtrack() { return backtrack_; }
jit::Label* loop_label() { return loop_label_; }
diff --git a/js/src/irregexp/RegExpInterpreter.cpp b/js/src/irregexp/RegExpInterpreter.cpp
index 7fd2d983a..d09b4671e 100644
--- a/js/src/irregexp/RegExpInterpreter.cpp
+++ b/js/src/irregexp/RegExpInterpreter.cpp
@@ -222,8 +222,8 @@ irregexp::InterpretCode(JSContext* cx, const uint8_t* byteCode, const CharT* cha
}
break;
BYTECODE(LOAD_CURRENT_CHAR) {
- size_t pos = current + (insn >> BYTECODE_SHIFT);
- if (pos >= length) {
+ int pos = current + (insn >> BYTECODE_SHIFT);
+ if (pos >= (int)length || pos < 0) {
pc = byteCode + Load32Aligned(pc + 4);
} else {
current_char = chars[pos];
@@ -238,8 +238,8 @@ irregexp::InterpretCode(JSContext* cx, const uint8_t* byteCode, const CharT* cha
break;
}
BYTECODE(LOAD_2_CURRENT_CHARS) {
- size_t pos = current + (insn >> BYTECODE_SHIFT);
- if (pos + 2 > length) {
+ int pos = current + (insn >> BYTECODE_SHIFT);
+ if (pos + 2 > (int)length || pos < 0) {
pc = byteCode + Load32Aligned(pc + 4);
} else {
CharT next = chars[pos + 1];
@@ -425,6 +425,30 @@ irregexp::InterpretCode(JSContext* cx, const uint8_t* byteCode, const CharT* cha
pc += BC_CHECK_NOT_BACK_REF_LENGTH;
break;
}
+ BYTECODE(CHECK_NOT_BACK_REF_BACKWARD) {
+ int from = registers[insn >> BYTECODE_SHIFT];
+ int len = registers[(insn >> BYTECODE_SHIFT) + 1] - from;
+ if (from < 0 || len <= 0) {
+ pc += BC_CHECK_NOT_BACK_REF_BACKWARD_LENGTH;
+ break;
+ }
+ if (int(current) - len < 0) {
+ pc = byteCode + Load32Aligned(pc + 4);
+ break;
+ } else {
+ int i;
+ for (i = 0; i < len; i++) {
+ if (chars[from + i] != chars[int(current) - len + i]) {
+ pc = byteCode + Load32Aligned(pc + 4);
+ break;
+ }
+ }
+ if (i < len) break;
+ current -= len;
+ }
+ pc += BC_CHECK_NOT_BACK_REF_BACKWARD_LENGTH;
+ break;
+ }
BYTECODE(CHECK_NOT_BACK_REF_NO_CASE) {
int from = registers[insn >> BYTECODE_SHIFT];
int len = registers[(insn >> BYTECODE_SHIFT) + 1] - from;
@@ -465,6 +489,46 @@ irregexp::InterpretCode(JSContext* cx, const uint8_t* byteCode, const CharT* cha
}
break;
}
+ BYTECODE(CHECK_NOT_BACK_REF_NO_CASE_BACKWARD) {
+ int from = registers[insn >> BYTECODE_SHIFT];
+ int len = registers[(insn >> BYTECODE_SHIFT) + 1] - from;
+ if (from < 0 || len <= 0) {
+ pc += BC_CHECK_NOT_BACK_REF_NO_CASE_BACKWARD_LENGTH;
+ break;
+ }
+ if (int(current) - len < 0) {
+ pc = byteCode + Load32Aligned(pc + 4);
+ break;
+ }
+ if (CaseInsensitiveCompareStrings(chars + from, chars + int(current) - len, len * sizeof(CharT))) {
+ current -= len;
+ pc += BC_CHECK_NOT_BACK_REF_NO_CASE_BACKWARD_LENGTH;
+ } else {
+ pc = byteCode + Load32Aligned(pc + 4);
+ }
+ break;
+
+ }
+ BYTECODE(CHECK_NOT_BACK_REF_NO_CASE_BACKWARD_UNICODE) {
+ int from = registers[insn >> BYTECODE_SHIFT];
+ int len = registers[(insn >> BYTECODE_SHIFT) + 1] - from;
+ if (from < 0 || len <= 0) {
+ pc += BC_CHECK_NOT_BACK_REF_NO_CASE_BACKWARD_LENGTH;
+ break;
+ }
+ if (int(current) - len < 0) {
+ pc = byteCode + Load32Aligned(pc + 4);
+ break;
+ }
+ if (CaseInsensitiveCompareUCStrings(chars + from, chars + int(current) - len, len * sizeof(CharT))) {
+ current -= len;
+ pc += BC_CHECK_NOT_BACK_REF_NO_CASE_BACKWARD_LENGTH;
+ } else {
+ pc = byteCode + Load32Aligned(pc + 4);
+ }
+ break;
+
+ }
BYTECODE(CHECK_AT_START)
if (current == 0)
pc = byteCode + Load32Aligned(pc + 4);
@@ -472,7 +536,7 @@ irregexp::InterpretCode(JSContext* cx, const uint8_t* byteCode, const CharT* cha
pc += BC_CHECK_AT_START_LENGTH;
break;
BYTECODE(CHECK_NOT_AT_START)
- if (current == 0)
+ if (current + (insn >> BYTECODE_SHIFT) == 0)
pc += BC_CHECK_NOT_AT_START_LENGTH;
else
pc = byteCode + Load32Aligned(pc + 4);
diff --git a/js/src/irregexp/RegExpMacroAssembler.cpp b/js/src/irregexp/RegExpMacroAssembler.cpp
index d66d0d204..6b1ceba8a 100644
--- a/js/src/irregexp/RegExpMacroAssembler.cpp
+++ b/js/src/irregexp/RegExpMacroAssembler.cpp
@@ -226,32 +226,37 @@ InterpretedRegExpMacroAssembler::CheckGreedyLoop(jit::Label* on_tos_equals_curre
}
void
-InterpretedRegExpMacroAssembler::CheckNotAtStart(jit::Label* on_not_at_start)
+InterpretedRegExpMacroAssembler::CheckNotAtStart(int cp_offset, jit::Label* on_not_at_start)
{
- Emit(BC_CHECK_NOT_AT_START, 0);
+ Emit(BC_CHECK_NOT_AT_START, cp_offset);
EmitOrLink(on_not_at_start);
}
void
-InterpretedRegExpMacroAssembler::CheckNotBackReference(int start_reg, jit::Label* on_no_match)
+InterpretedRegExpMacroAssembler::CheckNotBackReference(int start_reg, bool read_backward,
+ jit::Label* on_no_match)
{
MOZ_ASSERT(start_reg >= 0);
MOZ_ASSERT(start_reg <= kMaxRegister);
- Emit(BC_CHECK_NOT_BACK_REF, start_reg);
+ Emit(read_backward ? BC_CHECK_NOT_BACK_REF_BACKWARD : BC_CHECK_NOT_BACK_REF,
+ start_reg);
EmitOrLink(on_no_match);
}
void
InterpretedRegExpMacroAssembler::CheckNotBackReferenceIgnoreCase(int start_reg,
+ bool read_backward,
jit::Label* on_no_match,
bool unicode)
{
MOZ_ASSERT(start_reg >= 0);
MOZ_ASSERT(start_reg <= kMaxRegister);
if (unicode)
- Emit(BC_CHECK_NOT_BACK_REF_NO_CASE_UNICODE, start_reg);
+ Emit(read_backward ? BC_CHECK_NOT_BACK_REF_NO_CASE_BACKWARD_UNICODE : BC_CHECK_NOT_BACK_REF_NO_CASE_UNICODE,
+ start_reg);
else
- Emit(BC_CHECK_NOT_BACK_REF_NO_CASE, start_reg);
+ Emit(read_backward ? BC_CHECK_NOT_BACK_REF_NO_CASE_BACKWARD : BC_CHECK_NOT_BACK_REF_NO_CASE,
+ start_reg);
EmitOrLink(on_no_match);
}
diff --git a/js/src/irregexp/RegExpMacroAssembler.h b/js/src/irregexp/RegExpMacroAssembler.h
index dca2edf90..c5def92f2 100644
--- a/js/src/irregexp/RegExpMacroAssembler.h
+++ b/js/src/irregexp/RegExpMacroAssembler.h
@@ -110,10 +110,10 @@ class MOZ_STACK_CLASS RegExpMacroAssembler
virtual void CheckCharacterGT(char16_t limit, jit::Label* on_greater) = 0;
virtual void CheckCharacterLT(char16_t limit, jit::Label* on_less) = 0;
virtual void CheckGreedyLoop(jit::Label* on_tos_equals_current_position) = 0;
- virtual void CheckNotAtStart(jit::Label* on_not_at_start) = 0;
- virtual void CheckNotBackReference(int start_reg, jit::Label* on_no_match) = 0;
- virtual void CheckNotBackReferenceIgnoreCase(int start_reg, jit::Label* on_no_match,
- bool unicode) = 0;
+ virtual void CheckNotAtStart(int cp_offset, jit::Label* on_not_at_start) = 0;
+ virtual void CheckNotBackReference(int start_reg, bool read_backward, jit::Label* on_no_match) = 0;
+ virtual void CheckNotBackReferenceIgnoreCase(int start_reg, bool read_backward,
+ jit::Label* on_no_match, bool unicode) = 0;
// Check the current character for a match with a literal character. If we
// fail to match then goto the on_failure label. End of input always
@@ -245,9 +245,10 @@ class MOZ_STACK_CLASS InterpretedRegExpMacroAssembler final : public RegExpMacro
void CheckCharacterGT(char16_t limit, jit::Label* on_greater);
void CheckCharacterLT(char16_t limit, jit::Label* on_less);
void CheckGreedyLoop(jit::Label* on_tos_equals_current_position);
- void CheckNotAtStart(jit::Label* on_not_at_start);
- void CheckNotBackReference(int start_reg, jit::Label* on_no_match);
- void CheckNotBackReferenceIgnoreCase(int start_reg, jit::Label* on_no_match, bool unicode);
+ void CheckNotAtStart(int cp_offset, jit::Label* on_not_at_start);
+ void CheckNotBackReference(int start_reg, bool read_backward, jit::Label* on_no_match);
+ void CheckNotBackReferenceIgnoreCase(int start_reg, bool read_backward,
+ jit::Label* on_no_match, bool unicode);
void CheckNotCharacter(unsigned c, jit::Label* on_not_equal);
void CheckNotCharacterAfterAnd(unsigned c, unsigned and_with, jit::Label* on_not_equal);
void CheckNotCharacterAfterMinusAnd(char16_t c, char16_t minus, char16_t and_with,
diff --git a/js/src/irregexp/RegExpParser.cpp b/js/src/irregexp/RegExpParser.cpp
index 8bd88047a..1ad044e8e 100644
--- a/js/src/irregexp/RegExpParser.cpp
+++ b/js/src/irregexp/RegExpParser.cpp
@@ -222,11 +222,12 @@ RegExpBuilder::AddQuantifierToAtom(int min, int max,
template <typename CharT>
RegExpParser<CharT>::RegExpParser(frontend::TokenStream& ts, LifoAlloc* alloc,
const CharT* chars, const CharT* end, bool multiline_mode,
- bool unicode, bool ignore_case)
+ bool unicode, bool ignore_case, bool dotall)
: ts(ts),
alloc(alloc),
captures_(nullptr),
next_pos_(chars),
+ captures_started_(0),
end_(end),
current_(kEndMarker),
capture_count_(0),
@@ -234,6 +235,7 @@ RegExpParser<CharT>::RegExpParser(frontend::TokenStream& ts, LifoAlloc* alloc,
multiline_(multiline_mode),
unicode_(unicode),
ignore_case_(ignore_case),
+ dotall_(dotall),
simple_(false),
contains_anchor_(false),
is_scanned_for_captures_(false)
@@ -418,7 +420,8 @@ RangeAtom(LifoAlloc* alloc, char16_t from, char16_t to)
static inline RegExpTree*
NegativeLookahead(LifoAlloc* alloc, char16_t from, char16_t to)
{
- return alloc->newInfallible<RegExpLookahead>(RangeAtom(alloc, from, to), false, 0, 0);
+ return alloc->newInfallible<RegExpLookaround>(RangeAtom(alloc, from, to), false,
+ 0, 0, RegExpLookaround::LOOKAHEAD);
}
static bool
@@ -1213,6 +1216,38 @@ RegExpParser<CharT>::ParseBackReferenceIndex(int* index_out)
return true;
}
+template <typename CharT>
+RegExpCapture*
+RegExpParser<CharT>::GetCapture(int index) {
+ // The index for the capture groups are one-based. Its index in the list is
+ // zero-based.
+ int known_captures =
+ is_scanned_for_captures_ ? capture_count_ : captures_started_;
+ MOZ_ASSERT(index <= known_captures);
+ if (captures_ == NULL) {
+ captures_ = alloc->newInfallible<RegExpCaptureVector>(*alloc);
+ }
+ while ((int)captures_->length() < known_captures) {
+ RegExpCapture* capture = alloc->newInfallible<RegExpCapture>(nullptr, captures_->length() + 1);
+ captures_->append(capture);
+ }
+ return (*captures_)[index - 1];
+}
+
+
+template <typename CharT>
+bool
+RegExpParser<CharT>::RegExpParserState::IsInsideCaptureGroup(int index) {
+ for (RegExpParserState* s = this; s != NULL; s = s->previous_state()) {
+ if (s->group_type() != CAPTURE) continue;
+ // Return true if we found the matching capture index.
+ if (index == s->capture_index()) return true;
+ // Abort if index is larger than what has been parsed up till this state.
+ if (index > s->capture_index()) return false;
+ }
+ return false;
+}
+
// QuantifierPrefix ::
// { DecimalDigits }
// { DecimalDigits , }
@@ -1350,7 +1385,7 @@ UnicodeEverythingAtom(LifoAlloc* alloc)
{
RegExpBuilder* builder = alloc->newInfallible<RegExpBuilder>(alloc);
- // everything except \x0a, \x0d, \u2028 and \u2029
+ // Everything except \x0a, \x0d, \u2028 and \u2029
CharacterRangeVector* ranges = alloc->newInfallible<CharacterRangeVector>(*alloc);
ranges->append(CharacterRange::Range(0x0, 0x09));
@@ -1380,6 +1415,38 @@ UnicodeEverythingAtom(LifoAlloc* alloc)
return builder->ToRegExp();
}
+static inline RegExpTree*
+UnicodeDotAllAtom(LifoAlloc* alloc)
+{
+ RegExpBuilder* builder = alloc->newInfallible<RegExpBuilder>(alloc);
+
+ // Full range excluding surrogates because /s was specified
+
+ CharacterRangeVector* ranges = alloc->newInfallible<CharacterRangeVector>(*alloc);
+ ranges->append(CharacterRange::Range(0x0, unicode::LeadSurrogateMin - 1));
+ ranges->append(CharacterRange::Range(unicode::TrailSurrogateMax + 1, unicode::UTF16Max));
+ builder->AddAtom(alloc->newInfallible<RegExpCharacterClass>(ranges, false));
+
+ builder->NewAlternative();
+
+ builder->AddAtom(RangeAtom(alloc, unicode::LeadSurrogateMin, unicode::LeadSurrogateMax));
+ builder->AddAtom(NegativeLookahead(alloc, unicode::TrailSurrogateMin,
+ unicode::TrailSurrogateMax));
+
+ builder->NewAlternative();
+
+ builder->AddAssertion(alloc->newInfallible<RegExpAssertion>(
+ RegExpAssertion::NOT_AFTER_LEAD_SURROGATE));
+ builder->AddAtom(RangeAtom(alloc, unicode::TrailSurrogateMin, unicode::TrailSurrogateMax));
+
+ builder->NewAlternative();
+
+ builder->AddAtom(RangeAtom(alloc, unicode::LeadSurrogateMin, unicode::LeadSurrogateMax));
+ builder->AddAtom(RangeAtom(alloc, unicode::TrailSurrogateMin, unicode::TrailSurrogateMax));
+
+ return builder->ToRegExp();
+}
+
RegExpTree*
UnicodeCharacterClassEscapeAtom(LifoAlloc* alloc, char16_t char_class, bool ignore_case)
{
@@ -1423,24 +1490,24 @@ RegExpTree*
RegExpParser<CharT>::ParseDisjunction()
{
// Used to store current state while parsing subexpressions.
- RegExpParserState initial_state(alloc, nullptr, INITIAL, 0);
- RegExpParserState* stored_state = &initial_state;
+ RegExpParserState initial_state(alloc, nullptr, INITIAL, RegExpLookaround::LOOKAHEAD, 0);
+ RegExpParserState* state = &initial_state;
// Cache the builder in a local variable for quick access.
RegExpBuilder* builder = initial_state.builder();
while (true) {
switch (current()) {
case kEndMarker:
- if (stored_state->IsSubexpression()) {
+ if (state->IsSubexpression()) {
// Inside a parenthesized group when hitting end of input.
return ReportError(JSMSG_MISSING_PAREN);
}
- MOZ_ASSERT(INITIAL == stored_state->group_type());
+ MOZ_ASSERT(INITIAL == state->group_type());
// Parsing completed successfully.
return builder->ToRegExp();
case ')': {
- if (!stored_state->IsSubexpression())
+ if (!state->IsSubexpression())
return ReportError(JSMSG_UNMATCHED_RIGHT_PAREN);
- MOZ_ASSERT(INITIAL != stored_state->group_type());
+ MOZ_ASSERT(INITIAL != state->group_type());
Advance();
// End disjunction parsing and convert builder content to new single
@@ -1449,29 +1516,30 @@ RegExpParser<CharT>::ParseDisjunction()
int end_capture_index = captures_started();
- int capture_index = stored_state->capture_index();
- SubexpressionType group_type = stored_state->group_type();
-
- // Restore previous state.
- stored_state = stored_state->previous_state();
- builder = stored_state->builder();
+ int capture_index = state->capture_index();
+ SubexpressionType group_type = state->group_type();
// Build result of subexpression.
if (group_type == CAPTURE) {
- RegExpCapture* capture = alloc->newInfallible<RegExpCapture>(body, capture_index);
- (*captures_)[capture_index - 1] = capture;
+ RegExpCapture* capture = GetCapture(capture_index);
+ capture->set_body(body);
body = capture;
} else if (group_type != GROUPING) {
- MOZ_ASSERT(group_type == POSITIVE_LOOKAHEAD ||
- group_type == NEGATIVE_LOOKAHEAD);
- bool is_positive = (group_type == POSITIVE_LOOKAHEAD);
- body = alloc->newInfallible<RegExpLookahead>(body,
+ MOZ_ASSERT(group_type == POSITIVE_LOOKAROUND ||
+ group_type == NEGATIVE_LOOKAROUND);
+ bool is_positive = (group_type == POSITIVE_LOOKAROUND);
+ body = alloc->newInfallible<RegExpLookaround>(body,
is_positive,
end_capture_index - capture_index,
- capture_index);
+ capture_index,
+ state->lookaround_type());
}
+
+ // Restore previous state.
+ state = state->previous_state();
+ builder = state->builder();
builder->AddAtom(body);
- if (unicode_ && (group_type == POSITIVE_LOOKAHEAD || group_type == NEGATIVE_LOOKAHEAD))
+ if (unicode_ && (group_type == POSITIVE_LOOKAROUND || group_type == NEGATIVE_LOOKAROUND))
continue;
// For compatability with JSC and ES3, we allow quantifiers after
// lookaheads, and break in all cases.
@@ -1506,19 +1574,32 @@ RegExpParser<CharT>::ParseDisjunction()
}
case '.': {
Advance();
- // everything except \x0a, \x0d, \u2028 and \u2029
+
if (unicode_) {
- builder->AddAtom(UnicodeEverythingAtom(alloc));
+ if (dotall_) {
+ // Everything
+ builder->AddAtom(UnicodeDotAllAtom(alloc));
+ } else {
+ // Everything except \x0a, \x0d, \u2028 and \u2029
+ builder->AddAtom(UnicodeEverythingAtom(alloc));
+ }
break;
}
CharacterRangeVector* ranges = alloc->newInfallible<CharacterRangeVector>(*alloc);
- CharacterRange::AddClassEscape(alloc, '.', ranges);
+ if (dotall_) {
+ // Everything
+ CharacterRange::AddClassEscape(alloc, '*', ranges);
+ } else {
+ // Everything except \x0a, \x0d, \u2028 and \u2029
+ CharacterRange::AddClassEscape(alloc, '.', ranges);
+ }
RegExpTree* atom = alloc->newInfallible<RegExpCharacterClass>(ranges, false);
builder->AddAtom(atom);
break;
}
case '(': {
SubexpressionType subexpr_type = CAPTURE;
+ RegExpLookaround::Type lookaround_type = state->lookaround_type();
Advance();
if (current() == '?') {
switch (Next()) {
@@ -1526,26 +1607,39 @@ RegExpParser<CharT>::ParseDisjunction()
subexpr_type = GROUPING;
break;
case '=':
- subexpr_type = POSITIVE_LOOKAHEAD;
+ lookaround_type = RegExpLookaround::LOOKAHEAD;
+ subexpr_type = POSITIVE_LOOKAROUND;
break;
case '!':
- subexpr_type = NEGATIVE_LOOKAHEAD;
+ lookaround_type = RegExpLookaround::LOOKAHEAD;
+ subexpr_type = NEGATIVE_LOOKAROUND;
break;
+ case '<':
+ Advance();
+ lookaround_type = RegExpLookaround::LOOKBEHIND;
+ if (Next() == '=') {
+ subexpr_type = POSITIVE_LOOKAROUND;
+ break;
+ } else if (Next() == '!') {
+ subexpr_type = NEGATIVE_LOOKAROUND;
+ break;
+ }
+ // We didn't get a positive or negative after '<'.
+ // That's an error.
+ return ReportError(JSMSG_INVALID_GROUP);
default:
return ReportError(JSMSG_INVALID_GROUP);
}
Advance(2);
} else {
- if (captures_ == nullptr)
- captures_ = alloc->newInfallible<RegExpCaptureVector>(*alloc);
if (captures_started() >= kMaxCaptures)
return ReportError(JSMSG_TOO_MANY_PARENS);
- captures_->append((RegExpCapture*) nullptr);
+ captures_started_++;
}
// Store current state and begin new disjunction parsing.
- stored_state = alloc->newInfallible<RegExpParserState>(alloc, stored_state, subexpr_type,
- captures_started());
- builder = stored_state->builder();
+ state = alloc->newInfallible<RegExpParserState>(alloc, state, subexpr_type,
+ lookaround_type, captures_started_);
+ builder = state->builder();
continue;
}
case '[': {
@@ -1600,19 +1694,18 @@ RegExpParser<CharT>::ParseDisjunction()
case '7': case '8': case '9': {
int index = 0;
if (ParseBackReferenceIndex(&index)) {
- RegExpCapture* capture = nullptr;
- if (captures_ != nullptr && index <= (int) captures_->length()) {
- capture = (*captures_)[index - 1];
- }
- if (capture == nullptr) {
- builder->AddEmpty();
- break;
+ if (state->IsInsideCaptureGroup(index)) {
+ // The backreference is inside the capture group it refers to.
+ // Nothing can possibly have been captured yet.
+ builder->AddEmpty();
+ } else {
+ RegExpCapture* capture = GetCapture(index);
+ RegExpTree* atom = alloc->newInfallible<RegExpBackReference>(capture);
+ if (unicode_)
+ builder->AddAtom(UnicodeBackReferenceAtom(alloc, atom));
+ else
+ builder->AddAtom(atom);
}
- RegExpTree* atom = alloc->newInfallible<RegExpBackReference>(capture);
- if (unicode_)
- builder->AddAtom(UnicodeBackReferenceAtom(alloc, atom));
- else
- builder->AddAtom(atom);
break;
}
if (unicode_)
@@ -1832,7 +1925,7 @@ template <typename CharT>
static bool
ParsePattern(frontend::TokenStream& ts, LifoAlloc& alloc, const CharT* chars, size_t length,
bool multiline, bool match_only, bool unicode, bool ignore_case,
- bool global, bool sticky, RegExpCompileData* data)
+ bool global, bool sticky, bool dotall, RegExpCompileData* data)
{
if (match_only) {
// Try to strip a leading '.*' from the RegExp, but only if it is not
@@ -1859,7 +1952,7 @@ ParsePattern(frontend::TokenStream& ts, LifoAlloc& alloc, const CharT* chars, si
}
}
- RegExpParser<CharT> parser(ts, &alloc, chars, chars + length, multiline, unicode, ignore_case);
+ RegExpParser<CharT> parser(ts, &alloc, chars, chars + length, multiline, unicode, ignore_case, dotall);
data->tree = parser.ParsePattern();
if (!data->tree)
return false;
@@ -1873,33 +1966,33 @@ ParsePattern(frontend::TokenStream& ts, LifoAlloc& alloc, const CharT* chars, si
bool
irregexp::ParsePattern(frontend::TokenStream& ts, LifoAlloc& alloc, JSAtom* str,
bool multiline, bool match_only, bool unicode, bool ignore_case,
- bool global, bool sticky, RegExpCompileData* data)
+ bool global, bool sticky, bool dotall, RegExpCompileData* data)
{
JS::AutoCheckCannotGC nogc;
return str->hasLatin1Chars()
? ::ParsePattern(ts, alloc, str->latin1Chars(nogc), str->length(),
- multiline, match_only, unicode, ignore_case, global, sticky, data)
+ multiline, match_only, unicode, ignore_case, global, sticky, dotall, data)
: ::ParsePattern(ts, alloc, str->twoByteChars(nogc), str->length(),
- multiline, match_only, unicode, ignore_case, global, sticky, data);
+ multiline, match_only, unicode, ignore_case, global, sticky, dotall, data);
}
template <typename CharT>
static bool
ParsePatternSyntax(frontend::TokenStream& ts, LifoAlloc& alloc, const CharT* chars, size_t length,
- bool unicode)
+ bool unicode, bool dotall)
{
LifoAllocScope scope(&alloc);
- RegExpParser<CharT> parser(ts, &alloc, chars, chars + length, false, unicode, false);
+ RegExpParser<CharT> parser(ts, &alloc, chars, chars + length, false, unicode, dotall, false);
return parser.ParsePattern() != nullptr;
}
bool
irregexp::ParsePatternSyntax(frontend::TokenStream& ts, LifoAlloc& alloc, JSAtom* str,
- bool unicode)
+ bool unicode, bool dotall)
{
JS::AutoCheckCannotGC nogc;
return str->hasLatin1Chars()
- ? ::ParsePatternSyntax(ts, alloc, str->latin1Chars(nogc), str->length(), unicode)
- : ::ParsePatternSyntax(ts, alloc, str->twoByteChars(nogc), str->length(), unicode);
+ ? ::ParsePatternSyntax(ts, alloc, str->latin1Chars(nogc), str->length(), unicode, dotall)
+ : ::ParsePatternSyntax(ts, alloc, str->twoByteChars(nogc), str->length(), unicode, dotall);
}
diff --git a/js/src/irregexp/RegExpParser.h b/js/src/irregexp/RegExpParser.h
index 0a7e61858..ee57f0436 100644
--- a/js/src/irregexp/RegExpParser.h
+++ b/js/src/irregexp/RegExpParser.h
@@ -44,11 +44,11 @@ namespace irregexp {
bool
ParsePattern(frontend::TokenStream& ts, LifoAlloc& alloc, JSAtom* str,
bool multiline, bool match_only, bool unicode, bool ignore_case,
- bool global, bool sticky, RegExpCompileData* data);
+ bool global, bool sticky, bool dotall, RegExpCompileData* data);
bool
ParsePatternSyntax(frontend::TokenStream& ts, LifoAlloc& alloc, JSAtom* str,
- bool unicode);
+ bool unicode, bool dotall);
// A BufferedVector is an automatically growing list, just like (and backed
// by) a Vector, that is optimized for the case of adding and removing
@@ -178,7 +178,7 @@ class RegExpParser
public:
RegExpParser(frontend::TokenStream& ts, LifoAlloc* alloc,
const CharT* chars, const CharT* end, bool multiline_mode, bool unicode,
- bool ignore_case);
+ bool ignore_case, bool dotall);
RegExpTree* ParsePattern();
RegExpTree* ParseDisjunction();
@@ -229,7 +229,7 @@ class RegExpParser
bool simple() { return simple_; }
bool contains_anchor() { return contains_anchor_; }
void set_contains_anchor() { contains_anchor_ = true; }
- int captures_started() { return captures_ == nullptr ? 0 : captures_->length(); }
+ int captures_started() { return captures_started_; }
const CharT* position() { return next_pos_ - 1; }
static const int kMaxCaptures = 1 << 16;
@@ -239,8 +239,8 @@ class RegExpParser
enum SubexpressionType {
INITIAL,
CAPTURE, // All positive values represent captures.
- POSITIVE_LOOKAHEAD,
- NEGATIVE_LOOKAHEAD,
+ POSITIVE_LOOKAROUND,
+ NEGATIVE_LOOKAROUND,
GROUPING
};
@@ -249,10 +249,12 @@ class RegExpParser
RegExpParserState(LifoAlloc* alloc,
RegExpParserState* previous_state,
SubexpressionType group_type,
+ RegExpLookaround::Type lookaround_type,
int disjunction_capture_index)
: previous_state_(previous_state),
builder_(alloc->newInfallible<RegExpBuilder>(alloc)),
group_type_(group_type),
+ lookaround_type_(lookaround_type),
disjunction_capture_index_(disjunction_capture_index)
{}
// Parser state of containing expression, if any.
@@ -262,11 +264,16 @@ class RegExpParser
RegExpBuilder* builder() { return builder_; }
// Type of regexp being parsed (parenthesized group or entire regexp).
SubexpressionType group_type() { return group_type_; }
+ // Lookahead or Lookbehind.
+ RegExpLookaround::Type lookaround_type() { return lookaround_type_; }
// Index in captures array of first capture in this sub-expression, if any.
// Also the capture index of this sub-expression itself, if group_type
// is CAPTURE.
int capture_index() { return disjunction_capture_index_; }
+ // Check whether the parser is inside a capture group with the given index.
+ bool IsInsideCaptureGroup(int index);
+
private:
// Linked list implementation of stack of states.
RegExpParserState* previous_state_;
@@ -274,10 +281,15 @@ class RegExpParser
RegExpBuilder* builder_;
// Stored disjunction type (capture, look-ahead or grouping), if any.
SubexpressionType group_type_;
+ // Stored read direction.
+ RegExpLookaround::Type lookaround_type_;
// Stored disjunction's capture index (if any).
int disjunction_capture_index_;
};
+ // Return the 1-indexed RegExpCapture object, allocate if necessary.
+ RegExpCapture* GetCapture(int index);
+
widechar current() { return current_; }
bool has_more() { return has_more_; }
bool has_next() { return next_pos_ < end_; }
@@ -294,12 +306,14 @@ class RegExpParser
const CharT* next_pos_;
const CharT* end_;
widechar current_;
+ int captures_started_;
// The capture count is only valid after we have scanned for captures.
int capture_count_;
bool has_more_;
bool multiline_;
bool unicode_;
bool ignore_case_;
+ bool dotall_;
bool simple_;
bool contains_anchor_;
bool is_scanned_for_captures_;
diff --git a/js/src/jit-test/modules/empty.js b/js/src/jit-test/modules/empty.js
new file mode 100644
index 000000000..bd9ec079d
--- /dev/null
+++ b/js/src/jit-test/modules/empty.js
@@ -0,0 +1 @@
+// Intentionally empty.
diff --git a/js/src/jit-test/modules/export-circular-nonexisting-binding-1.js b/js/src/jit-test/modules/export-circular-nonexisting-binding-1.js
new file mode 100644
index 000000000..2b91b6a28
--- /dev/null
+++ b/js/src/jit-test/modules/export-circular-nonexisting-binding-1.js
@@ -0,0 +1,4 @@
+import "export-circular-nonexisting-binding-2.js";
+
+export* from "empty.js";
+export {x} from "empty.js";
diff --git a/js/src/jit-test/modules/export-circular-nonexisting-binding-2.js b/js/src/jit-test/modules/export-circular-nonexisting-binding-2.js
new file mode 100644
index 000000000..ba7dcc1b4
--- /dev/null
+++ b/js/src/jit-test/modules/export-circular-nonexisting-binding-2.js
@@ -0,0 +1 @@
+export {x} from "export-circular-nonexisting-binding-1.js";
diff --git a/js/src/jit-test/modules/export-star-circular-1.js b/js/src/jit-test/modules/export-star-circular-1.js
new file mode 100644
index 000000000..9a0771b02
--- /dev/null
+++ b/js/src/jit-test/modules/export-star-circular-1.js
@@ -0,0 +1 @@
+export* from "export-star-circular-2.js";
diff --git a/js/src/jit-test/modules/export-star-circular-2.js b/js/src/jit-test/modules/export-star-circular-2.js
new file mode 100644
index 000000000..b273d9cef
--- /dev/null
+++ b/js/src/jit-test/modules/export-star-circular-2.js
@@ -0,0 +1,3 @@
+export {y as x} from "export-star-circular-1.js";
+
+export var y = "pass";
diff --git a/js/src/jit-test/tests/auto-regress/bug466654.js b/js/src/jit-test/tests/auto-regress/bug466654.js
deleted file mode 100644
index 6c82c425b..000000000
--- a/js/src/jit-test/tests/auto-regress/bug466654.js
+++ /dev/null
@@ -1,8 +0,0 @@
-// |jit-test| error:TypeError
-
-// Binary: cache/js-dbg-32-29add08d84ae-linux
-// Flags: -j
-//
-this.watch('y', /x/g );
-for each (y in ['q', 'q', 'q']) continue;
-gc();
diff --git a/js/src/jit-test/tests/auto-regress/bug516897.js b/js/src/jit-test/tests/auto-regress/bug516897.js
deleted file mode 100644
index e3caf4e6e..000000000
--- a/js/src/jit-test/tests/auto-regress/bug516897.js
+++ /dev/null
@@ -1,6 +0,0 @@
-// Binary: cache/js-dbg-64-38754465ffde-linux
-// Flags:
-//
-this.__defineSetter__("x", gc);
-this.watch("x",function(){return});
-x = 3;
diff --git a/js/src/jit-test/tests/auto-regress/bug537854.js b/js/src/jit-test/tests/auto-regress/bug537854.js
deleted file mode 100644
index 80fb3c14a..000000000
--- a/js/src/jit-test/tests/auto-regress/bug537854.js
+++ /dev/null
@@ -1,4 +0,0 @@
-// Binary: cache/js-dbg-64-9d51f2a931f7-linux
-// Flags:
-//
-({x:function(){}}).watch('x',function(){});
diff --git a/js/src/jit-test/tests/auto-regress/bug560796.js b/js/src/jit-test/tests/auto-regress/bug560796.js
deleted file mode 100644
index 4ab93567e..000000000
--- a/js/src/jit-test/tests/auto-regress/bug560796.js
+++ /dev/null
@@ -1,9 +0,0 @@
-// Binary: cache/js-dbg-64-a6d7a5677b4c-linux
-// Flags:
-//
-this.__defineSetter__("x", function(){})
-this.watch("x", "".localeCompare)
-window = x
-Object.defineProperty(this, "x", ({
- set: window
-}))
diff --git a/js/src/jit-test/tests/auto-regress/bug638735.js b/js/src/jit-test/tests/auto-regress/bug638735.js
index 63071aa7c..c941f5369 100644
--- a/js/src/jit-test/tests/auto-regress/bug638735.js
+++ b/js/src/jit-test/tests/auto-regress/bug638735.js
@@ -4,7 +4,6 @@
var o9 = Function.prototype;
var o13 = Array;
function f5(o) {
-o.watch('p3', function() {});
ox1 = new Proxy(o, {});
}
f5(o9);
diff --git a/js/src/jit-test/tests/auto-regress/bug639413.js b/js/src/jit-test/tests/auto-regress/bug639413.js
deleted file mode 100644
index d8dd58eaf..000000000
--- a/js/src/jit-test/tests/auto-regress/bug639413.js
+++ /dev/null
@@ -1,9 +0,0 @@
-// |jit-test| error:TypeError
-
-// Binary: cache/js-dbg-32-1c8e91b2e3a4-linux
-// Flags:
-//
-a = evalcx("lazy");
-a.watch("x", function() {});
-({}).watch("x", function() {});
-a.__defineGetter__("y", {});
diff --git a/js/src/jit-test/tests/auto-regress/bug698899.js b/js/src/jit-test/tests/auto-regress/bug698899.js
deleted file mode 100644
index 644f45ec2..000000000
--- a/js/src/jit-test/tests/auto-regress/bug698899.js
+++ /dev/null
@@ -1,9 +0,0 @@
-// Binary: cache/js-dbg-32-f951e9151626-linux
-// Flags: -m -n
-//
-o = evalcx("lazy").__proto__
-gc()
-try {
- o.watch()
-} catch (e) {}
-o.constructor()
diff --git a/js/src/jit-test/tests/auto-regress/bug746397.js b/js/src/jit-test/tests/auto-regress/bug746397.js
deleted file mode 100644
index d915ca7bb..000000000
--- a/js/src/jit-test/tests/auto-regress/bug746397.js
+++ /dev/null
@@ -1,10 +0,0 @@
-// |jit-test| error:ReferenceError
-
-// Binary: cache/js-dbg-64-67bf9a4a1f77-linux
-// Flags: --ion-eager
-//
-
-(function () {
- var a = ['x', 'y'];
- obj.watch(a[+("0")], counter);
-})();
diff --git a/js/src/jit-test/tests/auto-regress/bug769192.js b/js/src/jit-test/tests/auto-regress/bug769192.js
deleted file mode 100644
index 531e37912..000000000
--- a/js/src/jit-test/tests/auto-regress/bug769192.js
+++ /dev/null
@@ -1,6 +0,0 @@
-// |jit-test| error:TypeError
-
-// Binary: cache/js-dbg-64-bf8f2961d0cc-linux
-// Flags:
-//
-Object.watch.call(new Uint8ClampedArray, "length", function() {});
diff --git a/js/src/jit-test/tests/baseline/bug843444.js b/js/src/jit-test/tests/baseline/bug843444.js
deleted file mode 100644
index 3a77402ac..000000000
--- a/js/src/jit-test/tests/baseline/bug843444.js
+++ /dev/null
@@ -1,8 +0,0 @@
-gczeal(8, 1)
-function recurse(x) {
- recurse;
- if (x < 20)
- recurse(x + 1);
-};
-this.watch(5, (function () {}))
-recurse(0)
diff --git a/js/src/jit-test/tests/basic/bug1220766.js b/js/src/jit-test/tests/basic/bug1220766.js
deleted file mode 100644
index fca11eafe..000000000
--- a/js/src/jit-test/tests/basic/bug1220766.js
+++ /dev/null
@@ -1,3 +0,0 @@
-iter = getSelfHostedValue("CreateListIterator")([]);
-iter.next();
-iter.next();
diff --git a/js/src/jit-test/tests/basic/bug510437.js b/js/src/jit-test/tests/basic/bug510437.js
deleted file mode 100644
index 2418b9b11..000000000
--- a/js/src/jit-test/tests/basic/bug510437.js
+++ /dev/null
@@ -1,13 +0,0 @@
-// Don't crash or assert.
-
-var d;
-this.watch("d", eval);
-(function () {
- (eval("\
- (function () {\
- for (let x = 0; x < 2; ++x) {\
- d = x\
- }\
- })\
-"))()
-})()
diff --git a/js/src/jit-test/tests/basic/bug605015.js b/js/src/jit-test/tests/basic/bug605015.js
deleted file mode 100644
index a35f7b6c7..000000000
--- a/js/src/jit-test/tests/basic/bug605015.js
+++ /dev/null
@@ -1,9 +0,0 @@
-// |jit-test| error: TypeError
-// don't assert
-
-print(this.watch("x",
-function() {
- Object.defineProperty(this, "x", ({
- get: (Int8Array)
- }))
-}))(x = /x/)
diff --git a/js/src/jit-test/tests/basic/bug631305.js b/js/src/jit-test/tests/basic/bug631305.js
deleted file mode 100644
index b0cbbbb24..000000000
--- a/js/src/jit-test/tests/basic/bug631305.js
+++ /dev/null
@@ -1,9 +0,0 @@
-var n = 0;
-var a = [];
-for (var i = 0; i < 20; i++)
- a[i] = {};
-a[18].watch("p", function () { n++; });
-delete a[18].p;
-for (var i = 0; i < 20; i++)
- a[i].p = 0;
-assertEq(n, 1);
diff --git a/js/src/jit-test/tests/basic/bug662562.js b/js/src/jit-test/tests/basic/bug662562.js
deleted file mode 100644
index 45b48589a..000000000
--- a/js/src/jit-test/tests/basic/bug662562.js
+++ /dev/null
@@ -1,6 +0,0 @@
-// |jit-test| error: TypeError
-function f(o) {
- o.watch("x", this);
-}
-var c = evalcx("");
-f(c);
diff --git a/js/src/jit-test/tests/basic/bug690292.js b/js/src/jit-test/tests/basic/bug690292.js
deleted file mode 100644
index 43ab56dd7..000000000
--- a/js/src/jit-test/tests/basic/bug690292.js
+++ /dev/null
@@ -1,12 +0,0 @@
-
-done = false;
-try {
- function x() {}
- print(this.watch("d", Object.create))
- var d = {}
-} catch (e) {}
-try {
- eval("d = ''")
- done = true;
-} catch (e) {}
-assertEq(done, false);
diff --git a/js/src/jit-test/tests/basic/bug696748.js b/js/src/jit-test/tests/basic/bug696748.js
index fe171f976..33fb4d52f 100644
--- a/js/src/jit-test/tests/basic/bug696748.js
+++ b/js/src/jit-test/tests/basic/bug696748.js
@@ -1,6 +1,3 @@
-try {
-this.watch("b", "".substring);
-} catch(exc1) {}
eval("\
var URI = '';\
test();\
diff --git a/js/src/jit-test/tests/basic/bug831846.js b/js/src/jit-test/tests/basic/bug831846.js
deleted file mode 100644
index 30bb3aa86..000000000
--- a/js/src/jit-test/tests/basic/bug831846.js
+++ /dev/null
@@ -1,3 +0,0 @@
-// |jit-test| error:TypeError
-
-evalcx('').watch("", /()/);
diff --git a/js/src/jit-test/tests/basic/testAssigningWatchedDeletedProperty.js b/js/src/jit-test/tests/basic/testAssigningWatchedDeletedProperty.js
deleted file mode 100644
index c22eabed0..000000000
--- a/js/src/jit-test/tests/basic/testAssigningWatchedDeletedProperty.js
+++ /dev/null
@@ -1,7 +0,0 @@
-var o = {};
-o.watch("p", function() { });
-
-for (var i = 0; i < 10; i++) {
- o.p = 123;
- delete o.p;
-}
diff --git a/js/src/jit-test/tests/basic/testBug566556.js b/js/src/jit-test/tests/basic/testBug566556.js
deleted file mode 100644
index 244be57d2..000000000
--- a/js/src/jit-test/tests/basic/testBug566556.js
+++ /dev/null
@@ -1,9 +0,0 @@
-var msg = "";
-try {
- this.__defineSetter__('x', Object.create);
- this.watch('x', function() {});
- x = 3;
-} catch (e) {
- msg = e.toString();
-}
-assertEq(msg, "TypeError: undefined is not an object or null");
diff --git a/js/src/jit-test/tests/basic/testBug578044.js b/js/src/jit-test/tests/basic/testBug578044.js
deleted file mode 100644
index c5b811dc9..000000000
--- a/js/src/jit-test/tests/basic/testBug578044.js
+++ /dev/null
@@ -1,13 +0,0 @@
-this.watch("x", Object.create)
-try {
- (function() {
- this.__defineGetter__("x",
- function() {
- return this
- })
- })()
-} catch(e) {}
-Object.defineProperty(x, "x", ({
- set: Uint16Array
-}))
-
diff --git a/js/src/jit-test/tests/basic/testBug584650.js b/js/src/jit-test/tests/basic/testBug584650.js
deleted file mode 100644
index b6c9d8ab7..000000000
--- a/js/src/jit-test/tests/basic/testBug584650.js
+++ /dev/null
@@ -1,9 +0,0 @@
-if (typeof gczeal != "function")
- gczeal = function() {}
-
-// don't crash
-x = (evalcx('lazy'))
-x.watch("", function () {})
-gczeal(1)
-for (w in x) {}
-
diff --git a/js/src/jit-test/tests/basic/testBug780288-1.js b/js/src/jit-test/tests/basic/testBug780288-1.js
deleted file mode 100644
index 90746a04a..000000000
--- a/js/src/jit-test/tests/basic/testBug780288-1.js
+++ /dev/null
@@ -1,20 +0,0 @@
-s = newGlobal()
-try {
- evalcx("\
- Object.defineProperty(this,\"i\",{enumerable:true,get:function(){t}});\
- for each(y in this)true\
- ", s)
-} catch (e) {}
-try {
- evalcx("\
- for(z=0,(7).watch(\"\",eval);;g){\
- if(z=1){({t:function(){}})\
- }\
- ", s)
-} catch (e) {}
-try {
- evalcx("\
- Object.defineProperty(this,\"g2\",{get:function(){return this}});\
- g2.y()\
- ", s)
-} catch (e) {}
diff --git a/js/src/jit-test/tests/basic/testBug780288-2.js b/js/src/jit-test/tests/basic/testBug780288-2.js
deleted file mode 100644
index 8c4c1737c..000000000
--- a/js/src/jit-test/tests/basic/testBug780288-2.js
+++ /dev/null
@@ -1,20 +0,0 @@
-s = newGlobal()
-try {
- evalcx("\
- Object.defineProperty(this,\"i\",{enumerable:true,get:function(){t}});\
- for each(y in this)true\
- ", s)
-} catch (e) {}
-try {
- evalcx("\
- for(z=0,(7).watch(\"\",eval);;g){\
- if(z=1){({t:function(){}})\
- }\
- ", s)
-} catch (e) {}
-try {
- evalcx("\
- Object.defineProperty(this,\"g2\",{get:function(){return this}});\
- g2.y(\"\")\
- ", s)
-} catch (e) {}
diff --git a/js/src/jit-test/tests/basic/testEvalCalledFromWatchOverSetter.js b/js/src/jit-test/tests/basic/testEvalCalledFromWatchOverSetter.js
deleted file mode 100644
index bcd60fd80..000000000
--- a/js/src/jit-test/tests/basic/testEvalCalledFromWatchOverSetter.js
+++ /dev/null
@@ -1,3 +0,0 @@
-this.__defineSetter__("x", function(){});
-this.watch("x", eval);
-x = 0;
diff --git a/js/src/jit-test/tests/basic/testNonStubGetter.js b/js/src/jit-test/tests/basic/testNonStubGetter.js
deleted file mode 100644
index 58a698eb4..000000000
--- a/js/src/jit-test/tests/basic/testNonStubGetter.js
+++ /dev/null
@@ -1,7 +0,0 @@
-function testNonStubGetter() {
- { let [] = []; (this.watch("x", function(p, o, n) { return /a/g.exec(p, o, n); })); };
- (function () { (eval("(function(){for each (x in [1, 2, 2]);});"))(); })();
- this.unwatch("x");
- return "ok";
-}
-assertEq(testNonStubGetter(), "ok");
diff --git a/js/src/jit-test/tests/basic/testSettingWatchPointOnReadOnlyProp.js b/js/src/jit-test/tests/basic/testSettingWatchPointOnReadOnlyProp.js
deleted file mode 100644
index 78c281f05..000000000
--- a/js/src/jit-test/tests/basic/testSettingWatchPointOnReadOnlyProp.js
+++ /dev/null
@@ -1,7 +0,0 @@
-for (var i = 0; i < 5; ++i) {
- var o = {}
- Object.defineProperty(o, 'x', { value:"cow", writable:false });
- var r = o.watch('x', function() {});
- assertEq(r, undefined);
- o.x = 4;
-}
diff --git a/js/src/jit-test/tests/basic/testTrueShiftTrue.js b/js/src/jit-test/tests/basic/testTrueShiftTrue.js
deleted file mode 100644
index 44c1290d8..000000000
--- a/js/src/jit-test/tests/basic/testTrueShiftTrue.js
+++ /dev/null
@@ -1,16 +0,0 @@
-// Test no assert or crash from outer recorders (bug 465145)
-function testBug465145() {
- this.__defineSetter__("x", function(){});
- this.watch("x", function(){});
- y = this;
- for (var z = 0; z < 2; ++z) { x = y };
- this.__defineSetter__("x", function(){});
- for (var z = 0; z < 2; ++z) { x = y };
-}
-
-function testTrueShiftTrue() {
- var a = new Array(5);
- for (var i=0;i<5;++i) a[i] = "" + (true << true);
- return a.join(",");
-}
-assertEq(testTrueShiftTrue(), "2,2,2,2,2");
diff --git a/js/src/jit-test/tests/basic/testWatchRecursion.js b/js/src/jit-test/tests/basic/testWatchRecursion.js
deleted file mode 100644
index e5d5877df..000000000
--- a/js/src/jit-test/tests/basic/testWatchRecursion.js
+++ /dev/null
@@ -1,63 +0,0 @@
-// Test that the watch handler is not called recursively for the same object
-// and property.
-(function() {
- var obj1 = {}, obj2 = {};
- var handler_entry_count = 0;
- var handler_exit_count = 0;
-
- obj1.watch('x', handler);
- obj1.watch('y', handler);
- obj2.watch('x', handler);
- obj1.x = 1;
- assertEq(handler_entry_count, 3);
- assertEq(handler_exit_count, 3);
-
- function handler(id) {
- handler_entry_count++;
- assertEq(handler_exit_count, 0);
- switch (true) {
- case this === obj1 && id === "x":
- assertEq(handler_entry_count, 1);
- obj2.x = 3;
- assertEq(handler_exit_count, 2);
- break;
- case this === obj2 && id === "x":
- assertEq(handler_entry_count, 2);
- obj1.y = 4;
- assertEq(handler_exit_count, 1);
- break;
- default:
- assertEq(this, obj1);
- assertEq(id, "y");
- assertEq(handler_entry_count, 3);
-
- // We expect no more watch handler invocations
- obj1.x = 5;
- obj1.y = 6;
- obj2.x = 7;
- assertEq(handler_exit_count, 0);
- break;
- }
- ++handler_exit_count;
- assertEq(handler_entry_count, 3);
- }
-})();
-
-
-// Test that run-away recursion in watch handlers is properly handled.
-(function() {
- var obj = {};
- var i = 0;
- try {
- handler();
- throw new Error("Unreachable");
- } catch(e) {
- assertEq(e instanceof InternalError, true);
- }
-
- function handler() {
- var prop = "a" + ++i;
- obj.watch(prop, handler);
- obj[prop] = 2;
- }
-})();
diff --git a/js/src/jit-test/tests/ctypes/function-definition.js b/js/src/jit-test/tests/ctypes/function-definition.js
index 4df317a09..5882ba889 100644
--- a/js/src/jit-test/tests/ctypes/function-definition.js
+++ b/js/src/jit-test/tests/ctypes/function-definition.js
@@ -27,7 +27,7 @@ function test() {
let lib;
try {
- lib = ctypes.open(ctypes.libraryName("c"));
+ lib = ctypes.open(ctypes.libraryName("m"));
} catch (e) {
}
if (!lib)
diff --git a/js/src/jit-test/tests/gc/bug-900405.js b/js/src/jit-test/tests/gc/bug-900405.js
deleted file mode 100644
index eeec6f25f..000000000
--- a/js/src/jit-test/tests/gc/bug-900405.js
+++ /dev/null
@@ -1,3 +0,0 @@
-(function() {
- [{ "9": [] }.watch([], function(){})]
-})()
diff --git a/js/src/jit-test/tests/gc/bug-913261.js b/js/src/jit-test/tests/gc/bug-913261.js
deleted file mode 100644
index 43066053f..000000000
--- a/js/src/jit-test/tests/gc/bug-913261.js
+++ /dev/null
@@ -1,5 +0,0 @@
-// |jit-test| error: InternalError: too much recursion
-(function f() {
- "".watch(2, function() {});
- f();
-})()
diff --git a/js/src/jit-test/tests/gc/bug-986864.js b/js/src/jit-test/tests/gc/bug-986864.js
deleted file mode 100644
index abb8de6b2..000000000
--- a/js/src/jit-test/tests/gc/bug-986864.js
+++ /dev/null
@@ -1,8 +0,0 @@
-// |jit-test| slow
-function x() {}
-for (var j = 0; j < 9999; ++j) {
- (function() {
- x += x.watch("endsWith", ArrayBuffer);
- return 0 >> Function(x)
- })()
-}
diff --git a/js/src/jit-test/tests/ion/bug1063182.js b/js/src/jit-test/tests/ion/bug1063182.js
deleted file mode 100644
index 9cda48099..000000000
--- a/js/src/jit-test/tests/ion/bug1063182.js
+++ /dev/null
@@ -1,8 +0,0 @@
-// |jit-test| error: ReferenceError
-
-eval("(function() { " + "\
-var o = {};\
-o.watch('p', function() { });\
-for (var i = 0; i < 10; \u5ede ++)\
- o.p = 123;\
-" + " })();");
diff --git a/js/src/jit-test/tests/ion/bug772901.js b/js/src/jit-test/tests/ion/bug772901.js
index eb71f6afb..164afd151 100644
--- a/js/src/jit-test/tests/ion/bug772901.js
+++ b/js/src/jit-test/tests/ion/bug772901.js
@@ -4,4 +4,4 @@ function f(x) {
delete ((x)++);
arguments[0] !== undefined;
}
-f(1, x = [f.ArrayBuffer,unwatch.Int32Array], this, this, this) ;
+f(1, x = [f.ArrayBuffer, undefined], this, this, this) ;
diff --git a/js/src/jit-test/tests/ion/bug774257-1.js b/js/src/jit-test/tests/ion/bug774257-1.js
deleted file mode 100644
index 9c998a028..000000000
--- a/js/src/jit-test/tests/ion/bug774257-1.js
+++ /dev/null
@@ -1,8 +0,0 @@
-Object.defineProperty(Object.prototype, 'x', {
- set: function() { evalcx('lazy'); }
-});
-var obj = {};
-obj.watch("x", function (id, oldval, newval) {});
-for (var str in 'A') {
- obj.x = 1;
-}
diff --git a/js/src/jit-test/tests/ion/bug774257-2.js b/js/src/jit-test/tests/ion/bug774257-2.js
deleted file mode 100644
index b31043b08..000000000
--- a/js/src/jit-test/tests/ion/bug774257-2.js
+++ /dev/null
@@ -1,10 +0,0 @@
-Object.defineProperty(Object.prototype, 'x', {
- set: function() { evalcx('lazy'); }
-});
-var obj = {};
-var prot = {};
-obj.__proto__ = prot;
-obj.watch("x", function (id, oldval, newval) {});
-for (var str in 'A') {
- obj.x = 1;
-}
diff --git a/js/src/jit-test/tests/ion/bug779631.js b/js/src/jit-test/tests/ion/bug779631.js
deleted file mode 100644
index 087aa01ac..000000000
--- a/js/src/jit-test/tests/ion/bug779631.js
+++ /dev/null
@@ -1,9 +0,0 @@
-var flag = 0;
-var a = {};
-Object.defineProperty(a, "value", {set: function(x) {}});
-a.watch("value", function(){flag++;});
-
-for(var i = 0; i < 100; i++) {
- a.value = i;
- assertEq(flag, i+1);
-}
diff --git a/js/src/jit-test/tests/ion/bug783590.js b/js/src/jit-test/tests/ion/bug783590.js
index d48cb609e..9d277e02c 100644
--- a/js/src/jit-test/tests/ion/bug783590.js
+++ b/js/src/jit-test/tests/ion/bug783590.js
@@ -7,7 +7,6 @@ Object.defineProperty(arr, 0, {
glob.__proto__;
})
});
-this.watch("s", function() {});
try {
arr.pop();
} catch (e) {}
diff --git a/js/src/jit-test/tests/jaeger/bug550665.js b/js/src/jit-test/tests/jaeger/bug550665.js
deleted file mode 100644
index 816888b5e..000000000
--- a/js/src/jit-test/tests/jaeger/bug550665.js
+++ /dev/null
@@ -1,8 +0,0 @@
-(function () {
- var a;
- eval("for(w in ((function(x,y){b:0})())) ;");
-})();
-
-this.__defineSetter__("l", function() { gc() });
-this.watch("l", function(x) { yield {} });
-l = true;
diff --git a/js/src/jit-test/tests/jaeger/bug557063.js b/js/src/jit-test/tests/jaeger/bug557063.js
deleted file mode 100644
index ea77fd2c8..000000000
--- a/js/src/jit-test/tests/jaeger/bug557063.js
+++ /dev/null
@@ -1,7 +0,0 @@
-(function() {
- for (a = 0; a < 2; a++)
- ''.watch("", function() {})
-})()
-
-/* Don't crash or assert. */
-
diff --git a/js/src/jit-test/tests/jaeger/bug588338.js b/js/src/jit-test/tests/jaeger/bug588338.js
index 457be238a..c400d7687 100644
--- a/js/src/jit-test/tests/jaeger/bug588338.js
+++ b/js/src/jit-test/tests/jaeger/bug588338.js
@@ -9,7 +9,6 @@ function f() {
}
}
})(/x/)))
-for (z = 0; z < 100; x.unwatch(), z++)
for (e in [0]) {
gczeal(2)
} ( [1,2,3])("")
diff --git a/js/src/jit-test/tests/jaeger/bug625438.js b/js/src/jit-test/tests/jaeger/bug625438.js
deleted file mode 100644
index 32586d8ab..000000000
--- a/js/src/jit-test/tests/jaeger/bug625438.js
+++ /dev/null
@@ -1,10 +0,0 @@
-// vim: set ts=8 sts=4 et sw=4 tw=99:
-
-var count = 0;
-this.watch("x", function() {
- count++;
-});
-for(var i=0; i<10; i++) {
- x = 2;
-}
-assertEq(count, 10);
diff --git a/js/src/jit-test/tests/jaeger/bug630366.js b/js/src/jit-test/tests/jaeger/bug630366.js
deleted file mode 100644
index acac8d3ef..000000000
--- a/js/src/jit-test/tests/jaeger/bug630366.js
+++ /dev/null
@@ -1,7 +0,0 @@
-var o = {};
-for(var i=0; i<5; i++) {
- o.p = 2;
- o.watch("p", function() { });
- o.p = 2;
- delete o.p;
-}
diff --git a/js/src/jit-test/tests/jaeger/recompile/bug641225.js b/js/src/jit-test/tests/jaeger/recompile/bug641225.js
index a6e3a86c7..7b7978197 100644
--- a/js/src/jit-test/tests/jaeger/recompile/bug641225.js
+++ b/js/src/jit-test/tests/jaeger/recompile/bug641225.js
@@ -118,7 +118,6 @@ for(var o2 in f5) {
f2(o5);
f2(o5);
f0(o3);
- o9.watch('p3', function() {});
o8[o8] = o8;
f0(o5);
f1(o6);
diff --git a/js/src/jit-test/tests/modules/bug-1320993.js b/js/src/jit-test/tests/modules/bug-1320993.js
new file mode 100644
index 000000000..bece5731a
--- /dev/null
+++ b/js/src/jit-test/tests/modules/bug-1320993.js
@@ -0,0 +1,2 @@
+parseModule("export default (class {})");
+parseModule("export default (class A {})");
diff --git a/js/src/jit-test/tests/modules/export-circular-nonexisting-binding.js b/js/src/jit-test/tests/modules/export-circular-nonexisting-binding.js
new file mode 100644
index 000000000..387c7c369
--- /dev/null
+++ b/js/src/jit-test/tests/modules/export-circular-nonexisting-binding.js
@@ -0,0 +1,3 @@
+// |jit-test| module; error:SyntaxError
+
+import "export-circular-nonexisting-binding-1.js";
diff --git a/js/src/jit-test/tests/modules/export-star-cannot-rescue-missing-export.js b/js/src/jit-test/tests/modules/export-star-cannot-rescue-missing-export.js
new file mode 100644
index 000000000..f87829d89
--- /dev/null
+++ b/js/src/jit-test/tests/modules/export-star-cannot-rescue-missing-export.js
@@ -0,0 +1,4 @@
+// |jit-test| module; error:SyntaxError
+
+export { a } from "empty.js";
+export* from "module1.js";
diff --git a/js/src/jit-test/tests/modules/export-star-circular-dependencies.js b/js/src/jit-test/tests/modules/export-star-circular-dependencies.js
new file mode 100644
index 000000000..9aa612f08
--- /dev/null
+++ b/js/src/jit-test/tests/modules/export-star-circular-dependencies.js
@@ -0,0 +1,6 @@
+// |jit-test| module
+
+import { x, y } from "export-star-circular-1.js";
+
+assertEq(x, "pass");
+assertEq(y, "pass");
diff --git a/js/src/jit-test/tests/modules/import-namespace.js b/js/src/jit-test/tests/modules/import-namespace.js
index f44d4568a..0287f7a60 100644
--- a/js/src/jit-test/tests/modules/import-namespace.js
+++ b/js/src/jit-test/tests/modules/import-namespace.js
@@ -19,9 +19,19 @@ function testHasNames(names, expected) {
});
}
+function testEqualArrays(actual, expected) {
+ assertEq(Array.isArray(actual), true);
+ assertEq(Array.isArray(expected), true);
+ assertEq(actual.length, expected.length);
+ for (let i = 0; i < expected.length; i++) {
+ assertEq(actual[i], expected[i]);
+ }
+}
+
let a = moduleRepo['a'] = parseModule(
- `export var a = 1;
- export var b = 2;`
+ `// Reflection methods should return these exports alphabetically sorted.
+ export var b = 2;
+ export var a = 1;`
);
let b = moduleRepo['b'] = parseModule(
@@ -35,11 +45,16 @@ b.evaluation();
testHasNames(getModuleEnvironmentNames(b), ["ns", "x"]);
let ns = getModuleEnvironmentValue(b, "ns");
testHasNames(Object.keys(ns), ["a", "b"]);
+assertEq(ns.a, 1);
+assertEq(ns.b, 2);
+assertEq(ns.c, undefined);
assertEq(getModuleEnvironmentValue(b, "x"), 3);
// Test module namespace internal methods as defined in 9.4.6
assertEq(Object.getPrototypeOf(ns), null);
-assertThrowsInstanceOf(() => Object.setPrototypeOf(ns, null), TypeError);
+assertEq(Reflect.setPrototypeOf(ns, null), true);
+assertEq(Reflect.setPrototypeOf(ns, Object.prototype), false);
+assertThrowsInstanceOf(() => Object.setPrototypeOf(ns, {}), TypeError);
assertThrowsInstanceOf(function() { ns.foo = 1; }, TypeError);
assertEq(Object.isExtensible(ns), false);
Object.preventExtensions(ns);
@@ -59,29 +74,15 @@ desc = Object.getOwnPropertyDescriptor(ns, Symbol.toStringTag);
assertEq(desc.value, "Module");
assertEq(desc.writable, false);
assertEq(desc.enumerable, false);
-assertEq(desc.configurable, true);
+assertEq(desc.configurable, false);
assertEq(typeof desc.get, "undefined");
assertEq(typeof desc.set, "undefined");
assertEq(Object.prototype.toString.call(ns), "[object Module]");
-// Test @@iterator method.
-let iteratorFun = ns[Symbol.iterator];
-assertEq(iteratorFun.name, "[Symbol.iterator]");
-
-let iterator = ns[Symbol.iterator]();
-assertEq(iterator[Symbol.iterator](), iterator);
-assertIteratorNext(iterator, "a");
-assertIteratorNext(iterator, "b");
-assertIteratorDone(iterator);
-
-// The iterator's next method can only be called on the object it was originally
-// associated with.
-iterator = ns[Symbol.iterator]();
-let iterator2 = ns[Symbol.iterator]();
-assertThrowsInstanceOf(() => iterator.next.call({}), TypeError);
-assertThrowsInstanceOf(() => iterator.next.call(iterator2), TypeError);
-assertEq(iterator.next.call(iterator).value, "a");
-assertEq(iterator2.next.call(iterator2).value, "a");
+// Test [[OwnPropertyKeys]] internal method.
+testEqualArrays(Reflect.ownKeys(ns), ["a", "b", Symbol.toStringTag]);
+testEqualArrays(Object.getOwnPropertyNames(ns), ["a", "b"]);
+testEqualArrays(Object.getOwnPropertySymbols(ns), [Symbol.toStringTag]);
// Test cyclic namespace import and access in module evaluation.
let c = moduleRepo['c'] =
diff --git a/js/src/jit-test/tests/pic/fuzz1.js b/js/src/jit-test/tests/pic/fuzz1.js
deleted file mode 100644
index 2481a1314..000000000
--- a/js/src/jit-test/tests/pic/fuzz1.js
+++ /dev/null
@@ -1,4 +0,0 @@
-(function() {
- for (a = 0; a < 2; a++)
- ''.watch("", function() {})
-})()
diff --git a/js/src/jit-test/tests/pic/fuzz3.js b/js/src/jit-test/tests/pic/fuzz3.js
deleted file mode 100644
index 17613b6f5..000000000
--- a/js/src/jit-test/tests/pic/fuzz3.js
+++ /dev/null
@@ -1,3 +0,0 @@
-for each(let w in [[], 0, [], 0]) {
- w.unwatch()
-}
diff --git a/js/src/jit-test/tests/pic/watch1.js b/js/src/jit-test/tests/pic/watch1.js
deleted file mode 100644
index 09d6347bf..000000000
--- a/js/src/jit-test/tests/pic/watch1.js
+++ /dev/null
@@ -1,7 +0,0 @@
-// assignments to watched objects must not be cached
-var obj = {x: 0};
-var hits = 0;
-obj.watch("x", function (id, oldval, newval) { hits++; return newval; });
-for (var i = 0; i < 10; i++)
- obj.x = i;
-assertEq(hits, 10);
diff --git a/js/src/jit-test/tests/pic/watch1a.js b/js/src/jit-test/tests/pic/watch1a.js
deleted file mode 100644
index 4b404f507..000000000
--- a/js/src/jit-test/tests/pic/watch1a.js
+++ /dev/null
@@ -1,17 +0,0 @@
-// assignments to watched objects must not be traced
-var hits = 0;
-function counter(id, oldval, newval) {
- hits++;
- return newval;
-}
-
-(function () {
- var obj = {x: 0, y: 0};
- var a = ['x', 'y'];
- obj.watch('z', counter);
- for (var i = 0; i < 14; i++) {
- obj.watch(a[+(i > 8)], counter);
- obj.y = i;
- }
-})();
-assertEq(hits, 5);
diff --git a/js/src/jit-test/tests/pic/watch2.js b/js/src/jit-test/tests/pic/watch2.js
deleted file mode 100644
index fb3e29617..000000000
--- a/js/src/jit-test/tests/pic/watch2.js
+++ /dev/null
@@ -1,8 +0,0 @@
-// assignments to watched properties via ++ must not be cached
-var obj = {x: 0};
-var hits = 0;
-obj.watch("x", function (id, oldval, newval) { hits++; return newval; });
-for (var i = 0; i < 10; i++)
- obj.x++;
-assertEq(hits, 10);
-
diff --git a/js/src/jit-test/tests/pic/watch2a.js b/js/src/jit-test/tests/pic/watch2a.js
deleted file mode 100644
index ce3294ba3..000000000
--- a/js/src/jit-test/tests/pic/watch2a.js
+++ /dev/null
@@ -1,18 +0,0 @@
-// assignments to watched properties via ++ must not be traced
-var hits = 0;
-function counter(id, oldval, newval) {
- hits++;
- return newval;
-}
-
-(function () {
- var obj = {x: 0, y: 0};
- var a = ['x', 'y'];
- obj.watch('z', counter);
- for (var i = 0; i < 14; i++) {
- obj.watch(a[+(i > 8)], counter);
- obj.y++;
- }
-})();
-assertEq(hits, 5);
-
diff --git a/js/src/jit-test/tests/pic/watch3.js b/js/src/jit-test/tests/pic/watch3.js
deleted file mode 100644
index 4c5c93d8b..000000000
--- a/js/src/jit-test/tests/pic/watch3.js
+++ /dev/null
@@ -1,7 +0,0 @@
-// assignment to watched global properties must not be cached
-x = 0;
-var hits = 0;
-this.watch("x", function (id, oldval, newval) { hits++; return newval; });
-for (var i = 0; i < 10; i++)
- x = i;
-assertEq(hits, 10);
diff --git a/js/src/jit-test/tests/pic/watch3a.js b/js/src/jit-test/tests/pic/watch3a.js
deleted file mode 100644
index 700daf6af..000000000
--- a/js/src/jit-test/tests/pic/watch3a.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// assignment to watched global properties must not be traced
-var hits = 0;
-function counter(id, oldval, newval) {
- hits++;
- return newval;
-}
-
-var x = 0;
-var y = 0;
-(function () {
- var a = ['x', 'y'];
- this.watch('z', counter);
- for (var i = 0; i < 14; i++) {
- this.watch(a[+(i > 8)], counter);
- y = 1;
- }
-})();
-assertEq(hits, 5);
-
diff --git a/js/src/jit-test/tests/pic/watch3b.js b/js/src/jit-test/tests/pic/watch3b.js
deleted file mode 100644
index 9b0dc8cc9..000000000
--- a/js/src/jit-test/tests/pic/watch3b.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// assignment to watched global properties must not be traced
-var hits = 0;
-function counter(id, oldval, newval) {
- hits++;
- return newval;
-}
-
-var x = 0;
-var y = 0;
-function f() {
- var a = [{}, this];
- for (var i = 0; i < 14; i++) {
- print(shapeOf(this));
- Object.prototype.watch.call(a[+(i > 8)], "y", counter);
- y++;
- }
-}
-f();
-assertEq(hits, 5);
-
diff --git a/js/src/jit-test/tests/pic/watch4.js b/js/src/jit-test/tests/pic/watch4.js
deleted file mode 100644
index 4b640c4df..000000000
--- a/js/src/jit-test/tests/pic/watch4.js
+++ /dev/null
@@ -1,9 +0,0 @@
-// adding assignment + watchpoint vs. caching
-var hits = 0;
-var obj = {};
-obj.watch("x", function (id, oldval, newval) { hits++; return newval; });
-for (var i = 0; i < 10; i++) {
- obj.x = 1;
- delete obj.x;
-}
-assertEq(hits, 10);
diff --git a/js/src/jit-test/tests/pic/watch5.js b/js/src/jit-test/tests/pic/watch5.js
deleted file mode 100644
index 6b22951a4..000000000
--- a/js/src/jit-test/tests/pic/watch5.js
+++ /dev/null
@@ -1,27 +0,0 @@
-// test against future pic support for symbols
-
-// assignments to watched objects must not be cached
-var obj = {};
-var x = Symbol.for("x");
-obj[x] = 0;
-var hits = 0;
-obj.watch(x, function (id, oldval, newval) { hits++; return newval; });
-for (var i = 0; i < 10; i++)
- obj[x] = i;
-assertEq(hits, 10);
-
-// assignments to watched properties via ++ must not be cached
-hits = 0;
-for (var i = 0; i < 10; i++)
- obj[x]++;
-assertEq(hits, 10);
-
-// adding assignment + watchpoint vs. caching
-hits = 0;
-obj = {};
-obj.watch(x, function (id, oldval, newval) { hits++; return newval; });
-for (var i = 0; i < 10; i++) {
- obj[x] = 1;
- delete obj[x];
-}
-assertEq(hits, 10);
diff --git a/js/src/jit-test/tests/profiler/bug1140643.js b/js/src/jit-test/tests/profiler/bug1140643.js
deleted file mode 100644
index 1b171aea2..000000000
--- a/js/src/jit-test/tests/profiler/bug1140643.js
+++ /dev/null
@@ -1,14 +0,0 @@
-// |jit-test| allow-oom
-enableSPSProfiling();
-loadFile('\
-for (var i = 0; i < 2; i++) {\
- obj = { m: function () {} };\
- obj.watch("m", function () { float32 = 0 + obj.foo; });\
- obj.m = 0;\
-}\
-');
-gcparam("maxBytes", gcparam("gcBytes") + (1)*1024);
-newGlobal("same-compartment");
-function loadFile(lfVarx) {
- evaluate(lfVarx, { noScriptRval : true, isRunOnce : true });
-}
diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp
index a001357f8..9530f65fa 100644
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -4053,9 +4053,6 @@ TryAttachSetValuePropStub(JSContext* cx, HandleScript script, jsbytecode* pc, IC
{
MOZ_ASSERT(!*attached);
- if (obj->watched())
- return true;
-
RootedShape shape(cx);
RootedObject holder(cx);
if (!EffectlesslyLookupProperty(cx, obj, id, &holder, &shape))
@@ -4151,9 +4148,6 @@ TryAttachSetAccessorPropStub(JSContext* cx, HandleScript script, jsbytecode* pc,
MOZ_ASSERT(!*attached);
MOZ_ASSERT(!*isTemporarilyUnoptimizable);
- if (obj->watched())
- return true;
-
RootedShape shape(cx);
RootedObject holder(cx);
if (!EffectlesslyLookupProperty(cx, obj, id, &holder, &shape))
diff --git a/js/src/jit/InlinableNatives.h b/js/src/jit/InlinableNatives.h
index 1d0506f74..9c864515d 100644
--- a/js/src/jit/InlinableNatives.h
+++ b/js/src/jit/InlinableNatives.h
@@ -119,7 +119,6 @@
_(IntrinsicGuardToArrayIterator) \
_(IntrinsicGuardToMapIterator) \
_(IntrinsicGuardToSetIterator) \
- _(IntrinsicIsListIterator) \
_(IntrinsicGuardToStringIterator) \
\
_(IntrinsicGuardToMapObject) \
diff --git a/js/src/jit/IonCaches.cpp b/js/src/jit/IonCaches.cpp
index 48e0792bb..fb4291188 100644
--- a/js/src/jit/IonCaches.cpp
+++ b/js/src/jit/IonCaches.cpp
@@ -3232,7 +3232,7 @@ SetPropertyIC::tryAttachStub(JSContext* cx, HandleScript outerScript, IonScript*
MOZ_ASSERT(!*emitted);
MOZ_ASSERT(!*tryNativeAddSlot);
- if (!canAttachStub() || obj->watched())
+ if (!canAttachStub())
return true;
// Fail cache emission if the object is frozen
@@ -3897,9 +3897,6 @@ IsDenseElementSetInlineable(JSObject* obj, const Value& idval, const ConstantOrR
if (!obj->is<ArrayObject>())
return false;
- if (obj->watched())
- return false;
-
if (!idval.isInt32())
return false;
diff --git a/js/src/jit/MCallOptimize.cpp b/js/src/jit/MCallOptimize.cpp
index 5eee30e49..236354530 100644
--- a/js/src/jit/MCallOptimize.cpp
+++ b/js/src/jit/MCallOptimize.cpp
@@ -285,8 +285,6 @@ IonBuilder::inlineNativeCall(CallInfo& callInfo, JSFunction* target)
return inlineGuardToClass(callInfo, &SetIteratorObject::class_);
case InlinableNative::IntrinsicGuardToStringIterator:
return inlineGuardToClass(callInfo, &StringIteratorObject::class_);
- case InlinableNative::IntrinsicIsListIterator:
- return inlineHasClass(callInfo, &ListIteratorObject::class_);
case InlinableNative::IntrinsicDefineDataProperty:
return inlineDefineDataProperty(callInfo);
case InlinableNative::IntrinsicObjectHasPrototype:
diff --git a/js/src/jit/arm/MacroAssembler-arm.cpp b/js/src/jit/arm/MacroAssembler-arm.cpp
index a4161ab00..3421001f7 100644
--- a/js/src/jit/arm/MacroAssembler-arm.cpp
+++ b/js/src/jit/arm/MacroAssembler-arm.cpp
@@ -3462,8 +3462,8 @@ MacroAssemblerARMCompat::storePayload(const Value& val, const Address& dest)
ScratchRegisterScope scratch(asMasm());
SecondScratchRegisterScope scratch2(asMasm());
- if (val.isMarkable())
- ma_mov(ImmGCPtr(val.toMarkablePointer()), scratch);
+ if (val.isGCThing())
+ ma_mov(ImmGCPtr(val.toGCThing()), scratch);
else
ma_mov(Imm32(val.toNunboxPayload()), scratch);
ma_str(scratch, ToPayload(dest), scratch2);
diff --git a/js/src/js.msg b/js/src/js.msg
index f57b36a90..e2d923bc4 100644
--- a/js/src/js.msg
+++ b/js/src/js.msg
@@ -47,7 +47,6 @@ MSG_DEF(JSMSG_MORE_ARGS_NEEDED, 3, JSEXN_TYPEERR, "{0} requires more than
MSG_DEF(JSMSG_INCOMPATIBLE_PROTO, 3, JSEXN_TYPEERR, "{0}.prototype.{1} called on incompatible {2}")
MSG_DEF(JSMSG_NO_CONSTRUCTOR, 1, JSEXN_TYPEERR, "{0} has no constructor")
MSG_DEF(JSMSG_BAD_SORT_ARG, 0, JSEXN_TYPEERR, "invalid Array.prototype.sort argument")
-MSG_DEF(JSMSG_CANT_WATCH, 1, JSEXN_TYPEERR, "can't watch non-native objects of class {0}")
MSG_DEF(JSMSG_READ_ONLY, 1, JSEXN_TYPEERR, "{0} is read-only")
MSG_DEF(JSMSG_CANT_DELETE, 1, JSEXN_TYPEERR, "property {0} is non-configurable and can't be deleted")
MSG_DEF(JSMSG_CANT_TRUNCATE_ARRAY, 0, JSEXN_TYPEERR, "can't delete non-configurable array element")
@@ -72,7 +71,6 @@ MSG_DEF(JSMSG_UNDEFINED_PROP, 1, JSEXN_REFERENCEERR, "reference to unde
MSG_DEF(JSMSG_INVALID_MAP_ITERABLE, 1, JSEXN_TYPEERR, "iterable for {0} should have array-like objects")
MSG_DEF(JSMSG_NESTING_GENERATOR, 0, JSEXN_TYPEERR, "already executing generator")
MSG_DEF(JSMSG_INCOMPATIBLE_METHOD, 3, JSEXN_TYPEERR, "{0} {1} called on incompatible {2}")
-MSG_DEF(JSMSG_OBJECT_WATCH_DEPRECATED, 0, JSEXN_WARN, "Object.prototype.watch and unwatch are very slow, non-standard, and deprecated; use a getter/setter instead")
MSG_DEF(JSMSG_ARRAYBUFFER_SLICE_DEPRECATED, 0, JSEXN_WARN, "ArrayBuffer.slice is deprecated; use ArrayBuffer.prototype.slice instead")
MSG_DEF(JSMSG_BAD_SURROGATE_CHAR, 1, JSEXN_TYPEERR, "bad surrogate character {0}")
MSG_DEF(JSMSG_UTF8_CHAR_TOO_LARGE, 1, JSEXN_TYPEERR, "UTF-8 character {0} too large")
@@ -134,6 +132,8 @@ MSG_DEF(JSMSG_INVALID_NORMALIZE_FORM, 0, JSEXN_RANGEERR, "form must be one of '
MSG_DEF(JSMSG_NEGATIVE_REPETITION_COUNT, 0, JSEXN_RANGEERR, "repeat count must be non-negative")
MSG_DEF(JSMSG_NOT_A_CODEPOINT, 1, JSEXN_RANGEERR, "{0} is not a valid code point")
MSG_DEF(JSMSG_RESULTING_STRING_TOO_LARGE, 0, JSEXN_RANGEERR, "repeat count must be less than infinity and not overflow maximum string size")
+MSG_DEF(JSMSG_FLAGS_UNDEFINED_OR_NULL, 0, JSEXN_TYPEERR, "'flags' property must neither be undefined nor null")
+MSG_DEF(JSMSG_REQUIRES_GLOBAL_REGEXP, 1, JSEXN_TYPEERR, "{0} must be called with a global RegExp")
// Number
MSG_DEF(JSMSG_BAD_RADIX, 0, JSEXN_RANGEERR, "radix must be an integer at least 2 and no greater than 36")
diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp
index cad0840e0..f9a0c6a6b 100644
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -39,7 +39,6 @@
#include "jsstr.h"
#include "jstypes.h"
#include "jsutil.h"
-#include "jswatchpoint.h"
#include "jsweakmap.h"
#include "jswrapper.h"
diff --git a/js/src/jsapi.h b/js/src/jsapi.h
index dc00c650d..4dad68e6e 100644
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -5087,7 +5087,8 @@ GetSymbolDescription(HandleSymbol symbol);
macro(split) \
macro(toPrimitive) \
macro(toStringTag) \
- macro(unscopables)
+ macro(unscopables) \
+ macro(matchAll)
enum class SymbolCode : uint32_t {
// There is one SymbolCode for each well-known symbol.
@@ -5704,6 +5705,7 @@ JS_ObjectIsDate(JSContext* cx, JS::HandleObject obj, bool* isDate);
#define JSREG_MULTILINE 0x04u /* treat ^ and $ as begin and end of line */
#define JSREG_STICKY 0x08u /* only match starting at lastIndex */
#define JSREG_UNICODE 0x10u /* unicode */
+#define JSREG_DOTALL 0x20u /* match . to everything including newlines */
extern JS_PUBLIC_API(JSObject*)
JS_NewRegExpObject(JSContext* cx, const char* bytes, size_t length, unsigned flags);
diff --git a/js/src/jscntxt.cpp b/js/src/jscntxt.cpp
index e505a4b34..23b9d27ae 100644
--- a/js/src/jscntxt.cpp
+++ b/js/src/jscntxt.cpp
@@ -37,7 +37,6 @@
#include "jsscript.h"
#include "jsstr.h"
#include "jstypes.h"
-#include "jswatchpoint.h"
#include "gc/Marking.h"
#include "jit/Ion.h"
diff --git a/js/src/jscompartment.cpp b/js/src/jscompartment.cpp
index d0caeb558..8ba186b08 100644
--- a/js/src/jscompartment.cpp
+++ b/js/src/jscompartment.cpp
@@ -13,7 +13,6 @@
#include "jsfriendapi.h"
#include "jsgc.h"
#include "jsiter.h"
-#include "jswatchpoint.h"
#include "jswrapper.h"
#include "gc/Marking.h"
@@ -76,7 +75,6 @@ JSCompartment::JSCompartment(Zone* zone, const JS::CompartmentOptions& options =
gcIncomingGrayPointers(nullptr),
debugModeBits(0),
randomKeyGenerator_(runtime_->forkRandomKeyGenerator()),
- watchpointMap(nullptr),
scriptCountsMap(nullptr),
debugScriptMap(nullptr),
debugEnvs(nullptr),
@@ -103,7 +101,6 @@ JSCompartment::~JSCompartment()
rt->lcovOutput.writeLCovResult(lcovOutput);
js_delete(jitCompartment_);
- js_delete(watchpointMap);
js_delete(scriptCountsMap);
js_delete(debugScriptMap);
js_delete(debugEnvs);
@@ -662,12 +659,6 @@ JSCompartment::traceRoots(JSTracer* trc, js::gc::GCRuntime::TraceOrMarkRuntime t
if (traceOrMark == js::gc::GCRuntime::MarkRuntime && !zone()->isCollecting())
return;
- // During a GC, these are treated as weak pointers.
- if (traceOrMark == js::gc::GCRuntime::TraceRuntime) {
- if (watchpointMap)
- watchpointMap->markAll(trc);
- }
-
/* Mark debug scopes, if present */
if (debugEnvs)
debugEnvs->mark(trc);
@@ -712,9 +703,6 @@ JSCompartment::traceRoots(JSTracer* trc, js::gc::GCRuntime::TraceOrMarkRuntime t
void
JSCompartment::finishRoots()
{
- if (watchpointMap)
- watchpointMap->clear();
-
if (debugEnvs)
debugEnvs->finish();
diff --git a/js/src/jscompartment.h b/js/src/jscompartment.h
index 83c15da3b..05ff40b43 100644
--- a/js/src/jscompartment.h
+++ b/js/src/jscompartment.h
@@ -282,7 +282,6 @@ class MOZ_RAII AutoSetNewObjectMetadata : private JS::CustomAutoRooter
namespace js {
class DebugEnvironments;
class ObjectWeakMap;
-class WatchpointMap;
class WeakMapBase;
} // namespace js
@@ -811,8 +810,6 @@ struct JSCompartment
void sweepBreakpoints(js::FreeOp* fop);
public:
- js::WatchpointMap* watchpointMap;
-
js::ScriptCountsMap* scriptCountsMap;
js::DebugScriptMap* debugScriptMap;
diff --git a/js/src/jsexn.cpp b/js/src/jsexn.cpp
index 65cc81a1a..3fc9200c1 100644
--- a/js/src/jsexn.cpp
+++ b/js/src/jsexn.cpp
@@ -205,7 +205,12 @@ size_t
ExtraMallocSize(JSErrorReport* report)
{
if (report->linebuf())
- return (report->linebufLength() + 1) * sizeof(char16_t);
+ /*
+ * Mozilla bug 1352449. Count with null
+ * terminator and alignment. See CopyExtraData for
+ * the details about alignment.
+ */
+ return (report->linebufLength() + 1) * sizeof(char16_t) + 1;
return 0;
}
@@ -220,10 +225,20 @@ bool
CopyExtraData(JSContext* cx, uint8_t** cursor, JSErrorReport* copy, JSErrorReport* report)
{
if (report->linebuf()) {
+ /*
+ * Make sure cursor is properly aligned for char16_t for platforms
+ * which need it and it's at the end of the buffer on exit.
+ */
+ size_t alignment_backlog = 0;
+ if (size_t(*cursor) % 2)
+ (*cursor)++;
+ else
+ alignment_backlog = 1;
+
size_t linebufSize = (report->linebufLength() + 1) * sizeof(char16_t);
const char16_t* linebufCopy = (const char16_t*)(*cursor);
js_memcpy(*cursor, report->linebuf(), linebufSize);
- *cursor += linebufSize;
+ *cursor += linebufSize + alignment_backlog;
copy->initBorrowedLinebuf(linebufCopy, report->linebufLength(), report->tokenOffset());
}
diff --git a/js/src/jsfriendapi.cpp b/js/src/jsfriendapi.cpp
index f7622cb44..bdb3c0a4d 100644
--- a/js/src/jsfriendapi.cpp
+++ b/js/src/jsfriendapi.cpp
@@ -15,7 +15,6 @@
#include "jsgc.h"
#include "jsobj.h"
#include "jsprf.h"
-#include "jswatchpoint.h"
#include "jsweakmap.h"
#include "jswrapper.h"
@@ -579,7 +578,6 @@ void
js::TraceWeakMaps(WeakMapTracer* trc)
{
WeakMapBase::traceAllMappings(trc);
- WatchpointMap::traceAll(trc);
}
extern JS_FRIEND_API(bool)
diff --git a/js/src/jsfriendapi.h b/js/src/jsfriendapi.h
index 351667fb3..491215456 100644
--- a/js/src/jsfriendapi.h
+++ b/js/src/jsfriendapi.h
@@ -2110,30 +2110,6 @@ JS_FRIEND_API(void*)
JS_GetDataViewData(JSObject* obj, const JS::AutoCheckCannotGC&);
namespace js {
-
-/**
- * Add a watchpoint -- in the Object.prototype.watch sense -- to |obj| for the
- * property |id|, using the callable object |callable| as the function to be
- * called for notifications.
- *
- * This is an internal function exposed -- temporarily -- only so that DOM
- * proxies can be watchable. Don't use it! We'll soon kill off the
- * Object.prototype.{,un}watch functions, at which point this will go too.
- */
-extern JS_FRIEND_API(bool)
-WatchGuts(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject callable);
-
-/**
- * Remove a watchpoint -- in the Object.prototype.watch sense -- from |obj| for
- * the property |id|.
- *
- * This is an internal function exposed -- temporarily -- only so that DOM
- * proxies can be watchable. Don't use it! We'll soon kill off the
- * Object.prototype.{,un}watch functions, at which point this will go too.
- */
-extern JS_FRIEND_API(bool)
-UnwatchGuts(JSContext* cx, JS::HandleObject obj, JS::HandleId id);
-
namespace jit {
enum class InlinableNative : uint16_t;
diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp
index b2ee8d67b..5a9d732b6 100644
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -207,7 +207,6 @@
#include "jsscript.h"
#include "jstypes.h"
#include "jsutil.h"
-#include "jswatchpoint.h"
#include "jsweakmap.h"
#ifdef XP_WIN
# include "jswin.h"
@@ -2392,11 +2391,6 @@ GCRuntime::updatePointersToRelocatedCells(Zone* zone, AutoLockForExclusiveAccess
Debugger::markIncomingCrossCompartmentEdges(&trc);
WeakMapBase::markAll(zone, &trc);
- for (CompartmentsInZoneIter c(zone); !c.done(); c.next()) {
- c->trace(&trc);
- if (c->watchpointMap)
- c->watchpointMap->markAll(&trc);
- }
// Mark all gray roots, making sure we call the trace callback to get the
// current set.
@@ -2405,7 +2399,6 @@ GCRuntime::updatePointersToRelocatedCells(Zone* zone, AutoLockForExclusiveAccess
}
// Sweep everything to fix up weak pointers
- WatchpointMap::sweepAll(rt);
Debugger::sweepAll(rt->defaultFreeOp());
jit::JitRuntime::SweepJitcodeGlobalTable(rt);
rt->gc.sweepZoneAfterCompacting(zone);
@@ -3850,10 +3843,6 @@ GCRuntime::markWeakReferences(gcstats::Phase phase)
for (ZoneIterT zone(rt); !zone.done(); zone.next())
markedAny |= WeakMapBase::markZoneIteratively(zone, &marker);
}
- for (CompartmentsIterT<ZoneIterT> c(rt); !c.done(); c.next()) {
- if (c->watchpointMap)
- markedAny |= c->watchpointMap->markIteratively(&marker);
- }
markedAny |= Debugger::markAllIteratively(&marker);
markedAny |= jit::JitRuntime::MarkJitcodeGlobalTableIteratively(&marker);
@@ -4625,9 +4614,6 @@ GCRuntime::beginSweepingZoneGroup(AutoLockForExclusiveAccess& lock)
// Bug 1071218: the following two methods have not yet been
// refactored to work on a single zone-group at once.
- // Collect watch points associated with unreachable objects.
- WatchpointMap::sweepAll(rt);
-
// Detach unreachable debuggers and global objects from each other.
Debugger::sweepAll(&fop);
diff --git a/js/src/jsiter.cpp b/js/src/jsiter.cpp
index 749e15d27..c4da86bdb 100644
--- a/js/src/jsiter.cpp
+++ b/js/src/jsiter.cpp
@@ -24,6 +24,7 @@
#include "jstypes.h"
#include "jsutil.h"
+#include "builtin/SelfHostingDefines.h"
#include "ds/Sort.h"
#include "gc/Marking.h"
#include "js/Proxy.h"
@@ -1135,16 +1136,36 @@ static const JSFunctionSpec string_iterator_methods[] = {
JS_FS_END
};
+static const Class RegExpStringIteratorPrototypeClass = {
+ "RegExp String Iterator",
+ 0
+};
+
enum {
- ListIteratorSlotIteratedObject,
- ListIteratorSlotNextIndex,
- ListIteratorSlotNextMethod,
- ListIteratorSlotCount
+ RegExpStringIteratorSlotRegExp,
+ RegExpStringIteratorSlotString,
+ RegExpStringIteratorSlotFlags,
+ RegExpStringIteratorSlotDone,
+ RegExpStringIteratorSlotCount
};
-const Class ListIteratorObject::class_ = {
- "List Iterator",
- JSCLASS_HAS_RESERVED_SLOTS(ListIteratorSlotCount)
+static_assert(RegExpStringIteratorSlotRegExp == REGEXP_STRING_ITERATOR_REGEXP_SLOT,
+ "RegExpStringIteratorSlotRegExp must match self-hosting define for regexp slot.");
+static_assert(RegExpStringIteratorSlotString == REGEXP_STRING_ITERATOR_STRING_SLOT,
+ "RegExpStringIteratorSlotString must match self-hosting define for string slot.");
+static_assert(RegExpStringIteratorSlotFlags == REGEXP_STRING_ITERATOR_FLAGS_SLOT,
+ "RegExpStringIteratorSlotFlags must match self-hosting define for flags slot.");
+static_assert(RegExpStringIteratorSlotDone == REGEXP_STRING_ITERATOR_DONE_SLOT,
+ "RegExpStringIteratorSlotDone must match self-hosting define for done slot.");
+
+const Class RegExpStringIteratorObject::class_ = {
+ "RegExp String Iterator",
+ JSCLASS_HAS_RESERVED_SLOTS(RegExpStringIteratorSlotCount)
+};
+
+static const JSFunctionSpec regexp_string_iterator_methods[] = {
+ JS_SELF_HOSTED_FN("next", "RegExpStringIteratorNext", 0, 0),
+ JS_FS_END
};
JSObject*
@@ -1553,6 +1574,30 @@ GlobalObject::initStringIteratorProto(JSContext* cx, Handle<GlobalObject*> globa
return true;
}
+/* static */ bool
+GlobalObject::initRegExpStringIteratorProto(JSContext* cx, Handle<GlobalObject*> global)
+{
+ if (global->getReservedSlot(REGEXP_STRING_ITERATOR_PROTO).isObject())
+ return true;
+
+ RootedObject iteratorProto(cx, GlobalObject::getOrCreateIteratorPrototype(cx, global));
+ if (!iteratorProto)
+ return false;
+
+ const Class* cls = &RegExpStringIteratorPrototypeClass;
+ RootedObject proto(cx, GlobalObject::createBlankPrototypeInheriting(cx, global, cls,
+ iteratorProto));
+ if (!proto ||
+ !DefinePropertiesAndFunctions(cx, proto, nullptr, regexp_string_iterator_methods) ||
+ !DefineToStringTag(cx, proto, cx->names().RegExpStringIterator))
+ {
+ return false;
+ }
+
+ global->setReservedSlot(REGEXP_STRING_ITERATOR_PROTO, ObjectValue(*proto));
+ return true;
+}
+
JSObject*
js::InitLegacyIteratorClass(JSContext* cx, HandleObject obj)
{
diff --git a/js/src/jsiter.h b/js/src/jsiter.h
index f11f09b55..52eb045c5 100644
--- a/js/src/jsiter.h
+++ b/js/src/jsiter.h
@@ -151,7 +151,7 @@ class StringIteratorObject : public JSObject
static const Class class_;
};
-class ListIteratorObject : public JSObject
+class RegExpStringIteratorObject : public JSObject
{
public:
static const Class class_;
diff --git a/js/src/jsnativestack.cpp b/js/src/jsnativestack.cpp
index 94a296bd0..4e96e01e8 100644
--- a/js/src/jsnativestack.cpp
+++ b/js/src/jsnativestack.cpp
@@ -67,6 +67,20 @@ js::GetNativeStackBaseImpl()
# endif
}
+#elif defined(XP_SOLARIS)
+
+#include <ucontext.h>
+
+JS_STATIC_ASSERT(JS_STACK_GROWTH_DIRECTION < 0);
+
+void*
+js::GetNativeStackBaseImpl()
+{
+ stack_t st;
+ stack_getbounds(&st);
+ return static_cast<char*>(st.ss_sp) + st.ss_size;
+}
+
#elif defined(XP_LINUX) && !defined(ANDROID) && defined(__GLIBC__)
void*
js::GetNativeStackBaseImpl()
diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp
index 6f9596924..ef1291079 100644
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -33,7 +33,6 @@
#include "jsstr.h"
#include "jstypes.h"
#include "jsutil.h"
-#include "jswatchpoint.h"
#include "jswin.h"
#include "jswrapper.h"
@@ -1011,13 +1010,7 @@ js::CreateThisForFunction(JSContext* cx, HandleObject callee, HandleObject newTa
JSObject::nonNativeSetProperty(JSContext* cx, HandleObject obj, HandleId id, HandleValue v,
HandleValue receiver, ObjectOpResult& result)
{
- RootedValue value(cx, v);
- if (MOZ_UNLIKELY(obj->watched())) {
- WatchpointMap* wpmap = cx->compartment()->watchpointMap;
- if (wpmap && !wpmap->triggerWatchpoint(cx, obj, id, &value))
- return false;
- }
- return obj->getOpsSetProperty()(cx, obj, id, value, receiver, result);
+ return obj->getOpsSetProperty()(cx, obj, id, v, receiver, result);
}
/* static */ bool
@@ -2795,68 +2788,6 @@ js::GetPropertyDescriptor(JSContext* cx, HandleObject obj, HandleId id,
return true;
}
-bool
-js::WatchGuts(JSContext* cx, JS::HandleObject origObj, JS::HandleId id, JS::HandleObject callable)
-{
- RootedObject obj(cx, ToWindowIfWindowProxy(origObj));
- if (obj->isNative()) {
- // Use sparse indexes for watched objects, as dense elements can be
- // written to without checking the watchpoint map.
- if (!NativeObject::sparsifyDenseElements(cx, obj.as<NativeObject>()))
- return false;
-
- MarkTypePropertyNonData(cx, obj, id);
- }
-
- WatchpointMap* wpmap = cx->compartment()->watchpointMap;
- if (!wpmap) {
- wpmap = cx->runtime()->new_<WatchpointMap>();
- if (!wpmap || !wpmap->init()) {
- ReportOutOfMemory(cx);
- js_delete(wpmap);
- return false;
- }
- cx->compartment()->watchpointMap = wpmap;
- }
-
- return wpmap->watch(cx, obj, id, js::WatchHandler, callable);
-}
-
-bool
-js::UnwatchGuts(JSContext* cx, JS::HandleObject origObj, JS::HandleId id)
-{
- // Looking in the map for an unsupported object will never hit, so we don't
- // need to check for nativeness or watchable-ness here.
- RootedObject obj(cx, ToWindowIfWindowProxy(origObj));
- if (WatchpointMap* wpmap = cx->compartment()->watchpointMap)
- wpmap->unwatch(obj, id, nullptr, nullptr);
- return true;
-}
-
-bool
-js::WatchProperty(JSContext* cx, HandleObject obj, HandleId id, HandleObject callable)
-{
- if (WatchOp op = obj->getOpsWatch())
- return op(cx, obj, id, callable);
-
- if (!obj->isNative() || obj->is<TypedArrayObject>()) {
- JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_CANT_WATCH,
- obj->getClass()->name);
- return false;
- }
-
- return WatchGuts(cx, obj, id, callable);
-}
-
-bool
-js::UnwatchProperty(JSContext* cx, HandleObject obj, HandleId id)
-{
- if (UnwatchOp op = obj->getOpsUnwatch())
- return op(cx, obj, id);
-
- return UnwatchGuts(cx, obj, id);
-}
-
const char*
js::GetObjectClassName(JSContext* cx, HandleObject obj)
{
@@ -3416,7 +3347,6 @@ JSObject::dump(FILE* fp) const
if (obj->isBoundFunction()) fprintf(fp, " bound_function");
if (obj->isQualifiedVarObj()) fprintf(fp, " varobj");
if (obj->isUnqualifiedVarObj()) fprintf(fp, " unqualified_varobj");
- if (obj->watched()) fprintf(fp, " watched");
if (obj->isIteratedSingleton()) fprintf(fp, " iterated_singleton");
if (obj->isNewGroupUnknown()) fprintf(fp, " new_type_unknown");
if (obj->hasUncacheableProto()) fprintf(fp, " has_uncacheable_proto");
diff --git a/js/src/jsobj.h b/js/src/jsobj.h
index db2c22b76..01845d7e6 100644
--- a/js/src/jsobj.h
+++ b/js/src/jsobj.h
@@ -141,8 +141,6 @@ class JSObject : public js::gc::Cell
js::GetOwnPropertyOp getOpsGetOwnPropertyDescriptor()
const { return getClass()->getOpsGetOwnPropertyDescriptor(); }
js::DeletePropertyOp getOpsDeleteProperty() const { return getClass()->getOpsDeleteProperty(); }
- js::WatchOp getOpsWatch() const { return getClass()->getOpsWatch(); }
- js::UnwatchOp getOpsUnwatch() const { return getClass()->getOpsUnwatch(); }
js::GetElementsOp getOpsGetElements() const { return getClass()->getOpsGetElements(); }
JSNewEnumerateOp getOpsEnumerate() const { return getClass()->getOpsEnumerate(); }
JSFunToStringOp getOpsFunToString() const { return getClass()->getOpsFunToString(); }
@@ -221,11 +219,6 @@ class JSObject : public js::gc::Cell
inline bool isBoundFunction() const;
inline bool hasSpecialEquality() const;
- inline bool watched() const;
- static bool setWatched(js::ExclusiveContext* cx, JS::HandleObject obj) {
- return setFlags(cx, obj, js::BaseShape::WATCHED, GENERATE_SHAPE);
- }
-
// A "qualified" varobj is the object on which "qualified" variable
// declarations (i.e., those defined with "var") are kept.
//
@@ -1032,21 +1025,6 @@ extern bool
DefineFunctions(JSContext* cx, HandleObject obj, const JSFunctionSpec* fs,
DefineAsIntrinsic intrinsic);
-/*
- * Set a watchpoint: a synchronous callback when the given property of the
- * given object is set.
- *
- * Watchpoints are nonstandard and do not fit in well with the way ES6
- * specifies [[Set]]. They are also insufficient for implementing
- * Object.observe.
- */
-extern bool
-WatchProperty(JSContext* cx, HandleObject obj, HandleId id, HandleObject callable);
-
-/* Clear a watchpoint. */
-extern bool
-UnwatchProperty(JSContext* cx, HandleObject obj, HandleId id);
-
/* ES6 draft rev 36 (2015 March 17) 7.1.1 ToPrimitive(vp[, preferredType]) */
extern bool
ToPrimitiveSlow(JSContext* cx, JSType hint, MutableHandleValue vp);
diff --git a/js/src/jsobjinlines.h b/js/src/jsobjinlines.h
index c132ee6b2..98e740142 100644
--- a/js/src/jsobjinlines.h
+++ b/js/src/jsobjinlines.h
@@ -464,12 +464,6 @@ JSObject::isBoundFunction() const
}
inline bool
-JSObject::watched() const
-{
- return hasAllFlags(js::BaseShape::WATCHED);
-}
-
-inline bool
JSObject::isDelegate() const
{
return hasAllFlags(js::BaseShape::DELEGATE);
diff --git a/js/src/jsstr.cpp b/js/src/jsstr.cpp
index 74f61b87d..3964ab84e 100644
--- a/js/src/jsstr.cpp
+++ b/js/src/jsstr.cpp
@@ -2584,6 +2584,7 @@ static const JSFunctionSpec string_methods[] = {
/* Perl-ish methods (search is actually Python-esque). */
JS_SELF_HOSTED_FN("match", "String_match", 1,0),
+ JS_SELF_HOSTED_FN("matchAll", "String_matchAll", 1,0),
JS_SELF_HOSTED_FN("search", "String_search", 1,0),
JS_SELF_HOSTED_FN("replace", "String_replace", 2,0),
JS_SELF_HOSTED_FN("split", "String_split", 2,0),
diff --git a/js/src/jsversion.h b/js/src/jsversion.h
index 8bdfe47b6..cf4c6e73a 100644
--- a/js/src/jsversion.h
+++ b/js/src/jsversion.h
@@ -12,7 +12,6 @@
*/
#define JS_HAS_STR_HTML_HELPERS 1 /* (no longer used) */
#define JS_HAS_OBJ_PROTO_PROP 1 /* has o.__proto__ etc. */
-#define JS_HAS_OBJ_WATCHPOINT 1 /* has o.watch and o.unwatch */
#define JS_HAS_TOSOURCE 1 /* has Object/Array toSource method */
#define JS_HAS_CATCH_GUARD 1 /* has exception handling catch guard */
#define JS_HAS_UNEVAL 1 /* has uneval() top-level function */
diff --git a/js/src/jswatchpoint.cpp b/js/src/jswatchpoint.cpp
deleted file mode 100644
index 34479a990..000000000
--- a/js/src/jswatchpoint.cpp
+++ /dev/null
@@ -1,246 +0,0 @@
-/* -*- 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/. */
-
-#include "jswatchpoint.h"
-
-#include "jsatom.h"
-#include "jscompartment.h"
-#include "jsfriendapi.h"
-
-#include "gc/Marking.h"
-#include "vm/Shape.h"
-
-#include "jsgcinlines.h"
-
-using namespace js;
-using namespace js::gc;
-
-inline HashNumber
-WatchKeyHasher::hash(const Lookup& key)
-{
- return MovableCellHasher<PreBarrieredObject>::hash(key.object) ^ HashId(key.id);
-}
-
-namespace {
-
-class AutoEntryHolder {
- typedef WatchpointMap::Map Map;
- Generation gen;
- Map& map;
- Map::Ptr p;
- RootedObject obj;
- RootedId id;
-
- public:
- AutoEntryHolder(JSContext* cx, Map& map, Map::Ptr p)
- : gen(map.generation()), map(map), p(p), obj(cx, p->key().object), id(cx, p->key().id)
- {
- MOZ_ASSERT(!p->value().held);
- p->value().held = true;
- }
-
- ~AutoEntryHolder() {
- if (gen != map.generation())
- p = map.lookup(WatchKey(obj, id));
- if (p)
- p->value().held = false;
- }
-};
-
-} /* anonymous namespace */
-
-bool
-WatchpointMap::init()
-{
- return map.init();
-}
-
-bool
-WatchpointMap::watch(JSContext* cx, HandleObject obj, HandleId id,
- JSWatchPointHandler handler, HandleObject closure)
-{
- MOZ_ASSERT(JSID_IS_STRING(id) || JSID_IS_INT(id) || JSID_IS_SYMBOL(id));
-
- if (!JSObject::setWatched(cx, obj))
- return false;
-
- Watchpoint w(handler, closure, false);
- if (!map.put(WatchKey(obj, id), w)) {
- ReportOutOfMemory(cx);
- return false;
- }
- /*
- * For generational GC, we don't need to post-barrier writes to the
- * hashtable here because we mark all watchpoints as part of root marking in
- * markAll().
- */
- return true;
-}
-
-void
-WatchpointMap::unwatch(JSObject* obj, jsid id,
- JSWatchPointHandler* handlerp, JSObject** closurep)
-{
- if (Map::Ptr p = map.lookup(WatchKey(obj, id))) {
- if (handlerp)
- *handlerp = p->value().handler;
- if (closurep) {
- // Read barrier to prevent an incorrectly gray closure from escaping the
- // watchpoint. See the comment before UnmarkGrayChildren in gc/Marking.cpp
- JS::ExposeObjectToActiveJS(p->value().closure);
- *closurep = p->value().closure;
- }
- map.remove(p);
- }
-}
-
-void
-WatchpointMap::unwatchObject(JSObject* obj)
-{
- for (Map::Enum e(map); !e.empty(); e.popFront()) {
- Map::Entry& entry = e.front();
- if (entry.key().object == obj)
- e.removeFront();
- }
-}
-
-void
-WatchpointMap::clear()
-{
- map.clear();
-}
-
-bool
-WatchpointMap::triggerWatchpoint(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue vp)
-{
- Map::Ptr p = map.lookup(WatchKey(obj, id));
- if (!p || p->value().held)
- return true;
-
- AutoEntryHolder holder(cx, map, p);
-
- /* Copy the entry, since GC would invalidate p. */
- JSWatchPointHandler handler = p->value().handler;
- RootedObject closure(cx, p->value().closure);
-
- /* Determine the property's old value. */
- Value old;
- old.setUndefined();
- if (obj->isNative()) {
- NativeObject* nobj = &obj->as<NativeObject>();
- if (Shape* shape = nobj->lookup(cx, id)) {
- if (shape->hasSlot())
- old = nobj->getSlot(shape->slot());
- }
- }
-
- // Read barrier to prevent an incorrectly gray closure from escaping the
- // watchpoint. See the comment before UnmarkGrayChildren in gc/Marking.cpp
- JS::ExposeObjectToActiveJS(closure);
-
- /* Call the handler. */
- return handler(cx, obj, id, old, vp.address(), closure);
-}
-
-bool
-WatchpointMap::markIteratively(JSTracer* trc)
-{
- bool marked = false;
- for (Map::Enum e(map); !e.empty(); e.popFront()) {
- Map::Entry& entry = e.front();
- JSObject* priorKeyObj = entry.key().object;
- jsid priorKeyId(entry.key().id.get());
- bool objectIsLive =
- IsMarked(trc->runtime(), const_cast<PreBarrieredObject*>(&entry.key().object));
- if (objectIsLive || entry.value().held) {
- if (!objectIsLive) {
- TraceEdge(trc, const_cast<PreBarrieredObject*>(&entry.key().object),
- "held Watchpoint object");
- marked = true;
- }
-
- MOZ_ASSERT(JSID_IS_STRING(priorKeyId) ||
- JSID_IS_INT(priorKeyId) ||
- JSID_IS_SYMBOL(priorKeyId));
- TraceEdge(trc, const_cast<PreBarrieredId*>(&entry.key().id), "WatchKey::id");
-
- if (entry.value().closure && !IsMarked(trc->runtime(), &entry.value().closure)) {
- TraceEdge(trc, &entry.value().closure, "Watchpoint::closure");
- marked = true;
- }
-
- /* We will sweep this entry in sweepAll if !objectIsLive. */
- if (priorKeyObj != entry.key().object || priorKeyId != entry.key().id)
- e.rekeyFront(WatchKey(entry.key().object, entry.key().id));
- }
- }
- return marked;
-}
-
-void
-WatchpointMap::markAll(JSTracer* trc)
-{
- for (Map::Enum e(map); !e.empty(); e.popFront()) {
- Map::Entry& entry = e.front();
- JSObject* object = entry.key().object;
- jsid id = entry.key().id;
- JSObject* priorObject = object;
- jsid priorId = id;
- MOZ_ASSERT(JSID_IS_STRING(priorId) || JSID_IS_INT(priorId) || JSID_IS_SYMBOL(priorId));
-
- TraceManuallyBarrieredEdge(trc, &object, "held Watchpoint object");
- TraceManuallyBarrieredEdge(trc, &id, "WatchKey::id");
- TraceEdge(trc, &entry.value().closure, "Watchpoint::closure");
-
- if (priorObject != object || priorId != id)
- e.rekeyFront(WatchKey(object, id));
- }
-}
-
-void
-WatchpointMap::sweepAll(JSRuntime* rt)
-{
- for (GCCompartmentsIter c(rt); !c.done(); c.next()) {
- if (WatchpointMap* wpmap = c->watchpointMap)
- wpmap->sweep();
- }
-}
-
-void
-WatchpointMap::sweep()
-{
- for (Map::Enum e(map); !e.empty(); e.popFront()) {
- Map::Entry& entry = e.front();
- JSObject* obj(entry.key().object);
- if (IsAboutToBeFinalizedUnbarriered(&obj)) {
- MOZ_ASSERT(!entry.value().held);
- e.removeFront();
- } else if (obj != entry.key().object) {
- e.rekeyFront(WatchKey(obj, entry.key().id));
- }
- }
-}
-
-void
-WatchpointMap::traceAll(WeakMapTracer* trc)
-{
- JSRuntime* rt = trc->context;
- for (CompartmentsIter comp(rt, SkipAtoms); !comp.done(); comp.next()) {
- if (WatchpointMap* wpmap = comp->watchpointMap)
- wpmap->trace(trc);
- }
-}
-
-void
-WatchpointMap::trace(WeakMapTracer* trc)
-{
- for (Map::Range r = map.all(); !r.empty(); r.popFront()) {
- Map::Entry& entry = r.front();
- trc->trace(nullptr,
- JS::GCCellPtr(entry.key().object.get()),
- JS::GCCellPtr(entry.value().closure.get()));
- }
-}
diff --git a/js/src/jswatchpoint.h b/js/src/jswatchpoint.h
deleted file mode 100644
index bba6c38ce..000000000
--- a/js/src/jswatchpoint.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/* -*- 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 jswatchpoint_h
-#define jswatchpoint_h
-
-#include "jsalloc.h"
-
-#include "gc/Barrier.h"
-#include "js/HashTable.h"
-
-namespace js {
-
-struct WeakMapTracer;
-
-struct WatchKey {
- WatchKey() {}
- WatchKey(JSObject* obj, jsid id) : object(obj), id(id) {}
- WatchKey(const WatchKey& key) : object(key.object.get()), id(key.id.get()) {}
-
- // These are traced unconditionally during minor GC, so do not require
- // post-barriers.
- PreBarrieredObject object;
- PreBarrieredId id;
-
- bool operator!=(const WatchKey& other) const {
- return object != other.object || id != other.id;
- }
-};
-
-typedef bool
-(* JSWatchPointHandler)(JSContext* cx, JSObject* obj, jsid id, const JS::Value& old,
- JS::Value* newp, void* closure);
-
-struct Watchpoint {
- JSWatchPointHandler handler;
- PreBarrieredObject closure; /* This is always marked in minor GCs and so doesn't require a postbarrier. */
- bool held; /* true if currently running handler */
- Watchpoint(JSWatchPointHandler handler, JSObject* closure, bool held)
- : handler(handler), closure(closure), held(held) {}
-};
-
-struct WatchKeyHasher
-{
- typedef WatchKey Lookup;
- static inline js::HashNumber hash(const Lookup& key);
-
- static bool match(const WatchKey& k, const Lookup& l) {
- return MovableCellHasher<PreBarrieredObject>::match(k.object, l.object) &&
- DefaultHasher<PreBarrieredId>::match(k.id, l.id);
- }
-
- static void rekey(WatchKey& k, const WatchKey& newKey) {
- k.object.unsafeSet(newKey.object);
- k.id.unsafeSet(newKey.id);
- }
-};
-
-class WatchpointMap {
- public:
- typedef HashMap<WatchKey, Watchpoint, WatchKeyHasher, SystemAllocPolicy> Map;
-
- bool init();
- bool watch(JSContext* cx, HandleObject obj, HandleId id,
- JSWatchPointHandler handler, HandleObject closure);
- void unwatch(JSObject* obj, jsid id,
- JSWatchPointHandler* handlerp, JSObject** closurep);
- void unwatchObject(JSObject* obj);
- void clear();
-
- bool triggerWatchpoint(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue vp);
-
- bool markIteratively(JSTracer* trc);
- void markAll(JSTracer* trc);
- static void sweepAll(JSRuntime* rt);
- void sweep();
-
- static void traceAll(WeakMapTracer* trc);
- void trace(WeakMapTracer* trc);
-
- private:
- Map map;
-};
-
-} // namespace js
-
-#endif /* jswatchpoint_h */
diff --git a/js/src/jswrapper.h b/js/src/jswrapper.h
index 5f3704e32..32336c68b 100644
--- a/js/src/jswrapper.h
+++ b/js/src/jswrapper.h
@@ -315,13 +315,6 @@ class JS_FRIEND_API(SecurityWrapper) : public Base
virtual bool regexp_toShared(JSContext* cx, HandleObject proxy, RegExpGuard* g) const override;
virtual bool boxedValue_unbox(JSContext* cx, HandleObject proxy, MutableHandleValue vp) const override;
- // Allow isCallable and isConstructor. They used to be class-level, and so could not be guarded
- // against.
-
- virtual bool watch(JSContext* cx, JS::HandleObject proxy, JS::HandleId id,
- JS::HandleObject callable) const override;
- virtual bool unwatch(JSContext* cx, JS::HandleObject proxy, JS::HandleId id) const override;
-
/*
* Allow our subclasses to select the superclass behavior they want without
* needing to specify an exact superclass.
diff --git a/js/src/moz.build b/js/src/moz.build
index a0f074d1c..d1e80b4ce 100644
--- a/js/src/moz.build
+++ b/js/src/moz.build
@@ -291,7 +291,6 @@ UNIFIED_SOURCES += [
'jspropertytree.cpp',
'jsscript.cpp',
'jsstr.cpp',
- 'jswatchpoint.cpp',
'jsweakmap.cpp',
'perf/jsperf.cpp',
'proxy/BaseProxyHandler.cpp',
@@ -721,6 +720,14 @@ if CONFIG['OS_ARCH'] == 'Linux':
'dl',
]
+if CONFIG['OS_ARCH'] == 'SunOS':
+ OS_LIBS += [
+ 'posix4',
+ 'dl',
+ 'nsl',
+ 'socket',
+ ]
+
OS_LIBS += CONFIG['REALTIME_LIBS']
CFLAGS += CONFIG['MOZ_ICU_CFLAGS']
diff --git a/js/src/old-configure.in b/js/src/old-configure.in
index 45108ee59..6566ce05e 100644
--- a/js/src/old-configure.in
+++ b/js/src/old-configure.in
@@ -923,6 +923,14 @@ case "$target" in
fi
;;
+i*86-*-solaris*)
+ MOZ_FIX_LINK_PATHS="-L${DIST}/bin -R'\$\$ORIGIN':/usr/gcc/7/lib"
+ ;;
+
+x86_64-*-solaris*)
+ MOZ_FIX_LINK_PATHS="-L${DIST}/bin -R'\$\$ORIGIN':/usr/gcc/7/lib/amd64"
+ ;;
+
esac
dnl Only one oddball right now (QNX), but this gives us flexibility
diff --git a/js/src/proxy/BaseProxyHandler.cpp b/js/src/proxy/BaseProxyHandler.cpp
index 8d5f30a19..423aa8671 100644
--- a/js/src/proxy/BaseProxyHandler.cpp
+++ b/js/src/proxy/BaseProxyHandler.cpp
@@ -419,20 +419,6 @@ BaseProxyHandler::setImmutablePrototype(JSContext* cx, HandleObject proxy, bool*
}
bool
-BaseProxyHandler::watch(JSContext* cx, HandleObject proxy, HandleId id, HandleObject callable) const
-{
- JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_CANT_WATCH,
- proxy->getClass()->name);
- return false;
-}
-
-bool
-BaseProxyHandler::unwatch(JSContext* cx, HandleObject proxy, HandleId id) const
-{
- return true;
-}
-
-bool
BaseProxyHandler::getElements(JSContext* cx, HandleObject proxy, uint32_t begin, uint32_t end,
ElementAdder* adder) const
{
diff --git a/js/src/proxy/Proxy.cpp b/js/src/proxy/Proxy.cpp
index 2c1cffb77..6b3a3d1e9 100644
--- a/js/src/proxy/Proxy.cpp
+++ b/js/src/proxy/Proxy.cpp
@@ -505,20 +505,6 @@ Proxy::boxedValue_unbox(JSContext* cx, HandleObject proxy, MutableHandleValue vp
JSObject * const TaggedProto::LazyProto = reinterpret_cast<JSObject*>(0x1);
/* static */ bool
-Proxy::watch(JSContext* cx, JS::HandleObject proxy, JS::HandleId id, JS::HandleObject callable)
-{
- JS_CHECK_RECURSION(cx, return false);
- return proxy->as<ProxyObject>().handler()->watch(cx, proxy, id, callable);
-}
-
-/* static */ bool
-Proxy::unwatch(JSContext* cx, JS::HandleObject proxy, JS::HandleId id)
-{
- JS_CHECK_RECURSION(cx, return false);
- return proxy->as<ProxyObject>().handler()->unwatch(cx, proxy, id);
-}
-
-/* static */ bool
Proxy::getElements(JSContext* cx, HandleObject proxy, uint32_t begin, uint32_t end,
ElementAdder* adder)
{
@@ -699,18 +685,6 @@ js::proxy_Construct(JSContext* cx, unsigned argc, Value* vp)
}
bool
-js::proxy_Watch(JSContext* cx, HandleObject obj, HandleId id, HandleObject callable)
-{
- return Proxy::watch(cx, obj, id, callable);
-}
-
-bool
-js::proxy_Unwatch(JSContext* cx, HandleObject obj, HandleId id)
-{
- return Proxy::unwatch(cx, obj, id);
-}
-
-bool
js::proxy_GetElements(JSContext* cx, HandleObject proxy, uint32_t begin, uint32_t end,
ElementAdder* adder)
{
@@ -750,7 +724,6 @@ const ObjectOps js::ProxyObjectOps = {
js::proxy_SetProperty,
js::proxy_GetOwnPropertyDescriptor,
js::proxy_DeleteProperty,
- js::proxy_Watch, js::proxy_Unwatch,
js::proxy_GetElements,
nullptr, /* enumerate */
js::proxy_FunToString
diff --git a/js/src/proxy/Proxy.h b/js/src/proxy/Proxy.h
index 89909a085..4a8ecf8ab 100644
--- a/js/src/proxy/Proxy.h
+++ b/js/src/proxy/Proxy.h
@@ -65,9 +65,6 @@ class Proxy
static bool regexp_toShared(JSContext* cx, HandleObject proxy, RegExpGuard* g);
static bool boxedValue_unbox(JSContext* cx, HandleObject proxy, MutableHandleValue vp);
- static bool watch(JSContext* cx, HandleObject proxy, HandleId id, HandleObject callable);
- static bool unwatch(JSContext* cx, HandleObject proxy, HandleId id);
-
static bool getElements(JSContext* cx, HandleObject obj, uint32_t begin, uint32_t end,
ElementAdder* adder);
diff --git a/js/src/proxy/SecurityWrapper.cpp b/js/src/proxy/SecurityWrapper.cpp
index 710faf9b0..71d22fca6 100644
--- a/js/src/proxy/SecurityWrapper.cpp
+++ b/js/src/proxy/SecurityWrapper.cpp
@@ -130,24 +130,5 @@ SecurityWrapper<Base>::defineProperty(JSContext* cx, HandleObject wrapper, Handl
return Base::defineProperty(cx, wrapper, id, desc, result);
}
-template <class Base>
-bool
-SecurityWrapper<Base>::watch(JSContext* cx, HandleObject proxy,
- HandleId id, HandleObject callable) const
-{
- ReportUnwrapDenied(cx);
- return false;
-}
-
-template <class Base>
-bool
-SecurityWrapper<Base>::unwatch(JSContext* cx, HandleObject proxy,
- HandleId id) const
-{
- ReportUnwrapDenied(cx);
- return false;
-}
-
-
template class js::SecurityWrapper<Wrapper>;
template class js::SecurityWrapper<CrossCompartmentWrapper>;
diff --git a/js/src/shell/OSObject.cpp b/js/src/shell/OSObject.cpp
index 846ec7b15..4fb3d4e77 100644
--- a/js/src/shell/OSObject.cpp
+++ b/js/src/shell/OSObject.cpp
@@ -184,6 +184,11 @@ FileAsTypedArray(JSContext* cx, JS::HandleString pathnameStr)
return nullptr;
JS_ReportErrorUTF8(cx, "can't seek start of %s", pathname.ptr());
} else {
+ if (len > INT32_MAX) {
+ JS_ReportErrorUTF8(cx, "file %s is too large for a Uint8Array",
+ pathname.ptr());
+ return nullptr;
+ }
obj = JS_NewUint8Array(cx, len);
if (!obj)
return nullptr;
diff --git a/js/src/tests/ecma_5/Array/frozen-dense-array.js b/js/src/tests/ecma_5/Array/frozen-dense-array.js
index 9db63036f..cdb86daa3 100644
--- a/js/src/tests/ecma_5/Array/frozen-dense-array.js
+++ b/js/src/tests/ecma_5/Array/frozen-dense-array.js
@@ -38,24 +38,5 @@ assertEq(delete a[0], false);
assertArrayIsExpected();
-var watchpointCalled = false;
-// NOTE: Be careful with the position of this test, since this sparsifies the
-// elements and you might not test what you think you're testing otherwise.
-a.watch(2, function(prop, oldValue, newValue) {
- watchpointCalled = true;
- assertEq(prop, 2);
- assertEq(oldValue, 1);
- assertEq(newValue, "foo");
-});
-
-assertArrayIsExpected();
-
-a.length = 5;
-a[2] = "foo";
-assertEq(watchpointCalled, true);
-assertEq(delete a[0], false);
-
-assertArrayIsExpected();
-
if (typeof reportCompare === "function")
reportCompare(true, true);
diff --git a/js/src/tests/ecma_5/extensions/watch-array-length.js b/js/src/tests/ecma_5/extensions/watch-array-length.js
deleted file mode 100644
index e9b356efa..000000000
--- a/js/src/tests/ecma_5/extensions/watch-array-length.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/licenses/publicdomain/
- */
-
-var hitCount;
-function watcher(p,o,n) { hitCount++; return n; }
-
-var a = [1];
-a.watch('length', watcher);
-hitCount = 0;
-a.length = 0;
-reportCompare(1, hitCount, "lenient; configurable: watchpoint hit");
-
-var b = Object.defineProperty([1],'0',{configurable:false});
-b.watch('length', watcher);
-hitCount = 0;
-var result;
-try {
- b.length = 0;
- result = "no error";
-} catch (x) {
- result = x.toString();
-}
-reportCompare(1, hitCount, "lenient; non-configurable: watchpoint hit");
-reportCompare(1, b.length, "lenient; non-configurable: length unchanged");
-reportCompare("no error", result, "lenient; non-configurable: no error thrown");
-
-var c = Object.defineProperty([1],'0',{configurable:false});
-c.watch('length', watcher);
-hitCount = 0;
-var threwTypeError;
-try {
- (function(){'use strict'; c.length = 0;})();
- threwTypeError = false;
-} catch (x) {
- threwTypeError = x instanceof TypeError;
-}
-reportCompare(1, hitCount, "strict; non-configurable: watchpoint hit");
-reportCompare(1, c.length, "strict; non-configurable: length unchanged");
-reportCompare(true, threwTypeError, "strict; non-configurable: TypeError thrown");
diff --git a/js/src/tests/ecma_5/extensions/watch-inherited-property.js b/js/src/tests/ecma_5/extensions/watch-inherited-property.js
deleted file mode 100644
index 1a0ad566b..000000000
--- a/js/src/tests/ecma_5/extensions/watch-inherited-property.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/licenses/publicdomain/
- */
-
-/* Create a prototype object with a setter property. */
-var protoSetterCount;
-var proto = ({ set x(v) { protoSetterCount++; } });
-
-/* Put a watchpoint on that setter. */
-var protoWatchCount;
-proto.watch('x', function() { protoWatchCount++; });
-
-/* Make an object with the above as its prototype. */
-function C() { }
-C.prototype = proto;
-var o = new C();
-
-/*
- * Set a watchpoint on the property in the inheriting object. We have
- * defined this to mean "duplicate the property, setter and all, in the
- * inheriting object." I don't think debugging observation mechanisms
- * should mutate the program being run, but that's what we've got.
- */
-var oWatchCount;
-o.watch('x', function() { oWatchCount++; });
-
-/*
- * Assign to the property. This should trip the watchpoint on the inheriting object and
- * the setter.
- */
-protoSetterCount = protoWatchCount = oWatchCount = 0;
-o.x = 1;
-assertEq(protoWatchCount, 0);
-assertEq(oWatchCount, 1);
-assertEq(protoSetterCount, 1);
-
-reportCompare(true, true);
diff --git a/js/src/tests/ecma_5/extensions/watch-replaced-setter.js b/js/src/tests/ecma_5/extensions/watch-replaced-setter.js
deleted file mode 100644
index 05cf60aff..000000000
--- a/js/src/tests/ecma_5/extensions/watch-replaced-setter.js
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/licenses/publicdomain/
- */
-
-/* A stock watcher function. */
-var watcherCount;
-function watcher(id, oldval, newval) { watcherCount++; return newval; }
-
-/* Create an object with a JavaScript setter. */
-var setterCount;
-var o = { w:2, set x(v) { setterCount++; } };
-
-/*
- * Put the object in dictionary mode, so that JSObject::putProperty will
- * mutate its shapes instead of creating new ones.
- */
-delete o.w;
-
-/*
- * Place a watchpoint on the property. The watchpoint structure holds the
- * original JavaScript setter, and a pointer to the shape.
- */
-o.watch('x', watcher);
-
-/*
- * Replace the accessor property with a value property. The shape's setter
- * should become a non-JS setter, js_watch_set, and the watchpoint
- * structure's saved setter should be updated (in this case, cleared).
- */
-Object.defineProperty(o, 'x', { value:3,
- writable:true,
- enumerable:true,
- configurable:true });
-
-/*
- * Assign to the property. This should trigger js_watch_set, which should
- * call the handler, and then see that there is no JS-level setter to pass
- * control on to, and return.
- */
-watcherCount = setterCount = 0;
-o.x = 3;
-assertEq(watcherCount, 1);
-assertEq(setterCount, 0);
-
-reportCompare(true, true);
diff --git a/js/src/tests/ecma_5/extensions/watch-setter-become-setter.js b/js/src/tests/ecma_5/extensions/watch-setter-become-setter.js
deleted file mode 100644
index f5eff98b8..000000000
--- a/js/src/tests/ecma_5/extensions/watch-setter-become-setter.js
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/licenses/publicdomain/
- */
-
-/* Create an object with a JavaScript setter. */
-var firstSetterCount;
-var o = { w:2, set x(v) { firstSetterCount++; } };
-
-/*
- * Put the object in dictionary mode, so that JSObject::putProperty will
- * mutate its shapes instead of creating new ones.
- */
-delete o.w;
-
-/* A stock watcher function. */
-var watcherCount;
-function watcher(id, oldval, newval) { watcherCount++; return newval; }
-
-/*
- * Place a watchpoint on the property. The property's shape now has the
- * watchpoint setter, with the original setter saved in the watchpoint
- * structure.
- */
-o.watch('x', watcher);
-
-/*
- * Replace the setter with a new setter. The shape should get updated to
- * refer to the new setter, and then the watchpoint setter should be
- * re-established.
- */
-var secondSetterCount;
-Object.defineProperty(o, 'x', { set: function () { secondSetterCount++ } });
-
-/*
- * Assign to the property. This should trigger the watchpoint and the new setter.
- */
-watcherCount = firstSetterCount = secondSetterCount = 0;
-o.x = 3;
-assertEq(watcherCount, 1);
-assertEq(firstSetterCount, 0);
-assertEq(secondSetterCount, 1);
-
-reportCompare(true, true);
diff --git a/js/src/tests/ecma_5/extensions/watch-value-prop-becoming-setter.js b/js/src/tests/ecma_5/extensions/watch-value-prop-becoming-setter.js
deleted file mode 100644
index 03cdd788e..000000000
--- a/js/src/tests/ecma_5/extensions/watch-value-prop-becoming-setter.js
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/licenses/publicdomain/
- */
-
-/* A stock watcher function. */
-var watcherCount;
-function watcher(id, old, newval) {
- watcherCount++;
- return newval;
-}
-
-/* Create an object with a value property. */
-var o = { w:2, x:3 };
-
-/*
- * Place a watchpoint on the value property. The watchpoint structure holds
- * the original JavaScript setter, and a pointer to the shape.
- */
-o.watch('x', watcher);
-
-/*
- * Put the object in dictionary mode, so that JSObject::putProperty will
- * mutate its shapes instead of creating new ones.
- */
-delete o.w;
-
-/*
- * Replace the value property with a setter.
- */
-var setterCount;
-o.__defineSetter__('x', function() { setterCount++; });
-
-/*
- * Trigger the watchpoint. The watchpoint handler should run, and then the
- * setter should run.
- */
-watcherCount = setterCount = 0;
-o.x = 4;
-assertEq(watcherCount, 1);
-assertEq(setterCount, 1);
-
-reportCompare(true, true);
diff --git a/js/src/tests/ecma_5/extensions/watchpoint-deletes-JSPropertyOp-setter.js b/js/src/tests/ecma_5/extensions/watchpoint-deletes-JSPropertyOp-setter.js
deleted file mode 100644
index 85410bbd4..000000000
--- a/js/src/tests/ecma_5/extensions/watchpoint-deletes-JSPropertyOp-setter.js
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/licenses/publicdomain/
- */
-
-function make_watcher(name) {
- return function (id, oldv, newv) {
- print("watched " + name + "[0]");
- };
-}
-
-var o, p;
-function f(flag) {
- if (flag) {
- o = arguments;
- } else {
- p = arguments;
- o.watch(0, make_watcher('o'));
- p.watch(0, make_watcher('p'));
-
- /*
- * Previously, the watchpoint implementation actually substituted its magic setter
- * functions for the setters of shared shapes, and then 1) carefully ignored calls
- * to its magic setter from unrelated objects, and 2) avoided restoring the
- * original setter until all watchpoints on that shape had been removed.
- *
- * However, when the watchpoint code began using JSObject::changeProperty and
- * js_ChangeNativePropertyAttrs to change shapes' setters, the shape tree code
- * became conscious of the presence of watchpoints, and shared shapes between
- * objects only when their watchpoint nature coincided. Clearing the magic setter
- * from one object's shape would not affect other objects, because the
- * watchpointed and non-watchpointed shapes were distinct if they were shared.
- *
- * Thus, the first unwatch call must go ahead and fix p's shape, even though a
- * watchpoint exists on the same shape in o. o's watchpoint's presence shouldn't
- * cause 'unwatch' to leave p's magic setter in place.
- */
-
- /* DropWatchPointAndUnlock would see o's watchpoint, and not change p's property. */
- p.unwatch(0);
-
- /* DropWatchPointAndUnlock would fix o's property, but not p's; p's setter would be gone. */
- o.unwatch(0);
-
- /* This would fail to invoke the arguments object's setter. */
- p[0] = 4;
-
- /* And the formal parameter would not get updated. */
- assertEq(flag, 4);
- }
-}
-
-f(true);
-f(false);
-
-reportCompare(true, true);
diff --git a/js/src/tests/js1_5/Object/regress-362872-01.js b/js/src/tests/js1_5/Object/regress-362872-01.js
deleted file mode 100644
index 0808ee82b..000000000
--- a/js/src/tests/js1_5/Object/regress-362872-01.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/* -*- tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* 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/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 362872;
-var summary = 'script should not drop watchpoint that is in use';
-var actual = 'No Crash';
-var expect = 'No Crash';
-
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
- enterFunc ('test');
- printBugNumber(BUGNUMBER);
- printStatus (summary);
-
- function exploit() {
- var rooter = {}, object = {}, filler1 = "", filler2 = "\u5555";
- for(var i = 0; i < 32/2-2; i++) { filler1 += "\u5050"; }
- object.watch("foo", function(){
- object.unwatch("foo");
- object.unwatch("foo");
- for(var i = 0; i < 8 * 1024; i++) {
- rooter[i] = filler1 + filler2;
- }
- });
- object.foo = "bar";
- }
- exploit();
-
-
- reportCompare(expect, actual, summary);
-
- exitFunc ('test');
-}
diff --git a/js/src/tests/js1_5/Object/regress-362872-02.js b/js/src/tests/js1_5/Object/regress-362872-02.js
deleted file mode 100644
index edee43a4a..000000000
--- a/js/src/tests/js1_5/Object/regress-362872-02.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/*
- * Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/licenses/publicdomain/
- * Contributor: Blake Kaplan
- */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 362872;
-var summary = 'script should not drop watchpoint that is in use';
-var actual = 'No Crash';
-var expect = 'No Crash';
-
-printBugNumber(BUGNUMBER);
-printStatus (summary);
-
-this.watch('x', function f() {
- print("before");
- x = 3;
- print("after");
- });
-x = 3;
-
-reportCompare(expect, actual, summary);
diff --git a/js/src/tests/js1_5/Regress/regress-127243.js b/js/src/tests/js1_5/Regress/regress-127243.js
deleted file mode 100644
index 11779f803..000000000
--- a/js/src/tests/js1_5/Regress/regress-127243.js
+++ /dev/null
@@ -1,75 +0,0 @@
-// |reftest| skip-if(xulRuntime.OS=="WINNT"&&isDebugBuild) slow
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 127243;
-var summary = 'Do not crash on watch';
-var actual = 'No Crash';
-var expect = 'No Crash';
-
-printBugNumber(BUGNUMBER);
-printStatus (summary);
-
-if (typeof window != 'undefined' && typeof document != 'undefined')
-{
- // delay test driver end
- gDelayTestDriverEnd = true;
- window.addEventListener('load', handleLoad, false);
-}
-else
-{
- printStatus('This test must be run in the browser');
- reportCompare(expect, actual, summary);
-
-}
-
-var div;
-
-function handleLoad()
-{
- div = document.createElement('div');
- document.body.appendChild(div);
- div.setAttribute('id', 'id1');
- div.style.width = '50px';
- div.style.height = '100px';
- div.style.overflow = 'auto';
-
- for (var i = 0; i < 5; i++)
- {
- var p = document.createElement('p');
- var t = document.createTextNode('blah');
- p.appendChild(t);
- div.appendChild(p);
- }
-
- div.watch('scrollTop', wee);
-
- setTimeout('setScrollTop()', 1000);
-}
-
-function wee(id, oldval, newval)
-{
- var t = document.createTextNode('setting ' + id +
- ' value ' + div.scrollTop +
- ' oldval ' + oldval +
- ' newval ' + newval);
- var p = document.createElement('p');
- p.appendChild(t);
- document.body.appendChild(p);
-
- return newval;
-}
-
-function setScrollTop()
-{
- div.scrollTop = 42;
-
- reportCompare(expect, actual, summary);
-
- gDelayTestDriverEnd = false;
- jsTestDriverEnd();
-
-}
diff --git a/js/src/tests/js1_5/Regress/regress-213482.js b/js/src/tests/js1_5/Regress/regress-213482.js
deleted file mode 100644
index 26ed7e894..000000000
--- a/js/src/tests/js1_5/Regress/regress-213482.js
+++ /dev/null
@@ -1,29 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* 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/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 213482;
-var summary = 'Do not crash watching property when watcher sets property';
-var actual = 'No Crash';
-var expect = 'No Crash';
-
-printBugNumber(BUGNUMBER);
-printStatus (summary);
-
-var testobj = {value: 'foo'};
-
-function watched (a, b, c) {
- testobj.value = (new Date()).getTime();
-}
-
-function setTest() {
- testobj.value = 'b';
-}
-
-testobj.watch("value", watched);
-
-setTest();
-
-reportCompare(expect, actual, summary);
diff --git a/js/src/tests/js1_5/Regress/regress-240577.js b/js/src/tests/js1_5/Regress/regress-240577.js
deleted file mode 100644
index ba8330aa0..000000000
--- a/js/src/tests/js1_5/Regress/regress-240577.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/*
- * Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/licenses/publicdomain/
- * Contributor: Bob Clary
- */
-
-//-----------------------------------------------------------------------------
-// originally reported by Jens Thiele <karme@unforgettable.com> in
-var BUGNUMBER = 240577;
-var summary = 'object.watch execution context';
-var actual = '';
-var expect = '';
-
-printBugNumber(BUGNUMBER);
-printStatus (summary);
-
-var createWatcher = function ( watchlabel )
-{
- var watcher = function (property, oldvalue, newvalue)
- {
- actual += watchlabel; return newvalue;
- };
- return watcher;
-};
-
-var watcher1 = createWatcher('watcher1');
-
-var object = {property: 'value'};
-
-object.watch('property', watcher1);
-
-object.property = 'newvalue';
-
-expect = 'watcher1';
-
-reportCompare(expect, actual, summary);
diff --git a/js/src/tests/js1_5/Regress/regress-355341.js b/js/src/tests/js1_5/Regress/regress-355341.js
deleted file mode 100644
index ab2a4b884..000000000
--- a/js/src/tests/js1_5/Regress/regress-355341.js
+++ /dev/null
@@ -1,29 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* 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/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 355341;
-var summary = 'Do not crash with watch and setter';
-var actual = '';
-var expect = '';
-
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
- enterFunc ('test');
- printBugNumber(BUGNUMBER);
- printStatus (summary);
-
- Object.defineProperty(this, "x", { set: Function, enumerable: true, configurable: true });
- this.watch('x', function () { }); x = 3;
-
- reportCompare(expect, actual, summary);
-
- exitFunc ('test');
-}
diff --git a/js/src/tests/js1_5/Regress/regress-355344.js b/js/src/tests/js1_5/Regress/regress-355344.js
deleted file mode 100644
index 00bd39147..000000000
--- a/js/src/tests/js1_5/Regress/regress-355344.js
+++ /dev/null
@@ -1,49 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* 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/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 355344;
-var summary = 'Exceptions thrown by watch point';
-var actual = '';
-var expect = '';
-
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
- enterFunc ('test');
- printBugNumber(BUGNUMBER);
- printStatus (summary);
-
- var o = {};
-
- expect = 'setter: yikes';
-
- o.watch('x', function(){throw 'yikes'});
- try
- {
- o.x = 3;
- }
- catch(ex)
- {
- actual = "setter: " + ex;
- }
-
- try
- {
- eval("") ;
- }
- catch(e)
- {
- actual = "eval: " + e;
- }
-
- reportCompare(expect, actual, summary);
-
- exitFunc ('test');
-}
diff --git a/js/src/tests/js1_5/Regress/regress-361467.js b/js/src/tests/js1_5/Regress/regress-361467.js
deleted file mode 100644
index 371c0a8b5..000000000
--- a/js/src/tests/js1_5/Regress/regress-361467.js
+++ /dev/null
@@ -1,32 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* 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/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 361467;
-var summary = 'Do not crash with certain watchers';
-var actual = '';
-var expect = '';
-
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
- enterFunc ('test');
- printBugNumber(BUGNUMBER);
- printStatus (summary);
-
- expect = actual = 'No Crash';
-
- var x;
- this.watch('x', print);
- x = 5;
-
- reportCompare(expect, actual, summary);
-
- exitFunc ('test');
-}
diff --git a/js/src/tests/js1_5/Regress/regress-361617.js b/js/src/tests/js1_5/Regress/regress-361617.js
deleted file mode 100644
index 5d20fd78f..000000000
--- a/js/src/tests/js1_5/Regress/regress-361617.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* 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/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 361617;
-var summary = 'Do not crash with getter, watch and gc';
-var actual = 'No Crash';
-var expect = 'No Crash';
-
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
- enterFunc ('test');
- printBugNumber(BUGNUMBER);
- printStatus (summary);
-
- (function() {
- Object.defineProperty(this, "x", { get: function(){}, enumerable: true, configurable: true });
- })();
- this.watch('x', print);
- Object.defineProperty(this, "x", { get: function(){}, enumerable: true, configurable: true });
- gc();
- this.unwatch('x');
- x;
-
- reportCompare(expect, actual, summary);
-
- exitFunc ('test');
-}
diff --git a/js/src/tests/js1_5/Regress/regress-385393-06.js b/js/src/tests/js1_5/Regress/regress-385393-06.js
deleted file mode 100644
index 327103f39..000000000
--- a/js/src/tests/js1_5/Regress/regress-385393-06.js
+++ /dev/null
@@ -1,28 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* 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/. */
-
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 385393;
-var summary = 'Regression test for bug 385393';
-var actual = 'No Crash';
-var expect = 'No Crash';
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
- enterFunc ('test');
- printBugNumber(BUGNUMBER);
- printStatus (summary);
-
- reportCompare(expect, actual, summary);
-
- true.watch("x", function(){});
-
- exitFunc ('test');
-}
diff --git a/js/src/tests/js1_5/Regress/regress-506567.js b/js/src/tests/js1_5/Regress/regress-506567.js
deleted file mode 100644
index e78dfe1db..000000000
--- a/js/src/tests/js1_5/Regress/regress-506567.js
+++ /dev/null
@@ -1,45 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* 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/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 506567;
-var summary = 'Do not crash with watched variables';
-var actual = '';
-var expect = '';
-
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
- enterFunc ('test');
- printBugNumber(BUGNUMBER);
- printStatus (summary);
-
- if (typeof clearInterval == 'undefined')
- {
- clearInterval = (function () {});
- }
-
- var obj = new Object();
- obj.test = null;
- obj.watch("test", (function(prop, oldval, newval)
- {
- if(false)
- {
- var test = newval % oldval;
- var func = (function(){clearInterval(myInterval);});
- }
- }));
-
- obj.test = 'null';
- print(obj.test);
-
- reportCompare(expect, actual, summary);
-
- exitFunc ('test');
-}
diff --git a/js/src/tests/js1_5/extensions/regress-303277.js b/js/src/tests/js1_5/extensions/regress-303277.js
deleted file mode 100644
index 319d9a2ed..000000000
--- a/js/src/tests/js1_5/extensions/regress-303277.js
+++ /dev/null
@@ -1,19 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* 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/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 303277;
-var summary = 'Do not crash with crash with a watchpoint for __proto__ property ';
-var actual = 'No Crash';
-var expect = 'No Crash';
-
-printBugNumber(BUGNUMBER);
-printStatus (summary);
-
-var o = {};
-o.watch("__proto__", function(){return null;});
-o.__proto__ = null;
-
-reportCompare(expect, actual, summary);
diff --git a/js/src/tests/js1_5/extensions/regress-355339.js b/js/src/tests/js1_5/extensions/regress-355339.js
deleted file mode 100644
index 9b15bd742..000000000
--- a/js/src/tests/js1_5/extensions/regress-355339.js
+++ /dev/null
@@ -1,32 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* 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/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 355339;
-var summary = 'Do not assert: sprop->setter != js_watch_set';
-var actual = '';
-var expect = '';
-
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
- enterFunc ('test');
- printBugNumber(BUGNUMBER);
- printStatus (summary);
-
- expect = actual = 'No Crash';
- o = {};
- o.watch("j", function(a,b,c) { print("*",a,b,c) });
- o.unwatch("j");
- o.watch("j", function(a,b,c) { print("*",a,b,c) });
-
- reportCompare(expect, actual, summary);
-
- exitFunc ('test');
-}
diff --git a/js/src/tests/js1_5/extensions/regress-361346.js b/js/src/tests/js1_5/extensions/regress-361346.js
deleted file mode 100644
index 297c3b1f2..000000000
--- a/js/src/tests/js1_5/extensions/regress-361346.js
+++ /dev/null
@@ -1,22 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* 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/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 361346;
-var summary = 'Crash with setter, watch, GC';
-var actual = '';
-var expect = '';
-
-printBugNumber(BUGNUMBER);
-printStatus (summary);
-
-expect = actual = 'No Crash';
-
-Object.defineProperty(this, "x", { set: new Function, enumerable: true, configurable: true });
-this.watch('x', function(){});
-gc();
-x = {};
-
-reportCompare(expect, actual, summary);
diff --git a/js/src/tests/js1_5/extensions/regress-361360.js b/js/src/tests/js1_5/extensions/regress-361360.js
deleted file mode 100644
index 98e6575d9..000000000
--- a/js/src/tests/js1_5/extensions/regress-361360.js
+++ /dev/null
@@ -1,32 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* 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/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 361360;
-var summary = 'Do not assert: !caller || caller->pc involving setter and watch';
-var actual = '';
-var expect = '';
-
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
- enterFunc ('test');
- printBugNumber(BUGNUMBER);
- printStatus (summary);
-
- expect = actual = 'No Crash';
-
- this.__defineSetter__('x', eval);
- this.watch('x', function(){});
- x = 3;
-
- reportCompare(expect, actual, summary);
-
- exitFunc ('test');
-}
diff --git a/js/src/tests/js1_5/extensions/regress-361552.js b/js/src/tests/js1_5/extensions/regress-361552.js
deleted file mode 100644
index eed54e6dd..000000000
--- a/js/src/tests/js1_5/extensions/regress-361552.js
+++ /dev/null
@@ -1,27 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* 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/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 361552;
-var summary = 'Crash with setter, watch, Script';
-var actual = '';
-var expect = '';
-
-printBugNumber(BUGNUMBER);
-printStatus (summary);
-
-expect = actual = 'No Crash';
-
-if (typeof Script == 'undefined')
-{
- print('Test skipped. Script not defined.');
-}
-else
-{
- this.__defineSetter__('x', gc);
- this.watch('x', new Script(''));
- x = 3;
-}
-reportCompare(expect, actual, summary);
diff --git a/js/src/tests/js1_5/extensions/regress-361558.js b/js/src/tests/js1_5/extensions/regress-361558.js
deleted file mode 100644
index a9a3ae725..000000000
--- a/js/src/tests/js1_5/extensions/regress-361558.js
+++ /dev/null
@@ -1,19 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* 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/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 361558;
-var summary = 'Do not assert: sprop->setter != js_watch_set';
-var actual = '';
-var expect = '';
-
-printBugNumber(BUGNUMBER);
-printStatus (summary);
-
-expect = actual = 'No Crash';
-
-({}.__proto__.watch('x', print)); ({}.watch('x', print));
-
-reportCompare(expect, actual, summary);
diff --git a/js/src/tests/js1_5/extensions/regress-361571.js b/js/src/tests/js1_5/extensions/regress-361571.js
deleted file mode 100644
index bf89d794b..000000000
--- a/js/src/tests/js1_5/extensions/regress-361571.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* 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/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 361571;
-var summary = 'Do not assert: fp->scopeChain == parent';
-var actual = 'No Crash';
-var expect = 'No Crash';
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
- enterFunc ('test');
- printBugNumber(BUGNUMBER);
- printStatus (summary);
-
- try
- {
- o = {};
- o.__defineSetter__('y', eval);
- o.watch('y', function () { return "";});
- o.y = 1;
- }
- catch(ex)
- {
- printStatus('Note eval can no longer be called directly');
- expect = 'EvalError: function eval must be called directly, and not by way of a function of another name';
- actual = ex + '';
- }
- reportCompare(expect, actual, summary);
-
- exitFunc ('test');
-}
diff --git a/js/src/tests/js1_5/extensions/regress-361856.js b/js/src/tests/js1_5/extensions/regress-361856.js
deleted file mode 100644
index e7e2f675b..000000000
--- a/js/src/tests/js1_5/extensions/regress-361856.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* 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/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 361856;
-var summary = 'Do not assert: overwriting @ js_AddScopeProperty';
-var actual = '';
-var expect = '';
-
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
- enterFunc ('test');
- printBugNumber(BUGNUMBER);
- printStatus (summary);
-
- function testit() {
- var obj = {};
- obj.watch("foo", function(){});
- delete obj.foo;
- obj = null;
- gc();
- }
- testit();
-
- reportCompare(expect, actual, summary);
-
- exitFunc ('test');
-}
diff --git a/js/src/tests/js1_5/extensions/regress-361964.js b/js/src/tests/js1_5/extensions/regress-361964.js
deleted file mode 100644
index fcb8bba01..000000000
--- a/js/src/tests/js1_5/extensions/regress-361964.js
+++ /dev/null
@@ -1,54 +0,0 @@
-// |reftest| skip -- slow, alert not dismissed, now busted by harness
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 361964;
-var summary = 'Crash [@ MarkGCThingChildren] involving watch and setter';
-var actual = 'No Crash';
-var expect = 'No Crash';
-
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
- enterFunc ('test');
- printBugNumber(BUGNUMBER);
- printStatus (summary);
-
- var doc;
- if (typeof document == 'undefined')
- {
- doc = {};
- }
- else
- {
- doc = document;
- }
-
- if (typeof alert == 'undefined')
- {
- alert = print;
- }
-
-// Crash:
- doc.watch("title", function(a,b,c,d) {
- return { toString : function() { alert(1); } };
- });
- doc.title = "xxx";
-
-// No crash:
- doc.watch("title", function() {
- return { toString : function() { alert(1); } };
- });
- doc.title = "xxx";
-
- reportCompare(expect, actual, summary);
-
- exitFunc ('test');
-}
diff --git a/js/src/tests/js1_5/extensions/regress-385134.js b/js/src/tests/js1_5/extensions/regress-385134.js
deleted file mode 100644
index 041f4d6e7..000000000
--- a/js/src/tests/js1_5/extensions/regress-385134.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* 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/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 385134;
-var summary = 'Do not crash with setter, watch, uneval';
-var actual = 'No Crash';
-var expect = 'No Crash';
-
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
- enterFunc ('test');
- printBugNumber(BUGNUMBER);
- printStatus (summary);
-
- if (typeof this.__defineSetter__ != 'undefined' &&
- typeof this.watch != 'undefined' &&
- typeof uneval != 'undefined')
- {
- try {
- this.__defineSetter__(0, function(){});
- } catch (exc) {
- // In the browser, this fails. Ignore the error.
- }
- this.watch(0, function(){});
- uneval(this);
- }
- reportCompare(expect, actual, summary);
-
- exitFunc ('test');
-}
diff --git a/js/src/tests/js1_5/extensions/regress-385393-09.js b/js/src/tests/js1_5/extensions/regress-385393-09.js
deleted file mode 100644
index 42834824a..000000000
--- a/js/src/tests/js1_5/extensions/regress-385393-09.js
+++ /dev/null
@@ -1,18 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* 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/. */
-
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 385393;
-var summary = 'Regression test for bug 385393';
-var actual = 'No Crash';
-var expect = 'No Crash';
-
-printBugNumber(BUGNUMBER);
-printStatus (summary);
-
-eval("this.__defineSetter__('x', gc); this.watch('x', [].slice); x = 1;");
-
-reportCompare(expect, actual, summary);
diff --git a/js/src/tests/js1_5/extensions/regress-390597.js b/js/src/tests/js1_5/extensions/regress-390597.js
deleted file mode 100644
index 9f8596adc..000000000
--- a/js/src/tests/js1_5/extensions/regress-390597.js
+++ /dev/null
@@ -1,42 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* 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/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 390597;
-var summary = 'watch point + eval-as-setter allows access to dead JSStackFrame';
-var actual = 'No Crash';
-var expect = 'No Crash';
-
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
- enterFunc ('test');
- printBugNumber(BUGNUMBER);
- printStatus (summary);
-
- function exploit() {
- try
- {
- var obj = this, args = null;
- obj.__defineSetter__("evil", eval);
- obj.watch("evil", function() { return "args = arguments;"; });
- obj.evil = null;
- eval("print(args[0]);");
- }
- catch(ex)
- {
- print('Caught ' + ex);
- }
- }
- exploit();
-
- reportCompare(expect, actual, summary);
-
- exitFunc ('test');
-}
diff --git a/js/src/tests/js1_5/extensions/regress-420612.js b/js/src/tests/js1_5/extensions/regress-420612.js
deleted file mode 100644
index a4491095e..000000000
--- a/js/src/tests/js1_5/extensions/regress-420612.js
+++ /dev/null
@@ -1,21 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* 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/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 420612;
-var summary = 'Do not assert: obj == pobj';
-var actual = 'No Crash';
-var expect = 'No Crash';
-
-printBugNumber(BUGNUMBER);
-printStatus (summary);
-
-var obj = Object.create([]);
-obj.unwatch("x");
-
-if (typeof reportCompare === "function")
- reportCompare(true, true);
-
-print("Tests complete");
diff --git a/js/src/tests/js1_5/extensions/regress-435345-01.js b/js/src/tests/js1_5/extensions/regress-435345-01.js
deleted file mode 100644
index 28beab473..000000000
--- a/js/src/tests/js1_5/extensions/regress-435345-01.js
+++ /dev/null
@@ -1,100 +0,0 @@
-// |reftest| fails
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 435345;
-var summary = 'Watch the length property of arrays';
-var actual = '';
-var expect = '';
-
-// see http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Object:watch
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
- enterFunc ('test');
- printBugNumber(BUGNUMBER);
- printStatus (summary);
-
- var arr;
-
- try
- {
- expect = 'watcher: propname=length, oldval=0, newval=1; ';
- actual = '';
- arr = [];
- arr.watch('length', watcher);
- arr[0] = '0';
- }
- catch(ex)
- {
- actual = ex + '';
- }
- reportCompare(expect, actual, summary + ': 1');
-
- try
- {
- expect = 'watcher: propname=length, oldval=1, newval=2; ' +
- 'watcher: propname=length, oldval=2, newval=2; ';
- actual = '';
- arr.push(5);
- }
- catch(ex)
- {
- actual = ex + '';
- }
- reportCompare(expect, actual, summary + ': 2');
-
- try
- {
- expect = 'watcher: propname=length, oldval=2, newval=1; ';
- actual = '';
- arr.pop();
- }
- catch(ex)
- {
- actual = ex + '';
- }
- reportCompare(expect, actual, summary + ': 3');
-
- try
- {
- expect = 'watcher: propname=length, oldval=1, newval=2; ';
- actual = '';
- arr.length++;
- }
- catch(ex)
- {
- actual = ex + '';
- }
- reportCompare(expect, actual, summary + ': 4');
-
- try
- {
- expect = 'watcher: propname=length, oldval=2, newval=5; ';
- actual = '';
- arr.length = 5;
- }
- catch(ex)
- {
- actual = ex + '';
- }
- reportCompare(expect, actual, summary + ': 5');
-
- exitFunc ('test');
-}
-
-function watcher(propname, oldval, newval)
-{
- actual += 'watcher: propname=' + propname + ', oldval=' + oldval +
- ', newval=' + newval + '; ';
-
- return newval;
-}
-
diff --git a/js/src/tests/js1_5/extensions/regress-454040.js b/js/src/tests/js1_5/extensions/regress-454040.js
deleted file mode 100644
index 63b5e1488..000000000
--- a/js/src/tests/js1_5/extensions/regress-454040.js
+++ /dev/null
@@ -1,25 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* 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/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 454040;
-var summary = 'Do not crash @ js_ComputeFilename';
-var actual = '';
-var expect = '';
-
-printBugNumber(BUGNUMBER);
-printStatus (summary);
-
-try
-{
- this.__defineGetter__("x", Function);
- this.__defineSetter__("x", Function);
- this.watch("x", x.__proto__);
- x = 1;
-}
-catch(ex)
-{
-}
-reportCompare(expect, actual, summary);
diff --git a/js/src/tests/js1_5/extensions/regress-454142.js b/js/src/tests/js1_5/extensions/regress-454142.js
deleted file mode 100644
index 05f331278..000000000
--- a/js/src/tests/js1_5/extensions/regress-454142.js
+++ /dev/null
@@ -1,30 +0,0 @@
-// |reftest| skip-if(Android)
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 454142;
-var summary = 'Do not crash with gczeal, setter, watch';
-var actual = '';
-var expect = '';
-
-printBugNumber(BUGNUMBER);
-printStatus (summary);
-
-this.watch("x", function(){});
-delete x;
-if (typeof gczeal == 'function')
-{
- gczeal(2);
-}
-
-this.__defineSetter__("x", function(){});
-
-if (typeof gczeal == 'function')
-{
- gczeal(0);
-}
-
-reportCompare(expect, actual, summary);
diff --git a/js/src/tests/js1_5/extensions/regress-455413.js b/js/src/tests/js1_5/extensions/regress-455413.js
deleted file mode 100644
index d00ab135b..000000000
--- a/js/src/tests/js1_5/extensions/regress-455413.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* 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/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 455413;
-var summary = 'Do not assert with JIT: (m != JSVAL_INT) || isInt32(*vp)';
-var actual = 'No Crash';
-var expect = 'No Crash';
-
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-printBugNumber(BUGNUMBER);
-printStatus (summary);
-
-
-this.watch('x', Math.pow); (function() { for(var j=0;j<4;++j){x=1;} })();
-
-
-reportCompare(expect, actual, summary);
diff --git a/js/src/tests/js1_5/extensions/regress-465145.js b/js/src/tests/js1_5/extensions/regress-465145.js
deleted file mode 100644
index 84f81703b..000000000
--- a/js/src/tests/js1_5/extensions/regress-465145.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* 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/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 465145;
-var summary = 'Do not crash with watched defined setter';
-var actual = '';
-var expect = '';
-
-printBugNumber(BUGNUMBER);
-printStatus (summary);
-
-
-this.__defineSetter__("x", function(){});
-this.watch("x", function(){});
-y = this;
-for (var z = 0; z < 2; ++z) { x = y };
-this.__defineSetter__("x", function(){});
-for (var z = 0; z < 2; ++z) { x = y };
-
-
-reportCompare(expect, actual, summary);
diff --git a/js/src/tests/js1_5/extensions/regress-472787.js b/js/src/tests/js1_5/extensions/regress-472787.js
deleted file mode 100755
index d3196f05f..000000000
--- a/js/src/tests/js1_5/extensions/regress-472787.js
+++ /dev/null
@@ -1,31 +0,0 @@
-// |reftest| skip-if(Android)
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 472787;
-var summary = 'Do not hang with gczeal, watch and concat';
-var actual = '';
-var expect = '';
-
-printBugNumber(BUGNUMBER);
-printStatus (summary);
-
-this.__defineSetter__("x", Math.sin);
-this.watch("x", '' .concat);
-
-if (typeof gczeal == 'function')
-{
- gczeal(2);
-}
-
-x = 1;
-
-if (typeof gczeal == 'function')
-{
- gczeal(0);
-}
-
-reportCompare(expect, actual, summary);
diff --git a/js/src/tests/js1_5/extensions/regress-488995.js b/js/src/tests/js1_5/extensions/regress-488995.js
deleted file mode 100644
index f7abbe439..000000000
--- a/js/src/tests/js1_5/extensions/regress-488995.js
+++ /dev/null
@@ -1,46 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* 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/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 488995;
-var summary = 'Do not crash with watch, __defineSetter__ on svg';
-var actual = '';
-var expect = '';
-
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
- enterFunc ('test');
- printBugNumber(BUGNUMBER);
- printStatus (summary);
-
- if (typeof document == 'undefined')
- {
- print('Test skipped: requires browser.');
- }
- else
- {
- try
- {
- var o=document.createElementNS("http://www.w3.org/2000/svg", "svg");
- var p=o.y;
- p.watch('animVal', function(id, oldvar, newval) {} );
- p.type='xxx';
- p.__defineSetter__('animVal', function() {});
- p.animVal=0;
- }
- catch(ex)
- {
- }
- }
-
- reportCompare(expect, actual, summary);
-
- exitFunc ('test');
-}
diff --git a/js/src/tests/js1_6/Regress/regress-476655.js b/js/src/tests/js1_6/Regress/regress-476655.js
deleted file mode 100644
index 9077ba3a0..000000000
--- a/js/src/tests/js1_6/Regress/regress-476655.js
+++ /dev/null
@@ -1,40 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* 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/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 476655;
-var summary = 'TM: Do not assert: count <= (size_t) (fp->regs->sp - StackBase(fp) - depth)';
-var actual = '';
-var expect = '';
-
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
- enterFunc ('test');
- printBugNumber(BUGNUMBER);
- printStatus (summary);
-
-
- try
- {
- eval(
- "(function (){ for (var y in this) {} })();" +
- "[''.watch(\"\", function(){}) for each (x in ['', '', eval, '', '']) if " +
- "(x)].map(Function)"
- );
- }
- catch(ex)
- {
- }
-
-
- reportCompare(expect, actual, summary);
-
- exitFunc ('test');
-}
diff --git a/js/src/tests/js1_6/extensions/regress-457521.js b/js/src/tests/js1_6/extensions/regress-457521.js
deleted file mode 100644
index 6f4fbda50..000000000
--- a/js/src/tests/js1_6/extensions/regress-457521.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* 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/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 457521;
-var summary = 'Do not crash @ js_DecompileValueGenerator';
-var actual = '';
-var expect = '';
-
-printBugNumber(BUGNUMBER);
-printStatus (summary);
-
-try
-{
- this.__defineSetter__("x", [,,,].map);
- this.watch("x", (new Function("var y, eval")));
- x = true;
-}
-catch(ex)
-{
-}
-reportCompare(expect, actual, summary);
diff --git a/js/src/tests/js1_6/extensions/regress-479567.js b/js/src/tests/js1_6/extensions/regress-479567.js
deleted file mode 100644
index 6f3525130..000000000
--- a/js/src/tests/js1_6/extensions/regress-479567.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* 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/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 479567;
-var summary = 'Do not assert: thing';
-var actual = '';
-var expect = '';
-
-printBugNumber(BUGNUMBER);
-printStatus (summary);
-
-
-function f()
-{
- (eval("(function(){for each (y in [false, false, false]);});"))();
-}
-
-try
-{
- this.__defineGetter__("x", gc);
- uneval(this.watch("y", this.toSource))
- f();
- throw x;
-}
-catch(ex)
-{
-}
-
-
-reportCompare(expect, actual, summary);
diff --git a/js/src/tests/js1_7/extensions/regress-453955.js b/js/src/tests/js1_7/extensions/regress-453955.js
deleted file mode 100644
index 454f712f3..000000000
--- a/js/src/tests/js1_7/extensions/regress-453955.js
+++ /dev/null
@@ -1,31 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* 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/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 453955;
-var summary = 'Do not assert: sprop->setter != js_watch_set || pobj != obj';
-var actual = '';
-var expect = '';
-
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
- enterFunc ('test');
- printBugNumber(BUGNUMBER);
- printStatus (summary);
-
- for (var z = 0; z < 2; ++z)
- {
- [].filter.watch("9", function(y) { yield y; });
- }
-
- reportCompare(expect, actual, summary);
-
- exitFunc ('test');
-}
diff --git a/js/src/tests/js1_7/extensions/regress-473282.js b/js/src/tests/js1_7/extensions/regress-473282.js
deleted file mode 100644
index c50ac9234..000000000
--- a/js/src/tests/js1_7/extensions/regress-473282.js
+++ /dev/null
@@ -1,20 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* 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/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 473282;
-var summary = 'Do not assert: thing';
-var actual = '';
-var expect = '';
-
-printBugNumber(BUGNUMBER);
-printStatus (summary);
-
-this.watch("b", "".substring);
-this.__defineGetter__("a", gc);
-for each (b in [this, null, null]);
-a;
-
-reportCompare(expect, actual, summary);
diff --git a/js/src/tests/js1_7/regress/regress-385133-01.js b/js/src/tests/js1_7/regress/regress-385133-01.js
deleted file mode 100644
index 03b09f535..000000000
--- a/js/src/tests/js1_7/regress/regress-385133-01.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* 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/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 385133;
-var summary = 'Do not crash due to recursion with watch, setter, delete, generator';
-var actual = 'No Crash';
-var expect = 'No Crash';
-
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
- enterFunc ('test');
- printBugNumber(BUGNUMBER);
- printStatus (summary);
-
- try
- {
- Object.defineProperty(this, "x", { set: {}.watch, enumerable: true, configurable: true });
- this.watch('x', 'foo'.split);
- delete x;
- function g(){ x = 1; yield; }
- for (i in g()) { }
- }
- catch(ex)
- {
- }
- reportCompare(expect, actual, summary);
-
- exitFunc ('test');
-}
diff --git a/js/src/tests/js1_8/extensions/regress-394709.js b/js/src/tests/js1_8/extensions/regress-394709.js
deleted file mode 100644
index d04d8832f..000000000
--- a/js/src/tests/js1_8/extensions/regress-394709.js
+++ /dev/null
@@ -1,51 +0,0 @@
-// |reftest| skip-if(!xulRuntime.shell)
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* 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/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 394709;
-var summary = 'Do not leak with object.watch and closure';
-var actual = 'No Leak';
-var expect = 'No Leak';
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
- enterFunc ('test');
- printBugNumber(BUGNUMBER);
- printStatus (summary);
-
- assertEq(finalizeCount(), 0, "invalid initial state");
-
- runtest();
- gc();
- assertEq(finalizeCount(), 1, "leaked");
-
- runtest();
- gc();
- assertEq(finalizeCount(), 2, "leaked");
-
- runtest();
- gc();
- assertEq(finalizeCount(), 3, "leaked");
-
-
- function runtest () {
- var obj = { b: makeFinalizeObserver() };
- obj.watch('b', watcher);
-
- function watcher(id, old, value) {
- ++obj.n;
- return value;
- }
- }
-
- reportCompare(expect, actual, summary);
-
- exitFunc ('test');
-}
diff --git a/js/src/tests/js1_8/extensions/regress-481989.js b/js/src/tests/js1_8/extensions/regress-481989.js
deleted file mode 100644
index 36efb7567..000000000
--- a/js/src/tests/js1_8/extensions/regress-481989.js
+++ /dev/null
@@ -1,19 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* 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/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 481989;
-var summary = 'TM: Do not assert: SPROP_HAS_STUB_SETTER(sprop)';
-var actual = '';
-var expect = '';
-
-printBugNumber(BUGNUMBER);
-printStatus (summary);
-
-
-y = this.watch("x", function(){}); for each (let y in ['', '']) x = y;
-
-
-reportCompare(expect, actual, summary);
diff --git a/js/src/tests/js1_8_1/extensions/regress-452498-193.js b/js/src/tests/js1_8_1/extensions/regress-452498-193.js
deleted file mode 100644
index 1397bf4bb..000000000
--- a/js/src/tests/js1_8_1/extensions/regress-452498-193.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* 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/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 452498;
-var summary = 'TM: upvar2 regression tests';
-var actual = '';
-var expect = '';
-
-//------- Comment #193 From Gary Kwong
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
- enterFunc ('test');
- printBugNumber(BUGNUMBER);
- printStatus (summary);
-
-// Assertion failure: afunbox->parent, at ../jsparse.cpp:1912
-
- this.x = undefined;
- this.watch("x", Function);
- NaN = uneval({ get \u3056 (){ return undefined } });
- x+=NaN;
-
- reportCompare(expect, actual, summary);
-
- exitFunc ('test');
-}
diff --git a/js/src/tests/js1_8_1/extensions/regress-452498-196.js b/js/src/tests/js1_8_1/extensions/regress-452498-196.js
index 69d5a3586..5b9191199 100644
--- a/js/src/tests/js1_8_1/extensions/regress-452498-196.js
+++ b/js/src/tests/js1_8_1/extensions/regress-452498-196.js
@@ -21,15 +21,6 @@ function test()
printBugNumber(BUGNUMBER);
printStatus (summary);
-// Assertion failure: localKind == JSLOCAL_VAR || localKind == JSLOCAL_CONST, at ../jsfun.cpp:916
-
- this.x = undefined;
- this.watch("x", Function);
- NaN = uneval({ get \u3056 (){ return undefined } });
- x+=NaN;
-
- reportCompare(expect, actual, summary + ': 1');
-
// Assertion failure: lexdep->isLet(), at ../jsparse.cpp:1900
(function (){
diff --git a/js/src/tests/js1_8_1/extensions/regress-520572.js b/js/src/tests/js1_8_1/extensions/regress-520572.js
deleted file mode 100644
index 97f00029a..000000000
--- a/js/src/tests/js1_8_1/extensions/regress-520572.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */
-/*
- * Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/licenses/publicdomain/
- * Contributor: Blake Kaplan
- */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 520572;
-var summary = 'watch should innerize the object being watched';
-var actual = 0;
-var expect = 2;
-
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
- enterFunc ('test');
- printBugNumber(BUGNUMBER);
- printStatus (summary);
-
- if ("evalcx" in this) {
- // shell
- let s = evalcx("lazy");
- s.n = 0;
- evalcx('this.watch("x", function(){ n++; }); this.x = 4; x = 6', s);
- actual = s.n;
- reportCompare(expect, actual, summary);
- } else {
- // browser
- this.watch('x', function(){ actual++; });
- this.x = 4;
- x = 6;
- reportCompare(expect, actual, summary);
- }
-
- exitFunc ('test');
-}
diff --git a/js/src/tests/js1_8_1/regress/regress-452498-160.js b/js/src/tests/js1_8_1/regress/regress-452498-160.js
index 6498a0b5a..305b41795 100644
--- a/js/src/tests/js1_8_1/regress/regress-452498-160.js
+++ b/js/src/tests/js1_8_1/regress/regress-452498-160.js
@@ -21,11 +21,6 @@ function test()
printBugNumber(BUGNUMBER);
printStatus (summary);
-// crash [@ js_Interpret]
- (eval("(function(){ this.watch(\"x\", function () { new function ()y } ); const y = undefined });"))();
- x = NaN;
- reportCompare(expect, actual, summary + ': 2');
-
// Assertion failure: JOF_OPTYPE(op) == JOF_ATOM, at ../jsemit.cpp:5916
({ set z(v){}, set y(v)--x, set w(v)--w });
reportCompare(expect, actual, summary + ': 3');
diff --git a/js/src/tests/js1_8_5/extensions/regress-604781-1.js b/js/src/tests/js1_8_5/extensions/regress-604781-1.js
deleted file mode 100644
index a7c43f95d..000000000
--- a/js/src/tests/js1_8_5/extensions/regress-604781-1.js
+++ /dev/null
@@ -1,24 +0,0 @@
-// Any copyright is dedicated to the Public Domain.
-// http://creativecommons.org/licenses/publicdomain/
-
-var watcherCount, setterCount;
-function watcher(id, oldval, newval) { watcherCount++; return newval; }
-function setter(newval) { setterCount++; }
-
-var p = { set x(v) { setter(v); } };
-p.watch('x', watcher);
-
-watcherCount = setterCount = 0;
-p.x = 2;
-assertEq(setterCount, 1);
-assertEq(watcherCount, 1);
-
-var o = Object.defineProperty({}, 'x', { set:setter, enumerable:true, configurable:true });
-o.watch('x', watcher);
-
-watcherCount = setterCount = 0;
-o.x = 2;
-assertEq(setterCount, 1);
-assertEq(watcherCount, 1);
-
-reportCompare(0, 0, 'ok');
diff --git a/js/src/tests/js1_8_5/extensions/regress-604781-2.js b/js/src/tests/js1_8_5/extensions/regress-604781-2.js
deleted file mode 100644
index 7aba4a274..000000000
--- a/js/src/tests/js1_8_5/extensions/regress-604781-2.js
+++ /dev/null
@@ -1,13 +0,0 @@
-// Any copyright is dedicated to the Public Domain.
-// http://creativecommons.org/licenses/publicdomain/
-
-var log;
-function watcher(id, old, newval) { log += 'watcher'; return newval; }
-var o = { set x(v) { log += 'setter'; } };
-o.watch('x', watcher);
-Object.defineProperty(o, 'x', {value: 3, writable: true});
-log = '';
-o.x = 3;
-assertEq(log, 'watcher');
-
-reportCompare(0, 0, 'ok');
diff --git a/js/src/tests/js1_8_5/extensions/regress-627984-1.js b/js/src/tests/js1_8_5/extensions/regress-627984-1.js
deleted file mode 100644
index a3726630a..000000000
--- a/js/src/tests/js1_8_5/extensions/regress-627984-1.js
+++ /dev/null
@@ -1,16 +0,0 @@
-// Any copyright is dedicated to the Public Domain.
-// http://creativecommons.org/licenses/publicdomain/
-
-// See bug 627984, comment 17, item 1.
-var obj;
-var methods = [];
-for (var i = 0; i < 2; i++) {
- obj = {m: function () { return this.x; }};
- obj.watch("m", function (id, oldval, newval) { methods[i] = oldval; });
- obj.m = 0;
-}
-assertEq(typeof methods[0], "function");
-assertEq(typeof methods[1], "function");
-assertEq(methods[0] !== methods[1], true);
-
-reportCompare(0, 0, 'ok');
diff --git a/js/src/tests/js1_8_5/extensions/regress-627984-2.js b/js/src/tests/js1_8_5/extensions/regress-627984-2.js
deleted file mode 100644
index c4f1b508c..000000000
--- a/js/src/tests/js1_8_5/extensions/regress-627984-2.js
+++ /dev/null
@@ -1,15 +0,0 @@
-// Any copyright is dedicated to the Public Domain.
-// http://creativecommons.org/licenses/publicdomain/
-
-// See bug 627984, comment 17, item 2.
-var obj = {};
-var x;
-obj.watch("m", function (id, oldval, newval) {
- x = this.m;
- return newval;
- });
-delete obj.m;
-obj.m = function () { return this.method; };
-obj.m = 2;
-
-reportCompare(0, 0, 'ok');
diff --git a/js/src/tests/js1_8_5/extensions/regress-627984-3.js b/js/src/tests/js1_8_5/extensions/regress-627984-3.js
deleted file mode 100644
index cbe4e10fa..000000000
--- a/js/src/tests/js1_8_5/extensions/regress-627984-3.js
+++ /dev/null
@@ -1,14 +0,0 @@
-// Any copyright is dedicated to the Public Domain.
-// http://creativecommons.org/licenses/publicdomain/
-
-// Don't write string value to method slot.
-// See bug 627984, comment 17, item 2.
-var obj = {};
-obj.watch("m", function (id, oldval, newval) {
- return 'ok';
- });
-delete obj.m;
-obj.m = function () { return this.x; };
-assertEq(obj.m, 'ok');
-
-reportCompare(0, 0, 'ok');
diff --git a/js/src/tests/js1_8_5/extensions/regress-627984-4.js b/js/src/tests/js1_8_5/extensions/regress-627984-4.js
deleted file mode 100644
index bbc017ffb..000000000
--- a/js/src/tests/js1_8_5/extensions/regress-627984-4.js
+++ /dev/null
@@ -1,15 +0,0 @@
-// Any copyright is dedicated to the Public Domain.
-// http://creativecommons.org/licenses/publicdomain/
-
-// See bug 627984, comment 17, item 3.
-var obj = {};
-obj.watch("m", function (id, oldval, newval) {
- delete obj.m;
- obj.m = function () {};
- return newval;
- });
-delete obj.m;
-obj.m = 1;
-assertEq(obj.m, 1);
-
-reportCompare(0, 0, 'ok');
diff --git a/js/src/tests/js1_8_5/extensions/regress-627984-5.js b/js/src/tests/js1_8_5/extensions/regress-627984-5.js
deleted file mode 100644
index 704d8421c..000000000
--- a/js/src/tests/js1_8_5/extensions/regress-627984-5.js
+++ /dev/null
@@ -1,13 +0,0 @@
-// Any copyright is dedicated to the Public Domain.
-// http://creativecommons.org/licenses/publicdomain/
-
-// Bug 627984 comment 11.
-var o = ({});
-o.p = function() {};
-o.watch('p', function() { });
-o.q = function() {}
-delete o.p;
-o.p = function() {};
-assertEq(o.p, void 0);
-
-reportCompare(0, 0, 'ok');
diff --git a/js/src/tests/js1_8_5/extensions/regress-627984-6.js b/js/src/tests/js1_8_5/extensions/regress-627984-6.js
deleted file mode 100644
index cb1a0fca9..000000000
--- a/js/src/tests/js1_8_5/extensions/regress-627984-6.js
+++ /dev/null
@@ -1,15 +0,0 @@
-// Any copyright is dedicated to the Public Domain.
-// http://creativecommons.org/licenses/publicdomain/
-
-// Bug 627984 description.
-var o = Array;
-o.p = function() {};
-o.watch('p', function() { });
-for(var x in o) {
- o[x];
-}
-delete o.p;
-o.p = function() {};
-assertEq(o.p, void 0);
-
-reportCompare(0, 0, 'ok');
diff --git a/js/src/tests/js1_8_5/extensions/regress-627984-7.js b/js/src/tests/js1_8_5/extensions/regress-627984-7.js
deleted file mode 100644
index b13a0e912..000000000
--- a/js/src/tests/js1_8_5/extensions/regress-627984-7.js
+++ /dev/null
@@ -1,9 +0,0 @@
-// Any copyright is dedicated to the Public Domain.
-// http://creativecommons.org/licenses/publicdomain/
-
-// See bug 627984 comment 20.
-var obj = {m: function () {}};
-obj.watch("m", function () { throw 'FAIL'; });
-var f = obj.m; // don't call the watchpoint
-
-reportCompare(0, 0, 'ok');
diff --git a/js/src/tests/js1_8_5/extensions/regress-631723.js b/js/src/tests/js1_8_5/extensions/regress-631723.js
deleted file mode 100644
index f7c755603..000000000
--- a/js/src/tests/js1_8_5/extensions/regress-631723.js
+++ /dev/null
@@ -1,10 +0,0 @@
-// Any copyright is dedicated to the Public Domain.
-// http://creativecommons.org/licenses/publicdomain/
-
-var o = {a:1, b:2};
-o.watch("p", function() { return 13; });
-delete o.p;
-o.p = 0;
-assertEq(o.p, 13);
-
-reportCompare(0, 0, 'ok');
diff --git a/js/src/tests/js1_8_5/extensions/regress-636697.js b/js/src/tests/js1_8_5/extensions/regress-636697.js
deleted file mode 100644
index 6b3b1de37..000000000
--- a/js/src/tests/js1_8_5/extensions/regress-636697.js
+++ /dev/null
@@ -1,11 +0,0 @@
-// Any copyright is dedicated to the Public Domain.
-// http://creativecommons.org/licenses/publicdomain/
-
-var a = {set p(x) {}};
-a.watch('p', function () {});
-var b = Object.create(a);
-b.watch('p', function () {});
-delete b.p;
-b.p = 0;
-
-reportCompare(0, 0, 'ok');
diff --git a/js/src/tests/js1_8_5/extensions/regress-637985.js b/js/src/tests/js1_8_5/extensions/regress-637985.js
deleted file mode 100644
index 305bfc820..000000000
--- a/js/src/tests/js1_8_5/extensions/regress-637985.js
+++ /dev/null
@@ -1,8 +0,0 @@
-// Any copyright is dedicated to the Public Domain.
-// http://creativecommons.org/licenses/publicdomain/
-
-var obj = {};
-obj.watch(-1, function(){});
-obj.unwatch("-1"); // don't assert
-
-reportCompare(0, 0, 'ok'); \ No newline at end of file
diff --git a/js/src/tests/js1_8_5/extensions/regress-691746.js b/js/src/tests/js1_8_5/extensions/regress-691746.js
deleted file mode 100644
index 26f732d07..000000000
--- a/js/src/tests/js1_8_5/extensions/regress-691746.js
+++ /dev/null
@@ -1,11 +0,0 @@
-// Any copyright is dedicated to the Public Domain.
-// http://creativecommons.org/licenses/publicdomain/
-
-var obj = {};
-try {
- obj.watch(QName(), function () {});
-} catch (exc) {
-}
-gc();
-
-reportCompare(0, 0, 'ok');
diff --git a/js/src/tests/js1_8_5/extensions/watch-undefined-setter.js b/js/src/tests/js1_8_5/extensions/watch-undefined-setter.js
deleted file mode 100644
index 92608de0e..000000000
--- a/js/src/tests/js1_8_5/extensions/watch-undefined-setter.js
+++ /dev/null
@@ -1,19 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/*
- * Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/licenses/publicdomain/
- * Contributor:
- * Gary Kwong
- */
-
-var gTestfile = 'watch-undefined-setter.js';
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 560277;
-var summary =
- 'Crash [@ JSObject::getParent] or [@ js_WrapWatchedSetter] or ' +
- '[@ js_GetClassPrototype]';
-
-this.watch("x", function() { });
-Object.defineProperty(this, "x", { set: undefined, configurable: true });
-
-reportCompare(true, true);
diff --git a/js/src/tests/js1_8_5/regress/regress-533876.js b/js/src/tests/js1_8_5/regress/regress-533876.js
deleted file mode 100644
index e44bc8a4f..000000000
--- a/js/src/tests/js1_8_5/regress/regress-533876.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/licenses/publicdomain/
- * Contributors: Gary Kwong and Jason Orendorff
- */
-
-var savedEval = eval;
-var x = [0];
-eval();
-
-x.__proto__ = this; // x has non-dictionary scope
-try {
- DIE;
-} catch(e) {
-}
-
-delete eval; // force dictionary scope for global
-gc();
-eval = savedEval;
-var f = eval("(function () { return /x/; })");
-x.watch('x', f); // clone property from global to x, including SPROP_IN_DICTIONARY flag
-
-reportCompare("ok", "ok", "bug 533876");
diff --git a/js/src/tests/js1_8_5/regress/regress-548276.js b/js/src/tests/js1_8_5/regress/regress-548276.js
deleted file mode 100644
index 5e306eba1..000000000
--- a/js/src/tests/js1_8_5/regress/regress-548276.js
+++ /dev/null
@@ -1,10 +0,0 @@
-// |reftest| skip
-/*
- * Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/licenses/publicdomain/
- * Contributors: Gary Kwong and Jason Orendorff
- */
-var obj = {};
-obj.__defineSetter__("x", function() {});
-obj.watch("x", function() {});
-obj.__defineSetter__("x", /a/);
diff --git a/js/src/tests/js1_8_5/regress/regress-584648.js b/js/src/tests/js1_8_5/regress/regress-584648.js
deleted file mode 100644
index a1635ea51..000000000
--- a/js/src/tests/js1_8_5/regress/regress-584648.js
+++ /dev/null
@@ -1,16 +0,0 @@
-// |reftest| skip
-// Any copyright is dedicated to the Public Domain.
-// http://creativecommons.org/licenses/publicdomain/
-// Contributors: Gary Kwong <gary@rumblingedge.com>
-// Jason Orendorff <jorendorff@mozilla.com>
-
-// on a non-global object
-var x = {};
-x.watch("p", function () { evalcx(''); });
-x.p = 0;
-
-// on the global
-watch("e", (function () { evalcx(''); }));
-e = function () {};
-
-reportCompare(0, 0, "ok");
diff --git a/js/src/tests/js1_8_5/regress/regress-635195.js b/js/src/tests/js1_8_5/regress/regress-635195.js
deleted file mode 100644
index 89980b05a..000000000
--- a/js/src/tests/js1_8_5/regress/regress-635195.js
+++ /dev/null
@@ -1,8 +0,0 @@
-// Any copyright is dedicated to the Public Domain.
-// http://creativecommons.org/licenses/publicdomain/
-
-var obj = {set x(v) {}};
-obj.watch("x", function() { delete obj.x; });
-obj.x = "hi"; // don't assert
-
-reportCompare(0, 0, 'ok');
diff --git a/js/src/tests/js1_8_5/regress/regress-636394.js b/js/src/tests/js1_8_5/regress/regress-636394.js
deleted file mode 100644
index d1a249786..000000000
--- a/js/src/tests/js1_8_5/regress/regress-636394.js
+++ /dev/null
@@ -1,10 +0,0 @@
-// Any copyright is dedicated to the Public Domain.
-// http://creativecommons.org/licenses/publicdomain/
-
-var a = {p0: function () {}};
-var b = /f/;
-b.__proto__ = a;
-b.watch("p0", function () {});
-b.p0;
-
-reportCompare(0, 0, "ok");
diff --git a/js/src/vm/CommonPropertyNames.h b/js/src/vm/CommonPropertyNames.h
index fd1c9f5e6..99cb02e58 100644
--- a/js/src/vm/CommonPropertyNames.h
+++ b/js/src/vm/CommonPropertyNames.h
@@ -97,6 +97,7 @@
macro(displayURL, displayURL, "displayURL") \
macro(do, do_, "do") \
macro(done, done, "done") \
+ macro(dotall, dotall, "dotall") \
macro(dotGenerator, dotGenerator, ".generator") \
macro(dotThis, dotThis, ".this") \
macro(each, each, "each") \
@@ -281,6 +282,7 @@
macro(RegExpFlagsGetter, RegExpFlagsGetter, "RegExpFlagsGetter") \
macro(RegExpMatcher, RegExpMatcher, "RegExpMatcher") \
macro(RegExpSearcher, RegExpSearcher, "RegExpSearcher") \
+ macro(RegExpStringIterator, RegExpStringIterator, "RegExp String Iterator") \
macro(RegExpTester, RegExpTester, "RegExpTester") \
macro(RegExp_prototype_Exec, RegExp_prototype_Exec, "RegExp_prototype_Exec") \
macro(Reify, Reify, "Reify") \
diff --git a/js/src/vm/EnvironmentObject.cpp b/js/src/vm/EnvironmentObject.cpp
index a5aac2ab4..c95bb0597 100644
--- a/js/src/vm/EnvironmentObject.cpp
+++ b/js/src/vm/EnvironmentObject.cpp
@@ -408,7 +408,6 @@ const ObjectOps ModuleEnvironmentObject::objectOps_ = {
ModuleEnvironmentObject::setProperty,
ModuleEnvironmentObject::getOwnPropertyDescriptor,
ModuleEnvironmentObject::deleteProperty,
- nullptr, nullptr, /* watch/unwatch */
nullptr, /* getElements */
ModuleEnvironmentObject::enumerate,
nullptr
@@ -491,7 +490,7 @@ ModuleEnvironmentObject::createImportBinding(JSContext* cx, HandleAtom importNam
{
RootedId importNameId(cx, AtomToId(importName));
RootedId localNameId(cx, AtomToId(localName));
- RootedModuleEnvironmentObject env(cx, module->environment());
+ RootedModuleEnvironmentObject env(cx, &module->initialEnvironment());
if (!importBindings().putNew(cx, importNameId, env, localNameId)) {
ReportOutOfMemory(cx);
return false;
@@ -790,7 +789,6 @@ static const ObjectOps WithEnvironmentObjectOps = {
with_SetProperty,
with_GetOwnPropertyDescriptor,
with_DeleteProperty,
- nullptr, nullptr, /* watch/unwatch */
nullptr, /* getElements */
nullptr, /* enumerate (native enumeration of target doesn't work) */
nullptr,
@@ -1159,7 +1157,6 @@ static const ObjectOps RuntimeLexicalErrorObjectObjectOps = {
lexicalError_SetProperty,
lexicalError_GetOwnPropertyDescriptor,
lexicalError_DeleteProperty,
- nullptr, nullptr, /* watch/unwatch */
nullptr, /* getElements */
nullptr, /* enumerate (native enumeration of target doesn't work) */
nullptr, /* this */
diff --git a/js/src/vm/GlobalObject.cpp b/js/src/vm/GlobalObject.cpp
index 85707e1c6..013208f66 100644
--- a/js/src/vm/GlobalObject.cpp
+++ b/js/src/vm/GlobalObject.cpp
@@ -468,62 +468,29 @@ GlobalObject::initSelfHostingBuiltins(JSContext* cx, Handle<GlobalObject*> globa
return false;
}
- RootedValue std_isConcatSpreadable(cx);
- std_isConcatSpreadable.setSymbol(cx->wellKnownSymbols().get(JS::SymbolCode::isConcatSpreadable));
- if (!JS_DefineProperty(cx, global, "std_isConcatSpreadable", std_isConcatSpreadable,
- JSPROP_PERMANENT | JSPROP_READONLY))
- {
- return false;
- }
-
- // Define a top-level property 'std_iterator' with the name of the method
- // used by for-of loops to create an iterator.
- RootedValue std_iterator(cx);
- std_iterator.setSymbol(cx->wellKnownSymbols().get(JS::SymbolCode::iterator));
- if (!JS_DefineProperty(cx, global, "std_iterator", std_iterator,
- JSPROP_PERMANENT | JSPROP_READONLY))
- {
- return false;
- }
-
- RootedValue std_match(cx);
- std_match.setSymbol(cx->wellKnownSymbols().get(JS::SymbolCode::match));
- if (!JS_DefineProperty(cx, global, "std_match", std_match,
- JSPROP_PERMANENT | JSPROP_READONLY))
- {
- return false;
- }
-
- RootedValue std_replace(cx);
- std_replace.setSymbol(cx->wellKnownSymbols().get(JS::SymbolCode::replace));
- if (!JS_DefineProperty(cx, global, "std_replace", std_replace,
- JSPROP_PERMANENT | JSPROP_READONLY))
- {
- return false;
- }
-
- RootedValue std_search(cx);
- std_search.setSymbol(cx->wellKnownSymbols().get(JS::SymbolCode::search));
- if (!JS_DefineProperty(cx, global, "std_search", std_search,
- JSPROP_PERMANENT | JSPROP_READONLY))
- {
- return false;
- }
-
- RootedValue std_species(cx);
- std_species.setSymbol(cx->wellKnownSymbols().get(JS::SymbolCode::species));
- if (!JS_DefineProperty(cx, global, "std_species", std_species,
- JSPROP_PERMANENT | JSPROP_READONLY))
- {
- return false;
- }
-
- RootedValue std_split(cx);
- std_split.setSymbol(cx->wellKnownSymbols().get(JS::SymbolCode::split));
- if (!JS_DefineProperty(cx, global, "std_split", std_split,
- JSPROP_PERMANENT | JSPROP_READONLY))
- {
- return false;
+ struct SymbolAndName {
+ JS::SymbolCode code;
+ const char* name;
+ };
+
+ SymbolAndName wellKnownSymbols[] = {
+ {JS::SymbolCode::isConcatSpreadable, "std_isConcatSpreadable"},
+ {JS::SymbolCode::iterator, "std_iterator"},
+ {JS::SymbolCode::match, "std_match"},
+ {JS::SymbolCode::matchAll, "std_matchAll"},
+ {JS::SymbolCode::replace, "std_replace"},
+ {JS::SymbolCode::search, "std_search"},
+ {JS::SymbolCode::species, "std_species"},
+ {JS::SymbolCode::split, "std_split"},
+ };
+
+ RootedValue symVal(cx);
+ for (const auto& sym : wellKnownSymbols) {
+ symVal.setSymbol(cx->wellKnownSymbols().get(sym.code));
+ if (!JS_DefineProperty(cx, global, sym.name, symVal,
+ JSPROP_PERMANENT | JSPROP_READONLY)) {
+ return false;
+ }
}
return InitBareBuiltinCtor(cx, global, JSProto_Array) &&
diff --git a/js/src/vm/GlobalObject.h b/js/src/vm/GlobalObject.h
index 5aacfc5dc..9179abbb7 100644
--- a/js/src/vm/GlobalObject.h
+++ b/js/src/vm/GlobalObject.h
@@ -93,6 +93,7 @@ class GlobalObject : public NativeObject
ITERATOR_PROTO,
ARRAY_ITERATOR_PROTO,
STRING_ITERATOR_PROTO,
+ REGEXP_STRING_ITERATOR_PROTO,
LEGACY_GENERATOR_OBJECT_PROTO,
STAR_GENERATOR_OBJECT_PROTO,
STAR_GENERATOR_FUNCTION_PROTO,
@@ -583,6 +584,12 @@ class GlobalObject : public NativeObject
}
static NativeObject*
+ getOrCreateRegExpStringIteratorPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+ return MaybeNativeObject(getOrCreateObject(cx, global, REGEXP_STRING_ITERATOR_PROTO,
+ initRegExpStringIteratorProto));
+ }
+
+ static NativeObject*
getOrCreateLegacyGeneratorObjectPrototype(JSContext* cx, Handle<GlobalObject*> global) {
return MaybeNativeObject(getOrCreateObject(cx, global, LEGACY_GENERATOR_OBJECT_PROTO,
initLegacyGeneratorProto));
@@ -767,6 +774,7 @@ class GlobalObject : public NativeObject
static bool initIteratorProto(JSContext* cx, Handle<GlobalObject*> global);
static bool initArrayIteratorProto(JSContext* cx, Handle<GlobalObject*> global);
static bool initStringIteratorProto(JSContext* cx, Handle<GlobalObject*> global);
+ static bool initRegExpStringIteratorProto(JSContext* cx, Handle<GlobalObject*> global);
// Implemented in vm/GeneratorObject.cpp.
static bool initLegacyGeneratorProto(JSContext* cx, Handle<GlobalObject*> global);
diff --git a/js/src/vm/NativeObject-inl.h b/js/src/vm/NativeObject-inl.h
index e55e3db04..030d92c12 100644
--- a/js/src/vm/NativeObject-inl.h
+++ b/js/src/vm/NativeObject-inl.h
@@ -158,11 +158,11 @@ NativeObject::extendDenseElements(ExclusiveContext* cx,
MOZ_ASSERT(!denseElementsAreFrozen());
/*
- * Don't grow elements for non-extensible objects or watched objects. Dense
- * elements can be added/written with no extensible or watchpoint checks as
- * long as there is capacity for them.
+ * Don't grow elements for non-extensible objects. Dense elements can be
+ * added/written with no extensible checks as long as there is capacity
+ * for them.
*/
- if (!nonProxyIsExtensible() || watched()) {
+ if (!nonProxyIsExtensible()) {
MOZ_ASSERT(getDenseCapacity() == 0);
return DenseElementResult::Incomplete;
}
diff --git a/js/src/vm/NativeObject.cpp b/js/src/vm/NativeObject.cpp
index da0f59fe2..d801fad06 100644
--- a/js/src/vm/NativeObject.cpp
+++ b/js/src/vm/NativeObject.cpp
@@ -9,8 +9,6 @@
#include "mozilla/ArrayUtils.h"
#include "mozilla/Casting.h"
-#include "jswatchpoint.h"
-
#include "gc/Marking.h"
#include "js/Value.h"
#include "vm/Debugger.h"
@@ -602,7 +600,7 @@ NativeObject::maybeDensifySparseElements(js::ExclusiveContext* cx, HandleNativeO
return DenseElementResult::Incomplete;
/* Watch for conditions under which an object's elements cannot be dense. */
- if (!obj->nonProxyIsExtensible() || obj->watched())
+ if (!obj->nonProxyIsExtensible())
return DenseElementResult::Incomplete;
/*
@@ -2410,17 +2408,9 @@ SetExistingProperty(JSContext* cx, HandleNativeObject obj, HandleId id, HandleVa
}
bool
-js::NativeSetProperty(JSContext* cx, HandleNativeObject obj, HandleId id, HandleValue value,
+js::NativeSetProperty(JSContext* cx, HandleNativeObject obj, HandleId id, HandleValue v,
HandleValue receiver, QualifiedBool qualified, ObjectOpResult& result)
{
- // Fire watchpoints, if any.
- RootedValue v(cx, value);
- if (MOZ_UNLIKELY(obj->watched())) {
- WatchpointMap* wpmap = cx->compartment()->watchpointMap;
- if (wpmap && !wpmap->triggerWatchpoint(cx, obj, id, &v))
- return false;
- }
-
// Step numbers below reference ES6 rev 27 9.1.9, the [[Set]] internal
// method for ordinary objects. We substitute our own names for these names
// used in the spec: O -> pobj, P -> id, ownDesc -> shape.
diff --git a/js/src/vm/RegExpObject.cpp b/js/src/vm/RegExpObject.cpp
index ef97ed816..cd0b54c9d 100644
--- a/js/src/vm/RegExpObject.cpp
+++ b/js/src/vm/RegExpObject.cpp
@@ -49,6 +49,7 @@ JS_STATIC_ASSERT(GlobalFlag == JSREG_GLOB);
JS_STATIC_ASSERT(MultilineFlag == JSREG_MULTILINE);
JS_STATIC_ASSERT(StickyFlag == JSREG_STICKY);
JS_STATIC_ASSERT(UnicodeFlag == JSREG_UNICODE);
+JS_STATIC_ASSERT(DotAllFlag == JSREG_DOTALL);
RegExpObject*
js::RegExpAlloc(ExclusiveContext* cx, HandleObject proto /* = nullptr */)
@@ -267,7 +268,7 @@ RegExpObject::create(ExclusiveContext* cx, HandleAtom source, RegExpFlag flags,
tokenStream = dummyTokenStream.ptr();
}
- if (!irregexp::ParsePatternSyntax(*tokenStream, alloc, source, flags & UnicodeFlag))
+ if (!irregexp::ParsePatternSyntax(*tokenStream, alloc, source, flags & UnicodeFlag, flags & DotAllFlag))
return nullptr;
Rooted<RegExpObject*> regexp(cx, RegExpAlloc(cx));
@@ -1017,7 +1018,7 @@ RegExpShared::compile(JSContext* cx, HandleAtom pattern, HandleLinearString inpu
irregexp::RegExpCompileData data;
if (!irregexp::ParsePattern(dummyTokenStream, cx->tempLifoAlloc(), pattern,
multiline(), mode == MatchOnly, unicode(), ignoreCase(),
- global(), sticky(), &data))
+ global(), sticky(), dotall(), &data))
{
return false;
}
diff --git a/js/src/vm/RegExpObject.h b/js/src/vm/RegExpObject.h
index f1ea101ed..95c64fa67 100644
--- a/js/src/vm/RegExpObject.h
+++ b/js/src/vm/RegExpObject.h
@@ -53,16 +53,18 @@ enum RegExpFlag
MultilineFlag = 0x04,
StickyFlag = 0x08,
UnicodeFlag = 0x10,
+ DotAllFlag = 0x20,
NoFlags = 0x00,
- AllFlags = 0x1f
+ AllFlags = 0x3f
};
static_assert(IgnoreCaseFlag == REGEXP_IGNORECASE_FLAG &&
GlobalFlag == REGEXP_GLOBAL_FLAG &&
MultilineFlag == REGEXP_MULTILINE_FLAG &&
StickyFlag == REGEXP_STICKY_FLAG &&
- UnicodeFlag == REGEXP_UNICODE_FLAG,
+ UnicodeFlag == REGEXP_UNICODE_FLAG &&
+ DotAllFlag == REGEXP_DOTALL_FLAG,
"Flag values should be in sync with self-hosted JS");
enum RegExpRunStatus
@@ -193,6 +195,7 @@ class RegExpShared
bool multiline() const { return flags & MultilineFlag; }
bool sticky() const { return flags & StickyFlag; }
bool unicode() const { return flags & UnicodeFlag; }
+ bool dotall() const { return flags & DotAllFlag; }
bool isCompiled(CompilationMode mode, bool latin1,
ForceByteCodeEnum force = DontForceByteCode) const {
@@ -480,6 +483,7 @@ class RegExpObject : public NativeObject
bool multiline() const { return getFlags() & MultilineFlag; }
bool sticky() const { return getFlags() & StickyFlag; }
bool unicode() const { return getFlags() & UnicodeFlag; }
+ bool dotall() const { return getFlags() & DotAllFlag; }
static bool isOriginalFlagGetter(JSNative native, RegExpFlag* mask);
diff --git a/js/src/vm/Runtime.cpp b/js/src/vm/Runtime.cpp
index 5fc8e0e17..284a4f3d7 100644
--- a/js/src/vm/Runtime.cpp
+++ b/js/src/vm/Runtime.cpp
@@ -34,7 +34,6 @@
#include "jsnativestack.h"
#include "jsobj.h"
#include "jsscript.h"
-#include "jswatchpoint.h"
#include "jswin.h"
#include "jswrapper.h"
diff --git a/js/src/vm/SelfHosting.cpp b/js/src/vm/SelfHosting.cpp
index 792a00490..ffd707b14 100644
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -857,33 +857,20 @@ intrinsic_NewStringIterator(JSContext* cx, unsigned argc, Value* vp)
}
static bool
-intrinsic_NewListIterator(JSContext* cx, unsigned argc, Value* vp)
+intrinsic_NewRegExpStringIterator(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
MOZ_ASSERT(args.length() == 0);
- RootedObject proto(cx, GlobalObject::getOrCreateIteratorPrototype(cx, cx->global()));
+ RootedObject proto(cx, GlobalObject::getOrCreateRegExpStringIteratorPrototype(cx, cx->global()));
if (!proto)
return false;
- RootedObject iterator(cx);
- iterator = NewObjectWithGivenProto(cx, &ListIteratorObject::class_, proto);
- if (!iterator)
+ JSObject* obj = NewObjectWithGivenProto(cx, &RegExpStringIteratorObject::class_, proto);
+ if (!obj)
return false;
- args.rval().setObject(*iterator);
- return true;
-}
-
-static bool
-intrinsic_ActiveFunction(JSContext* cx, unsigned argc, Value* vp)
-{
- CallArgs args = CallArgsFromVp(argc, vp);
- MOZ_ASSERT(args.length() == 0);
-
- ScriptFrameIter iter(cx);
- MOZ_ASSERT(iter.isFunctionFrame());
- args.rval().setObject(*iter.callee(cx));
+ args.rval().setObject(*obj);
return true;
}
@@ -2133,6 +2120,21 @@ intrinsic_ModuleNamespaceExports(JSContext* cx, unsigned argc, Value* vp)
return true;
}
+static bool
+intrinsic_PromiseResolve(JSContext* cx, unsigned argc, Value* vp)
+{
+ CallArgs args = CallArgsFromVp(argc, vp);
+ MOZ_ASSERT(args.length() == 2);
+
+ RootedObject constructor(cx, &args[0].toObject());
+ JSObject* promise = js::PromiseResolve(cx, constructor, args[1]);
+ if (!promise)
+ return false;
+
+ args.rval().setObject(*promise);
+ return true;
+}
+
// The self-hosting global isn't initialized with the normal set of builtins.
// Instead, individual C++-implemented functions that're required by
// self-hosted code are defined as global functions. Accessing these
@@ -2290,11 +2292,6 @@ static const JSFunctionSpec intrinsic_functions[] = {
JS_FN("CallArrayIteratorMethodIfWrapped",
CallNonGenericSelfhostedMethod<Is<ArrayIteratorObject>>, 2,0),
- JS_FN("NewListIterator", intrinsic_NewListIterator, 0,0),
- JS_FN("CallListIteratorMethodIfWrapped",
- CallNonGenericSelfhostedMethod<Is<ListIteratorObject>>, 2,0),
- JS_FN("ActiveFunction", intrinsic_ActiveFunction, 0,0),
-
JS_FN("_SetCanonicalName", intrinsic_SetCanonicalName, 2,0),
JS_INLINABLE_FN("GuardToArrayIterator",
@@ -2309,9 +2306,8 @@ static const JSFunctionSpec intrinsic_functions[] = {
JS_INLINABLE_FN("GuardToStringIterator",
intrinsic_GuardToBuiltin<StringIteratorObject>, 1,0,
IntrinsicGuardToStringIterator),
- JS_INLINABLE_FN("IsListIterator",
- intrinsic_IsInstanceOfBuiltin<ListIteratorObject>, 1,0,
- IntrinsicIsListIterator),
+ JS_FN("GuardToRegExpStringIterator",
+ intrinsic_GuardToBuiltin<RegExpStringIteratorObject>, 1,0),
JS_FN("_CreateMapIterationResultPair", intrinsic_CreateMapIterationResultPair, 0, 0),
JS_INLINABLE_FN("_GetNextMapEntryForIterator", intrinsic_GetNextMapEntryForIterator, 2,0,
@@ -2329,6 +2325,9 @@ static const JSFunctionSpec intrinsic_functions[] = {
JS_FN("NewStringIterator", intrinsic_NewStringIterator, 0,0),
JS_FN("CallStringIteratorMethodIfWrapped",
CallNonGenericSelfhostedMethod<Is<StringIteratorObject>>, 2,0),
+ JS_FN("NewRegExpStringIterator", intrinsic_NewRegExpStringIterator, 0,0),
+ JS_FN("CallRegExpStringIteratorMethodIfWrapped",
+ CallNonGenericSelfhostedMethod<Is<RegExpStringIteratorObject>>, 2,0),
JS_FN("IsStarGeneratorObject",
intrinsic_IsInstanceOfBuiltin<StarGeneratorObject>, 1,0),
@@ -2533,11 +2532,14 @@ static const JSFunctionSpec intrinsic_functions[] = {
intrinsic_InstantiateModuleFunctionDeclarations, 1, 0),
JS_FN("SetModuleState", intrinsic_SetModuleState, 1, 0),
JS_FN("EvaluateModule", intrinsic_EvaluateModule, 1, 0),
- JS_FN("IsModuleNamespace", intrinsic_IsInstanceOfBuiltin<ModuleNamespaceObject>, 1, 0),
JS_FN("NewModuleNamespace", intrinsic_NewModuleNamespace, 2, 0),
JS_FN("AddModuleNamespaceBinding", intrinsic_AddModuleNamespaceBinding, 4, 0),
JS_FN("ModuleNamespaceExports", intrinsic_ModuleNamespaceExports, 1, 0),
+ JS_FN("IsPromiseObject", intrinsic_IsInstanceOfBuiltin<PromiseObject>, 1, 0),
+ JS_FN("CallPromiseMethodIfWrapped", CallNonGenericSelfhostedMethod<Is<PromiseObject>>, 2, 0),
+ JS_FN("PromiseResolve", intrinsic_PromiseResolve, 2, 0),
+
JS_FS_END
};
diff --git a/js/src/vm/Shape.h b/js/src/vm/Shape.h
index fd6d843e0..85bc044a5 100644
--- a/js/src/vm/Shape.h
+++ b/js/src/vm/Shape.h
@@ -387,7 +387,7 @@ class BaseShape : public gc::TenuredCell
INDEXED = 0x20,
/* (0x40 is unused) */
HAD_ELEMENTS_ACCESS = 0x80,
- WATCHED = 0x100,
+ /* (0x100 is unused) */
ITERATED_SINGLETON = 0x200,
NEW_GROUP_UNKNOWN = 0x400,
UNCACHEABLE_PROTO = 0x800,
diff --git a/js/src/vm/Time.cpp b/js/src/vm/Time.cpp
index 87531c148..a9a5b7f0f 100644
--- a/js/src/vm/Time.cpp
+++ b/js/src/vm/Time.cpp
@@ -11,6 +11,10 @@
#include "mozilla/DebugOnly.h"
#include "mozilla/MathAlgorithms.h"
+#ifdef XP_SOLARIS
+#define _REENTRANT 1
+#endif
+
#include <string.h>
#include <time.h>
@@ -30,6 +34,10 @@
#ifdef XP_UNIX
+#ifdef _SVID_GETTOD /* Defined only on Solaris, see Solaris <sys/types.h> */
+extern int gettimeofday(struct timeval* tv);
+#endif
+
#include <sys/time.h>
#endif /* XP_UNIX */
@@ -42,7 +50,11 @@ PRMJ_Now()
{
struct timeval tv;
+#ifdef _SVID_GETTOD /* Defined only on Solaris, see Solaris <sys/types.h> */
+ gettimeofday(&tv);
+#else
gettimeofday(&tv, 0);
+#endif /* _SVID_GETTOD */
return int64_t(tv.tv_sec) * PRMJ_USEC_PER_SEC + int64_t(tv.tv_usec);
}
diff --git a/js/src/vm/TypeInference.cpp b/js/src/vm/TypeInference.cpp
index 88327b47e..2b1fa0e3b 100644
--- a/js/src/vm/TypeInference.cpp
+++ b/js/src/vm/TypeInference.cpp
@@ -2670,14 +2670,6 @@ ObjectGroup::updateNewPropertyTypes(ExclusiveContext* cx, JSObject* objArg, jsid
if (shape)
UpdatePropertyType(cx, types, obj, shape, false);
}
-
- if (obj->watched()) {
- /*
- * Mark the property as non-data, to inhibit optimizations on it
- * and avoid bypassing the watchpoint handler.
- */
- types->setNonDataProperty(cx);
- }
}
void
@@ -3622,42 +3614,42 @@ struct DestroyTypeNewScript
} // namespace
-bool DPAConstraintInfo::finishConstraints(JSContext* cx, ObjectGroup* group) {
- for (const ProtoConstraint& constraint : protoConstraints_) {
- ObjectGroup* protoGroup = constraint.proto->group();
-
- // Note: we rely on the group's type information being unchanged since
- // AddClearDefiniteGetterSetterForPrototypeChain.
-
- bool unknownProperties = protoGroup->unknownProperties();
- MOZ_RELEASE_ASSERT(!unknownProperties);
-
- HeapTypeSet* protoTypes =
- protoGroup->getProperty(cx, constraint.proto, constraint.id);
- MOZ_RELEASE_ASSERT(protoTypes);
-
- MOZ_ASSERT(!protoTypes->nonDataProperty());
- MOZ_ASSERT(!protoTypes->nonWritableProperty());
-
- if (!protoTypes->addConstraint(
- cx,
- cx->typeLifoAlloc().new_<TypeConstraintClearDefiniteGetterSetter>(
- group))) {
- ReportOutOfMemory(cx);
- return false;
- }
- }
-
- for (const InliningConstraint& constraint : inliningConstraints_) {
- if (!AddClearDefiniteFunctionUsesInScript(cx, group, constraint.caller,
- constraint.callee)) {
- ReportOutOfMemory(cx);
- return false;
- }
- }
-
- return true;
-}
+bool DPAConstraintInfo::finishConstraints(JSContext* cx, ObjectGroup* group) {
+ for (const ProtoConstraint& constraint : protoConstraints_) {
+ ObjectGroup* protoGroup = constraint.proto->group();
+
+ // Note: we rely on the group's type information being unchanged since
+ // AddClearDefiniteGetterSetterForPrototypeChain.
+
+ bool unknownProperties = protoGroup->unknownProperties();
+ MOZ_RELEASE_ASSERT(!unknownProperties);
+
+ HeapTypeSet* protoTypes =
+ protoGroup->getProperty(cx, constraint.proto, constraint.id);
+ MOZ_RELEASE_ASSERT(protoTypes);
+
+ MOZ_ASSERT(!protoTypes->nonDataProperty());
+ MOZ_ASSERT(!protoTypes->nonWritableProperty());
+
+ if (!protoTypes->addConstraint(
+ cx,
+ cx->typeLifoAlloc().new_<TypeConstraintClearDefiniteGetterSetter>(
+ group))) {
+ ReportOutOfMemory(cx);
+ return false;
+ }
+ }
+
+ for (const InliningConstraint& constraint : inliningConstraints_) {
+ if (!AddClearDefiniteFunctionUsesInScript(cx, group, constraint.caller,
+ constraint.callee)) {
+ ReportOutOfMemory(cx);
+ return false;
+ }
+ }
+
+ return true;
+}
bool
TypeNewScript::maybeAnalyze(JSContext* cx, ObjectGroup* group, bool* regenerate, bool force)
@@ -3826,13 +3818,13 @@ TypeNewScript::maybeAnalyze(JSContext* cx, ObjectGroup* group, bool* regenerate,
// The definite properties analysis found exactly the properties that
// are held in common by the preliminary objects. No further analysis
// is needed.
-
- if (!constraintInfo.finishConstraints(cx, group)) {
- return false;
- }
- if (!group->newScript()) {
- return true;
- }
+
+ if (!constraintInfo.finishConstraints(cx, group)) {
+ return false;
+ }
+ if (!group->newScript()) {
+ return true;
+ }
group->addDefiniteProperties(cx, templateObject()->lastProperty());
@@ -3854,16 +3846,16 @@ TypeNewScript::maybeAnalyze(JSContext* cx, ObjectGroup* group, bool* regenerate,
initialFlags);
if (!initialGroup)
return false;
-
- // Add the constraints. Use the initialGroup as group referenced by the
- // constraints because that's the group that will have the TypeNewScript
- // associated with it. See the detachNewScript and setNewScript calls below.
- if (!constraintInfo.finishConstraints(cx, initialGroup)) {
- return false;
- }
- if (!group->newScript()) {
- return true;
- }
+
+ // Add the constraints. Use the initialGroup as group referenced by the
+ // constraints because that's the group that will have the TypeNewScript
+ // associated with it. See the detachNewScript and setNewScript calls below.
+ if (!constraintInfo.finishConstraints(cx, initialGroup)) {
+ return false;
+ }
+ if (!group->newScript()) {
+ return true;
+ }
initialGroup->addDefiniteProperties(cx, templateObject()->lastProperty());
group->addDefiniteProperties(cx, prefixShape);
diff --git a/js/src/wasm/WasmSignalHandlers.cpp b/js/src/wasm/WasmSignalHandlers.cpp
index c4733cc96..21093ca9a 100644
--- a/js/src/wasm/WasmSignalHandlers.cpp
+++ b/js/src/wasm/WasmSignalHandlers.cpp
@@ -130,11 +130,16 @@ class AutoSetHandlingSegFault
# define EPC_sig(p) ((p)->sc_pc)
# define RFP_sig(p) ((p)->sc_regs[30])
# endif
-#elif defined(__linux__)
+#elif defined(__linux__) || defined(__sun)
# if defined(__linux__)
# define XMM_sig(p,i) ((p)->uc_mcontext.fpregs->_xmm[i])
# define EIP_sig(p) ((p)->uc_mcontext.gregs[REG_EIP])
-# else
+# else // defined(__sun)
+/* See https://www.illumos.org/issues/5876. They keep arguing over whether
+ * <ucontext.h> should provide the register index defines in regset.h or
+ * require applications to request them specifically, and we need them here. */
+#include <ucontext.h>
+#include <sys/regset.h>
# define XMM_sig(p,i) ((p)->uc_mcontext.fpregs.fp_reg_set.fpchip_state.xmm[i])
# define EIP_sig(p) ((p)->uc_mcontext.gregs[REG_PC])
# endif