author | Brindusan Cristian <cbrindusan@mozilla.com> |
Fri, 21 Sep 2018 20:29:29 +0300 | |
changeset 437712 | ce4e883f7642c2c8652e7c065f5bfb122a71cb95 |
parent 437711 | 3ffe4318af3ad3033e22c80f1d4c8d1e8222a5f7 (current diff) |
parent 437664 | 1330a9eb3da56d783aefabe063764eb55e9adadc (diff) |
child 437713 | 1879856ca1ab0def40038be7482a9bc2e140cfee |
child 437744 | 7d5961e2ffe35c5618814354daf8c93c9204e69d |
child 437750 | bb920e4191661b821481bfc9cba14a5ab84dc241 |
push id | 108133 |
push user | cbrindusan@mozilla.com |
push date | Fri, 21 Sep 2018 17:33:11 +0000 |
treeherder | mozilla-inbound@1879856ca1ab [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | merge |
milestone | 64.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/accessible/generic/ImageAccessible.cpp +++ b/accessible/generic/ImageAccessible.cpp @@ -56,17 +56,17 @@ ImageAccessible::NativeState() const content->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST, getter_AddRefs(imageRequest)); nsCOMPtr<imgIContainer> imgContainer; if (imageRequest) imageRequest->GetImage(getter_AddRefs(imgContainer)); if (imgContainer) { - bool animated; + bool animated = false; imgContainer->GetAnimated(&animated); if (animated) state |= states::ANIMATED; } return state; }
--- a/browser/config/mozconfigs/win64/nightly-asan-reporter +++ b/browser/config/mozconfigs/win64/nightly-asan-reporter @@ -30,13 +30,9 @@ export MOZILLA_OFFICIAL=1 ac_add_options --disable-sandbox # Enable Telemetry # The channel reported by Telemetry here will be "nightly-asan" as specified # in the respective override pref (toolkit.telemetry.overrideUpdateChannel), # while the build otherwise identifies as "nightly" to receive its updates. export MOZ_TELEMETRY_REPORTING=1 -# Disable stack instrumentation until we can tackle bug 1477490 -export CFLAGS="-mllvm -asan-stack=0" -export CXXFLAGS="-mllvm -asan-stack=0" - . "$topsrcdir/build/mozconfig.common.override"
--- a/build/build-clang/clang-win64.json +++ b/build/build-clang/clang-win64.json @@ -10,11 +10,13 @@ "compiler_repo": "https://llvm.org/svn/llvm-project/compiler-rt/tags/RELEASE_700/final", "libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/tags/RELEASE_700/final", "python_path": "c:/mozilla-build/python/python.exe", "cc": "cl.exe", "cxx": "cl.exe", "ml": "ml64.exe", "patches": [ "workaround-issue38586.patch", + "r342649-hotpatch-8-byte-nops.patch", + "r342652-unpoison-thread-stacks.patch", "loosen-msvc-detection.patch" ] }
new file mode 100644 --- /dev/null +++ b/build/build-clang/r342649-hotpatch-8-byte-nops.patch @@ -0,0 +1,30 @@ +[winasan] Reduce hotpatch prefix check to 8 bytes + +Same idea as r310419: The 8 byte nop is a suffix of the 9 byte nop, and we need at most 6 bytes. + +Differential Revision: https://reviews.llvm.org/D51788 + +--- a/compiler-rt/lib/interception/interception_win.cc (revision 342648) ++++ b/compiler-rt/lib/interception/interception_win.cc (revision 342649) +@@ -223,8 +223,8 @@ + return true; + } + +-static const u8 kHintNop9Bytes[] = { +- 0x66, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 ++static const u8 kHintNop8Bytes[] = { ++ 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + template<class T> +@@ -239,8 +239,8 @@ + static bool FunctionHasPadding(uptr address, uptr size) { + if (IsMemoryPadding(address - size, size)) + return true; +- if (size <= sizeof(kHintNop9Bytes) && +- FunctionHasPrefix(address, kHintNop9Bytes)) ++ if (size <= sizeof(kHintNop8Bytes) && ++ FunctionHasPrefix(address, kHintNop8Bytes)) + return true; + return false; + }
new file mode 100644 --- /dev/null +++ b/build/build-clang/r342652-unpoison-thread-stacks.patch @@ -0,0 +1,34 @@ +[winasan] Unpoison the stack in NtTerminateThread + +In long-running builds we've seen some ASan complaints during thread creation that we suspect are due to leftover poisoning from previous threads whose stacks occupied that memory. This patch adds a hook that unpoisons the stack just before the NtTerminateThread syscall. + +Differential Revision: https://reviews.llvm.org/D52091 + +--- a/compiler-rt/lib/asan/asan_win.cc (revision 342651) ++++ b/compiler-rt/lib/asan/asan_win.cc (revision 342652) +@@ -154,6 +154,14 @@ + asan_thread_start, t, thr_flags, tid); + } + ++INTERCEPTOR_WINAPI(void, NtTerminateThread, void *rcx) { ++ // Unpoison the terminating thread's stack because the memory may be re-used. ++ NT_TIB *tib = (NT_TIB *)NtCurrentTeb(); ++ uptr stackSize = (uptr)tib->StackBase - (uptr)tib->StackLimit; ++ __asan_unpoison_memory_region(tib->StackLimit, stackSize); ++ return REAL(NtTerminateThread(rcx)); ++} ++ + // }}} + + namespace __asan { +@@ -161,7 +169,9 @@ + void InitializePlatformInterceptors() { + ASAN_INTERCEPT_FUNC(CreateThread); + ASAN_INTERCEPT_FUNC(SetUnhandledExceptionFilter); +- ++ CHECK(::__interception::OverrideFunction("NtTerminateThread", ++ (uptr)WRAP(NtTerminateThread), ++ (uptr *)&REAL(NtTerminateThread))); + #ifdef _WIN64 + ASAN_INTERCEPT_FUNC(__C_specific_handler); + #else
--- a/build/mach_bootstrap.py +++ b/build/mach_bootstrap.py @@ -185,61 +185,42 @@ def bootstrap(topsrcdir, mozilla_dir=Non # more robust. return mozversioncontrol.get_repository_object(path=mozilla_dir) except (mozversioncontrol.InvalidRepoPath, mozversioncontrol.MissingVCSTool): return None def telemetry_handler(context, data): # We have not opted-in to telemetry - if 'BUILD_SYSTEM_TELEMETRY' not in os.environ: + if not context.settings.build.telemetry: return telemetry_dir = os.path.join(get_state_dir()[0], 'telemetry') try: os.mkdir(telemetry_dir) except OSError as e: if e.errno != errno.EEXIST: raise outgoing_dir = os.path.join(telemetry_dir, 'outgoing') try: os.mkdir(outgoing_dir) except OSError as e: if e.errno != errno.EEXIST: raise - # Add common metadata to help submit sorted data later on. - data['argv'] = sys.argv - data.setdefault('system', {}).update(dict( - architecture=list(platform.architecture()), - machine=platform.machine(), - python_version=platform.python_version(), - release=platform.release(), - system=platform.system(), - version=platform.version(), - )) - - if platform.system() == 'Linux': - dist = list(platform.linux_distribution()) - data['system']['linux_distribution'] = dist - elif platform.system() == 'Windows': - win32_ver = list((platform.win32_ver())), - data['system']['win32_ver'] = win32_ver - elif platform.system() == 'Darwin': - # mac version is a special Cupertino snowflake - r, v, m = platform.mac_ver() - data['system']['mac_ver'] = [r, list(v), m] - with open(os.path.join(outgoing_dir, str(uuid.uuid4()) + '.json'), 'w') as f: json.dump(data, f, sort_keys=True) def should_skip_dispatch(context, handler): # The user is performing a maintenance command. - if handler.name in ('bootstrap', 'doctor', 'mach-commands', 'vcs-setup'): + if handler.name in ('bootstrap', 'doctor', 'mach-commands', 'vcs-setup', + # We call mach environment in client.mk which would cause the + # data submission to block the forward progress of make. + 'environment'): return True # We are running in automation. if 'MOZ_AUTOMATION' in os.environ or 'TASK_ID' in os.environ: return True # The environment is likely a machine invocation. if sys.stdin.closed or not sys.stdin.isatty(): @@ -252,23 +233,18 @@ def bootstrap(topsrcdir, mozilla_dir=Non For now, we will use this to handle build system telemetry. """ # Don't do anything when... if should_skip_dispatch(context, handler): return - # We call mach environment in client.mk which would cause the - # data submission below to block the forward progress of make. - if handler.name in ('environment'): - return - # We have not opted-in to telemetry - if 'BUILD_SYSTEM_TELEMETRY' not in os.environ: + if not context.settings.build.telemetry: return # Every n-th operation if random.randint(1, TELEMETRY_SUBMISSION_FREQUENCY) != 1: return with open(os.devnull, 'wb') as devnull: subprocess.Popen([sys.executable,
--- a/dom/svg/SVGTextPathElement.cpp +++ b/dom/svg/SVGTextPathElement.cpp @@ -85,16 +85,28 @@ nsSVGElement::StringInfo SVGTextPathElem //---------------------------------------------------------------------- // Implementation SVGTextPathElement::SVGTextPathElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo) : SVGTextPathElementBase(aNodeInfo) { } +void +SVGTextPathElement::HrefAsString(nsAString& aHref) +{ + if (mStringAttributes[SVGTextPathElement::HREF].IsExplicitlySet()) { + mStringAttributes[SVGTextPathElement::HREF] + .GetAnimValue(aHref, this); + } else { + mStringAttributes[SVGTextPathElement::XLINK_HREF] + .GetAnimValue(aHref, this); + } +} + //---------------------------------------------------------------------- // nsINode methods NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGTextPathElement) already_AddRefed<SVGAnimatedString> SVGTextPathElement::Href() {
--- a/dom/svg/SVGTextPathElement.h +++ b/dom/svg/SVGTextPathElement.h @@ -54,16 +54,18 @@ public: // WebIDL already_AddRefed<SVGAnimatedLength> StartOffset(); already_AddRefed<SVGAnimatedEnumeration> Method(); already_AddRefed<SVGAnimatedEnumeration> Spacing(); already_AddRefed<SVGAnimatedEnumeration> Side(); already_AddRefed<SVGAnimatedString> Href(); + void HrefAsString(nsAString& aHref); + protected: virtual LengthAttributesInfo GetLengthInfo() override; virtual EnumAttributesInfo GetEnumInfo() override; virtual StringAttributesInfo GetStringInfo() override; enum { /* TEXTLENGTH, */ STARTOFFSET = 1 }; nsSVGLength2 mLengthAttributes[2];
--- a/gfx/layers/client/ContentClient.cpp +++ b/gfx/layers/client/ContentClient.cpp @@ -190,17 +190,16 @@ ContentClient::BeginPaint(PaintedLayer* } // Try to rotate the buffer or unrotate it if we cannot be rotated if (needsUnrotate) { if (canUnrotate && mBuffer->UnrotateBufferTo(newParameters)) { newParameters.SetUnrotated(); mBuffer->SetParameters(newParameters); } else { - MOZ_ASSERT(!result.mAsyncPaint); MOZ_ASSERT(GetFrontBuffer()); mBuffer->Unlock(); dest.mBufferRect = ComputeBufferRect(dest.mNeededRegion.GetBounds()); dest.mCanReuseBuffer = false; } } else { mBuffer->SetParameters(newParameters); }
new file mode 100644 --- /dev/null +++ b/gfx/tests/crashtests/1470440.html @@ -0,0 +1,7 @@ +<style> +:last-child{ + border-width: 9596.6vmin thin; + border-style: dotted; +} +</style> +<rect id='id3'/>
--- a/gfx/tests/crashtests/crashtests.list +++ b/gfx/tests/crashtests/crashtests.list @@ -162,9 +162,10 @@ load 1308394.html load 1317403-1.html # bug 1331533 load 1325159-1.html load 1331683.html skip-if(Android) pref(dom.disable_open_during_load,false) load 1343666.html load 1408078-1.html load 1464243.html load 1467847-1.html load 1468020.html +load 1470440.html load 1478035.html
--- a/js/src/devtools/automation/autospider.py +++ b/js/src/devtools/automation/autospider.py @@ -418,17 +418,17 @@ if not args.nobuild: if not os.path.isdir(hostdir): os.makedirs(hostdir) shutil.copy(os.path.join(DIR.tooltool, "breakpad-tools", "dump_syms"), os.path.join(hostdir, 'dump_syms')) run_command([ 'make', 'recurse_syms', 'MOZ_SOURCE_REPO=file://' + DIR.source, - 'RUST_TARGET=0', 'RUSTC_COMMIT=0', + 'RUSTC_COMMIT=0', 'MOZ_CRASHREPORTER=1', 'MOZ_AUTOMATION_BUILD_SYMBOLS=1', ], check=True) COMMAND_PREFIX = [] # On Linux, disable ASLR to make shell builds a bit more reproducible. if subprocess.call("type setarch >/dev/null 2>&1", shell=True) == 0: COMMAND_PREFIX.extend(['setarch', platform.machine(), '-R'])
--- a/js/src/gc/GC.cpp +++ b/js/src/gc/GC.cpp @@ -4278,16 +4278,21 @@ GCRuntime::purgeRuntime() rt->caches().purge(); if (auto cache = rt->maybeThisRuntimeSharedImmutableStrings()) { cache->purge(); } MOZ_ASSERT(unmarkGrayStack.empty()); unmarkGrayStack.clearAndFree(); + + // If we're the main runtime, tell helper threads to free their unused + // memory when they are next idle. + if (!rt->parentRuntime) + HelperThreadState().triggerFreeUnusedMemory(); } bool GCRuntime::shouldPreserveJITCode(Realm* realm, const TimeStamp ¤tTime, JS::gcreason::Reason reason, bool canAllocateMoreCode) { static const auto oneSecond = TimeDuration::FromSeconds(1);
--- a/js/src/jit-test/tests/wasm/gc/anyref-global-object.js +++ b/js/src/jit-test/tests/wasm/gc/anyref-global-object.js @@ -42,19 +42,18 @@ assertEq(new WebAssembly.Global({value: g = new WebAssembly.Global({value: "anyref"}, true); assertEq(g.value instanceof Boolean, true); assertEq(!!g.value, true); g = new WebAssembly.Global({value: "anyref"}, Symbol("status")); assertEq(g.value instanceof Symbol, true); assertEq(g.value.toString(), "Symbol(status)"); - assertErrorMessage(() => new WebAssembly.Global({value: "anyref"}, undefined), - TypeError, - "can't convert undefined to object"); + g = new WebAssembly.Global({value: "anyref"}, undefined); + assertEq(g.value, null); })(); (function() { // Test mutable property and assignment. let g = new WebAssembly.Global({value: "anyref", mutable: true}, null); assertEq(g.value, null); let obj = { x: 42 };
--- a/js/src/jit-test/tests/wasm/gc/anyref.js +++ b/js/src/jit-test/tests/wasm/gc/anyref.js @@ -88,21 +88,35 @@ let { exports } = wasmEvalText(`(module ref.null anyref set_local 0 i32.const 58 call $sum drop get_local 0 ref.is_null ) -)`); + + (func (export "ref_eq") (param $a anyref) (param $b anyref) (result i32) + (ref.eq (get_local $a) (get_local $b))) + + (func (export "ref_eq_for_control") (param $a anyref) (param $b anyref) (result f64) + (if f64 (ref.eq (get_local $a) (get_local $b)) + (f64.const 5.0) + (f64.const 3.0))) + )`); assertEq(exports.is_null(), 1); assertEq(exports.is_null_spill(), 1); assertEq(exports.is_null_local(), 1); +assertEq(exports.ref_eq(null, null), 1); +assertEq(exports.ref_eq(null, {}), 0); +assertEq(exports.ref_eq(this, this), 1); +assertEq(exports.ref_eq_for_control(null, null), 5); +assertEq(exports.ref_eq_for_control(null, {}), 3); +assertEq(exports.ref_eq_for_control(this, this), 5); // Anyref param and result in wasm functions. exports = wasmEvalText(`(module (gc_feature_opt_in 1) (func (export "is_null") (result i32) (param $ref anyref) get_local $ref ref.is_null
--- a/js/src/jit-test/tests/wasm/gc/gc-feature-opt-in.js +++ b/js/src/jit-test/tests/wasm/gc/gc-feature-opt-in.js @@ -113,8 +113,14 @@ assertErrorMessage(() => new WebAssembly WebAssembly.CompileError, /unrecognized opcode/); assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary( `(module (func ref.is_null))`)), WebAssembly.CompileError, /unrecognized opcode/); + +assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary( + `(module + (func ref.eq))`)), + WebAssembly.CompileError, + /unrecognized opcode/);
--- a/js/src/jit-test/tests/wasm/gc/ref.js +++ b/js/src/jit-test/tests/wasm/gc/ref.js @@ -53,16 +53,21 @@ var bin = wasmTextToBinary( (ref.null (ref $even))) (func (param (ref $cons)) (call $cdr (get_local 0)) drop (call $imp (get_local 0)) drop) + (func (param (ref $cons)) + (drop (ref.eq (get_local 0) (ref.null (ref $cons)))) + (drop (ref.eq (ref.null (ref $cons)) (get_local 0))) + (drop (ref.eq (get_local 0) (ref.null anyref))) + (drop (ref.eq (ref.null anyref) (get_local 0)))) )`); // Validation assertEq(WebAssembly.validate(bin), true); // ref.is_null should work on any reference type
--- a/js/src/jit-test/tests/wasm/globals.js +++ b/js/src/jit-test/tests/wasm/globals.js @@ -338,22 +338,22 @@ wasmAssert(`(module let mod = wasmEvalText(`(module (import "" "g" (global i64)) (func (export "f") (result i32) (i64.eqz (get_global 0))))`, {"":{g: new Global({value: "i64"})}}); assertEq(mod.exports.f(), 1); { - // "value" is enumerable + // "value" is enumerable and is the first enumerated value let x = new Global({value: "i32"}); let s = ""; for ( let i in x ) s = s + i + ","; - assertEq(s, "value,"); + assertEq(s.substring(0,6), "value,"); } // "value" is defined on the prototype, not on the object assertEq("value" in Global.prototype, true); // Can't set the value of an immutable global assertErrorMessage(() => (new Global({value: "i32"})).value = 10, TypeError,
rename from js/src/jit-test/tests/wasm/regress/proxy-has-trap-table.js rename to js/src/jit-test/tests/wasm/regress/proxy-get-trap-table.js --- a/js/src/jit-test/tests/wasm/regress/proxy-has-trap-table.js +++ b/js/src/jit-test/tests/wasm/regress/proxy-get-trap-table.js @@ -1,11 +1,14 @@ +// The 'get' handler should be invoked directly when reading fields of the +// descriptor. + assertErrorMessage(() => { var desc = { element: "anyfunc", initial: 1 }; var proxy = new Proxy({}, { - has: true + get: true }); Object.setPrototypeOf(desc, proxy); let table = new WebAssembly.Table(desc); -}, TypeError, /proxy handler's has trap/); +}, TypeError, /proxy handler's get trap/);
--- a/js/src/jit-test/tests/wasm/spec/jsapi.js +++ b/js/src/jit-test/tests/wasm/spec/jsapi.js @@ -251,17 +251,17 @@ test(() => { assert_equals(String(emptyModule), "[object WebAssembly.Module]"); assert_equals(Object.getPrototypeOf(emptyModule), moduleProto); }, "'WebAssembly.Module' instance objects"); test(() => { const moduleImportsDesc = Object.getOwnPropertyDescriptor(Module, 'imports'); assert_equals(typeof moduleImportsDesc.value, "function"); assert_equals(moduleImportsDesc.writable, true); - assert_equals(moduleImportsDesc.enumerable, false); + assert_equals(moduleImportsDesc.enumerable, true); assert_equals(moduleImportsDesc.configurable, true); }, "'WebAssembly.Module.imports' data property"); test(() => { const moduleImportsDesc = Object.getOwnPropertyDescriptor(Module, 'imports'); const moduleImports = moduleImportsDesc.value; assert_equals(moduleImports.length, 1); assertThrows(() => moduleImports(), TypeError); @@ -286,17 +286,17 @@ test(() => { assert_equals(arr[3].module, "g"); assert_equals(arr[3].name, "âš¡"); }, "'WebAssembly.Module.imports' method"); test(() => { const moduleExportsDesc = Object.getOwnPropertyDescriptor(Module, 'exports'); assert_equals(typeof moduleExportsDesc.value, "function"); assert_equals(moduleExportsDesc.writable, true); - assert_equals(moduleExportsDesc.enumerable, false); + assert_equals(moduleExportsDesc.enumerable, true); assert_equals(moduleExportsDesc.configurable, true); }, "'WebAssembly.Module.exports' data property"); test(() => { const moduleExportsDesc = Object.getOwnPropertyDescriptor(Module, 'exports'); const moduleExports = moduleExportsDesc.value; assert_equals(moduleExports.length, 1); assertThrows(() => moduleExports(), TypeError); @@ -317,28 +317,28 @@ test(() => { assert_equals(arr[3].kind, "global"); assert_equals(arr[3].name, "âš¡"); }, "'WebAssembly.Module.exports' method"); test(() => { const customSectionsDesc = Object.getOwnPropertyDescriptor(Module, 'customSections'); assert_equals(typeof customSectionsDesc.value, "function"); assert_equals(customSectionsDesc.writable, true); - assert_equals(customSectionsDesc.enumerable, false); + assert_equals(customSectionsDesc.enumerable, true); assert_equals(customSectionsDesc.configurable, true); }, "'WebAssembly.Module.customSections' data property"); test(() => { const customSectionsDesc = Object.getOwnPropertyDescriptor(Module, 'customSections'); const moduleCustomSections = customSectionsDesc.value; assert_equals(moduleCustomSections.length, 2); assertThrows(() => moduleCustomSections(), TypeError); assertThrows(() => moduleCustomSections(undefined), TypeError); assertThrows(() => moduleCustomSections({}), TypeError); - var arr = moduleCustomSections(emptyModule); + var arr = moduleCustomSections(emptyModule, "abracadabra"); assert_equals(arr instanceof Array, true); assert_equals(arr.length, 0); }, "'WebAssembly.Module.customSections' method"); test(() => { const instanceDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'Instance'); assert_equals(typeof instanceDesc.value, "function"); assert_equals(instanceDesc.writable, true); @@ -388,17 +388,17 @@ test(() => { assert_equals(String(exportingInstance), "[object WebAssembly.Instance]"); assert_equals(Object.getPrototypeOf(exportingInstance), instanceProto); }, "'WebAssembly.Instance' instance objects"); test(() => { const exportsDesc = Object.getOwnPropertyDescriptor(instanceProto, 'exports'); assert_equals(typeof exportsDesc.get, "function"); assert_equals(exportsDesc.set, undefined); - assert_equals(exportsDesc.enumerable, false); + assert_equals(exportsDesc.enumerable, true); assert_equals(exportsDesc.configurable, true); const exportsGetter = exportsDesc.get; assertThrows(() => exportsGetter.call(), TypeError); assertThrows(() => exportsGetter.call({}), TypeError); assert_equals(typeof exportsGetter.call(exportingInstance), "object"); }, "'WebAssembly.Instance.prototype.exports' accessor property"); test(() => { @@ -437,21 +437,21 @@ test(() => { test(() => { const memoryDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'Memory'); assert_equals(Memory, memoryDesc.value); assert_equals(Memory.length, 1); assert_equals(Memory.name, "Memory"); assertThrows(() => Memory(), TypeError); assertThrows(() => new Memory(1), TypeError); assertThrows(() => new Memory({initial:{valueOf() { throw new Error("here")}}}), Error); - assertThrows(() => new Memory({initial:-1}), RangeError); - assertThrows(() => new Memory({initial:Math.pow(2,32)}), RangeError); + assertThrows(() => new Memory({initial:-1}), TypeError); + assertThrows(() => new Memory({initial:Math.pow(2,32)}), TypeError); assertThrows(() => new Memory({initial:1, maximum: Math.pow(2,32)/Math.pow(2,14) }), RangeError); assertThrows(() => new Memory({initial:2, maximum:1 }), RangeError); - assertThrows(() => new Memory({maximum: -1 }), RangeError); + assertThrows(() => new Memory({maximum: -1 }), TypeError); assert_equals(new Memory({initial:1}) instanceof Memory, true); assert_equals(new Memory({initial:1.5}).buffer.byteLength, WasmPage); }, "'WebAssembly.Memory' constructor function"); test(() => { const memoryProtoDesc = Object.getOwnPropertyDescriptor(Memory, 'prototype'); assert_equals(typeof memoryProtoDesc.value, "object"); assert_equals(memoryProtoDesc.writable, false); @@ -473,44 +473,44 @@ test(() => { assert_equals(String(mem1), "[object WebAssembly.Memory]"); assert_equals(Object.getPrototypeOf(mem1), memoryProto); }, "'WebAssembly.Memory' instance objects"); test(() => { const bufferDesc = Object.getOwnPropertyDescriptor(memoryProto, 'buffer'); assert_equals(typeof bufferDesc.get, "function"); assert_equals(bufferDesc.set, undefined); - assert_equals(bufferDesc.enumerable, false); + assert_equals(bufferDesc.enumerable, true); assert_equals(bufferDesc.configurable, true); }, "'WebAssembly.Memory.prototype.buffer' accessor property"); test(() => { const bufferDesc = Object.getOwnPropertyDescriptor(memoryProto, 'buffer'); const bufferGetter = bufferDesc.get; assertThrows(() => bufferGetter.call(), TypeError); assertThrows(() => bufferGetter.call({}), TypeError); assert_equals(bufferGetter.call(mem1) instanceof ArrayBuffer, true); assert_equals(bufferGetter.call(mem1).byteLength, WasmPage); }, "'WebAssembly.Memory.prototype.buffer' getter"); test(() => { const memGrowDesc = Object.getOwnPropertyDescriptor(memoryProto, 'grow'); assert_equals(typeof memGrowDesc.value, "function"); - assert_equals(memGrowDesc.enumerable, false); + assert_equals(memGrowDesc.enumerable, true); assert_equals(memGrowDesc.configurable, true); }, "'WebAssembly.Memory.prototype.grow' data property"); test(() => { const memGrowDesc = Object.getOwnPropertyDescriptor(memoryProto, 'grow'); const memGrow = memGrowDesc.value; assert_equals(memGrow.length, 1); assertThrows(() => memGrow.call(), TypeError); assertThrows(() => memGrow.call({}), TypeError); - assertThrows(() => memGrow.call(mem1, -1), RangeError); - assertThrows(() => memGrow.call(mem1, Math.pow(2,32)), RangeError); + assertThrows(() => memGrow.call(mem1, -1), TypeError); + assertThrows(() => memGrow.call(mem1, Math.pow(2,32)), TypeError); var mem = new Memory({initial:1, maximum:2}); var buf = mem.buffer; assert_equals(buf.byteLength, WasmPage); assert_equals(mem.grow(0), 1); assert_not_equals(buf, mem.buffer) assert_equals(buf.byteLength, 0); buf = mem.buffer; assert_equals(buf.byteLength, WasmPage); @@ -545,20 +545,20 @@ test(() => { assert_equals(Table.length, 1); assert_equals(Table.name, "Table"); assertThrows(() => Table(), TypeError); assertThrows(() => new Table(1), TypeError); assertThrows(() => new Table({initial:1, element:1}), TypeError); assertThrows(() => new Table({initial:1, element:"any"}), TypeError); assertThrows(() => new Table({initial:1, element:{valueOf() { return "anyfunc" }}}), TypeError); assertThrows(() => new Table({initial:{valueOf() { throw new Error("here")}}, element:"anyfunc"}), Error); - assertThrows(() => new Table({initial:-1, element:"anyfunc"}), RangeError); - assertThrows(() => new Table({initial:Math.pow(2,32), element:"anyfunc"}), RangeError); + assertThrows(() => new Table({initial:-1, element:"anyfunc"}), TypeError); + assertThrows(() => new Table({initial:Math.pow(2,32), element:"anyfunc"}), TypeError); assertThrows(() => new Table({initial:2, maximum:1, element:"anyfunc"}), RangeError); - assertThrows(() => new Table({initial:2, maximum:Math.pow(2,32), element:"anyfunc"}), RangeError); + assertThrows(() => new Table({initial:2, maximum:Math.pow(2,32), element:"anyfunc"}), TypeError); assert_equals(new Table({initial:1, element:"anyfunc"}) instanceof Table, true); assert_equals(new Table({initial:1.5, element:"anyfunc"}) instanceof Table, true); assert_equals(new Table({initial:1, maximum:1.5, element:"anyfunc"}) instanceof Table, true); assertThrows(() => new Table({initial:1, maximum:Math.pow(2,32)-1, element:"anyfunc"}), RangeError); }, "'WebAssembly.Table' constructor function"); test(() => { const tableProtoDesc = Object.getOwnPropertyDescriptor(Table, 'prototype'); @@ -582,94 +582,94 @@ test(() => { assert_equals(String(tbl1), "[object WebAssembly.Table]"); assert_equals(Object.getPrototypeOf(tbl1), tableProto); }, "'WebAssembly.Table' instance objects"); test(() => { const lengthDesc = Object.getOwnPropertyDescriptor(tableProto, 'length'); assert_equals(typeof lengthDesc.get, "function"); assert_equals(lengthDesc.set, undefined); - assert_equals(lengthDesc.enumerable, false); + assert_equals(lengthDesc.enumerable, true); assert_equals(lengthDesc.configurable, true); }, "'WebAssembly.Table.prototype.length' accessor data property"); test(() => { const lengthDesc = Object.getOwnPropertyDescriptor(tableProto, 'length'); const lengthGetter = lengthDesc.get; assert_equals(lengthGetter.length, 0); assertThrows(() => lengthGetter.call(), TypeError); assertThrows(() => lengthGetter.call({}), TypeError); assert_equals(typeof lengthGetter.call(tbl1), "number"); assert_equals(lengthGetter.call(tbl1), 2); }, "'WebAssembly.Table.prototype.length' getter"); test(() => { const getDesc = Object.getOwnPropertyDescriptor(tableProto, 'get'); assert_equals(typeof getDesc.value, "function"); - assert_equals(getDesc.enumerable, false); + assert_equals(getDesc.enumerable, true); assert_equals(getDesc.configurable, true); }, "'WebAssembly.Table.prototype.get' data property"); test(() => { const getDesc = Object.getOwnPropertyDescriptor(tableProto, 'get'); const get = getDesc.value; assert_equals(get.length, 1); assertThrows(() => get.call(), TypeError); assertThrows(() => get.call({}), TypeError); assert_equals(get.call(tbl1, 0), null); assert_equals(get.call(tbl1, 1), null); assert_equals(get.call(tbl1, 1.5), null); assertThrows(() => get.call(tbl1, 2), RangeError); assertThrows(() => get.call(tbl1, 2.5), RangeError); - assertThrows(() => get.call(tbl1, -1), RangeError); - assertThrows(() => get.call(tbl1, Math.pow(2,33)), RangeError); + assertThrows(() => get.call(tbl1, -1), TypeError); + assertThrows(() => get.call(tbl1, Math.pow(2,33)), TypeError); assertThrows(() => get.call(tbl1, {valueOf() { throw new Error("hi") }}), Error); }, "'WebAssembly.Table.prototype.get' method"); test(() => { const setDesc = Object.getOwnPropertyDescriptor(tableProto, 'set'); assert_equals(typeof setDesc.value, "function"); - assert_equals(setDesc.enumerable, false); + assert_equals(setDesc.enumerable, true); assert_equals(setDesc.configurable, true); }, "'WebAssembly.Table.prototype.set' data property"); test(() => { const setDesc = Object.getOwnPropertyDescriptor(tableProto, 'set'); const set = setDesc.value; assert_equals(set.length, 2); assertThrows(() => set.call(), TypeError); assertThrows(() => set.call({}), TypeError); assertThrows(() => set.call(tbl1, 0), TypeError); assertThrows(() => set.call(tbl1, 2, null), RangeError); - assertThrows(() => set.call(tbl1, -1, null), RangeError); - assertThrows(() => set.call(tbl1, Math.pow(2,33), null), RangeError); + assertThrows(() => set.call(tbl1, -1, null), TypeError); + assertThrows(() => set.call(tbl1, Math.pow(2,33), null), TypeError); assertThrows(() => set.call(tbl1, 0, undefined), TypeError); assertThrows(() => set.call(tbl1, 0, {}), TypeError); assertThrows(() => set.call(tbl1, 0, function() {}), TypeError); assertThrows(() => set.call(tbl1, 0, Math.sin), TypeError); assertThrows(() => set.call(tbl1, {valueOf() { throw Error("hai") }}, null), Error); assert_equals(set.call(tbl1, 0, null), undefined); assert_equals(set.call(tbl1, 1, null), undefined); }, "'WebAssembly.Table.prototype.set' method"); test(() => { const tblGrowDesc = Object.getOwnPropertyDescriptor(tableProto, 'grow'); assert_equals(typeof tblGrowDesc.value, "function"); - assert_equals(tblGrowDesc.enumerable, false); + assert_equals(tblGrowDesc.enumerable, true); assert_equals(tblGrowDesc.configurable, true); }, "'WebAssembly.Table.prototype.grow' data property"); test(() => { const tblGrowDesc = Object.getOwnPropertyDescriptor(tableProto, 'grow'); const tblGrow = tblGrowDesc.value; assert_equals(tblGrow.length, 1); assertThrows(() => tblGrow.call(), TypeError); assertThrows(() => tblGrow.call({}), TypeError); - assertThrows(() => tblGrow.call(tbl1, -1), RangeError); - assertThrows(() => tblGrow.call(tbl1, Math.pow(2,32)), RangeError); + assertThrows(() => tblGrow.call(tbl1, -1), TypeError); + assertThrows(() => tblGrow.call(tbl1, Math.pow(2,32)), TypeError); var tbl = new Table({element:"anyfunc", initial:1, maximum:2}); assert_equals(tbl.length, 1); assert_equals(tbl.grow(0), 1); assert_equals(tbl.length, 1); assert_equals(tbl.grow(1), 1); assert_equals(tbl.length, 2); assertThrows(() => tbl.grow(1), Error); }, "'WebAssembly.Table.prototype.grow' method"); @@ -832,17 +832,17 @@ test(() => { assert_equals(globalI32Mut.value, 1234); assert_equals(globalF32Mut.value, 5678); assert_equals(globalF64Mut.value, 9012); }, "'WebAssembly.Global.prototype.value' setter"); test(() => { const valueOfDesc = Object.getOwnPropertyDescriptor(globalProto, 'valueOf'); assert_equals(typeof valueOfDesc.value, "function"); - assert_equals(valueOfDesc.enumerable, false); + assert_equals(valueOfDesc.enumerable, true); assert_equals(valueOfDesc.configurable, true); }, "'WebAssembly.Global.prototype.valueOf' data property"); test(() => { const valueOfDesc = Object.getOwnPropertyDescriptor(globalProto, 'valueOf'); const valueOf = valueOfDesc.value; assert_equals(valueOf.length, 0); assertThrows(() => valueOf.call(), TypeError); @@ -954,17 +954,17 @@ test(() => { assert_false(WebAssembly.validate(moduleBinaryImporting2Memories)); assert_false(WebAssembly.validate(moduleBinaryWithMemSectionAndMemImport)); }, "'WebAssembly.validate' method"); test(() => { const compileDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'compile'); assert_equals(typeof compileDesc.value, "function"); assert_equals(compileDesc.writable, true); - assert_equals(compileDesc.enumerable, false); + assert_equals(compileDesc.enumerable, true); assert_equals(compileDesc.configurable, true); }, "'WebAssembly.compile' data property"); test(() => { const compile = WebAssembly.compile; const compileDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'compile'); assert_equals(compile, compileDesc.value); @@ -1006,17 +1006,17 @@ function assertCompileSuccess(bytes) { assertCompileSuccess(emptyModuleBinary); assertCompileSuccess(new Uint8Array(emptyModuleBinary)); test(() => { const instantiateDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'instantiate'); assert_equals(typeof instantiateDesc.value, "function"); assert_equals(instantiateDesc.writable, true); - assert_equals(instantiateDesc.enumerable, false); + assert_equals(instantiateDesc.enumerable, true); assert_equals(instantiateDesc.configurable, true); }, "'WebAssembly.instantiate' data property"); test(() => { const instantiateDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'instantiate'); const instantiate = WebAssembly.instantiate; assert_equals(instantiate, instantiateDesc.value); assert_equals(instantiate.length, 1);
--- a/js/src/jit/mips-shared/AtomicOperations-mips-shared.h +++ b/js/src/jit/mips-shared/AtomicOperations-mips-shared.h @@ -27,17 +27,17 @@ #endif #if defined(JS_SIMULATOR_MIPS32) && !defined(__i386__) # error "The MIPS32 simulator atomics assume x86" #endif namespace js { namespace jit { -#if defined(JS_CODEGEN_MIPS32) +#if !defined(JS_64BIT) struct AddressLock { public: void acquire(); void release(); private: uint32_t spinlock; @@ -96,17 +96,17 @@ js::jit::AtomicOperations::loadSeqCst(T* static_assert(sizeof(T) <= sizeof(void*), "atomics supported up to pointer size only"); T v; __atomic_load(addr, &v, __ATOMIC_SEQ_CST); return v; } namespace js { namespace jit { -#if defined(JS_CODEGEN_MIPS32) +#if !defined(JS_64BIT) template<> inline int64_t js::jit::AtomicOperations::loadSeqCst(int64_t* addr) { AddressGuard guard(addr); return *addr; } @@ -128,17 +128,17 @@ inline void js::jit::AtomicOperations::storeSeqCst(T* addr, T val) { static_assert(sizeof(T) <= sizeof(void*), "atomics supported up to pointer size only"); __atomic_store(addr, &val, __ATOMIC_SEQ_CST); } namespace js { namespace jit { -#if defined(JS_CODEGEN_MIPS32) +#if !defined(JS_64BIT) template<> inline void js::jit::AtomicOperations::storeSeqCst(int64_t* addr, int64_t val) { AddressGuard guard(addr); *addr = val; } @@ -161,17 +161,17 @@ js::jit::AtomicOperations::compareExchan { static_assert(sizeof(T) <= sizeof(void*), "atomics supported up to pointer size only"); __atomic_compare_exchange(addr, &oldval, &newval, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); return oldval; } namespace js { namespace jit { -#if defined(JS_CODEGEN_MIPS32) +#if !defined(JS_64BIT) template<> inline int64_t js::jit::AtomicOperations::compareExchangeSeqCst(int64_t* addr, int64_t oldval, int64_t newval) { AddressGuard guard(addr); int64_t val = *addr; if (val == oldval) { @@ -201,17 +201,17 @@ inline T js::jit::AtomicOperations::fetchAddSeqCst(T* addr, T val) { static_assert(sizeof(T) <= sizeof(void*), "atomics supported up to pointer size only"); return __atomic_fetch_add(addr, val, __ATOMIC_SEQ_CST); } namespace js { namespace jit { -#if defined(JS_CODEGEN_MIPS32) +#if !defined(JS_64BIT) template<> inline int64_t js::jit::AtomicOperations::fetchAddSeqCst(int64_t* addr, int64_t val) { AddressGuard guard(addr); int64_t old = *addr; *addr = old + val; @@ -237,17 +237,17 @@ inline T js::jit::AtomicOperations::fetchSubSeqCst(T* addr, T val) { static_assert(sizeof(T) <= sizeof(void*), "atomics supported up to pointer size only"); return __atomic_fetch_sub(addr, val, __ATOMIC_SEQ_CST); } namespace js { namespace jit { -#if defined(JS_CODEGEN_MIPS32) +#if !defined(JS_64BIT) template<> inline int64_t js::jit::AtomicOperations::fetchSubSeqCst(int64_t* addr, int64_t val) { AddressGuard guard(addr); int64_t old = *addr; *addr = old - val; @@ -274,17 +274,17 @@ js::jit::AtomicOperations::fetchAndSeqCs { static_assert(sizeof(T) <= sizeof(void*), "atomics supported up to pointer size only"); return __atomic_fetch_and(addr, val, __ATOMIC_SEQ_CST); } namespace js { namespace jit { -#if defined(JS_CODEGEN_MIPS32) +#if !defined(JS_64BIT) template<> inline int64_t js::jit::AtomicOperations::fetchAndSeqCst(int64_t* addr, int64_t val) { AddressGuard guard(addr); int64_t old = *addr; *addr = old & val; @@ -310,17 +310,17 @@ inline T js::jit::AtomicOperations::fetchOrSeqCst(T* addr, T val) { static_assert(sizeof(T) <= sizeof(void*), "atomics supported up to pointer size only"); return __atomic_fetch_or(addr, val, __ATOMIC_SEQ_CST); } namespace js { namespace jit { -#if defined(JS_CODEGEN_MIPS32) +#if !defined(JS_64BIT) template<> inline int64_t js::jit::AtomicOperations::fetchOrSeqCst(int64_t* addr, int64_t val) { AddressGuard guard(addr); int64_t old = *addr; *addr = old | val; @@ -347,17 +347,17 @@ js::jit::AtomicOperations::fetchXorSeqCs { static_assert(sizeof(T) <= sizeof(void*), "atomics supported up to pointer size only"); return __atomic_fetch_xor(addr, val, __ATOMIC_SEQ_CST); } namespace js { namespace jit { -#if defined(JS_CODEGEN_MIPS32) +#if !defined(JS_64BIT) template<> inline int64_t js::jit::AtomicOperations::fetchXorSeqCst(int64_t* addr, int64_t val) { AddressGuard guard(addr); int64_t old = *addr; *addr = old ^ val; @@ -385,17 +385,17 @@ js::jit::AtomicOperations::loadSafeWhenR static_assert(sizeof(T) <= sizeof(void*), "atomics supported up to pointer size only"); T v; __atomic_load(addr, &v, __ATOMIC_RELAXED); return v; } namespace js { namespace jit { -#if defined(JS_CODEGEN_MIPS32) +#if !defined(JS_64BIT) template<> inline int64_t js::jit::AtomicOperations::loadSafeWhenRacy(int64_t* addr) { return *addr; } @@ -438,17 +438,17 @@ inline void js::jit::AtomicOperations::storeSafeWhenRacy(T* addr, T val) { static_assert(sizeof(T) <= sizeof(void*), "atomics supported up to pointer size only"); __atomic_store(addr, &val, __ATOMIC_RELAXED); } namespace js { namespace jit { -#if defined(JS_CODEGEN_MIPS32) +#if !defined(JS_64BIT) template<> inline void js::jit::AtomicOperations::storeSafeWhenRacy(int64_t* addr, int64_t val) { *addr = val; } @@ -505,17 +505,17 @@ js::jit::AtomicOperations::exchangeSeqCs static_assert(sizeof(T) <= sizeof(void*), "atomics supported up to pointer size only"); T v; __atomic_exchange(addr, &val, &v, __ATOMIC_SEQ_CST); return v; } namespace js { namespace jit { -#if defined(JS_CODEGEN_MIPS32) +#if !defined(JS_64BIT) template<> inline int64_t js::jit::AtomicOperations::exchangeSeqCst(int64_t* addr, int64_t val) { AddressGuard guard(addr); int64_t old = *addr; *addr = val; @@ -531,17 +531,17 @@ js::jit::AtomicOperations::exchangeSeqCs *addr = val; return old; } #endif } } -#if defined(JS_CODEGEN_MIPS32) +#if !defined(JS_64BIT) inline void js::jit::AddressLock::acquire() { uint32_t zero = 0; uint32_t one = 1; while (!__atomic_compare_exchange(&spinlock, &zero, &one, true, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST))
--- a/js/src/js.msg +++ b/js/src/js.msg @@ -388,18 +388,19 @@ MSG_DEF(JSMSG_WASM_UNREACHABLE, 0 MSG_DEF(JSMSG_WASM_INTEGER_OVERFLOW, 0, JSEXN_WASMRUNTIMEERROR, "integer overflow") MSG_DEF(JSMSG_WASM_INVALID_CONVERSION, 0, JSEXN_WASMRUNTIMEERROR, "invalid conversion to integer") MSG_DEF(JSMSG_WASM_INT_DIVIDE_BY_ZERO, 0, JSEXN_WASMRUNTIMEERROR, "integer divide by zero") MSG_DEF(JSMSG_WASM_OUT_OF_BOUNDS, 0, JSEXN_WASMRUNTIMEERROR, "index out of bounds") MSG_DEF(JSMSG_WASM_UNALIGNED_ACCESS, 0, JSEXN_WASMRUNTIMEERROR, "unaligned memory access") MSG_DEF(JSMSG_WASM_WAKE_OVERFLOW, 0, JSEXN_WASMRUNTIMEERROR, "too many woken agents") MSG_DEF(JSMSG_WASM_INVALID_PASSIVE_DATA_SEG, 0, JSEXN_WASMRUNTIMEERROR, "use of invalid passive data segment") MSG_DEF(JSMSG_WASM_INVALID_PASSIVE_ELEM_SEG, 0, JSEXN_WASMRUNTIMEERROR, "use of invalid passive element segment") -MSG_DEF(JSMSG_WASM_BAD_UINT32, 2, JSEXN_RANGEERR, "bad {0} {1}") +MSG_DEF(JSMSG_WASM_BAD_RANGE , 2, JSEXN_RANGEERR, "bad {0} {1}") MSG_DEF(JSMSG_WASM_BAD_GROW, 1, JSEXN_RANGEERR, "failed to grow {0}") +MSG_DEF(JSMSG_WASM_BAD_UINT32, 2, JSEXN_TYPEERR, "bad {0} {1}") MSG_DEF(JSMSG_WASM_BAD_BUF_ARG, 0, JSEXN_TYPEERR, "first argument must be an ArrayBuffer or typed array object") MSG_DEF(JSMSG_WASM_BAD_MOD_ARG, 0, JSEXN_TYPEERR, "first argument must be a WebAssembly.Module") MSG_DEF(JSMSG_WASM_BAD_BUF_MOD_ARG, 0, JSEXN_TYPEERR, "first argument must be a WebAssembly.Module, ArrayBuffer or typed array object") MSG_DEF(JSMSG_WASM_BAD_DESC_ARG, 1, JSEXN_TYPEERR, "first argument must be a {0} descriptor") MSG_DEF(JSMSG_WASM_BAD_ELEMENT, 0, JSEXN_TYPEERR, "\"element\" property of table descriptor must be \"anyfunc\"") MSG_DEF(JSMSG_WASM_BAD_IMPORT_ARG, 0, JSEXN_TYPEERR, "second argument must be an object") MSG_DEF(JSMSG_WASM_BAD_IMPORT_FIELD, 1, JSEXN_TYPEERR, "import object field '{0}' is not an Object") MSG_DEF(JSMSG_WASM_BAD_TABLE_VALUE, 0, JSEXN_TYPEERR, "can only assign WebAssembly exported functions to Table")
--- a/js/src/vm/HelperThreads.cpp +++ b/js/src/vm/HelperThreads.cpp @@ -1232,16 +1232,28 @@ GlobalHelperThreadState::checkTaskThread // run. if (isMaster && idle == 1) { return false; } return true; } +void +GlobalHelperThreadState::triggerFreeUnusedMemory() +{ + if (!CanUseExtraThreads()) + return; + + AutoLockHelperThreadState lock; + for (auto& thread : *threads) + thread.shouldFreeUnusedMemory = true; + notifyAll(PRODUCER, lock); +} + struct MOZ_RAII AutoSetContextRuntime { explicit AutoSetContextRuntime(JSRuntime* rt) { TlsContext.get()->setRuntime(rt); } ~AutoSetContextRuntime() { TlsContext.get()->setRuntime(nullptr); } @@ -2561,16 +2573,18 @@ HelperThread::threadLoop() } // Now that we are holding the helper thread state lock again, // notify the record/replay system that we might block soon. // The helper thread state lock may not be released until the // block occurs. mozilla::recordreplay::NotifyUnrecordedWait(WakeupAll); } + maybeFreeUnusedMemory(&cx); + // The selectors may depend on the HelperThreadState not changing // between task selection and task execution, in particular, on new // tasks not being added (because of the lifo structure of the work // lists). Unlocking the HelperThreadState between task selection and // execution is not well-defined. const TaskSpec* task = findHighestPriorityTask(lock); if (!task) { @@ -2595,8 +2609,21 @@ HelperThread::findHighestPriorityTask(co for (const auto& task : taskSpecs) { if ((HelperThreadState().*(task.canStart))(locked)) { return &task; } } return nullptr; } + +void +HelperThread::maybeFreeUnusedMemory(JSContext* cx) +{ + MOZ_ASSERT(idle()); + + cx->tempLifoAlloc().releaseAll(); + + if (shouldFreeUnusedMemory) { + cx->tempLifoAlloc().freeAll(); + shouldFreeUnusedMemory = false; + } +}
--- a/js/src/vm/HelperThreads.h +++ b/js/src/vm/HelperThreads.h @@ -310,16 +310,18 @@ class GlobalHelperThreadState bool hasActiveThreads(const AutoLockHelperThreadState&); void waitForAllThreads(); void waitForAllThreadsLocked(AutoLockHelperThreadState&); template <typename T> bool checkTaskThreadLimit(size_t maxThreads, bool isMaster = false) const; + void triggerFreeUnusedMemory(); + private: /* * Lock protecting all mutable shared state accessed by helper threads, and * used by all condition variables. */ js::Mutex helperLock; /* Condvars for threads waiting/notifying each other. */ @@ -358,16 +360,22 @@ struct HelperThread mozilla::Maybe<Thread> thread; /* * Indicate to a thread that it should terminate itself. This is only read * or written with the helper thread state lock held. */ bool terminate; + /* + * Indicates that this thread should free its unused memory when it is next + * idle. + */ + bool shouldFreeUnusedMemory; + /* The current task being executed by this thread, if any. */ mozilla::Maybe<HelperTaskUnion> currentTask; bool idle() const { return currentTask.isNothing(); } /* Any builder currently being compiled by Ion on this thread. */ @@ -447,16 +455,18 @@ struct HelperThread T maybeCurrentTaskAs() { if (currentTask.isSome() && currentTask->is<T>()) { return currentTask->as<T>(); } return nullptr; } + void maybeFreeUnusedMemory(JSContext* cx); + void handleWasmWorkload(AutoLockHelperThreadState& locked, wasm::CompileMode mode); void handleWasmTier1Workload(AutoLockHelperThreadState& locked); void handleWasmTier2Workload(AutoLockHelperThreadState& locked); void handleWasmTier2GeneratorWorkload(AutoLockHelperThreadState& locked); void handlePromiseHelperTaskWorkload(AutoLockHelperThreadState& locked); void handleIonWorkload(AutoLockHelperThreadState& locked); void handleIonFreeWorkload(AutoLockHelperThreadState& locked);
--- a/js/src/wasm/WasmBaselineCompile.cpp +++ b/js/src/wasm/WasmBaselineCompile.cpp @@ -6018,16 +6018,17 @@ class BaseCompiler final : public BaseCo void doReturn(ExprType returnType, bool popStack); void pushReturnedIfNonVoid(const FunctionCall& call, ExprType type); void emitCompareI32(Assembler::Condition compareOp, ValType compareType); void emitCompareI64(Assembler::Condition compareOp, ValType compareType); void emitCompareF32(Assembler::DoubleCondition compareOp, ValType compareType); void emitCompareF64(Assembler::DoubleCondition compareOp, ValType compareType); + void emitCompareRef(Assembler::Condition compareOp, ValType compareType); void emitAddI32(); void emitAddI64(); void emitAddF64(); void emitAddF32(); void emitSubtractI32(); void emitSubtractI64(); void emitSubtractF32(); @@ -7379,16 +7380,21 @@ BaseCompiler::sniffConditionalControlCmp // On x86, latent i64 binary comparisons use too many registers: the // reserved join register and the lhs and rhs operands require six, but we // only have five. if (operandType == ValType::I64) { return false; } #endif + // No optimization for pointer compares yet. + if (operandType.isRefOrAnyRef()) { + return false; + } + OpBytes op; iter_.peekOp(&op); switch (op.b0) { case uint16_t(Op::BrIf): case uint16_t(Op::If): case uint16_t(Op::Select): setLatentCompare(compareOp, operandType); return true; @@ -9165,16 +9171,30 @@ BaseCompiler::emitCompareF64(Assembler:: moveImm32(0, rd); masm.bind(&across); freeF64(rs0); freeF64(rs1); pushI32(rd); } void +BaseCompiler::emitCompareRef(Assembler::Condition compareOp, ValType compareType) +{ + MOZ_ASSERT(!sniffConditionalControlCmp(compareOp, compareType)); + + RegPtr rs1, rs2; + pop2xRef(&rs1, &rs2); + RegI32 rd = needI32(); + masm.cmpPtrSet(compareOp, rs1, rs2, rd); + freeRef(rs1); + freeRef(rs2); + pushI32(rd); +} + +void BaseCompiler::emitInstanceCall(uint32_t lineOrBytecode, const MIRTypeVector& sig, ExprType retType, SymbolicAddress builtin) { MOZ_ASSERT(sig[0] == MIRType::Pointer); sync(); uint32_t numArgs = sig.length() - 1 /* instance */; @@ -9634,21 +9654,23 @@ BaseCompiler::emitMemOrTableCopy(bool is } bool BaseCompiler::emitMemOrTableDrop(bool isMem) { uint32_t lineOrBytecode = readCallSiteLineOrBytecode(); uint32_t segIndex = 0; - if (!iter_.readMemOrTableDrop(isMem, &segIndex)) + if (!iter_.readMemOrTableDrop(isMem, &segIndex)) { return false; - - if (deadCode_) + } + + if (deadCode_) { return true; + } // Despite the cast to int32_t, the callee regards the value as unsigned. pushI32(int32_t(segIndex)); SymbolicAddress callee = isMem ? SymbolicAddress::MemDrop : SymbolicAddress::TableDrop; emitInstanceCall(lineOrBytecode, SigPI_, ExprType::Void, callee); Label ok; @@ -9685,21 +9707,23 @@ BaseCompiler::emitMemFill() bool BaseCompiler::emitMemOrTableInit(bool isMem) { uint32_t lineOrBytecode = readCallSiteLineOrBytecode(); uint32_t segIndex = 0; Nothing nothing; - if (!iter_.readMemOrTableInit(isMem, &segIndex, ¬hing, ¬hing, ¬hing)) + if (!iter_.readMemOrTableInit(isMem, &segIndex, ¬hing, ¬hing, ¬hing)) { return false; - - if (deadCode_) + } + + if (deadCode_) { return true; + } pushI32(int32_t(segIndex)); SymbolicAddress callee = isMem ? SymbolicAddress::MemInit : SymbolicAddress::TableInit; emitInstanceCall(lineOrBytecode, SigPIIII_, ExprType::Void, callee); Label ok; masm.branchTest32(Assembler::NotSigned, ReturnReg, ReturnReg, &ok); @@ -10270,16 +10294,21 @@ BaseCompiler::emitBody() // Memory Related case uint16_t(Op::GrowMemory): CHECK_NEXT(emitGrowMemory()); case uint16_t(Op::CurrentMemory): CHECK_NEXT(emitCurrentMemory()); #ifdef ENABLE_WASM_GC + case uint16_t(Op::RefEq): + if (env_.gcTypesEnabled() == HasGcTypes::False) { + return iter_.unrecognizedOpcode(&op); + } + CHECK_NEXT(emitComparison(emitCompareRef, ValType::AnyRef, Assembler::Equal)); case uint16_t(Op::RefNull): if (env_.gcTypesEnabled() == HasGcTypes::False) { return iter_.unrecognizedOpcode(&op); } CHECK_NEXT(emitRefNull()); break; case uint16_t(Op::RefIsNull): if (env_.gcTypesEnabled() == HasGcTypes::False) {
--- a/js/src/wasm/WasmConstants.h +++ b/js/src/wasm/WasmConstants.h @@ -355,16 +355,17 @@ enum class Op I32Extend16S = 0xc1, I64Extend8S = 0xc2, I64Extend16S = 0xc3, I64Extend32S = 0xc4, // GC ops RefNull = 0xd0, RefIsNull = 0xd1, + RefEq = 0xd2, // Unofficial FirstPrefix = 0xfc, MiscPrefix = 0xfc, ThreadPrefix = 0xfe, MozPrefix = 0xff, Limit = 0x100 };
--- a/js/src/wasm/WasmIonCompile.cpp +++ b/js/src/wasm/WasmIonCompile.cpp @@ -3554,16 +3554,17 @@ EmitBodyExprs(FunctionCompiler& f) case uint16_t(Op::I64ReinterpretF64): CHECK(EmitReinterpret(f, ValType::I64, ValType::F64, MIRType::Int64)); case uint16_t(Op::F32ReinterpretI32): CHECK(EmitReinterpret(f, ValType::F32, ValType::I32, MIRType::Float32)); case uint16_t(Op::F64ReinterpretI64): CHECK(EmitReinterpret(f, ValType::F64, ValType::I64, MIRType::Double)); // GC types are NYI in Ion. + case uint16_t(Op::RefEq): case uint16_t(Op::RefNull): case uint16_t(Op::RefIsNull): return f.iter().unrecognizedOpcode(&op); // Sign extensions case uint16_t(Op::I32Extend8S): CHECK(EmitSignExtend(f, 1, 4)); case uint16_t(Op::I32Extend16S):
--- a/js/src/wasm/WasmJS.cpp +++ b/js/src/wasm/WasmJS.cpp @@ -443,18 +443,17 @@ wasm::Eval(JSContext* cx, Handle<TypedAr // ============================================================================ // Common functions // '[EnforceRange] unsigned long' types are coerced with // ConvertToInt(v, 32, 'unsigned') // defined in Web IDL Section 3.2.4.9. static bool -EnforceRangeU32(JSContext* cx, HandleValue v, uint32_t max, const char* kind, const char* noun, - uint32_t* u32) +EnforceRangeU32(JSContext* cx, HandleValue v, const char* kind, const char* noun, uint32_t* u32) { // Step 4. double x; if (!ToNumber(cx, v, &x)) { return false; } // Step 5. @@ -466,18 +465,18 @@ EnforceRangeU32(JSContext* cx, HandleVal if (!mozilla::IsFinite(x)) { JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_UINT32, kind, noun); return false; } // Step 6.2. x = JS::ToInteger(x); - // Step 6.3, allowing caller to supply a more restrictive uint32_t max. - if (x < 0 || x > double(max)) { + // Step 6.3. + if (x < 0 || x > double(UINT32_MAX)) { JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_UINT32, kind, noun); return false; } *u32 = uint32_t(x); MOZ_ASSERT(double(*u32) == x); return true; } @@ -492,74 +491,72 @@ GetLimits(JSContext* cx, HandleObject ob } RootedId initialId(cx, AtomToId(initialAtom)); RootedValue initialVal(cx); if (!GetProperty(cx, obj, obj, initialId, &initialVal)) { return false; } - if (!EnforceRangeU32(cx, initialVal, maxInitial, kind, "initial size", &limits->initial)) { + if (!EnforceRangeU32(cx, initialVal, kind, "initial size", &limits->initial)) { + return false; + } + + if (limits->initial > maxInitial) { + JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_RANGE, + kind, "initial size"); return false; } JSAtom* maximumAtom = Atomize(cx, "maximum", strlen("maximum")); if (!maximumAtom) { return false; } RootedId maximumId(cx, AtomToId(maximumAtom)); - bool foundMaximum; - if (!HasProperty(cx, obj, maximumId, &foundMaximum)) { + RootedValue maxVal(cx); + if (!GetProperty(cx, obj, obj, maximumId, &maxVal)) { return false; } - if (foundMaximum) { - RootedValue maxVal(cx); - if (!GetProperty(cx, obj, obj, maximumId, &maxVal)) { + // maxVal does not have a default value. + if (!maxVal.isUndefined()) { + limits->maximum.emplace(); + if (!EnforceRangeU32(cx, maxVal, kind, "maximum size", limits->maximum.ptr())) { return false; } - limits->maximum.emplace(); - if (!EnforceRangeU32(cx, maxVal, maxMaximum, kind, "maximum size", limits->maximum.ptr())) { - return false; - } - - if (limits->initial > *limits->maximum) { - JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_UINT32, + if (*limits->maximum > maxMaximum || limits->initial > *limits->maximum) { + JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_RANGE, kind, "maximum size"); return false; } } limits->shared = Shareable::False; #ifdef ENABLE_WASM_THREAD_OPS if (allowShared == Shareable::True) { JSAtom* sharedAtom = Atomize(cx, "shared", strlen("shared")); if (!sharedAtom) { return false; } RootedId sharedId(cx, AtomToId(sharedAtom)); - bool foundShared; - if (!HasProperty(cx, obj, sharedId, &foundShared)) { + RootedValue sharedVal(cx); + if (!GetProperty(cx, obj, obj, sharedId, &sharedVal)) { return false; } - if (foundShared) { - RootedValue sharedVal(cx); - if (!GetProperty(cx, obj, obj, sharedId, &sharedVal)) { - return false; - } - + // shared's default value is false, which is already the value set above. + if (!sharedVal.isUndefined()) { limits->shared = ToBoolean(sharedVal) ? Shareable::True : Shareable::False; if (limits->shared == Shareable::True) { - if (!foundMaximum) { + if (maxVal.isUndefined()) { JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_WASM_MISSING_MAXIMUM, kind); return false; } if (!cx->realm()->creationOptions().getSharedMemoryAndAtomicsEnabled()) { JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_WASM_NO_SHMEM_LINK); @@ -599,19 +596,19 @@ const Class WasmModuleObject::class_ = const JSPropertySpec WasmModuleObject::properties[] = { JS_PS_END }; const JSFunctionSpec WasmModuleObject::methods[] = { JS_FS_END }; const JSFunctionSpec WasmModuleObject::static_methods[] = { - JS_FN("imports", WasmModuleObject::imports, 1, 0), - JS_FN("exports", WasmModuleObject::exports, 1, 0), - JS_FN("customSections", WasmModuleObject::customSections, 2, 0), + JS_FN("imports", WasmModuleObject::imports, 1, JSPROP_ENUMERATE), + JS_FN("exports", WasmModuleObject::exports, 1, JSPROP_ENUMERATE), + JS_FN("customSections", WasmModuleObject::customSections, 2, JSPROP_ENUMERATE), JS_FS_END }; /* static */ void WasmModuleObject::finalize(FreeOp* fop, JSObject* obj) { obj->as<WasmModuleObject>().module().Release(); } @@ -624,19 +621,19 @@ IsModuleObject(JSObject* obj, const Modu return false; } *module = &unwrapped->as<WasmModuleObject>().module(); return true; } static bool -GetModuleArg(JSContext* cx, CallArgs args, const char* name, const Module** module) +GetModuleArg(JSContext* cx, CallArgs args, uint32_t numRequired, const char* name, const Module** module) { - if (!args.requireAtLeast(cx, name, 1)) { + if (!args.requireAtLeast(cx, name, numRequired)) { return false; } if (!args[0].isObject() || !IsModuleObject(&args[0].toObject(), module)) { JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_MOD_ARG); return false; } @@ -747,17 +744,17 @@ UTF8CharsToString(JSContext* cx, const c } /* static */ bool WasmModuleObject::imports(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); const Module* module; - if (!GetModuleArg(cx, args, "WebAssembly.Module.imports", &module)) { + if (!GetModuleArg(cx, args, 1, "WebAssembly.Module.imports", &module)) { return false; } KindNames names(cx); if (!InitKindNames(cx, &names)) { return false; } @@ -821,17 +818,17 @@ WasmModuleObject::imports(JSContext* cx, } /* static */ bool WasmModuleObject::exports(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); const Module* module; - if (!GetModuleArg(cx, args, "WebAssembly.Module.exports", &module)) { + if (!GetModuleArg(cx, args, 1, "WebAssembly.Module.exports", &module)) { return false; } KindNames names(cx); if (!InitKindNames(cx, &names)) { return false; } @@ -889,17 +886,17 @@ WasmModuleObject::exports(JSContext* cx, } /* static */ bool WasmModuleObject::customSections(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); const Module* module; - if (!GetModuleArg(cx, args, "WebAssembly.Module.customSections", &module)) { + if (!GetModuleArg(cx, args, 2, "WebAssembly.Module.customSections", &module)) { return false; } Vector<char, 8> name(cx); { RootedString str(cx, ToString(cx, args.get(1))); if (!str) { return false; @@ -1127,17 +1124,17 @@ WasmInstanceObject::exportsGetterImpl(JS WasmInstanceObject::exportsGetter(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); return CallNonGenericMethod<IsInstance, exportsGetterImpl>(cx, args); } const JSPropertySpec WasmInstanceObject::properties[] = { - JS_PSG("exports", WasmInstanceObject::exportsGetter, 0), + JS_PSG("exports", WasmInstanceObject::exportsGetter, JSPROP_ENUMERATE), JS_PS_END }; const JSFunctionSpec WasmInstanceObject::methods[] = { JS_FS_END }; const JSFunctionSpec WasmInstanceObject::static_methods[] = { JS_FS_END }; @@ -1737,27 +1734,31 @@ WasmMemoryObject::bufferGetterImpl(JSCon WasmMemoryObject::bufferGetter(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); return CallNonGenericMethod<IsMemory, bufferGetterImpl>(cx, args); } const JSPropertySpec WasmMemoryObject::properties[] = { - JS_PSG("buffer", WasmMemoryObject::bufferGetter, 0), + JS_PSG("buffer", WasmMemoryObject::bufferGetter, JSPROP_ENUMERATE), JS_PS_END }; /* static */ bool WasmMemoryObject::growImpl(JSContext* cx, const CallArgs& args) { RootedWasmMemoryObject memory(cx, &args.thisv().toObject().as<WasmMemoryObject>()); + if (!args.requireAtLeast(cx, "WebAssembly.Memory.grow", 1)) { + return false; + } + uint32_t delta; - if (!EnforceRangeU32(cx, args.get(0), UINT32_MAX, "Memory", "grow delta", &delta)) { + if (!EnforceRangeU32(cx, args.get(0), "Memory", "grow delta", &delta)) { return false; } uint32_t ret = grow(memory, delta, cx); if (ret == uint32_t(-1)) { JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_GROW, "memory"); return false; @@ -1771,17 +1772,17 @@ WasmMemoryObject::growImpl(JSContext* cx WasmMemoryObject::grow(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); return CallNonGenericMethod<IsMemory, growImpl>(cx, args); } const JSFunctionSpec WasmMemoryObject::methods[] = { - JS_FN("grow", WasmMemoryObject::grow, 1, 0), + JS_FN("grow", WasmMemoryObject::grow, 1, JSPROP_ENUMERATE), JS_FS_END }; const JSFunctionSpec WasmMemoryObject::static_methods[] = { JS_FS_END }; ArrayBufferObjectMaybeShared& WasmMemoryObject::buffer() const @@ -2072,27 +2073,27 @@ WasmTableObject::construct(JSContext* cx } RootedId elementId(cx, AtomToId(elementAtom)); RootedValue elementVal(cx); if (!GetProperty(cx, obj, obj, elementId, &elementVal)) { return false; } - if (!elementVal.isString()) { - JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_ELEMENT); - return false; - } - - JSLinearString* elementStr = elementVal.toString()->ensureLinear(cx); + RootedString elementStr(cx, ToString(cx, elementVal)); if (!elementStr) { return false; } - if (!StringEqualsAscii(elementStr, "anyfunc")) { + RootedLinearString elementLinearStr(cx, elementStr->ensureLinear(cx)); + if (!elementLinearStr) { + return false; + } + + if (!StringEqualsAscii(elementLinearStr, "anyfunc")) { JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_ELEMENT); return false; } Limits limits; if (!GetLimits(cx, obj, MaxTableInitialLength, MaxTableMaximumLength, "Table", &limits, Shareable::False)) { @@ -2125,41 +2126,45 @@ WasmTableObject::lengthGetterImpl(JSCont WasmTableObject::lengthGetter(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); return CallNonGenericMethod<IsTable, lengthGetterImpl>(cx, args); } const JSPropertySpec WasmTableObject::properties[] = { - JS_PSG("length", WasmTableObject::lengthGetter, 0), + JS_PSG("length", WasmTableObject::lengthGetter, JSPROP_ENUMERATE), JS_PS_END }; static bool ToTableIndex(JSContext* cx, HandleValue v, const Table& table, const char* noun, uint32_t* index) { - if (!EnforceRangeU32(cx, v, UINT32_MAX, "Table", noun, index)) { + if (!EnforceRangeU32(cx, v, "Table", noun, index)) { return false; } if (*index >= table.length()) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_UINT32, "Table", noun); + JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_RANGE, "Table", noun); return false; } return true; } /* static */ bool WasmTableObject::getImpl(JSContext* cx, const CallArgs& args) { RootedWasmTableObject tableObj(cx, &args.thisv().toObject().as<WasmTableObject>()); const Table& table = tableObj->table(); + if (!args.requireAtLeast(cx, "WebAssembly.Table.get", 1)) { + return false; + } + uint32_t index; if (!ToTableIndex(cx, args.get(0), table, "get index", &index)) { return false; } ExternalTableElem& elem = table.externalArray()[index]; if (!elem.code) { args.rval().setNull(); @@ -2187,17 +2192,17 @@ WasmTableObject::get(JSContext* cx, unsi } /* static */ bool WasmTableObject::setImpl(JSContext* cx, const CallArgs& args) { RootedWasmTableObject tableObj(cx, &args.thisv().toObject().as<WasmTableObject>()); Table& table = tableObj->table(); - if (!args.requireAtLeast(cx, "set", 2)) { + if (!args.requireAtLeast(cx, "WebAssembly.Table.set", 2)) { return false; } uint32_t index; if (!ToTableIndex(cx, args.get(0), table, "set index", &index)) { return false; } @@ -2238,18 +2243,22 @@ WasmTableObject::set(JSContext* cx, unsi return CallNonGenericMethod<IsTable, setImpl>(cx, args); } /* static */ bool WasmTableObject::growImpl(JSContext* cx, const CallArgs& args) { RootedWasmTableObject table(cx, &args.thisv().toObject().as<WasmTableObject>()); + if (!args.requireAtLeast(cx, "WebAssembly.Table.grow", 1)) { + return false; + } + uint32_t delta; - if (!EnforceRangeU32(cx, args.get(0), UINT32_MAX, "Table", "grow delta", &delta)) { + if (!EnforceRangeU32(cx, args.get(0), "Table", "grow delta", &delta)) { return false; } uint32_t ret = table->table().grow(delta, cx); if (ret == uint32_t(-1)) { JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_GROW, "table"); return false; @@ -2263,19 +2272,19 @@ WasmTableObject::growImpl(JSContext* cx, WasmTableObject::grow(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); return CallNonGenericMethod<IsTable, growImpl>(cx, args); } const JSFunctionSpec WasmTableObject::methods[] = { - JS_FN("get", WasmTableObject::get, 1, 0), - JS_FN("set", WasmTableObject::set, 2, 0), - JS_FN("grow", WasmTableObject::grow, 1, 0), + JS_FN("get", WasmTableObject::get, 1, JSPROP_ENUMERATE), + JS_FN("set", WasmTableObject::set, 2, JSPROP_ENUMERATE), + JS_FN("grow", WasmTableObject::grow, 1, JSPROP_ENUMERATE), JS_FS_END }; const JSFunctionSpec WasmTableObject::static_methods[] = { JS_FS_END }; Table& WasmTableObject::table() const @@ -2416,16 +2425,23 @@ WasmGlobalObject::construct(JSContext* c if (!args.get(0).isObject()) { JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_DESC_ARG, "global"); return false; } RootedObject obj(cx, &args[0].toObject()); + // Extract properties in lexicographic order per spec. + + RootedValue mutableVal(cx); + if (!JS_GetProperty(cx, obj, "mutable", &mutableVal)) { + return false; + } + RootedValue typeVal(cx); if (!JS_GetProperty(cx, obj, "value", &typeVal)) { return false; } RootedString typeStr(cx, ToString(cx, typeVal)); if (!typeStr) { return false; @@ -2451,39 +2467,37 @@ WasmGlobalObject::construct(JSContext* c } else if (cx->options().wasmGc() && StringEqualsAscii(typeLinearStr, "anyref")) { globalType = ValType::AnyRef; #endif } else { JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_GLOBAL_TYPE); return false; } - RootedValue mutableVal(cx); - if (!JS_GetProperty(cx, obj, "mutable", &mutableVal)) { - return false; - } - bool isMutable = ToBoolean(mutableVal); // Extract the initial value, or provide a suitable default. RootedVal globalVal(cx); - if (args.length() >= 2) { - RootedValue valueVal(cx, args.get(1)); + + // Initialize with default value. + switch (globalType.code()) { + case ValType::I32: globalVal = Val(uint32_t(0)); break; + case ValType::I64: globalVal = Val(uint64_t(0)); break; + case ValType::F32: globalVal = Val(float(0.0)); break; + case ValType::F64: globalVal = Val(double(0.0)); break; + case ValType::AnyRef: globalVal = Val(nullptr); break; + case ValType::Ref: MOZ_CRASH("Ref NYI"); + } + + // Override with non-undefined value, if provided. + RootedValue valueVal(cx, args.get(1)); + if (!valueVal.isUndefined()) { if (!ToWebAssemblyValue(cx, globalType, valueVal, &globalVal)) { return false; } - } else { - switch (globalType.code()) { - case ValType::I32: globalVal = Val(uint32_t(0)); break; - case ValType::I64: globalVal = Val(uint64_t(0)); break; - case ValType::F32: globalVal = Val(float(0.0)); break; - case ValType::F64: globalVal = Val(double(0.0)); break; - case ValType::AnyRef: globalVal = Val(nullptr); break; - case ValType::Ref: MOZ_CRASH("Ref NYI"); - } } WasmGlobalObject* global = WasmGlobalObject::create(cx, globalVal, isMutable); if (!global) { return false; } args.rval().setObject(*global); @@ -2520,16 +2534,20 @@ WasmGlobalObject::valueGetter(JSContext* { CallArgs args = CallArgsFromVp(argc, vp); return CallNonGenericMethod<IsGlobal, valueGetterImpl>(cx, args); } /* static */ bool WasmGlobalObject::valueSetterImpl(JSContext* cx, const CallArgs& args) { + if (!args.requireAtLeast(cx, "WebAssembly.Global setter", 1)) { + return false; + } + RootedWasmGlobalObject global(cx, &args.thisv().toObject().as<WasmGlobalObject>()); if (!global->isMutable()) { JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_WASM_GLOBAL_IMMUTABLE); return false; } if (global->type() == ValType::I64) { JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_I64_TYPE); @@ -2582,17 +2600,17 @@ const JSPropertySpec WasmGlobalObject::p { JS_PSGS("value", WasmGlobalObject::valueGetter, WasmGlobalObject::valueSetter, JSPROP_ENUMERATE), JS_PS_END }; const JSFunctionSpec WasmGlobalObject::methods[] = { - JS_FN(js_valueOf_str, WasmGlobalObject::valueGetter, 0, 0), + JS_FN(js_valueOf_str, WasmGlobalObject::valueGetter, 0, JSPROP_ENUMERATE), JS_FS_END }; const JSFunctionSpec WasmGlobalObject::static_methods[] = { JS_FS_END }; ValType WasmGlobalObject::type() const @@ -3469,21 +3487,21 @@ WebAssembly_instantiateStreaming(JSConte callArgs.rval().setObject(*promise); return true; } static const JSFunctionSpec WebAssembly_static_methods[] = { JS_FN(js_toSource_str, WebAssembly_toSource, 0, 0), - JS_FN("compile", WebAssembly_compile, 1, 0), - JS_FN("instantiate", WebAssembly_instantiate, 1, 0), - JS_FN("validate", WebAssembly_validate, 1, 0), - JS_FN("compileStreaming", WebAssembly_compileStreaming, 1, 0), - JS_FN("instantiateStreaming", WebAssembly_instantiateStreaming, 1, 0), + JS_FN("compile", WebAssembly_compile, 1, JSPROP_ENUMERATE), + JS_FN("instantiate", WebAssembly_instantiate, 1, JSPROP_ENUMERATE), + JS_FN("validate", WebAssembly_validate, 1, JSPROP_ENUMERATE), + JS_FN("compileStreaming", WebAssembly_compileStreaming, 1, JSPROP_ENUMERATE), + JS_FN("instantiateStreaming", WebAssembly_instantiateStreaming, 1, JSPROP_ENUMERATE), JS_FS_END }; const Class js::WebAssemblyClass = { js_WebAssembly_str, JSCLASS_HAS_CACHED_PROTO(JSProto_WebAssembly) };
--- a/js/src/wasm/WasmOpIter.cpp +++ b/js/src/wasm/WasmOpIter.cpp @@ -144,16 +144,17 @@ wasm::Classify(OpBytes op) case Op::F32Gt: case Op::F32Ge: case Op::F64Eq: case Op::F64Ne: case Op::F64Lt: case Op::F64Le: case Op::F64Gt: case Op::F64Ge: + case Op::RefEq: return OpKind::Comparison; case Op::I32Eqz: case Op::I32WrapI64: case Op::I32TruncSF32: case Op::I32TruncUF32: case Op::I32ReinterpretF32: case Op::I32TruncSF64: case Op::I32TruncUF64:
--- a/js/src/wasm/WasmTextToBinary.cpp +++ b/js/src/wasm/WasmTextToBinary.cpp @@ -2049,16 +2049,19 @@ WasmTokenStream::next() case 'r': if (consume(u"result")) { return WasmToken(WasmToken::Result, begin, cur_); } if (consume(u"return")) { return WasmToken(WasmToken::Return, begin, cur_); } if (consume(u"ref")) { + if (consume(u".eq")) { + return WasmToken(WasmToken::ComparisonOpcode, Op::RefEq, begin, cur_); + } if (consume(u".null")) { return WasmToken(WasmToken::RefNull, begin, cur_); } if (consume(u".is_null")) { return WasmToken(WasmToken::UnaryOpcode, Op::RefIsNull, begin, cur_); } return WasmToken(WasmToken::Ref, begin, cur_); }
--- a/js/src/wasm/WasmValidate.cpp +++ b/js/src/wasm/WasmValidate.cpp @@ -932,16 +932,23 @@ DecodeFunctionBodyExprs(const ModuleEnvi } #endif default: return iter.unrecognizedOpcode(&op); } break; } #ifdef ENABLE_WASM_GC + case uint16_t(Op::RefEq): { + if (env.gcTypesEnabled() == HasGcTypes::False) { + return iter.unrecognizedOpcode(&op); + } + CHECK(iter.readComparison(ValType::AnyRef, ¬hing, ¬hing)); + break; + } case uint16_t(Op::RefNull): { if (env.gcTypesEnabled() == HasGcTypes::False) { return iter.unrecognizedOpcode(&op); } ValType unusedType; CHECK(iter.readRefNull(&unusedType)); break; }
--- a/layout/svg/SVGContextPaint.cpp +++ b/layout/svg/SVGContextPaint.cpp @@ -85,33 +85,30 @@ SVGContextPaint::IsAllowedForImageFromUR /** * Stores in |aTargetPaint| information on how to reconstruct the current * fill or stroke pattern. Will also set the paint opacity to transparent if * the paint is set to "none". * @param aOuterContextPaint pattern information from the outer text context * @param aTargetPaint where to store the current pattern information * @param aFillOrStroke member pointer to the paint we are setting up - * @param aProperty the frame property descriptor of the fill or stroke paint - * server frame */ static void SetupInheritablePaint(const DrawTarget* aDrawTarget, const gfxMatrix& aContextMatrix, nsIFrame* aFrame, float& aOpacity, SVGContextPaint* aOuterContextPaint, SVGContextPaintImpl::Paint& aTargetPaint, nsStyleSVGPaint nsStyleSVG::*aFillOrStroke, - SVGObserverUtils::PaintingPropertyDescriptor aProperty, imgDrawingParams& aImgParams) { const nsStyleSVG *style = aFrame->StyleSVG(); nsSVGPaintServerFrame *ps = - SVGObserverUtils::GetPaintServer(aFrame, aFillOrStroke, aProperty); + SVGObserverUtils::GetPaintServer(aFrame, aFillOrStroke); if (ps) { RefPtr<gfxPattern> pattern = ps->GetPaintServerPattern(aFrame, aDrawTarget, aContextMatrix, aFillOrStroke, aOpacity, aImgParams); if (pattern) { aTargetPaint.SetPaintServer(aFrame, aContextMatrix, ps); @@ -162,36 +159,34 @@ SVGContextPaintImpl::Init(const DrawTarg SetFillOpacity(0.0f); } else { float opacity = nsSVGUtils::GetOpacity(style->FillOpacitySource(), style->mFillOpacity, aOuterContextPaint); SetupInheritablePaint(aDrawTarget, aContextMatrix, aFrame, opacity, aOuterContextPaint, mFillPaint, &nsStyleSVG::mFill, - SVGObserverUtils::FillProperty(), aImgParams); + aImgParams); SetFillOpacity(opacity); toDraw |= DrawMode::GLYPH_FILL; } // stroke: if (style->mStroke.Type() == eStyleSVGPaintType_None) { SetStrokeOpacity(0.0f); } else { float opacity = nsSVGUtils::GetOpacity(style->StrokeOpacitySource(), style->mStrokeOpacity, aOuterContextPaint); SetupInheritablePaint(aDrawTarget, aContextMatrix, aFrame, opacity, aOuterContextPaint, mStrokePaint, - &nsStyleSVG::mStroke, - SVGObserverUtils::StrokeProperty(), - aImgParams); + &nsStyleSVG::mStroke, aImgParams); SetStrokeOpacity(opacity); toDraw |= DrawMode::GLYPH_STROKE; } return toDraw; }
--- a/layout/svg/SVGGeometryFrame.cpp +++ b/layout/svg/SVGGeometryFrame.cpp @@ -636,44 +636,33 @@ SVGGeometryFrame::GetBBoxContribution(co MOZ_ASSERT(ToRect(strokeBBoxExtents).IsFinite(), "bbox is about to go bad"); bbox.UnionEdges(strokeBBoxExtents); #endif } } // Account for markers: if ((aFlags & nsSVGUtils::eBBoxIncludeMarkers) != 0 && - static_cast<SVGGeometryElement*>(GetContent())->IsMarkable()) { - - float strokeWidth = nsSVGUtils::GetStrokeWidth(this); - MarkerProperties properties = GetMarkerProperties(this); - - if (properties.MarkersExist()) { + element->IsMarkable()) { + nsSVGMarkerFrame* markerFrames[nsSVGMark::eTypeCount]; + if (SVGObserverUtils::GetMarkerFrames(this, &markerFrames)) { nsTArray<nsSVGMark> marks; - static_cast<SVGGeometryElement*>(GetContent())->GetMarkPoints(&marks); - uint32_t num = marks.Length(); - - // These are in the same order as the nsSVGMark::Type constants. - nsSVGMarkerFrame* markerFrames[] = { - properties.GetMarkerStartFrame(), - properties.GetMarkerMidFrame(), - properties.GetMarkerEndFrame(), - }; - static_assert(MOZ_ARRAY_LENGTH(markerFrames) == nsSVGMark::eTypeCount, - "Number of Marker frames should be equal to eTypeCount"); - - for (uint32_t i = 0; i < num; i++) { - const nsSVGMark& mark = marks[i]; - nsSVGMarkerFrame* frame = markerFrames[mark.type]; - if (frame) { - SVGBBox mbbox = - frame->GetMarkBBoxContribution(aToBBoxUserspace, aFlags, this, - mark, strokeWidth); - MOZ_ASSERT(mbbox.IsFinite(), "bbox is about to go bad"); - bbox.UnionEdges(mbbox); + element->GetMarkPoints(&marks); + if (uint32_t num = marks.Length()) { + float strokeWidth = nsSVGUtils::GetStrokeWidth(this); + for (uint32_t i = 0; i < num; i++) { + const nsSVGMark& mark = marks[i]; + nsSVGMarkerFrame* frame = markerFrames[mark.type]; + if (frame) { + SVGBBox mbbox = + frame->GetMarkBBoxContribution(aToBBoxUserspace, aFlags, this, + mark, strokeWidth); + MOZ_ASSERT(mbbox.IsFinite(), "bbox is about to go bad"); + bbox.UnionEdges(mbbox); + } } } } } return bbox; } @@ -686,67 +675,16 @@ SVGGeometryFrame::GetCanvasTM() NS_ASSERTION(GetParent(), "null parent"); nsSVGContainerFrame *parent = static_cast<nsSVGContainerFrame*>(GetParent()); SVGGraphicsElement *content = static_cast<SVGGraphicsElement*>(GetContent()); return content->PrependLocalTransformsTo(parent->GetCanvasTM()); } -SVGGeometryFrame::MarkerProperties -SVGGeometryFrame::GetMarkerProperties(SVGGeometryFrame *aFrame) -{ - NS_ASSERTION(!aFrame->GetPrevContinuation(), "aFrame should be first continuation"); - - MarkerProperties result; - RefPtr<URLAndReferrerInfo> markerURL = - SVGObserverUtils::GetMarkerURI(aFrame, &nsStyleSVG::mMarkerStart); - result.mMarkerStart = - SVGObserverUtils::GetMarkerProperty(markerURL, aFrame, - SVGObserverUtils::MarkerBeginProperty()); - - markerURL = SVGObserverUtils::GetMarkerURI(aFrame, &nsStyleSVG::mMarkerMid); - result.mMarkerMid = - SVGObserverUtils::GetMarkerProperty(markerURL, aFrame, - SVGObserverUtils::MarkerMiddleProperty()); - - markerURL = SVGObserverUtils::GetMarkerURI(aFrame, &nsStyleSVG::mMarkerEnd); - result.mMarkerEnd = - SVGObserverUtils::GetMarkerProperty(markerURL, aFrame, - SVGObserverUtils::MarkerEndProperty()); - return result; -} - -nsSVGMarkerFrame * -SVGGeometryFrame::MarkerProperties::GetMarkerStartFrame() -{ - if (!mMarkerStart) - return nullptr; - return static_cast<nsSVGMarkerFrame*>( - mMarkerStart->GetReferencedFrame(LayoutFrameType::SVGMarker, nullptr)); -} - -nsSVGMarkerFrame * -SVGGeometryFrame::MarkerProperties::GetMarkerMidFrame() -{ - if (!mMarkerMid) - return nullptr; - return static_cast<nsSVGMarkerFrame*>( - mMarkerMid->GetReferencedFrame(LayoutFrameType::SVGMarker, nullptr)); -} - -nsSVGMarkerFrame * -SVGGeometryFrame::MarkerProperties::GetMarkerEndFrame() -{ - if (!mMarkerEnd) - return nullptr; - return static_cast<nsSVGMarkerFrame*>( - mMarkerEnd->GetReferencedFrame(LayoutFrameType::SVGMarker, nullptr)); -} - void SVGGeometryFrame::Render(gfxContext* aContext, uint32_t aRenderComponents, const gfxMatrix& aNewTransform, imgDrawingParams& aImgParams) { MOZ_ASSERT(!aNewTransform.IsSingular()); @@ -861,38 +799,27 @@ SVGGeometryFrame::Render(gfxContext* aCo } } void SVGGeometryFrame::PaintMarkers(gfxContext& aContext, const gfxMatrix& aTransform, imgDrawingParams& aImgParams) { - SVGContextPaint* contextPaint = SVGContextPaint::GetContextPaint(GetContent()); - if (static_cast<SVGGeometryElement*>(GetContent())->IsMarkable()) { - MarkerProperties properties = GetMarkerProperties(this); - - if (properties.MarkersExist()) { - float strokeWidth = nsSVGUtils::GetStrokeWidth(this, contextPaint); - - nsTArray<nsSVGMark> marks; - static_cast<SVGGeometryElement*> - (GetContent())->GetMarkPoints(&marks); + auto element = static_cast<SVGGeometryElement*>(GetContent()); - uint32_t num = marks.Length(); - if (num) { - // These are in the same order as the nsSVGMark::Type constants. - nsSVGMarkerFrame* markerFrames[] = { - properties.GetMarkerStartFrame(), - properties.GetMarkerMidFrame(), - properties.GetMarkerEndFrame(), - }; - static_assert(MOZ_ARRAY_LENGTH(markerFrames) == nsSVGMark::eTypeCount, - "Number of Marker frames should be equal to eTypeCount"); - + if (element->IsMarkable()) { + nsSVGMarkerFrame* markerFrames[nsSVGMark::eTypeCount]; + if (SVGObserverUtils::GetMarkerFrames(this, &markerFrames)) { + nsTArray<nsSVGMark> marks; + element->GetMarkPoints(&marks); + if (uint32_t num = marks.Length()) { + SVGContextPaint* contextPaint = + SVGContextPaint::GetContextPaint(GetContent()); + float strokeWidth = nsSVGUtils::GetStrokeWidth(this, contextPaint); for (uint32_t i = 0; i < num; i++) { const nsSVGMark& mark = marks[i]; nsSVGMarkerFrame* frame = markerFrames[mark.type]; if (frame) { frame->PaintMark(aContext, aTransform, this, mark, strokeWidth, aImgParams); } }
--- a/layout/svg/SVGGeometryFrame.h +++ b/layout/svg/SVGGeometryFrame.h @@ -124,31 +124,12 @@ private: const gfxMatrix& aTransform, imgDrawingParams& aImgParams); /** * @param aMatrix The transform that must be multiplied onto aContext to * establish this frame's SVG user space. */ void PaintMarkers(gfxContext& aContext, const gfxMatrix& aMatrix, imgDrawingParams& aImgParams); - - struct MarkerProperties { - SVGMarkerObserver* mMarkerStart; - SVGMarkerObserver* mMarkerMid; - SVGMarkerObserver* mMarkerEnd; - - bool MarkersExist() const { - return mMarkerStart || mMarkerMid || mMarkerEnd; - } - - nsSVGMarkerFrame *GetMarkerStartFrame(); - nsSVGMarkerFrame *GetMarkerMidFrame(); - nsSVGMarkerFrame *GetMarkerEndFrame(); - }; - - /** - * @param aFrame should be the first continuation - */ - static MarkerProperties GetMarkerProperties(SVGGeometryFrame *aFrame); }; } // namespace mozilla #endif // __SVGGEOMETRYFRAME_H__
--- a/layout/svg/SVGObserverUtils.cpp +++ b/layout/svg/SVGObserverUtils.cpp @@ -13,16 +13,17 @@ #include "nsISupportsImpl.h" #include "nsSVGClipPathFrame.h" #include "nsSVGPaintServerFrame.h" #include "nsSVGFilterFrame.h" #include "nsSVGMaskFrame.h" #include "nsIReflowCallback.h" #include "nsCycleCollectionParticipant.h" #include "SVGGeometryElement.h" +#include "SVGTextPathElement.h" #include "SVGUseElement.h" #include "ImageLoader.h" #include "mozilla/net/ReferrerPolicy.h" using namespace mozilla::dom; namespace mozilla { @@ -218,28 +219,51 @@ nsSVGFrameReferenceFromProperty::Get() { if (mFramePresShell && mFramePresShell->IsDestroying()) { // mFrame is no longer valid. Detach(); } return mFrame; } + +NS_IMPL_ISUPPORTS(SVGTemplateElementObserver, nsIMutationObserver) + +void +SVGTemplateElementObserver::OnRenderingChange() +{ + SVGIDRenderingObserver::OnRenderingChange(); + + if (nsIFrame* frame = mFrameReference.Get()) { + // We know that we don't need to walk the parent chain notifying rendering + // observers since changes to a gradient etc. do not affect ancestor + // elements. So we only invalidate *direct* rendering observers here. + // Since we don't need to walk the parent chain, we don't need to worry + // about coalescing multiple invalidations by using a change hint as we do + // in nsSVGRenderingObserverProperty::OnRenderingChange. + SVGObserverUtils::InvalidateDirectRenderingObservers(frame); + } +} + + NS_IMPL_ISUPPORTS(nsSVGRenderingObserverProperty, nsIMutationObserver) void nsSVGRenderingObserverProperty::OnRenderingChange() { SVGIDRenderingObserver::OnRenderingChange(); nsIFrame* frame = mFrameReference.Get(); if (frame && frame->HasAllStateBits(NS_FRAME_SVG_LAYOUT)) { - // Changes should propagate out to things that might be observing - // the referencing frame or its ancestors. + // We need to notify anything that is observing the referencing frame or + // any of its ancestors that the referencing frame has been invalidated. + // Since walking the parent chain checking for observers is expensive we + // do that using a change hint (multiple change hints of the same type are + // coalesced). nsLayoutUtils::PostRestyleEvent( frame->GetContent()->AsElement(), nsRestyleHint(0), nsChangeHint_InvalidateRenderingObservers); } } NS_IMPL_CYCLE_COLLECTING_ADDREF(SVGFilterObserver) @@ -566,29 +590,97 @@ GetEffectProperty(URLAndReferrerInfo* aU if (prop) return prop; prop = new T(aURI, aFrame, false); NS_ADDREF(prop); aFrame->SetProperty(aProperty, prop); return prop; } -SVGMarkerObserver* -SVGObserverUtils::GetMarkerProperty(URLAndReferrerInfo* aURI, nsIFrame* aFrame, - const mozilla::FramePropertyDescriptor<SVGMarkerObserver>* aProperty) +bool +SVGObserverUtils::GetMarkerFrames(nsIFrame* aMarkedFrame, + nsSVGMarkerFrame*(*aFrames)[3]) { - MOZ_ASSERT(aFrame->IsSVGGeometryFrame() && - static_cast<SVGGeometryElement*>(aFrame->GetContent())->IsMarkable(), + MOZ_ASSERT(!aMarkedFrame->GetPrevContinuation() && + aMarkedFrame->IsSVGGeometryFrame() && + static_cast<SVGGeometryElement*>(aMarkedFrame->GetContent())->IsMarkable(), "Bad frame"); - return GetEffectProperty(aURI, aFrame, aProperty); + + bool foundMarker = false; + RefPtr<URLAndReferrerInfo> markerURL; + SVGMarkerObserver* observer; + nsIFrame* marker; + +#define GET_MARKER(type) \ + markerURL = GetMarkerURI(aMarkedFrame, &nsStyleSVG::mMarker##type); \ + observer = GetEffectProperty(markerURL, aMarkedFrame, \ + SVGObserverUtils::Marker##type##Property()); \ + marker = observer ? \ + observer->GetReferencedFrame(LayoutFrameType::SVGMarker, nullptr) :\ + nullptr; \ + foundMarker = foundMarker || bool(marker); \ + (*aFrames)[nsSVGMark::e##type] = static_cast<nsSVGMarkerFrame*>(marker); + + GET_MARKER(Start) + GET_MARKER(Mid) + GET_MARKER(End) + +#undef GET_MARKER + + return foundMarker; } -SVGTextPathObserver* -SVGObserverUtils::GetTextPathProperty(URLAndReferrerInfo* aURI, nsIFrame* aFrame, - const mozilla::FramePropertyDescriptor<SVGTextPathObserver>* aProperty) +SVGGeometryElement* +SVGObserverUtils::GetTextPathsReferencedPath(nsIFrame* aTextPathFrame) +{ + SVGTextPathObserver* property = + aTextPathFrame->GetProperty(SVGObserverUtils::HrefAsTextPathProperty()); + + if (!property) { + nsIContent* content = aTextPathFrame->GetContent(); + nsAutoString href; + static_cast<SVGTextPathElement*>(content)->HrefAsString(href); + if (href.IsEmpty()) { + return nullptr; // no URL + } + + nsCOMPtr<nsIURI> targetURI; + nsCOMPtr<nsIURI> base = content->GetBaseURI(); + nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(targetURI), href, + content->GetUncomposedDoc(), base); + + // There's no clear refererer policy spec about non-CSS SVG resource references + // Bug 1415044 to investigate which referrer we should use + RefPtr<URLAndReferrerInfo> target = + new URLAndReferrerInfo(targetURI, + content->OwnerDoc()->GetDocumentURI(), + content->OwnerDoc()->GetReferrerPolicy()); + + property = GetEffectProperty(target, aTextPathFrame, + HrefAsTextPathProperty()); + if (!property) { + return nullptr; + } + } + + Element* element = property->GetReferencedElement(); + return (element && element->IsNodeOfType(nsINode::eSHAPE)) ? + static_cast<SVGGeometryElement*>(element) : nullptr; +} + +void +SVGObserverUtils::RemoveTextPathObserver(nsIFrame* aTextPathFrame) +{ + aTextPathFrame->DeleteProperty(HrefAsTextPathProperty()); +} + +SVGTemplateElementObserver* +SVGObserverUtils::GetTemplateElementObserver(URLAndReferrerInfo* aURI, + nsIFrame* aFrame, + const mozilla::FramePropertyDescriptor<SVGTemplateElementObserver>* aProperty) { return GetEffectProperty(aURI, aFrame, aProperty); } nsSVGPaintingProperty* SVGObserverUtils::GetPaintingProperty(URLAndReferrerInfo* aURI, nsIFrame* aFrame, const mozilla::FramePropertyDescriptor<nsSVGPaintingProperty>* aProperty) { @@ -641,18 +733,17 @@ SVGObserverUtils::GetEffectProperties(ns result.mMaskObservers = style->HasMask() ? GetOrCreateMaskProperty(aFrame) : nullptr; return result; } nsSVGPaintServerFrame * SVGObserverUtils::GetPaintServer(nsIFrame* aTargetFrame, - nsStyleSVGPaint nsStyleSVG::* aPaint, - PaintingPropertyDescriptor aType) + nsStyleSVGPaint nsStyleSVG::* aPaint) { // If we're looking at a frame within SVG text, then we need to look up // to find the right frame to get the painting property off. We should at // least look up past a text frame, and if the text frame's parent is the // anonymous block frame, then we look up to its parent (the SVGTextFrame). nsIFrame* frame = aTargetFrame; if (frame->GetContent()->IsText()) { frame = frame->GetParent(); @@ -663,18 +754,22 @@ SVGObserverUtils::GetPaintServer(nsIFram } const nsStyleSVG* svgStyle = frame->StyleSVG(); if ((svgStyle->*aPaint).Type() != eStyleSVGPaintType_Server) return nullptr; RefPtr<URLAndReferrerInfo> paintServerURL = SVGObserverUtils::GetPaintURI(frame, aPaint); + MOZ_ASSERT(aPaint == &nsStyleSVG::mFill || aPaint == &nsStyleSVG::mStroke); + PaintingPropertyDescriptor propDesc = (aPaint == &nsStyleSVG::mFill) ? + SVGObserverUtils::FillProperty() : + SVGObserverUtils::StrokeProperty(); nsSVGPaintingProperty *property = - SVGObserverUtils::GetPaintingProperty(paintServerURL, frame, aType); + SVGObserverUtils::GetPaintingProperty(paintServerURL, frame, propDesc); if (!property) return nullptr; nsIFrame* result = property->GetReferencedFrame(); if (!result) return nullptr; LayoutFrameType type = result->Type(); if (type != LayoutFrameType::SVGLinearGradient && @@ -770,38 +865,38 @@ void SVGObserverUtils::UpdateEffects(nsIFrame* aFrame) { NS_ASSERTION(aFrame->GetContent()->IsElement(), "aFrame's content should be an element"); aFrame->DeleteProperty(FilterProperty()); aFrame->DeleteProperty(MaskProperty()); aFrame->DeleteProperty(ClipPathProperty()); - aFrame->DeleteProperty(MarkerBeginProperty()); - aFrame->DeleteProperty(MarkerMiddleProperty()); + aFrame->DeleteProperty(MarkerStartProperty()); + aFrame->DeleteProperty(MarkerMidProperty()); aFrame->DeleteProperty(MarkerEndProperty()); aFrame->DeleteProperty(FillProperty()); aFrame->DeleteProperty(StrokeProperty()); aFrame->DeleteProperty(BackgroundImageProperty()); // Ensure that the filter is repainted correctly // We can't do that in OnRenderingChange as the referenced frame may // not be valid GetOrCreateFilterObserverListForCSS(aFrame); if (aFrame->IsSVGGeometryFrame() && static_cast<SVGGeometryElement*>(aFrame->GetContent())->IsMarkable()) { // Set marker properties here to avoid reference loops RefPtr<URLAndReferrerInfo> markerURL = GetMarkerURI(aFrame, &nsStyleSVG::mMarkerStart); - GetMarkerProperty(markerURL, aFrame, MarkerBeginProperty()); + GetEffectProperty(markerURL, aFrame, MarkerStartProperty()); markerURL = GetMarkerURI(aFrame, &nsStyleSVG::mMarkerMid); - GetMarkerProperty(markerURL, aFrame, MarkerMiddleProperty()); + GetEffectProperty(markerURL, aFrame, MarkerMidProperty()); markerURL = GetMarkerURI(aFrame, &nsStyleSVG::mMarkerEnd); - GetMarkerProperty(markerURL, aFrame, MarkerEndProperty()); + GetEffectProperty(markerURL, aFrame, MarkerEndProperty()); } } SVGFilterObserverListForCSSProp* SVGObserverUtils::GetFilterObserverList(nsIFrame* aFrame) { NS_ASSERTION(!aFrame->GetPrevContinuation(), "aFrame should be first continuation");
--- a/layout/svg/SVGObserverUtils.h +++ b/layout/svg/SVGObserverUtils.h @@ -23,21 +23,25 @@ #include "nsTHashtable.h" #include "nsURIHashKey.h" #include "nsCycleCollectionParticipant.h" class nsAtom; class nsIPresShell; class nsIURI; class nsSVGClipPathFrame; +class nsSVGMarkerFrame; class nsSVGPaintServerFrame; class nsSVGFilterFrame; class nsSVGMaskFrame; namespace mozilla { class SVGFilterObserverList; +namespace dom { +class SVGGeometryElement; +} } namespace mozilla { /* * This class contains URL and referrer information (referrer and referrer * policy). * We use it to pass to svg system instead of nsIURI. The object brings referrer @@ -230,16 +234,49 @@ private: // the presshell for the frames we care about and, before we use the frame, // we test the presshell to see if it's destroying itself. If it is, // then the frame pointer is not valid and we know the frame has gone away. // mFramePresShell may be null, but when mFrame is non-null, mFramePresShell // is guaranteed to be non-null, too. nsIPresShell *mFramePresShell; }; +/** + * Used for gradient-to-gradient, pattern-to-pattern and filter-to-filter + * references to "template" elements (specified via the 'href' attributes). + * + * This is a special class for the case where we know we only want to call + * InvalidateDirectRenderingObservers (as opposed to + * InvalidateRenderingObservers). + * + * TODO(jwatt): If we added a new NS_FRAME_RENDERING_OBSERVER_CONTAINER state + * bit to clipPath, filter, gradients, marker, mask, pattern and symbol, and + * could have InvalidateRenderingObservers stop on reaching such an element, + * then we would no longer need this class (not to mention improving perf by + * significantly cutting down on ancestor traversal). + */ +class SVGTemplateElementObserver : public SVGIDRenderingObserver +{ +public: + NS_DECL_ISUPPORTS + + SVGTemplateElementObserver(URLAndReferrerInfo* aURI, nsIFrame* aFrame, + bool aReferenceImage) + : SVGIDRenderingObserver(aURI, aFrame->GetContent(), aReferenceImage) + , mFrameReference(aFrame) + {} + +protected: + virtual ~SVGTemplateElementObserver() = default; // non-public + + virtual void OnRenderingChange() override; + + nsSVGFrameReferenceFromProperty mFrameReference; +}; + class nsSVGRenderingObserverProperty : public SVGIDRenderingObserver { public: NS_DECL_ISUPPORTS nsSVGRenderingObserverProperty(URLAndReferrerInfo* aURI, nsIFrame *aFrame, bool aReferenceImage) : SVGIDRenderingObserver(aURI, aFrame->GetContent(), aReferenceImage) @@ -494,16 +531,17 @@ public: private: nsTHashtable<nsPtrHashKey<SVGRenderingObserver>> mObservers; }; class SVGObserverUtils { public: typedef mozilla::dom::Element Element; + typedef dom::SVGGeometryElement SVGGeometryElement; typedef nsInterfaceHashtable<nsRefPtrHashKey<URLAndReferrerInfo>, nsIMutationObserver> URIObserverHashtable; using PaintingPropertyDescriptor = const mozilla::FramePropertyDescriptor<nsSVGPaintingProperty>*; using URIObserverHashtablePropertyDescriptor = const mozilla::FramePropertyDescriptor<URIObserverHashtable>*; @@ -512,40 +550,33 @@ public: // SVGFilterObserverListForCSSProp is cycle-collected, so dropping the last // reference doesn't necessarily destroy it. We need to tell it that the // frame has now become invalid. aProp->DetachFromFrame(); aProp->Release(); } + NS_DECLARE_FRAME_PROPERTY_RELEASABLE(HrefToTemplateProperty, + SVGTemplateElementObserver) NS_DECLARE_FRAME_PROPERTY_WITH_DTOR(FilterProperty, SVGFilterObserverListForCSSProp, DestroyFilterProperty) NS_DECLARE_FRAME_PROPERTY_RELEASABLE(MaskProperty, SVGMaskObserverList) NS_DECLARE_FRAME_PROPERTY_RELEASABLE(ClipPathProperty, nsSVGPaintingProperty) - NS_DECLARE_FRAME_PROPERTY_RELEASABLE(MarkerBeginProperty, SVGMarkerObserver) - NS_DECLARE_FRAME_PROPERTY_RELEASABLE(MarkerMiddleProperty, SVGMarkerObserver) + NS_DECLARE_FRAME_PROPERTY_RELEASABLE(MarkerStartProperty, SVGMarkerObserver) + NS_DECLARE_FRAME_PROPERTY_RELEASABLE(MarkerMidProperty, SVGMarkerObserver) NS_DECLARE_FRAME_PROPERTY_RELEASABLE(MarkerEndProperty, SVGMarkerObserver) NS_DECLARE_FRAME_PROPERTY_RELEASABLE(FillProperty, nsSVGPaintingProperty) NS_DECLARE_FRAME_PROPERTY_RELEASABLE(StrokeProperty, nsSVGPaintingProperty) NS_DECLARE_FRAME_PROPERTY_RELEASABLE(HrefAsTextPathProperty, SVGTextPathObserver) - NS_DECLARE_FRAME_PROPERTY_RELEASABLE(HrefAsPaintingProperty, - nsSVGPaintingProperty) NS_DECLARE_FRAME_PROPERTY_DELETABLE(BackgroundImageProperty, URIObserverHashtable) - /** - * Get the paint server for a aTargetFrame. - */ - static nsSVGPaintServerFrame *GetPaintServer(nsIFrame* aTargetFrame, - nsStyleSVGPaint nsStyleSVG::* aPaint, - PaintingPropertyDescriptor aProperty); - struct EffectProperties { SVGFilterObserverListForCSSProp* mFilterObservers; SVGMaskObserverList* mMaskObservers; nsSVGPaintingProperty* mClipPath; /** * @return the clip-path frame, or null if there is no clip-path frame */ @@ -680,27 +711,47 @@ public: /** * This can be called on any element or frame. Only direct observers of this * (frame's) element, if any, are invalidated. */ static void InvalidateDirectRenderingObservers(Element* aElement, uint32_t aFlags = 0); static void InvalidateDirectRenderingObservers(nsIFrame* aFrame, uint32_t aFlags = 0); /** - * Get an SVGMarkerObserver for the frame, creating a fresh one if necessary + * Get the paint server for a aTargetFrame. */ - static SVGMarkerObserver * - GetMarkerProperty(URLAndReferrerInfo* aURI, nsIFrame* aFrame, - const mozilla::FramePropertyDescriptor<SVGMarkerObserver>* aProperty); + static nsSVGPaintServerFrame *GetPaintServer(nsIFrame* aTargetFrame, + nsStyleSVGPaint nsStyleSVG::* aPaint); + + /** + * Get the start/mid/end-markers for the given frame, and add the frame as + * an observer to those markers. Returns true if at least one marker type is + * found, false otherwise. + */ + static bool + GetMarkerFrames(nsIFrame* aMarkedFrame, nsSVGMarkerFrame*(*aFrames)[3]); + /** - * Get an SVGTextPathObserver for the frame, creating a fresh one if necessary + * Get the SVGGeometryElement that is referenced by aTextPathFrame, and make + * aTextPathFrame start observing rendering changes to that element. */ - static SVGTextPathObserver * - GetTextPathProperty(URLAndReferrerInfo* aURI, nsIFrame* aFrame, - const mozilla::FramePropertyDescriptor<SVGTextPathObserver>* aProperty); + static SVGGeometryElement* + GetTextPathsReferencedPath(nsIFrame* aTextPathFrame); + + /** + * Make aTextPathFrame stop observing rendering changes to the + * SVGGeometryElement that it references, if any. + */ + static void + RemoveTextPathObserver(nsIFrame* aTextPathFrame); + + static SVGTemplateElementObserver* + GetTemplateElementObserver(URLAndReferrerInfo* aURI, nsIFrame* aFrame, + const mozilla::FramePropertyDescriptor<SVGTemplateElementObserver>* aProperty); + /** * Get an nsSVGPaintingProperty for the frame, creating a fresh one if necessary */ static nsSVGPaintingProperty* GetPaintingProperty(URLAndReferrerInfo* aURI, nsIFrame* aFrame, const mozilla::FramePropertyDescriptor<nsSVGPaintingProperty>* aProperty); /** * Get an nsSVGPaintingProperty for the frame for that URI, creating a fresh
--- a/layout/svg/SVGTextFrame.cpp +++ b/layout/svg/SVGTextFrame.cpp @@ -3392,18 +3392,17 @@ SVGTextFrame::HandleAttributeChangeInDes aAttribute == nsGkAtoms::side_)) { NotifyGlyphMetricsChange(); } else if ((aNameSpaceID == kNameSpaceID_XLink || aNameSpaceID == kNameSpaceID_None) && aAttribute == nsGkAtoms::href) { // Blow away our reference, if any nsIFrame* childElementFrame = aElement->GetPrimaryFrame(); if (childElementFrame) { - childElementFrame->DeleteProperty( - SVGObserverUtils::HrefAsTextPathProperty()); + SVGObserverUtils::RemoveTextPathObserver(childElementFrame); NotifyGlyphMetricsChange(); } } } else { if (aNameSpaceID == kNameSpaceID_None && IsGlyphPositioningAttribute(aAttribute)) { NotifyGlyphMetricsChange(); } @@ -4978,75 +4977,29 @@ SVGTextFrame::AdjustPositionsForClusters mPositions[charIndex + 1].mStartOfChunk = true; } } it.Next(); } } -SVGGeometryElement* -SVGTextFrame::GetTextPathGeometryElement(nsIFrame* aTextPathFrame) -{ - SVGTextPathObserver *property = - aTextPathFrame->GetProperty(SVGObserverUtils::HrefAsTextPathProperty()); - - if (!property) { - nsIContent* content = aTextPathFrame->GetContent(); - SVGTextPathElement* tp = static_cast<SVGTextPathElement*>(content); - nsAutoString href; - if (tp->mStringAttributes[SVGTextPathElement::HREF].IsExplicitlySet()) { - tp->mStringAttributes[SVGTextPathElement::HREF] - .GetAnimValue(href, tp); - } else { - tp->mStringAttributes[SVGTextPathElement::XLINK_HREF] - .GetAnimValue(href, tp); - } - - if (href.IsEmpty()) { - return nullptr; // no URL - } - - nsCOMPtr<nsIURI> targetURI; - nsCOMPtr<nsIURI> base = content->GetBaseURI(); - nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(targetURI), href, - content->GetUncomposedDoc(), base); - - // There's no clear refererer policy spec about non-CSS SVG resource references - // Bug 1415044 to investigate which referrer we should use - RefPtr<URLAndReferrerInfo> target = - new URLAndReferrerInfo(targetURI, - mContent->OwnerDoc()->GetDocumentURI(), - mContent->OwnerDoc()->GetReferrerPolicy()); - - property = SVGObserverUtils::GetTextPathProperty( - target, - aTextPathFrame, - SVGObserverUtils::HrefAsTextPathProperty()); - if (!property) - return nullptr; - } - - Element* element = property->GetReferencedElement(); - return (element && element->IsNodeOfType(nsINode::eSHAPE)) ? - static_cast<SVGGeometryElement*>(element) : nullptr; -} - already_AddRefed<Path> SVGTextFrame::GetTextPath(nsIFrame* aTextPathFrame) { nsIContent* content = aTextPathFrame->GetContent(); SVGTextPathElement* tp = static_cast<SVGTextPathElement*>(content); if (tp->mPath.IsRendered()) { // This is just an attribute so there's no transform that can apply // so we can just return the path directly. return tp->mPath.GetAnimValue().BuildPathForMeasuring(); } - SVGGeometryElement* geomElement = GetTextPathGeometryElement(aTextPathFrame); + SVGGeometryElement* geomElement = + SVGObserverUtils::GetTextPathsReferencedPath(aTextPathFrame); if (!geomElement) { return nullptr; } RefPtr<Path> path = geomElement->GetOrBuildPathForMeasuring(); if (!path) { return nullptr; } @@ -5068,17 +5021,18 @@ SVGTextFrame::GetOffsetScale(nsIFrame* a nsIContent* content = aTextPathFrame->GetContent(); SVGTextPathElement* tp = static_cast<SVGTextPathElement*>(content); if (tp->mPath.IsRendered()) { // A path attribute has no pathLength or transform // so we return a unit scale. return 1.0; } - SVGGeometryElement* geomElement = GetTextPathGeometryElement(aTextPathFrame); + SVGGeometryElement* geomElement = + SVGObserverUtils::GetTextPathsReferencedPath(aTextPathFrame); if (!geomElement) return 1.0; return geomElement->GetPathLengthScale(SVGGeometryElement::eForTextPath); } gfxFloat SVGTextFrame::GetStartOffset(nsIFrame* aTextPathFrame)
--- a/layout/svg/SVGTextFrame.h +++ b/layout/svg/SVGTextFrame.h @@ -533,18 +533,16 @@ private: * the text frames. * * @param aShouldPaintSVGGlyphs (out) Whether SVG glyphs in the text * should be painted. */ bool ShouldRenderAsPath(nsTextFrame* aFrame, bool& aShouldPaintSVGGlyphs); // Methods to get information for a <textPath> frame. - mozilla::dom::SVGGeometryElement* - GetTextPathGeometryElement(nsIFrame* aTextPathFrame); already_AddRefed<Path> GetTextPath(nsIFrame* aTextPathFrame); gfxFloat GetOffsetScale(nsIFrame* aTextPathFrame); gfxFloat GetStartOffset(nsIFrame* aTextPathFrame); /** * The MutationObserver we have registered for the <text> element subtree. */ RefPtr<MutationObserver> mMutationObserver;
--- a/layout/svg/nsSVGFilterFrame.cpp +++ b/layout/svg/nsSVGFilterFrame.cpp @@ -112,20 +112,20 @@ nsSVGFilterFrame::GetFilterContent(nsICo } nsSVGFilterFrame * nsSVGFilterFrame::GetReferencedFilter() { if (mNoHRefURI) return nullptr; - nsSVGPaintingProperty *property = - GetProperty(SVGObserverUtils::HrefAsPaintingProperty()); + SVGTemplateElementObserver* observer = + GetProperty(SVGObserverUtils::HrefToTemplateProperty()); - if (!property) { + if (!observer) { // Fetch our Filter element's href or xlink:href attribute SVGFilterElement *filter = static_cast<SVGFilterElement *>(GetContent()); nsAutoString href; if (filter->mStringAttributes[SVGFilterElement::HREF].IsExplicitlySet()) { filter->mStringAttributes[SVGFilterElement::HREF] .GetAnimValue(href, filter); } else { filter->mStringAttributes[SVGFilterElement::XLINK_HREF] @@ -144,23 +144,24 @@ nsSVGFilterFrame::GetReferencedFilter() mContent->GetUncomposedDoc(), base); // There's no clear refererer policy spec about non-CSS SVG resource references // Bug 1415044 to investigate which referrer we should use RefPtr<URLAndReferrerInfo> target = new URLAndReferrerInfo(targetURI, mContent->OwnerDoc()->GetDocumentURI(), mContent->OwnerDoc()->GetReferrerPolicy()); - property = SVGObserverUtils::GetPaintingProperty(target, this, - SVGObserverUtils::HrefAsPaintingProperty()); - if (!property) + observer = SVGObserverUtils::GetTemplateElementObserver(target, this, + SVGObserverUtils::HrefToTemplateProperty()); + if (!observer) { return nullptr; + } } - nsIFrame *result = property->GetReferencedFrame(); + nsIFrame* result = observer->GetReferencedFrame(); if (!result) return nullptr; LayoutFrameType frameType = result->Type(); if (frameType != LayoutFrameType::SVGFilter) return nullptr; return static_cast<nsSVGFilterFrame*>(result); @@ -178,17 +179,17 @@ nsSVGFilterFrame::AttributeChanged(int32 aAttribute == nsGkAtoms::height || aAttribute == nsGkAtoms::filterUnits || aAttribute == nsGkAtoms::primitiveUnits)) { SVGObserverUtils::InvalidateDirectRenderingObservers(this); } else if ((aNameSpaceID == kNameSpaceID_XLink || aNameSpaceID == kNameSpaceID_None) && aAttribute == nsGkAtoms::href) { // Blow away our reference, if any - DeleteProperty(SVGObserverUtils::HrefAsPaintingProperty()); + DeleteProperty(SVGObserverUtils::HrefToTemplateProperty()); mNoHRefURI = false; // And update whoever references us SVGObserverUtils::InvalidateDirectRenderingObservers(this); } return nsSVGContainerFrame::AttributeChanged(aNameSpaceID, aAttribute, aModType); }
--- a/layout/svg/nsSVGGradientFrame.cpp +++ b/layout/svg/nsSVGGradientFrame.cpp @@ -51,17 +51,17 @@ nsSVGGradientFrame::AttributeChanged(int (aAttribute == nsGkAtoms::gradientUnits || aAttribute == nsGkAtoms::gradientTransform || aAttribute == nsGkAtoms::spreadMethod)) { SVGObserverUtils::InvalidateDirectRenderingObservers(this); } else if ((aNameSpaceID == kNameSpaceID_XLink || aNameSpaceID == kNameSpaceID_None) && aAttribute == nsGkAtoms::href) { // Blow away our reference, if any - DeleteProperty(SVGObserverUtils::HrefAsPaintingProperty()); + DeleteProperty(SVGObserverUtils::HrefToTemplateProperty()); mNoHRefURI = false; // And update whoever references us SVGObserverUtils::InvalidateDirectRenderingObservers(this); } return nsSVGPaintServerFrame::AttributeChanged(aNameSpaceID, aAttribute, aModType); } @@ -337,20 +337,20 @@ nsSVGGradientFrame::GetPaintServerPatter // Private (helper) methods nsSVGGradientFrame * nsSVGGradientFrame::GetReferencedGradient() { if (mNoHRefURI) return nullptr; - nsSVGPaintingProperty *property = - GetProperty(SVGObserverUtils::HrefAsPaintingProperty()); + SVGTemplateElementObserver* observer = + GetProperty(SVGObserverUtils::HrefToTemplateProperty()); - if (!property) { + if (!observer) { // Fetch our gradient element's href or xlink:href attribute dom::SVGGradientElement* grad = static_cast<dom::SVGGradientElement*>(GetContent()); nsAutoString href; if (grad->mStringAttributes[dom::SVGGradientElement::HREF] .IsExplicitlySet()) { grad->mStringAttributes[dom::SVGGradientElement::HREF] .GetAnimValue(href, grad); @@ -372,23 +372,24 @@ nsSVGGradientFrame::GetReferencedGradien // There's no clear refererer policy spec about non-CSS SVG resource references // Bug 1415044 to investigate which referrer we should use RefPtr<URLAndReferrerInfo> target = new URLAndReferrerInfo(targetURI, mContent->OwnerDoc()->GetDocumentURI(), mContent->OwnerDoc()->GetReferrerPolicy()); - property = SVGObserverUtils::GetPaintingProperty(target, this, - SVGObserverUtils::HrefAsPaintingProperty()); - if (!property) + observer = SVGObserverUtils::GetTemplateElementObserver(target, this, + SVGObserverUtils::HrefToTemplateProperty()); + if (!observer) { return nullptr; + } } - nsIFrame *result = property->GetReferencedFrame(); + nsIFrame* result = observer->GetReferencedFrame(); if (!result) return nullptr; LayoutFrameType frameType = result->Type(); if (frameType != LayoutFrameType::SVGLinearGradient && frameType != LayoutFrameType::SVGRadialGradient) return nullptr;
--- a/layout/svg/nsSVGPatternFrame.cpp +++ b/layout/svg/nsSVGPatternFrame.cpp @@ -65,17 +65,17 @@ nsSVGPatternFrame::AttributeChanged(int3 aAttribute == nsGkAtoms::viewBox)) { SVGObserverUtils::InvalidateDirectRenderingObservers(this); } if ((aNameSpaceID == kNameSpaceID_XLink || aNameSpaceID == kNameSpaceID_None) && aAttribute == nsGkAtoms::href) { // Blow away our reference, if any - DeleteProperty(SVGObserverUtils::HrefAsPaintingProperty()); + DeleteProperty(SVGObserverUtils::HrefToTemplateProperty()); mNoHRefURI = false; // And update whoever references us SVGObserverUtils::InvalidateDirectRenderingObservers(this); } return nsSVGPaintServerFrame::AttributeChanged(aNameSpaceID, aAttribute, aModType); } @@ -573,20 +573,20 @@ nsSVGPatternFrame::GetLengthValue(uint32 // Private (helper) methods nsSVGPatternFrame * nsSVGPatternFrame::GetReferencedPattern() { if (mNoHRefURI) return nullptr; - nsSVGPaintingProperty *property = - GetProperty(SVGObserverUtils::HrefAsPaintingProperty()); + SVGTemplateElementObserver* observer = + GetProperty(SVGObserverUtils::HrefToTemplateProperty()); - if (!property) { + if (!observer) { // Fetch our pattern element's href or xlink:href attribute SVGPatternElement *pattern = static_cast<SVGPatternElement *>(GetContent()); nsAutoString href; if (pattern->mStringAttributes[SVGPatternElement::HREF].IsExplicitlySet()) { pattern->mStringAttributes[SVGPatternElement::HREF] .GetAnimValue(href, pattern); } else { pattern->mStringAttributes[SVGPatternElement::XLINK_HREF] @@ -606,23 +606,24 @@ nsSVGPatternFrame::GetReferencedPattern( // There's no clear refererer policy spec about non-CSS SVG resource references // Bug 1415044 to investigate which referrer we should use RefPtr<URLAndReferrerInfo> target = new URLAndReferrerInfo(targetURI, mContent->OwnerDoc()->GetDocumentURI(), mContent->OwnerDoc()->GetReferrerPolicy()); - property = SVGObserverUtils::GetPaintingProperty(target, this, - SVGObserverUtils::HrefAsPaintingProperty()); - if (!property) + observer = SVGObserverUtils::GetTemplateElementObserver(target, this, + SVGObserverUtils::HrefToTemplateProperty()); + if (!observer) { return nullptr; + } } - nsIFrame *result = property->GetReferencedFrame(); + nsIFrame* result = observer->GetReferencedFrame(); if (!result) return nullptr; LayoutFrameType frameType = result->Type(); if (frameType != LayoutFrameType::SVGPattern) return nullptr; return static_cast<nsSVGPatternFrame*>(result);
--- a/layout/svg/nsSVGUtils.cpp +++ b/layout/svg/nsSVGUtils.cpp @@ -1495,18 +1495,17 @@ nsSVGUtils::MakeFillPatternFor(nsIFrame* // Combine the group opacity into the fill opacity (we will have skipped // creating an offscreen surface to apply the group opacity). fillOpacity *= opacity; } const DrawTarget* dt = aContext->GetDrawTarget(); nsSVGPaintServerFrame *ps = - SVGObserverUtils::GetPaintServer(aFrame, &nsStyleSVG::mFill, - SVGObserverUtils::FillProperty()); + SVGObserverUtils::GetPaintServer(aFrame, &nsStyleSVG::mFill); if (ps) { RefPtr<gfxPattern> pattern = ps->GetPaintServerPattern(aFrame, dt, aContext->CurrentMatrixDouble(), &nsStyleSVG::mFill, fillOpacity, aImgParams); if (pattern) { pattern->CacheColorStops(dt); aOutPattern->Init(*pattern->GetPattern(dt)); @@ -1571,18 +1570,17 @@ nsSVGUtils::MakeStrokePatternFor(nsIFram // Combine the group opacity into the stroke opacity (we will have skipped // creating an offscreen surface to apply the group opacity). strokeOpacity *= opacity; } const DrawTarget* dt = aContext->GetDrawTarget(); nsSVGPaintServerFrame *ps = - SVGObserverUtils::GetPaintServer(aFrame, &nsStyleSVG::mStroke, - SVGObserverUtils::StrokeProperty()); + SVGObserverUtils::GetPaintServer(aFrame, &nsStyleSVG::mStroke); if (ps) { RefPtr<gfxPattern> pattern = ps->GetPaintServerPattern(aFrame, dt, aContext->CurrentMatrixDouble(), &nsStyleSVG::mStroke, strokeOpacity, aImgParams); if (pattern) { pattern->CacheColorStops(dt); aOutPattern->Init(*pattern->GetPattern(dt));
--- a/layout/tools/reftest/api.js +++ b/layout/tools/reftest/api.js @@ -61,16 +61,21 @@ this.reftest = class extends ExtensionAP // Starting tests is handled quite differently on android and desktop. // On Android, OnRefTestLoad() takes over the main browser window so // we just need to call it as soon as the browser window is available. // On desktop, a separate window (dummy) is created and explicitly given // focus (see bug 859339 for details), then tests are launched in a new // top-level window. let win = Services.wm.getMostRecentWindow("navigator:browser"); + if (!win) { + // There is no navigator:browser in the geckoview TestRunnerActivity; + // try navigator.geckoview instead. + win = Services.wm.getMostRecentWindow("navigator:geckoview"); + } if (Services.appinfo.OS == "Android") { ChromeUtils.import("resource://reftest/reftest.jsm"); if (win) { startAndroid(win); } else { Services.wm.addListener(WindowListener); }
--- a/python/mach/mach/registrar.py +++ b/python/mach/mach/registrar.py @@ -87,17 +87,17 @@ class MachRegistrar(object): import pdb result = pdb.runcall(fn, **kwargs) else: result = fn(**kwargs) result = result or 0 assert isinstance(result, (int, long)) - if context: + if context and not debug_command: postrun = getattr(context, 'post_dispatch_handler', None) if postrun: postrun(context, handler, args=kwargs) return result def dispatch(self, name, context=None, argv=None, subcommand=None, **kwargs): """Dispatch/run a command.
--- a/python/mozbuild/mozbuild/controller/building.py +++ b/python/mozbuild/mozbuild/controller/building.py @@ -36,32 +36,34 @@ from mozsystemmonitor.resourcemonitor im from mozterm.widgets import Footer import mozpack.path as mozpath from .clobber import ( Clobberer, ) from ..base import ( - BuildEnvironmentNotFoundException, MozbuildObject, ) from ..backend import ( get_backend_class, ) from ..testing import ( install_test_files, ) from ..compilation.warnings import ( WarningsCollector, WarningsDatabase, ) from ..shellutil import ( quote as shell_quote, ) +from ..telemetry import ( + gather_telemetry, +) from ..util import ( FileAvoidWrite, mkdir, resolve_target_to_make, ) FINDER_SLOW_MESSAGE = ''' @@ -1280,62 +1282,37 @@ class BuildDriver(MozbuildObject): except ValueError: # Just stick with the default pass if monitor.elapsed > notify_minimum_time: # Display a notification when the build completes. self.notify('Build complete' if not status else 'Build failed') + gather_telemetry(command='build', success=(status == 0), monitor=monitor, + mach_context=mach_context, substs=self.substs, + paths=[self.topsrcdir, self.topobjdir]) + if status: return status - long_build = monitor.elapsed > 600 - - if long_build: - output.on_line('We know it took a while, but your build finally finished successfully!') - else: - output.on_line('Your build was successful!') - if monitor.have_resource_usage: excessive, swap_in, swap_out = monitor.have_excessive_swapping() # if excessive: # print(EXCESSIVE_SWAP_MESSAGE) print('To view resource usage of the build, run |mach ' - 'resource-usage|.') + 'resource-usage|.') - telemetry_handler = getattr(mach_context, - 'telemetry_handler', None) - telemetry_data = monitor.get_resource_usage() + long_build = monitor.elapsed > 600 - # Record build configuration data. For now, we cherry pick - # items we need rather than grabbing everything, in order - # to avoid accidentally disclosing PII. - telemetry_data['substs'] = {} - try: - for key in ['MOZ_ARTIFACT_BUILDS', 'MOZ_USING_CCACHE', 'MOZ_USING_SCCACHE']: - value = self.substs.get(key, False) - telemetry_data['substs'][key] = value - except BuildEnvironmentNotFoundException: - pass - - # Grab ccache stats if available. We need to be careful not - # to capture information that can potentially identify the - # user (such as the cache location) - if ccache_diff: - telemetry_data['ccache'] = {} - for key in [key[0] for key in ccache_diff.STATS_KEYS]: - try: - telemetry_data['ccache'][key] = ccache_diff._values[key] - except KeyError: - pass - - if telemetry_handler: - telemetry_handler(mach_context, telemetry_data) + if long_build: + output.on_line('We know it took a while, but your build finally finished successfully!') + else: + output.on_line('Your build was successful!') # Only for full builds because incremental builders likely don't # need to be burdened with this. if not what: try: # Fennec doesn't have useful output from just building. We should # arguably make the build action useful for Fennec. Another day... if self.substs['MOZ_BUILD_APP'] != 'mobile/android':
--- a/python/mozbuild/mozbuild/mach_commands.py +++ b/python/mozbuild/mozbuild/mach_commands.py @@ -2837,8 +2837,17 @@ class Analyze(MachCommandBase): # path to cost_dict.gz was specified if os.path.isfile(path): r = Report(days, path) r.generate_output(format, limit, self.topobjdir) else: res = 'Please specify the location of cost_dict.gz with --path.' print ('Could not find cost_dict.gz at %s' % path, res, sep='\n') return 1 + + +@SettingsProvider +class TelemetrySettings(): + config_settings = [ + ('build.telemetry', 'boolean', """ +Enable submission of build system telemetry. + """.strip(), False), + ]
--- a/python/mozbuild/mozbuild/telemetry.py +++ b/python/mozbuild/mozbuild/telemetry.py @@ -1,27 +1,41 @@ # 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/. from __future__ import absolute_import, print_function, unicode_literals ''' -This file contains a voluptuous schema definition for build system telemetry. +This file contains a voluptuous schema definition for build system telemetry, and functions +to fill an instance of that schema for a single mach invocation. ''' -from mozbuild.configure.constants import CompilerType +from datetime import datetime +import json +import os +import math +import platform +import pprint +import sys from voluptuous import ( Any, Optional, + MultipleInvalid, Required, Schema, ) from voluptuous.validators import Datetime +import mozpack.path as mozpath +from .base import ( + BuildEnvironmentNotFoundException, +) +from .configure.constants import CompilerType + schema = Schema({ Required('client_id', description='A UUID to uniquely identify a client'): basestring, Required('time', description='Time at which this event happened'): Datetime(), Required('command', description='The mach command that was invoked'): basestring, Required('argv', description=( 'Full mach commandline. ' + 'If the commandline contains absolute paths they will be sanitized.')): [basestring], Required('success', description='true if the command succeeded'): bool, @@ -55,8 +69,206 @@ schema = Schema({ Optional('physical_cores', description='Number of physical CPU cores present'): int, Optional('memory_gb', description='System memory in GB'): int, Optional('drive_is_ssd', description='true if the source directory is on a solid-state disk'): bool, Optional('virtual_machine', description='true if the OS appears to be running in a virtual machine'): bool, }, }) + + +def get_client_id(state_dir): + ''' + Get a client id, which is a UUID, from a file in the state directory. If the file doesn't + exist, generate a UUID and save it to a file. + ''' + path = os.path.join(state_dir, 'telemetry_client_id.json') + if os.path.exists(path): + with open(path, 'rb') as f: + return json.load(f)['client_id'] + import uuid + # uuid4 is random, other uuid types may include identifiers from the local system. + client_id = str(uuid.uuid4()) + with open(path, 'wb') as f: + json.dump({'client_id': client_id}, f) + return client_id + + +def cpu_brand_linux(): + ''' + Read the CPU brand string out of /proc/cpuinfo on Linux. + ''' + with open('/proc/cpuinfo', 'rb') as f: + for line in f: + if line.startswith('model name'): + _, brand = line.split(': ', 1) + return brand.rstrip().decode('ascii') + # not found? + return None + + +def cpu_brand_windows(): + ''' + Read the CPU brand string from the registry on Windows. + ''' + try: + import _winreg + except ImportError: + import winreg as _winreg + + try: + h = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, + r'HARDWARE\DESCRIPTION\System\CentralProcessor\0') + (brand, ty) = _winreg.QueryValueEx(h, 'ProcessorNameString') + if ty == _winreg.REG_SZ: + return brand + except WindowsError: + pass + return None + + +def cpu_brand_mac(): + ''' + Get the CPU brand string via sysctl on macos. + ''' + import ctypes + import ctypes.util + + libc = ctypes.cdll.LoadLibrary(ctypes.util.find_library("c")) + # First, find the required buffer size. + bufsize = ctypes.c_size_t(0) + result = libc.sysctlbyname(b'machdep.cpu.brand_string', None, ctypes.byref(bufsize), + None, 0) + if result != 0: + return None + bufsize.value += 1 + buf = ctypes.create_string_buffer(bufsize.value) + # Now actually get the value. + result = libc.sysctlbyname(b'machdep.cpu.brand_string', buf, ctypes.byref(bufsize), None, 0) + if result != 0: + return None + + return buf.value.decode() + + +def get_cpu_brand(): + ''' + Get the CPU brand string as returned by CPUID. + ''' + return { + 'Linux': cpu_brand_linux, + 'Windows': cpu_brand_windows, + 'Darwin': cpu_brand_mac, + }.get(platform.system(), lambda: None)() + + +def get_system_info(): + ''' + Gather info to fill the `system` keys in the schema. + ''' + # Normalize OS names a bit, and bucket non-tier-1 platforms into "other". + info = { + 'os': { + 'Linux': 'linux', + 'Windows': 'windows', + 'Darwin': 'macos', + }.get(platform.system(), 'other') + } + try: + import psutil + + info['logical_cores'] = psutil.cpu_count() + info['physical_cores'] = psutil.cpu_count(logical=False) + # `total` on Linux is gathered from /proc/meminfo's `MemTotal`, which is the total + # amount of physical memory minus some kernel usage, so round up to the nearest GB + # to get a sensible answer. + info['memory_gb'] = int( + math.ceil(float(psutil.virtual_memory().total) / (1024 * 1024 * 1024))) + except ImportError: + # TODO: sort out psutil availability on Windows, or write a fallback impl for Windows. + # https://bugzilla.mozilla.org/show_bug.cgi?id=1481612 + pass + cpu_brand = get_cpu_brand() + if cpu_brand is not None: + info['cpu_brand'] = cpu_brand + # TODO: drive_is_ssd, virtual_machine: https://bugzilla.mozilla.org/show_bug.cgi?id=1481613 + return info + + +def get_build_opts(substs): + ''' + Translate selected items from `substs` into `build_opts` keys in the schema. + ''' + try: + return { + k: ty(substs.get(s, None)) for (k, s, ty) in ( + # Selected substitutions. + ('compiler', 'CC_TYPE', str), + ('artifact', 'MOZ_ARTIFACT_BUILDS', bool), + ('debug', 'MOZ_DEBUG', bool), + ('opt', 'MOZ_OPTIMIZE', bool), + ('ccache', 'CCACHE', bool), + ('sccache', 'MOZ_USING_SCCACHE', bool), + # TODO: detect icecream: https://bugzilla.mozilla.org/show_bug.cgi?id=1481614 + ) + } + except BuildEnvironmentNotFoundException: + return {} + + +def filter_args(command, argv, paths): + ''' + Given the full list of command-line arguments, remove anything up to and including `command`, + and attempt to filter absolute pathnames out of any arguments after that. + ''' + args = list(argv) + while args: + a = args.pop(0) + if a == command: + break + + def filter_path(p): + p = mozpath.abspath(p) + base = mozpath.basedir(p, paths) + if base: + return mozpath.relpath(p, base) + # Best-effort. + return '<path omitted>' + return [filter_path(arg) for arg in args] + + +def gather_telemetry(command='', success=False, monitor=None, mach_context=None, substs={}, + paths=[]): + ''' + Gather telemetry about the build and the user's system and pass it to the telemetry + handler to be stored for later submission. + + Any absolute paths on the command line will be made relative to `paths` or replaced + with a placeholder to avoid including paths from developer's machines. + ''' + data = { + 'client_id': get_client_id(mach_context.state_dir), + # Simplest way to get an rfc3339 datetime string, AFAICT. + 'time': datetime.utcfromtimestamp(monitor.start_time).isoformat(b'T') + 'Z', + 'command': command, + 'argv': filter_args(command, sys.argv, paths), + 'success': success, + # TODO: use a monotonic clock: https://bugzilla.mozilla.org/show_bug.cgi?id=1481624 + 'duration_ms': int(monitor.elapsed * 1000), + 'build_opts': get_build_opts(substs), + 'system': get_system_info(), + # TODO: exception: https://bugzilla.mozilla.org/show_bug.cgi?id=1481617 + # TODO: file_types_changed: https://bugzilla.mozilla.org/show_bug.cgi?id=1481774 + } + try: + # Validate against the schema. + schema(data) + except MultipleInvalid as exc: + msg = ['Build telemetry is invalid:'] + for error in exc.errors: + msg.append(str(error)) + print('\n'.join(msg) + '\n' + pprint.pformat(data)) + + telemetry_handler = getattr(mach_context, + 'telemetry_handler', None) + if telemetry_handler: + telemetry_handler(mach_context, data)
--- a/taskcluster/scripts/builder/hazard-analysis.sh +++ b/taskcluster/scripts/builder/hazard-analysis.sh @@ -9,16 +9,17 @@ JS_SRCDIR=$GECKO_DIR/js/src ANALYSIS_SRCDIR=$JS_SRCDIR/devtools/rootAnalysis export CC="$TOOLTOOL_DIR/gcc/bin/gcc" export CXX="$TOOLTOOL_DIR/gcc/bin/g++" export PATH="$TOOLTOOL_DIR/gcc/bin:$PATH" export LD_LIBRARY_PATH="$TOOLTOOL_DIR/gcc/lib64" export RUSTC="$TOOLTOOL_DIR/rustc/bin/rustc" export CARGO="$TOOLTOOL_DIR/rustc/bin/cargo" +export LLVM_CONFIG="$TOOLTOOL_DIR/clang/bin/llvm-config" PYTHON=python2.7 if ! which $PYTHON; then PYTHON=python fi function check_commit_msg () {
deleted file mode 100644 --- a/testing/geckodriver/.gitignore +++ /dev/null @@ -1,1 +0,0 @@ -/target
--- a/testing/geckodriver/build.rs +++ b/testing/geckodriver/build.rs @@ -106,16 +106,20 @@ impl Git { self.exec(&["cinnabar", "git2hg", &git_sha]) } } impl BuildInfo for Git { fn hash(&self) -> Option<String> { self.exec(&["rev-parse", "HEAD"]) .and_then(|sha| self.to_hg_sha(sha)) + .map(|mut s| { + s.truncate(12); + s + }) } fn date(&self) -> Option<String> { self.exec(&["log", "-1", "--date=short", "--pretty=format:%cd"]) } } struct Noop;
--- a/testing/geckodriver/src/main.rs +++ b/testing/geckodriver/src/main.rs @@ -175,17 +175,17 @@ fn run() -> ProgramResult { } else { match matches.occurrences_of("verbosity") { 0 => Some(logging::Level::Info), 1 => Some(logging::Level::Debug), _ => Some(logging::Level::Trace), } }; if let Some(ref level) = log_level { - logging::init_with_level(level.clone()).unwrap(); + logging::init_with_level(*level).unwrap(); } else { logging::init().unwrap(); } let settings = MarionetteSettings { port: marionette_port, binary, connect_existing: matches.is_present("connect_existing"),
--- a/testing/mozharness/mozharness/mozilla/testing/android.py +++ b/testing/mozharness/mozharness/mozilla/testing/android.py @@ -1,35 +1,32 @@ #!/usr/bin/env python # ***** BEGIN LICENSE BLOCK ***** # 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/. # ***** END LICENSE BLOCK ***** -import datetime import glob import os import subprocess import tempfile -import time from mozharness.mozilla.automation import TBPL_RETRY, EXIT_STATUS_DICT class AndroidMixin(object): """ Mixin class used by Android test scripts. """ def __init__(self, **kwargs): self.logcat_proc = None self.logcat_file = None self._adb_path = None - self.sdk_level = None self.device_name = os.environ.get('DEVICE_NAME', None) self.device_serial = os.environ.get('DEVICE_SERIAL', None) self.device_ip = os.environ.get('DEVICE_IP', None) super(AndroidMixin, self).__init__(**kwargs) @property def adb_path(self): '''Get the path to the adb executable. @@ -45,95 +42,16 @@ class AndroidMixin(object): # Ignore attribute errors since BaseScript will # attempt to access properties before the other Mixins # have completed initialization. We recover afterwards # when additional attemps occur after initialization # is completed. pass return self._adb_path - def _retry(self, max_attempts, interval, func, description, max_time=0): - ''' - Execute func until it returns True, up to max_attempts times, waiting for - interval seconds between each attempt. description is logged on each attempt. - If max_time is specified, no further attempts will be made once max_time - seconds have elapsed; this provides some protection for the case where - the run-time for func is long or highly variable. - ''' - status = False - attempts = 0 - if max_time > 0: - end_time = datetime.datetime.now() + datetime.timedelta(seconds=max_time) - else: - end_time = None - while attempts < max_attempts and not status: - if (end_time is not None) and (datetime.datetime.now() > end_time): - self.info("Maximum retry run-time of %d seconds exceeded; " - "remaining attempts abandoned" % max_time) - break - if attempts != 0: - self.info("Sleeping %d seconds" % interval) - time.sleep(interval) - attempts += 1 - self.info(">> %s: Attempt #%d of %d" % (description, attempts, max_attempts)) - status = func() - return status - - def _run_proc(self, cmd, quiet=False): - self.info('Running %s' % subprocess.list2cmdline(cmd)) - p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=0) - out, err = p.communicate() - if out and not quiet: - self.info('%s' % str(out.strip())) - if err and not quiet: - self.info('stderr: %s' % str(err.strip())) - return out, err - - def _run_with_timeout(self, timeout, cmd, quiet=False): - timeout_cmd = ['timeout', '%s' % timeout] + cmd - return self._run_proc(timeout_cmd, quiet=quiet) - - def _run_adb_with_timeout(self, timeout, cmd, quiet=False): - cmd = [self.adb_path, '-s', self.device_serial] + cmd - return self._run_with_timeout(timeout, cmd, quiet) - - def _verify_adb(self): - self.info('Verifying adb connectivity') - self._run_with_timeout(180, [self.adb_path, - '-s', - self.device_serial, - 'wait-for-device']) - return True - - def _verify_adb_device(self): - out, _ = self._run_with_timeout(30, [self.adb_path, 'devices']) - if (self.device_serial in out) and ("device" in out): - return True - return False - - def _is_boot_completed(self): - boot_cmd = ['shell', 'getprop', 'sys.boot_completed'] - out, _ = self._run_adb_with_timeout(30, boot_cmd) - if out.strip() == '1': - return True - return False - - def _install_apk(self): - install_ok = False - if int(self.sdk_level) >= 23: - cmd = ['install', '-r', '-g', self.installer_path] - else: - cmd = ['install', '-r', self.installer_path] - self.warning("Installing apk with default run-time permissions (sdk %s)" % - str(self.sdk_level)) - out, err = self._run_adb_with_timeout(300, cmd, True) - if 'Success' in out or 'Success' in err: - install_ok = True - return install_ok - def _get_repo_url(self, path): """ Return a url for a file (typically a tooltool manifest) in this hg repo and using this revision (or mozilla-central/default if repo/rev cannot be determined). :param path specifies the directory path to the file of interest. """ @@ -196,26 +114,24 @@ class AndroidMixin(object): self.info("Killing logcat pid %d." % self.logcat_proc.pid) self.logcat_proc.kill() self.logcat_file.close() def install_apk(self, apk): """ Install the specified apk. """ - cmd = [self.adb_path, '-s', self.device_serial, 'shell', - 'getprop', 'ro.build.version.sdk'] - self.sdk_level, _ = self._run_with_timeout(30, cmd) - - install_ok = self._retry(3, 30, self._install_apk, "Install app APK") - if not install_ok: + import mozdevice + try: + device = mozdevice.ADBAndroid(adb=self.adb_path, device=self.device_serial) + device.install_app(apk) + except mozdevice.ADBError: self.fatal('INFRA-ERROR: Failed to install %s on %s' % (self.installer_path, self.device_name), EXIT_STATUS_DICT[TBPL_RETRY]) - return install_ok def screenshot(self, prefix): """ Save a screenshot of the entire screen to the blob upload directory. """ dirs = self.query_abs_dirs() utility = os.path.join(self.xre_path, "screentopng") if not os.path.exists(utility):
--- a/testing/mozharness/mozharness/mozilla/testing/raptor.py +++ b/testing/mozharness/mozharness/mozilla/testing/raptor.py @@ -361,17 +361,17 @@ class Raptor(TestingMixin, MercurialScri # listed in raptor requirements.txt file. self.install_module( requirements=[os.path.join(self.raptor_path, 'requirements.txt')] ) def install(self): if self.app == "geckoview": - self.install_apk(os.path.basename(self.installer_url)) + self.install_apk(self.installer_path) else: super(Raptor, self).install() def _validate_treeherder_data(self, parser): # late import is required, because install is done in create_virtualenv import jsonschema if len(parser.found_perf_data) != 1:
--- a/testing/web-platform/meta/MANIFEST.json +++ b/testing/web-platform/meta/MANIFEST.json @@ -313741,16 +313741,21 @@ {} ] ], "wasm/jsapi/bad-imports.js": [ [ {} ] ], + "wasm/jsapi/instanceTestFactory.js": [ + [ + {} + ] + ], "wasm/jsapi/table/assertions.js": [ [ {} ] ], "wasm/jsapi/wasm-constants.js": [ [ {} @@ -401345,29 +401350,29 @@ "jsshell": true } ], [ "/wasm/jsapi/global/toString.any.worker.html", {} ] ], - "wasm/jsapi/global/value-set.any.js": [ - [ - "/wasm/jsapi/global/value-set.any.html", - {} - ], - [ - "/wasm/jsapi/global/value-set.any.js", + "wasm/jsapi/global/value-get-set.any.js": [ + [ + "/wasm/jsapi/global/value-get-set.any.html", + {} + ], + [ + "/wasm/jsapi/global/value-get-set.any.js", { "jsshell": true } ], [ - "/wasm/jsapi/global/value-set.any.worker.html", + "/wasm/jsapi/global/value-get-set.any.worker.html", {} ] ], "wasm/jsapi/global/valueOf.any.js": [ [ "/wasm/jsapi/global/valueOf.any.html", {} ], @@ -579661,25 +579666,25 @@ "bfa3211ae26bfaa992b541d3b0c92f3df0503499", "reftest" ], "css/filter-effects/svg-feoffset-001.html": [ "3d8118b387d938b588e8e88ad5ec87a5343e4f72", "reftest" ], "css/filter-effects/svg-unknown-input-001.html": [ - "7789f2a9af4f1492fa6db36b53a72ada151f61d5", + "4ed1335caab262c39193ff752b4023718f1acca2", "reftest" ], "css/filter-effects/svg-unknown-input-002.html": [ - "f45d3e344ad193c59826543239c33fffc61d6527", + "915a3df0245ce56db9929236a6ee70b19d413250", "reftest" ], "css/filter-effects/svg-unknown-input-ref.html": [ - "1fff2a6175cfe1956ff2c451aece45ec73345d81", + "fd8af11300031fb9051df2ef288c96e3f1dcb6cd", "support" ], "css/geometry/DOMMatrix-001.html": [ "a8a357bff606925aaa95dce6c4642b81bd8c88ea", "testharness" ], "css/geometry/DOMMatrix-002.html": [ "d5f1137a413ce747f40792b06504255d151bd97b", @@ -646389,17 +646394,17 @@ "2490f05b3e80aa67a0c70a9cb12be282fa0e15b2", "testharness" ], "shadow-dom/input-element-list.html": [ "b571534eb0d6f3f57cfbec3e706648b19848b6d6", "testharness" ], "shadow-dom/input-type-radio.html": [ - "bd5d8e43b0fd9d0c9f1e078ed97a1bbd18b7b0be", + "9c90fcf0603222785aa81990fb2b09511ff6ba86", "testharness" ], "shadow-dom/layout-slot-no-longer-assigned.html": [ "dfcac99da023ec2bbd94835f71efaef952a62341", "reftest" ], "shadow-dom/layout-slot-no-longer-fallback.html": [ "7507f11ac18e6590367a147acbc78834b0d19afd", @@ -656985,17 +656990,17 @@ "bd6553fadcb16db177e522a0e60c82e8c55bca03", "support" ], "tools/wptrunner/wptrunner/executors/executorinternetexplorer.py": [ "898ff144593877c3be33a33be567816e869dcf3e", "support" ], "tools/wptrunner/wptrunner/executors/executormarionette.py": [ - "ad71a8fa31c7cf4626c11214a520a2121db897c4", + "9ec8f6e5832619905118db632e32dc50fe74c131", "support" ], "tools/wptrunner/wptrunner/executors/executoropera.py": [ "55f1f0d59590807452a9ffc201ad8d0f8f972fcd", "support" ], "tools/wptrunner/wptrunner/executors/executorsafari.py": [ "ed01f4d8341b5497473b6f535ac4a2c04158cd9e", @@ -657021,17 +657026,17 @@ "c728ae18e03b09f6c690be82efc78bd0c2ff7347", "support" ], "tools/wptrunner/wptrunner/executors/process.py": [ "fb8c17a96ba04ce601ad3cb9ad4c7588f947e949", "support" ], "tools/wptrunner/wptrunner/executors/protocol.py": [ - "71fc3c9a8f651913e53266f181ef2161ac91c97e", + "f8292ff5ec118b8f3d80da96bcd07586bedba45a", "support" ], "tools/wptrunner/wptrunner/executors/pytestrunner/__init__.py": [ "1baaf9573aa804df8b9a853fef7382715fc4bf59", "support" ], "tools/wptrunner/wptrunner/executors/pytestrunner/runner.py": [ "9555f5f51dcc84a19186ff0c8bde7e87e0153891", @@ -657121,17 +657126,17 @@ "62ddaffb443c94505383083923dc13fcb1cf5660", "support" ], "tools/wptrunner/wptrunner/testloader.py": [ "2313a80c745bfac9946119926411234c506c6654", "support" ], "tools/wptrunner/wptrunner/testrunner.py": [ - "90f7e4615e078840f9804f791422f9f2f3464a72", + "7e386b881d4c83a93d2543b7e5b9afd01623a5bc", "support" ], "tools/wptrunner/wptrunner/tests/__init__.py": [ "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", "support" ], "tools/wptrunner/wptrunner/tests/base.py": [ "84dc4f2e7f82ee2e3a2aa6f4d8bdda76b1581da1", @@ -657205,17 +657210,17 @@ "1de951938cf57692edca2e019bdfdc6260b8fe62", "support" ], "tools/wptrunner/wptrunner/webdriver_server.py": [ "4ec415ce78bb89a82d5f098b1c4e8560e7ec39e4", "support" ], "tools/wptrunner/wptrunner/wptcommandline.py": [ - "0075ad9096201a04c5342ad92aab59ab8dcf434e", + "d25e561ad195ef3de91a42871820ad372269f016", "support" ], "tools/wptrunner/wptrunner/wptlogging.py": [ "ac311816c18b7f898e4421410f97d9357d2edd2d", "support" ], "tools/wptrunner/wptrunner/wptmanifest/__init__.py": [ "8985b5ae35067a24fbc87fdd2e61d72794123892", @@ -659773,121 +659778,125 @@ "bda3ae7bc3c8dc5020a50c645b8dba2aaeb44591", "support" ], "wasm/jsapi/bad-imports.js": [ "f076baacca8b3e6addf49f6841874d11bfcfe5a2", "support" ], "wasm/jsapi/constructor/compile.any.js": [ - "0139a18fda3f928dc0eed0bef86098dcbabf5979", + "bd23a8666e76f30d212524bc30ffd00c0a546e70", "testharness" ], "wasm/jsapi/constructor/instantiate-bad-imports.any.js": [ "86700298dfae66de6f4d026baa29e6e3584320f7", "testharness" ], "wasm/jsapi/constructor/instantiate.any.js": [ - "e90f21e28ebf478c7af7d40c8744fba9e5f48720", + "5da6bd58dfc3463bdead679143566cfaeb8bf281", "testharness" ], "wasm/jsapi/constructor/validate.any.js": [ - "70bd9f7022ad616c2d5e0be636f6935923e19173", + "c8613cbd9b3a467a919d87d3244c4f508dce6317", "testharness" ], "wasm/jsapi/global/constructor.any.js": [ - "7a45cc4191c55684cde187fc73fb9741d6f5c2c5", + "237f99c8b298183a557c10778c70e1d359b9d6b6", "testharness" ], "wasm/jsapi/global/toString.any.js": [ "ca025576c2b49604f053c83002f3a9cc8ef41a7b", "testharness" ], - "wasm/jsapi/global/value-set.any.js": [ - "b4e6770f10ed9e3ad55b9ae18ee96deda3ff171e", + "wasm/jsapi/global/value-get-set.any.js": [ + "6de62d5f58362bab593ae7eb453fa14c1424cf2c", "testharness" ], "wasm/jsapi/global/valueOf.any.js": [ - "176c5a784698399351eedeaac0ec305aa8ab7b81", + "d4a84b254f76ea50284619967ab6dc98c99bfea2", "testharness" ], "wasm/jsapi/instance/constructor-bad-imports.any.js": [ "24c51c10dc5df9d52c06bfb0715e435b17f24f7a", "testharness" ], "wasm/jsapi/instance/constructor.any.js": [ - "f9bd06ac8e95e0f4dc2ce96560529fad9bf2095b", + "e6a0450202e94baa82eb4797fed6a7c248ed00a7", "testharness" ], "wasm/jsapi/instance/exports.any.js": [ - "31423918720543da2ba25e392267bf541b756242", + "cad468660e099b33f0a03b83a09df0498d67a7e0", "testharness" ], "wasm/jsapi/instance/toString.any.js": [ "08dcb14a50d04f6db196626ddb93f2b50da8f055", "testharness" ], + "wasm/jsapi/instanceTestFactory.js": [ + "24f849e6f943d9008343909a00b2f2b0d1ea0c3d", + "support" + ], "wasm/jsapi/interface.any.js": [ - "5d76ac56ec5fafde8dde3924df863a2694bd6691", + "98c4a1d781b7d77709a7f1df5adb3c756648fbd3", "testharness" ], "wasm/jsapi/memory/buffer.any.js": [ - "b04460b6c5e56cf1fe990e3107aa9efcb4964ed5", + "4788ffcf84ff8d88adbafbe416dd7d5b80ec89d1", "testharness" ], "wasm/jsapi/memory/constructor.any.js": [ - "f9907ca6104d8ec76861e43b6b981042d86fb865", + "a584a23ecf0a582b21b913a780accee38e277927", "testharness" ], "wasm/jsapi/memory/grow.any.js": [ - "95300399f192b7eab70dd8f07c43f4db37eebe01", + "1ccfb946756fef71b89672dfc86830c620a9e981", "testharness" ], "wasm/jsapi/memory/toString.any.js": [ "4e15d75ea20f1ebfeba5dc7c8a9a52c253dd01bf", "testharness" ], "wasm/jsapi/module/constructor.any.js": [ - "32f183fac8738d30cc8a432768da315949320257", + "a467c1a17bb62ac52d323e1976cd067d92a9410d", "testharness" ], "wasm/jsapi/module/customSections.any.js": [ - "58ac63b61c93a015bfa9d5daab39f8d5b48548da", + "04c5abed52435714a18467c419dce17dfcf4073d", "testharness" ], "wasm/jsapi/module/exports.any.js": [ - "e63a885a4c34add0f6787d3642de83d9766568d1", + "9d95b652233b3d7687d4fe14371144519719e97b", "testharness" ], "wasm/jsapi/module/imports.any.js": [ - "640da591d21d8924d261fdc58b8e7cc762187a11", + "b3bb8598b080c376f4de1294780e6072eac2b354", "testharness" ], "wasm/jsapi/module/toString.any.js": [ "d9231a132ca8bf965f69c3cc81070a2ffe179efa", "testharness" ], "wasm/jsapi/table/assertions.js": [ - "dde2fd770904207a1f9f287fa48d82954a418f2e", + "c88972b4ebdcd760b2a441835c2c9eb31dabfea8", "support" ], "wasm/jsapi/table/constructor.any.js": [ - "e924bdb2ba42c67bcc6d4a949c2eeb50eac63e31", + "99eee19fecd49e432c7f6774c0968218e6d931a3", "testharness" ], "wasm/jsapi/table/get-set.any.js": [ - "2bb43a9308d732b5b6fa689c181ac411880c3733", + "f8a0194364fde1b25eeb998d1837349c3a8bafc2", "testharness" ], "wasm/jsapi/table/grow.any.js": [ - "d3efb511e4b1db1efa089322c0a3079705dfbdbd", + "4978e3ca23d0261aaccf4aad97dd348da22a54d0", "testharness" ], "wasm/jsapi/table/length.any.js": [ - "a6a9661dbaddc800cb99b7b8e2b804cb0c8e3c62", + "b1bfa6cfd1f44fbdbf18769b3f3e8129310c7e0e", "testharness" ], "wasm/jsapi/table/toString.any.js": [ "e576477910ad3198b446b4addf89ba9a571d020b", "testharness" ], "wasm/jsapi/wasm-constants.js": [ "f056f9cbfcfbac52d0506edddd01c8fad8636ebb",
--- a/testing/web-platform/meta/wasm/idlharness.any.js.ini +++ b/testing/web-platform/meta/wasm/idlharness.any.js.ini @@ -204,28 +204,16 @@ expected: FAIL [RuntimeError interface: existence and properties of interface prototype object's "constructor" property] expected: FAIL [RuntimeError interface: existence and properties of interface prototype object's @@unscopables property] expected: FAIL - [WebAssembly namespace: operation compile(BufferSource)] - expected: FAIL - - [WebAssembly namespace: operation instantiate(Module, object)] - expected: FAIL - - [WebAssembly namespace: operation instantiate(BufferSource, object)] - expected: FAIL - - [WebAssembly namespace: operation validate(BufferSource)] - expected: FAIL - [idlharness.any.worker.html] [Module interface: existence and properties of interface object] expected: FAIL [Module interface object length] expected: FAIL @@ -373,21 +361,8 @@ [Global interface: existence and properties of interface prototype object's @@unscopables property] expected: FAIL [Global interface: operation valueOf()] expected: FAIL [Global interface: attribute value] expected: FAIL - - [WebAssembly namespace: operation instantiate(BufferSource, object)] - expected: FAIL - - [WebAssembly namespace: operation validate(BufferSource)] - expected: FAIL - - [WebAssembly namespace: operation instantiate(Module, object)] - expected: FAIL - - [WebAssembly namespace: operation compile(BufferSource)] - expected: FAIL -
deleted file mode 100644 --- a/testing/web-platform/meta/wasm/jsapi/global/constructor.any.js.ini +++ /dev/null @@ -1,39 +0,0 @@ -[constructor.any.html] - [Order of evaluation] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490232 - expected: FAIL - - [Explicit value undefined for type f32] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490286 - expected: FAIL - - [Explicit value undefined for type f64] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490286 - expected: FAIL - -[constructor.any.worker.html] - [Order of evaluation] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490232 - expected: FAIL - - [Explicit value undefined for type f32] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490286 - expected: FAIL - - [Explicit value undefined for type f64] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490286 - expected: FAIL - -[constructor.any.js] - [Order of evaluation] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490232 - expected: FAIL - - [Explicit value undefined for type f32] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490286 - expected: FAIL - - [Explicit value undefined for type f64] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490286 - expected: FAIL -
deleted file mode 100644 --- a/testing/web-platform/meta/wasm/jsapi/global/value-set.any.js.ini +++ /dev/null @@ -1,15 +0,0 @@ -[value-set.any.html] - [Calling setter without argument] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490274 - expected: FAIL - -[value-set.any.worker.html] - [Calling setter without argument] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490274 - expected: FAIL - -[value-set.any.js] - [Calling setter without argument] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490274 - expected: FAIL -
deleted file mode 100644 --- a/testing/web-platform/meta/wasm/jsapi/interface.any.js.ini +++ /dev/null @@ -1,170 +0,0 @@ -[interface.any.html] - [WebAssembly.validate] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490229 - expected: FAIL - - [WebAssembly.compile] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490229 - expected: FAIL - - [WebAssembly.instantiate] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490229 - expected: FAIL - - [WebAssembly.Module.exports] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490229 - expected: FAIL - - [WebAssembly.Module.imports] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490229 - expected: FAIL - - [WebAssembly.Module.customSections] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490229 - expected: FAIL - - [WebAssembly.Instance.exports] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490229 - expected: FAIL - - [WebAssembly.Memory.grow] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490229 - expected: FAIL - - [WebAssembly.Memory.buffer] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490229 - expected: FAIL - - [WebAssembly.Table.grow] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490229 - expected: FAIL - - [WebAssembly.Table.get] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490229 - expected: FAIL - - [WebAssembly.Table.set] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490229 - expected: FAIL - - [WebAssembly.Table.length] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490229 - expected: FAIL - - [WebAssembly.Global.valueOf] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490229 - expected: FAIL - -[interface.any.worker.html] - [WebAssembly.validate] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490229 - expected: FAIL - - [WebAssembly.compile] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490229 - expected: FAIL - - [WebAssembly.instantiate] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490229 - expected: FAIL - - [WebAssembly.Module.exports] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490229 - expected: FAIL - - [WebAssembly.Module.imports] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490229 - expected: FAIL - - [WebAssembly.Module.customSections] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490229 - expected: FAIL - - [WebAssembly.Instance.exports] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490229 - expected: FAIL - - [WebAssembly.Memory.grow] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490229 - expected: FAIL - - [WebAssembly.Memory.buffer] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490229 - expected: FAIL - - [WebAssembly.Table.grow] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490229 - expected: FAIL - - [WebAssembly.Table.get] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490229 - expected: FAIL - - [WebAssembly.Table.set] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490229 - expected: FAIL - - [WebAssembly.Table.length] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490229 - expected: FAIL - - [WebAssembly.Global.valueOf] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490229 - expected: FAIL - -[interface.any.js] - [WebAssembly.validate] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490229 - expected: FAIL - - [WebAssembly.compile] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490229 - expected: FAIL - - [WebAssembly.instantiate] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490229 - expected: FAIL - - [WebAssembly.Module.exports] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490229 - expected: FAIL - - [WebAssembly.Module.imports] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490229 - expected: FAIL - - [WebAssembly.Module.customSections] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490229 - expected: FAIL - - [WebAssembly.Instance.exports] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490229 - expected: FAIL - - [WebAssembly.Memory.grow] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490229 - expected: FAIL - - [WebAssembly.Memory.buffer] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490229 - expected: FAIL - - [WebAssembly.Table.grow] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490229 - expected: FAIL - - [WebAssembly.Table.get] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490229 - expected: FAIL - - [WebAssembly.Table.set] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490229 - expected: FAIL - - [WebAssembly.Table.length] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490229 - expected: FAIL - - [WebAssembly.Global.valueOf] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490229 - expected: FAIL
deleted file mode 100644 --- a/testing/web-platform/meta/wasm/jsapi/memory/constructor.any.js.ini +++ /dev/null @@ -1,182 +0,0 @@ -[constructor.any.html] - [Invalid descriptor argument] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490277 - expected: FAIL - - [Undefined initial value in descriptor] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490277 - expected: FAIL - - [Out-of-range initial value in descriptor: NaN] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range maximum value in descriptor: NaN] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range initial value in descriptor: Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range maximum value in descriptor: Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range initial value in descriptor: -Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range maximum value in descriptor: -Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range initial value in descriptor: -1] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range maximum value in descriptor: -1] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range initial value in descriptor: 4294967296] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range maximum value in descriptor: 4294967296] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range initial value in descriptor: 68719476736] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range maximum value in descriptor: 68719476736] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Proxy descriptor] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490277 - expected: FAIL - -[constructor.any.worker.html] - [Invalid descriptor argument] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490277 - expected: FAIL - - [Undefined initial value in descriptor] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490277 - expected: FAIL - - [Out-of-range initial value in descriptor: NaN] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range maximum value in descriptor: NaN] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range initial value in descriptor: Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range maximum value in descriptor: Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range initial value in descriptor: -Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range maximum value in descriptor: -Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range initial value in descriptor: -1] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range maximum value in descriptor: -1] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range initial value in descriptor: 4294967296] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range maximum value in descriptor: 4294967296] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range initial value in descriptor: 68719476736] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range maximum value in descriptor: 68719476736] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Proxy descriptor] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490277 - expected: FAIL - -[constructor.any.js] - [Invalid descriptor argument] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490277 - expected: FAIL - - [Undefined initial value in descriptor] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490277 - expected: FAIL - - [Out-of-range initial value in descriptor: NaN] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range maximum value in descriptor: NaN] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range initial value in descriptor: Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range maximum value in descriptor: Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range initial value in descriptor: -Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range maximum value in descriptor: -Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range initial value in descriptor: -1] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range maximum value in descriptor: -1] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range initial value in descriptor: 4294967296] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range maximum value in descriptor: 4294967296] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range initial value in descriptor: 68719476736] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range maximum value in descriptor: 68719476736] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Proxy descriptor] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490277 - expected: FAIL
deleted file mode 100644 --- a/testing/web-platform/meta/wasm/jsapi/memory/grow.any.js.ini +++ /dev/null @@ -1,123 +0,0 @@ -[grow.any.html] - [Missing arguments] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490274 - expected: FAIL - - [Out-of-range argument: undefined] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: NaN] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: -Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: -1] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: 4294967296] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: 68719476736] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: "0x100000000"] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: object "[object Object\]"] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - -[grow.any.worker.html] - [Missing arguments] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490274 - expected: FAIL - - [Out-of-range argument: undefined] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: NaN] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: -Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: -1] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: 4294967296] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: 68719476736] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: "0x100000000"] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: object "[object Object\]"] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - -[grow.any.js] - [Missing arguments] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490274 - expected: FAIL - - [Out-of-range argument: undefined] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: NaN] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: -Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: -1] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: 4294967296] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: 68719476736] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: "0x100000000"] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: object "[object Object\]"] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL -
deleted file mode 100644 --- a/testing/web-platform/meta/wasm/jsapi/module/customSections.any.js.ini +++ /dev/null @@ -1,14 +0,0 @@ -[customSections.any.html] - [Missing arguments] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490274 - expected: FAIL - -[customSections.any.worker.html] - [Missing arguments] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490274 - expected: FAIL - -[customSections.any.js] - [Missing arguments] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490274 - expected: FAIL
deleted file mode 100644 --- a/testing/web-platform/meta/wasm/jsapi/table/constructor.any.js.ini +++ /dev/null @@ -1,195 +0,0 @@ -[constructor.any.html] - [Undefined initial value in descriptor] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490277 - expected: FAIL - - [Out-of-range initial value in descriptor: NaN] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range maximum value in descriptor: NaN] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range initial value in descriptor: Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range maximum value in descriptor: Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range initial value in descriptor: -Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range maximum value in descriptor: -Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range initial value in descriptor: -1] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range maximum value in descriptor: -1] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range initial value in descriptor: 4294967296] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range maximum value in descriptor: 4294967296] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range initial value in descriptor: 68719476736] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range maximum value in descriptor: 68719476736] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Proxy descriptor] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490277 - expected: FAIL - - [Type conversion for descriptor.element] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490275 - expected: FAIL - - [Order of evaluation for descriptor] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490275 - expected: FAIL - -[constructor.any.worker.html] - [Undefined initial value in descriptor] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490277 - expected: FAIL - - [Out-of-range initial value in descriptor: NaN] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range maximum value in descriptor: NaN] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range initial value in descriptor: Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range maximum value in descriptor: Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range initial value in descriptor: -Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range maximum value in descriptor: -Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range initial value in descriptor: -1] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range maximum value in descriptor: -1] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range initial value in descriptor: 4294967296] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range maximum value in descriptor: 4294967296] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range initial value in descriptor: 68719476736] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range maximum value in descriptor: 68719476736] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Proxy descriptor] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490277 - expected: FAIL - - [Type conversion for descriptor.element] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490275 - expected: FAIL - - [Order of evaluation for descriptor] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490275 - expected: FAIL - -[constructor.any.js] - [Undefined initial value in descriptor] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490277 - expected: FAIL - - [Out-of-range initial value in descriptor: NaN] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range maximum value in descriptor: NaN] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range initial value in descriptor: Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range maximum value in descriptor: Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range initial value in descriptor: -Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range maximum value in descriptor: -Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range initial value in descriptor: -1] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range maximum value in descriptor: -1] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range initial value in descriptor: 4294967296] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range maximum value in descriptor: 4294967296] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range initial value in descriptor: 68719476736] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range maximum value in descriptor: 68719476736] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Proxy descriptor] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490277 - expected: FAIL - - [Type conversion for descriptor.element] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490275 - expected: FAIL - - [Order of evaluation for descriptor] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490275 - expected: FAIL -
deleted file mode 100644 --- a/testing/web-platform/meta/wasm/jsapi/table/get-set.any.js.ini +++ /dev/null @@ -1,231 +0,0 @@ -[get-set.any.html] - [Missing arguments: get] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490274 - expected: FAIL - - [Getting out-of-range argument: undefined] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Setting out-of-range argument: undefined] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Getting out-of-range argument: NaN] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Setting out-of-range argument: NaN] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Getting out-of-range argument: Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Setting out-of-range argument: Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Getting out-of-range argument: -Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Setting out-of-range argument: -Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Getting out-of-range argument: -1] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Setting out-of-range argument: -1] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Getting out-of-range argument: 4294967296] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Setting out-of-range argument: 4294967296] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Getting out-of-range argument: 68719476736] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Setting out-of-range argument: 68719476736] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Getting out-of-range argument: "0x100000000"] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Setting out-of-range argument: "0x100000000"] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Getting out-of-range argument: object "[object Object\]"] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Setting out-of-range argument: object "[object Object\]"] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - -[get-set.any.worker.html] - [Missing arguments: get] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490274 - expected: FAIL - - [Getting out-of-range argument: undefined] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Setting out-of-range argument: undefined] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Getting out-of-range argument: NaN] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Setting out-of-range argument: NaN] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Getting out-of-range argument: Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Setting out-of-range argument: Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Getting out-of-range argument: -Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Setting out-of-range argument: -Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Getting out-of-range argument: -1] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Setting out-of-range argument: -1] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Getting out-of-range argument: 4294967296] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Setting out-of-range argument: 4294967296] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Getting out-of-range argument: 68719476736] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Setting out-of-range argument: 68719476736] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Getting out-of-range argument: "0x100000000"] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Setting out-of-range argument: "0x100000000"] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Getting out-of-range argument: object "[object Object\]"] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Setting out-of-range argument: object "[object Object\]"] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - -[get-set.any.js] - [Missing arguments: get] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490274 - expected: FAIL - - [Getting out-of-range argument: undefined] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Setting out-of-range argument: undefined] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Getting out-of-range argument: NaN] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Setting out-of-range argument: NaN] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Getting out-of-range argument: Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Setting out-of-range argument: Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Getting out-of-range argument: -Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Setting out-of-range argument: -Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Getting out-of-range argument: -1] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Setting out-of-range argument: -1] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Getting out-of-range argument: 4294967296] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Setting out-of-range argument: 4294967296] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Getting out-of-range argument: 68719476736] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Setting out-of-range argument: 68719476736] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Getting out-of-range argument: "0x100000000"] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Setting out-of-range argument: "0x100000000"] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Getting out-of-range argument: object "[object Object\]"] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Setting out-of-range argument: object "[object Object\]"] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL -
deleted file mode 100644 --- a/testing/web-platform/meta/wasm/jsapi/table/grow.any.js.ini +++ /dev/null @@ -1,123 +0,0 @@ -[grow.any.html] - [Missing arguments] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490274 - expected: FAIL - - [Out-of-range argument: undefined] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: NaN] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: -Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: -1] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: 4294967296] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: 68719476736] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: "0x100000000"] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: object "[object Object\]"] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - -[grow.any.worker.html] - [Missing arguments] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490274 - expected: FAIL - - [Out-of-range argument: undefined] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: NaN] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: -Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: -1] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: 4294967296] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: 68719476736] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: "0x100000000"] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: object "[object Object\]"] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - -[grow.any.js] - [Missing arguments] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1490274 - expected: FAIL - - [Out-of-range argument: undefined] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: NaN] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: -Infinity] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: -1] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: 4294967296] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: 68719476736] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: "0x100000000"] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL - - [Out-of-range argument: object "[object Object\]"] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1488473 - expected: FAIL -
--- a/testing/web-platform/mozilla/meta/MANIFEST.json +++ b/testing/web-platform/mozilla/meta/MANIFEST.json @@ -1560,17 +1560,17 @@ "c7b1a5cd565107a9d2ed860c88bbbda7f20c111f", "support" ], "wasm/js/int_literals.wast.js": [ "60ae9db6154aa04e03604c80a769061b042ad490", "support" ], "wasm/js/jsapi.js": [ - "c0b9c4a200b6ec7132d81d48259ec97e2a047ae8", + "b7f30d280b9d5cb37c3c007e31e1717ca4290601", "support" ], "wasm/js/labels.wast.js": [ "75e5c04f8317e5c3363981a5488ddb808293cae1", "support" ], "wasm/js/left-to-right.wast.js": [ "6a3522dc0303bf525b7d52b7ac7d0330979a15b9",
--- a/testing/web-platform/mozilla/tests/wasm/js/jsapi.js +++ b/testing/web-platform/mozilla/tests/wasm/js/jsapi.js @@ -228,17 +228,17 @@ test(() => { assert_equals(String(emptyModule), "[object WebAssembly.Module]"); assert_equals(Object.getPrototypeOf(emptyModule), moduleProto); }, "'WebAssembly.Module' instance objects"); test(() => { const moduleImportsDesc = Object.getOwnPropertyDescriptor(Module, 'imports'); assert_equals(typeof moduleImportsDesc.value, "function"); assert_equals(moduleImportsDesc.writable, true); - assert_equals(moduleImportsDesc.enumerable, false); + assert_equals(moduleImportsDesc.enumerable, true); assert_equals(moduleImportsDesc.configurable, true); }, "'WebAssembly.Module.imports' data property"); test(() => { const moduleImportsDesc = Object.getOwnPropertyDescriptor(Module, 'imports'); const moduleImports = moduleImportsDesc.value; assert_equals(moduleImports.length, 1); assertThrows(() => moduleImports(), TypeError); @@ -263,17 +263,17 @@ test(() => { assert_equals(arr[3].module, "g"); assert_equals(arr[3].name, "âš¡"); }, "'WebAssembly.Module.imports' method"); test(() => { const moduleExportsDesc = Object.getOwnPropertyDescriptor(Module, 'exports'); assert_equals(typeof moduleExportsDesc.value, "function"); assert_equals(moduleExportsDesc.writable, true); - assert_equals(moduleExportsDesc.enumerable, false); + assert_equals(moduleExportsDesc.enumerable, true); assert_equals(moduleExportsDesc.configurable, true); }, "'WebAssembly.Module.exports' data property"); test(() => { const moduleExportsDesc = Object.getOwnPropertyDescriptor(Module, 'exports'); const moduleExports = moduleExportsDesc.value; assert_equals(moduleExports.length, 1); assertThrows(() => moduleExports(), TypeError); @@ -294,28 +294,28 @@ test(() => { assert_equals(arr[3].kind, "global"); assert_equals(arr[3].name, "âš¡"); }, "'WebAssembly.Module.exports' method"); test(() => { const customSectionsDesc = Object.getOwnPropertyDescriptor(Module, 'customSections'); assert_equals(typeof customSectionsDesc.value, "function"); assert_equals(customSectionsDesc.writable, true); - assert_equals(customSectionsDesc.enumerable, false); + assert_equals(customSectionsDesc.enumerable, true); assert_equals(customSectionsDesc.configurable, true); }, "'WebAssembly.Module.customSections' data property"); test(() => { const customSectionsDesc = Object.getOwnPropertyDescriptor(Module, 'customSections'); const moduleCustomSections = customSectionsDesc.value; assert_equals(moduleCustomSections.length, 2); assertThrows(() => moduleCustomSections(), TypeError); assertThrows(() => moduleCustomSections(undefined), TypeError); assertThrows(() => moduleCustomSections({}), TypeError); - var arr = moduleCustomSections(emptyModule); + var arr = moduleCustomSections(emptyModule, ""); assert_equals(arr instanceof Array, true); assert_equals(arr.length, 0); }, "'WebAssembly.Module.customSections' method"); test(() => { const instanceDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'Instance'); assert_equals(typeof instanceDesc.value, "function"); assert_equals(instanceDesc.writable, true); @@ -365,17 +365,17 @@ test(() => { assert_equals(String(exportingInstance), "[object WebAssembly.Instance]"); assert_equals(Object.getPrototypeOf(exportingInstance), instanceProto); }, "'WebAssembly.Instance' instance objects"); test(() => { const exportsDesc = Object.getOwnPropertyDescriptor(instanceProto, 'exports'); assert_equals(typeof exportsDesc.get, "function"); assert_equals(exportsDesc.set, undefined); - assert_equals(exportsDesc.enumerable, false); + assert_equals(exportsDesc.enumerable, true); assert_equals(exportsDesc.configurable, true); const exportsGetter = exportsDesc.get; assertThrows(() => exportsGetter.call(), TypeError); assertThrows(() => exportsGetter.call({}), TypeError); assert_equals(typeof exportsGetter.call(exportingInstance), "object"); }, "'WebAssembly.Instance.prototype.exports' accessor property"); test(() => { @@ -413,21 +413,21 @@ test(() => { test(() => { const memoryDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'Memory'); assert_equals(Memory, memoryDesc.value); assert_equals(Memory.length, 1); assert_equals(Memory.name, "Memory"); assertThrows(() => Memory(), TypeError); assertThrows(() => new Memory(1), TypeError); assertThrows(() => new Memory({initial:{valueOf() { throw new Error("here")}}}), Error); - assertThrows(() => new Memory({initial:-1}), RangeError); - assertThrows(() => new Memory({initial:Math.pow(2,32)}), RangeError); + assertThrows(() => new Memory({initial:-1}), TypeError); + assertThrows(() => new Memory({initial:Math.pow(2,32)}), TypeError); assertThrows(() => new Memory({initial:1, maximum: Math.pow(2,32)/Math.pow(2,14) }), RangeError); assertThrows(() => new Memory({initial:2, maximum:1 }), RangeError); - assertThrows(() => new Memory({maximum: -1 }), RangeError); + assertThrows(() => new Memory({maximum: -1 }), TypeError); assert_equals(new Memory({initial:1}) instanceof Memory, true); assert_equals(new Memory({initial:1.5}).buffer.byteLength, WasmPage); }, "'WebAssembly.Memory' constructor function"); test(() => { const memoryProtoDesc = Object.getOwnPropertyDescriptor(Memory, 'prototype'); assert_equals(typeof memoryProtoDesc.value, "object"); assert_equals(memoryProtoDesc.writable, false); @@ -449,44 +449,44 @@ test(() => { assert_equals(String(mem1), "[object WebAssembly.Memory]"); assert_equals(Object.getPrototypeOf(mem1), memoryProto); }, "'WebAssembly.Memory' instance objects"); test(() => { const bufferDesc = Object.getOwnPropertyDescriptor(memoryProto, 'buffer'); assert_equals(typeof bufferDesc.get, "function"); assert_equals(bufferDesc.set, undefined); - assert_equals(bufferDesc.enumerable, false); + assert_equals(bufferDesc.enumerable, true); assert_equals(bufferDesc.configurable, true); }, "'WebAssembly.Memory.prototype.buffer' accessor property"); test(() => { const bufferDesc = Object.getOwnPropertyDescriptor(memoryProto, 'buffer'); const bufferGetter = bufferDesc.get; assertThrows(() => bufferGetter.call(), TypeError); assertThrows(() => bufferGetter.call({}), TypeError); assert_equals(bufferGetter.call(mem1) instanceof ArrayBuffer, true); assert_equals(bufferGetter.call(mem1).byteLength, WasmPage); }, "'WebAssembly.Memory.prototype.buffer' getter"); test(() => { const memGrowDesc = Object.getOwnPropertyDescriptor(memoryProto, 'grow'); assert_equals(typeof memGrowDesc.value, "function"); - assert_equals(memGrowDesc.enumerable, false); + assert_equals(memGrowDesc.enumerable, true); assert_equals(memGrowDesc.configurable, true); }, "'WebAssembly.Memory.prototype.grow' data property"); test(() => { const memGrowDesc = Object.getOwnPropertyDescriptor(memoryProto, 'grow'); const memGrow = memGrowDesc.value; assert_equals(memGrow.length, 1); assertThrows(() => memGrow.call(), TypeError); assertThrows(() => memGrow.call({}), TypeError); - assertThrows(() => memGrow.call(mem1, -1), RangeError); - assertThrows(() => memGrow.call(mem1, Math.pow(2,32)), RangeError); + assertThrows(() => memGrow.call(mem1, -1), TypeError); + assertThrows(() => memGrow.call(mem1, Math.pow(2,32)), TypeError); var mem = new Memory({initial:1, maximum:2}); var buf = mem.buffer; assert_equals(buf.byteLength, WasmPage); assert_equals(mem.grow(0), 1); assert_equals(buf !== mem.buffer, true); assert_equals(buf.byteLength, 0); buf = mem.buffer; assert_equals(buf.byteLength, WasmPage); @@ -514,20 +514,20 @@ test(() => { assert_equals(Table.length, 1); assert_equals(Table.name, "Table"); assertThrows(() => Table(), TypeError); assertThrows(() => new Table(1), TypeError); assertThrows(() => new Table({initial:1, element:1}), TypeError); assertThrows(() => new Table({initial:1, element:"any"}), TypeError); assertThrows(() => new Table({initial:1, element:{valueOf() { return "anyfunc" }}}), TypeError); assertThrows(() => new Table({initial:{valueOf() { throw new Error("here")}}, element:"anyfunc"}), Error); - assertThrows(() => new Table({initial:-1, element:"anyfunc"}), RangeError); - assertThrows(() => new Table({initial:Math.pow(2,32), element:"anyfunc"}), RangeError); + assertThrows(() => new Table({initial:-1, element:"anyfunc"}), TypeError); + assertThrows(() => new Table({initial:Math.pow(2,32), element:"anyfunc"}), TypeError); assertThrows(() => new Table({initial:2, maximum:1, element:"anyfunc"}), RangeError); - assertThrows(() => new Table({initial:2, maximum:Math.pow(2,32), element:"anyfunc"}), RangeError); + assertThrows(() => new Table({initial:2, maximum:Math.pow(2,32), element:"anyfunc"}), TypeError); assert_equals(new Table({initial:1, element:"anyfunc"}) instanceof Table, true); assert_equals(new Table({initial:1.5, element:"anyfunc"}) instanceof Table, true); assert_equals(new Table({initial:1, maximum:1.5, element:"anyfunc"}) instanceof Table, true); assertThrows(() => new Table({initial:1, maximum:Math.pow(2,32)-1, element:"anyfunc"}), RangeError); }, "'WebAssembly.Table' constructor function"); test(() => { const tableProtoDesc = Object.getOwnPropertyDescriptor(Table, 'prototype'); @@ -551,94 +551,94 @@ test(() => { assert_equals(String(tbl1), "[object WebAssembly.Table]"); assert_equals(Object.getPrototypeOf(tbl1), tableProto); }, "'WebAssembly.Table' instance objects"); test(() => { const lengthDesc = Object.getOwnPropertyDescriptor(tableProto, 'length'); assert_equals(typeof lengthDesc.get, "function"); assert_equals(lengthDesc.set, undefined); - assert_equals(lengthDesc.enumerable, false); + assert_equals(lengthDesc.enumerable, true); assert_equals(lengthDesc.configurable, true); }, "'WebAssembly.Table.prototype.length' accessor data property"); test(() => { const lengthDesc = Object.getOwnPropertyDescriptor(tableProto, 'length'); const lengthGetter = lengthDesc.get; assert_equals(lengthGetter.length, 0); assertThrows(() => lengthGetter.call(), TypeError); assertThrows(() => lengthGetter.call({}), TypeError); assert_equals(typeof lengthGetter.call(tbl1), "number"); assert_equals(lengthGetter.call(tbl1), 2); }, "'WebAssembly.Table.prototype.length' getter"); test(() => { const getDesc = Object.getOwnPropertyDescriptor(tableProto, 'get'); assert_equals(typeof getDesc.value, "function"); - assert_equals(getDesc.enumerable, false); + assert_equals(getDesc.enumerable, true); assert_equals(getDesc.configurable, true); }, "'WebAssembly.Table.prototype.get' data property"); test(() => { const getDesc = Object.getOwnPropertyDescriptor(tableProto, 'get'); const get = getDesc.value; assert_equals(get.length, 1); assertThrows(() => get.call(), TypeError); assertThrows(() => get.call({}), TypeError); assert_equals(get.call(tbl1, 0), null); assert_equals(get.call(tbl1, 1), null); assert_equals(get.call(tbl1, 1.5), null); assertThrows(() => get.call(tbl1, 2), RangeError); assertThrows(() => get.call(tbl1, 2.5), RangeError); - assertThrows(() => get.call(tbl1, -1), RangeError); - assertThrows(() => get.call(tbl1, Math.pow(2,33)), RangeError); + assertThrows(() => get.call(tbl1, -1), TypeError); + assertThrows(() => get.call(tbl1, Math.pow(2,33)), TypeError); assertThrows(() => get.call(tbl1, {valueOf() { throw new Error("hi") }}), Error); }, "'WebAssembly.Table.prototype.get' method"); test(() => { const setDesc = Object.getOwnPropertyDescriptor(tableProto, 'set'); assert_equals(typeof setDesc.value, "function"); - assert_equals(setDesc.enumerable, false); + assert_equals(setDesc.enumerable, true); assert_equals(setDesc.configurable, true); }, "'WebAssembly.Table.prototype.set' data property"); test(() => { const setDesc = Object.getOwnPropertyDescriptor(tableProto, 'set'); const set = setDesc.value; assert_equals(set.length, 2); assertThrows(() => set.call(), TypeError); assertThrows(() => set.call({}), TypeError); assertThrows(() => set.call(tbl1, 0), TypeError); assertThrows(() => set.call(tbl1, 2, null), RangeError); - assertThrows(() => set.call(tbl1, -1, null), RangeError); - assertThrows(() => set.call(tbl1, Math.pow(2,33), null), RangeError); + assertThrows(() => set.call(tbl1, -1, null), TypeError); + assertThrows(() => set.call(tbl1, Math.pow(2,33), null), TypeError); assertThrows(() => set.call(tbl1, 0, undefined), TypeError); assertThrows(() => set.call(tbl1, 0, {}), TypeError); assertThrows(() => set.call(tbl1, 0, function() {}), TypeError); assertThrows(() => set.call(tbl1, 0, Math.sin), TypeError); assertThrows(() => set.call(tbl1, {valueOf() { throw Error("hai") }}, null), Error); assert_equals(set.call(tbl1, 0, null), undefined); assert_equals(set.call(tbl1, 1, null), undefined); }, "'WebAssembly.Table.prototype.set' method"); test(() => { const tblGrowDesc = Object.getOwnPropertyDescriptor(tableProto, 'grow'); assert_equals(typeof tblGrowDesc.value, "function"); - assert_equals(tblGrowDesc.enumerable, false); + assert_equals(tblGrowDesc.enumerable, true); assert_equals(tblGrowDesc.configurable, true); }, "'WebAssembly.Table.prototype.grow' data property"); test(() => { const tblGrowDesc = Object.getOwnPropertyDescriptor(tableProto, 'grow'); const tblGrow = tblGrowDesc.value; assert_equals(tblGrow.length, 1); assertThrows(() => tblGrow.call(), TypeError); assertThrows(() => tblGrow.call({}), TypeError); - assertThrows(() => tblGrow.call(tbl1, -1), RangeError); - assertThrows(() => tblGrow.call(tbl1, Math.pow(2,32)), RangeError); + assertThrows(() => tblGrow.call(tbl1, -1), TypeError); + assertThrows(() => tblGrow.call(tbl1, Math.pow(2,32)), TypeError); var tbl = new Table({element:"anyfunc", initial:1, maximum:2}); assert_equals(tbl.length, 1); assert_equals(tbl.grow(0), 1); assert_equals(tbl.length, 1); assert_equals(tbl.grow(1), 1); assert_equals(tbl.length, 2); assertThrows(() => tbl.grow(1), Error); }, "'WebAssembly.Table.prototype.grow' method"); @@ -651,17 +651,17 @@ test(() => { assert_false(WebAssembly.validate(moduleBinaryImporting2Memories)); assert_false(WebAssembly.validate(moduleBinaryWithMemSectionAndMemImport)); }, "'WebAssembly.validate' method"), test(() => { const compileDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'compile'); assert_equals(typeof compileDesc.value, "function"); assert_equals(compileDesc.writable, true); - assert_equals(compileDesc.enumerable, false); + assert_equals(compileDesc.enumerable, true); assert_equals(compileDesc.configurable, true); }, "'WebAssembly.compile' data property"); test(() => { const compile = WebAssembly.compile; const compileDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'compile'); assert_equals(compile, compileDesc.value); @@ -704,17 +704,17 @@ function assertCompileSuccess(bytes) { assertCompileSuccess(emptyModuleBinary); assertCompileSuccess(emptyModuleBinary.buffer); test(() => { const instantiateDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'instantiate'); assert_equals(typeof instantiateDesc.value, "function"); assert_equals(instantiateDesc.writable, true); - assert_equals(instantiateDesc.enumerable, false); + assert_equals(instantiateDesc.enumerable, true); assert_equals(instantiateDesc.configurable, true); }, "'WebAssembly.instantiate' data property"); test(() => { const instantiateDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'instantiate'); const instantiate = WebAssembly.instantiate; assert_equals(instantiate, instantiateDesc.value); assert_equals(instantiate.length, 1);
--- a/testing/web-platform/tests/css/filter-effects/svg-unknown-input-001.html +++ b/testing/web-platform/tests/css/filter-effects/svg-unknown-input-001.html @@ -1,19 +1,20 @@ <!DOCTYPE html> <title>Filter Effects: The in attribute</title> <link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au"> <link rel="help" href="https://www.w3.org/TR/filter-effects-1/#CommonAttributes"> <link rel="match" href="svg-unknown-input-ref.html"> <meta name="flags" content="svg"> <meta name="assert" content="References to non-existent results on a first primitive must be treated like SourceGraphic."> <p>The test passes if you see a green square and no red.</p> -<svg width="100" height="100"> +<svg width="200" height="200"> <defs> - <filter id="f" x="0" y="0" width="100" height="100" filterUnits="userSpaceOnUse"> + <filter id="f" x="10" y="10" width="100" height="100" filterUnits="userSpaceOnUse"> <feComposite in="unknown" in2="SourceGraphic" result="a"/> <feFlood flood-color="green" result="b"/> <feComposite in="b" in2="a"/> </filter> </defs> - <rect width="100" height="100" fill="red"/> - <rect x="25" y="25" width="50" height="50" fill="green" filter="url(#f)"/> + <rect x="10" y="10" width="100" height="100" fill="red"/> + <rect x="35" y="35" width="50" height="50" fill="green" filter="url(#f)"/> + <rect x="10" y="10" width="100" height="100" fill="none" stroke="green" stroke-width="4"/> </svg>
--- a/testing/web-platform/tests/css/filter-effects/svg-unknown-input-002.html +++ b/testing/web-platform/tests/css/filter-effects/svg-unknown-input-002.html @@ -1,18 +1,19 @@ <!DOCTYPE html> <title>Filter Effects: The in attribute</title> <link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au"> <link rel="help" href="https://www.w3.org/TR/filter-effects-1/#CommonAttributes"> <link rel="match" href="svg-unknown-input-ref.html"> <meta name="flags" content="svg"> <meta name="assert" content="References to non-existent results on a subsequent primitive must be treated like the previous primitive result."> <p>The test passes if you see a green square and no red.</p> -<svg width="100" height="100"> +<svg width="200" height="200"> <defs> - <filter id="f" x="0" y="0" width="100" height="100" filterUnits="userSpaceOnUse"> + <filter id="f" x="10" y="10" width="100" height="100" filterUnits="userSpaceOnUse"> <feFlood flood-color="green"/> <feComposite in="unknown" in2="SourceGraphic"/> </filter> </defs> - <rect width="100" height="100" fill="red"/> - <rect x="25" y="25" width="50" height="50" fill="blue" filter="url(#f)"/> + <rect x="10" y="10" width="100" height="100" fill="red"/> + <rect x="35" y="35" width="50" height="50" fill="blue" filter="url(#f)"/> + <rect x="10" y="10" width="100" height="100" fill="none" stroke="green" stroke-width="4"/> </svg>
--- a/testing/web-platform/tests/css/filter-effects/svg-unknown-input-ref.html +++ b/testing/web-platform/tests/css/filter-effects/svg-unknown-input-ref.html @@ -1,8 +1,8 @@ <!DOCTYPE html> <title>Filter Effects: Reference</title> <link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au"> <meta name="flags" content="svg"> <p>The test passes if you see a green square and no red.</p> -<svg width="100" height="100"> - <rect width="100" height="100" fill="green"/> +<svg width="200" height="200"> + <rect x="10" y="10" width="100" height="100" fill="green" stroke="green" stroke-width="4"/> </svg>
--- a/testing/web-platform/tests/wasm/jsapi/constructor/compile.any.js +++ b/testing/web-platform/tests/wasm/jsapi/constructor/compile.any.js @@ -64,14 +64,18 @@ promise_test(t => { return promise_rejects(t, new WebAssembly.CompileError(), WebAssembly.compile(buffer)); }, "Invalid code"); promise_test(() => { return WebAssembly.compile(emptyModuleBinary).then(assert_Module); }, "Result type"); promise_test(() => { + return WebAssembly.compile(emptyModuleBinary, {}).then(assert_Module); +}, "Stray argument"); + +promise_test(() => { const buffer = new WasmModuleBuilder().toBuffer(); assert_equals(buffer[0], 0); const promise = WebAssembly.compile(buffer); buffer[0] = 1; return promise.then(assert_Module); }, "Changing the buffer");
--- a/testing/web-platform/tests/wasm/jsapi/constructor/instantiate.any.js +++ b/testing/web-platform/tests/wasm/jsapi/constructor/instantiate.any.js @@ -1,12 +1,13 @@ // META: global=jsshell // META: script=/wasm/jsapi/wasm-constants.js // META: script=/wasm/jsapi/wasm-module-builder.js // META: script=/wasm/jsapi/assertions.js +// META: script=/wasm/jsapi/instanceTestFactory.js function assert_WebAssemblyInstantiatedSource(actual, expected_exports={}) { assert_equals(Object.getPrototypeOf(actual), Object.prototype, "Prototype"); assert_true(Object.isExtensible(actual), "Extensibility"); const module = Object.getOwnPropertyDescriptor(actual, "module"); assert_equals(typeof module, "object", "module: type of descriptor"); @@ -72,120 +73,34 @@ promise_test(t => { }, "Invalid arguments"); test(() => { const promise = WebAssembly.instantiate(emptyModuleBinary); assert_equals(Object.getPrototypeOf(promise), Promise.prototype, "prototype"); assert_true(Object.isExtensible(promise), "extensibility"); }, "Promise type"); -const createModule = () => { - const builder = new WasmModuleBuilder(); - - builder - .addFunction("fn", kSig_v_d) - .addBody([ - kExprEnd - ]) - .exportFunc(); - builder - .addFunction("fn2", kSig_v_v) - .addBody([ - kExprEnd - ]) - .exportFunc(); - - builder.setFunctionTableLength(1); - builder.addExportOfKind("table", kExternalTable, 0); - - builder.addGlobal(kWasmI32, true) - .exportAs("global") - .init = 7; - builder.addGlobal(kWasmF64, true) - .exportAs("global2") - .init = 1.2; - - builder.addMemory(4, 8, true); - - const buffer = builder.toBuffer(); - - const exports = { - "fn": { "kind": "function", "name": "0", "length": 1 }, - "fn2": { "kind": "function", "name": "1", "length": 0 }, - "table": { "kind": "table", "length": 1 }, - "global": { "kind": "global", "value": 7 }, - "global2": { "kind": "global", "value": 1.2 }, - "memory": { "kind": "memory", "size": 4 }, - }; - - return [buffer, exports]; -} - -promise_test(() => { - const [buffer, expected] = createModule(); - return WebAssembly.instantiate(buffer).then(result => assert_WebAssemblyInstantiatedSource(result, expected)); -}, "BufferSource argument"); +for (const [name, fn] of instanceTestFactory) { + promise_test(() => { + const { buffer, args, exports, verify } = fn(); + return WebAssembly.instantiate(buffer, ...args).then(result => { + assert_WebAssemblyInstantiatedSource(result, exports); + verify(result.instance); + }); + }, `${name}: BufferSource argument`); -promise_test(() => { - const [buffer, expected] = createModule(); - const module = new WebAssembly.Module(buffer); - return WebAssembly.instantiate(module).then(instance => assert_Instance(instance, expected)); -}, "Module argument"); - -const createModuleWithImports = () => { - const builder = new WasmModuleBuilder(); - - const index = builder.addImportedGlobal("module", "global", kWasmI32); - builder - .addFunction("fn", kSig_i_v) - .addBody([ - kExprGetGlobal, - index, - kExprReturn, - kExprEnd, - ]) - .exportFunc(); - - const buffer = builder.toBuffer(); - - const expected = { - "fn": { "kind": "function", "name": "0", "length": 0 }, - }; - - return [buffer, expected]; -}; - -promise_test(() => { - const [buffer, expected] = createModuleWithImports(); - - const value = 102; - return WebAssembly.instantiate(buffer, { - "module": { - "global": value, - }, - }).then(result => { - assert_WebAssemblyInstantiatedSource(result, expected) - assert_equals(result.instance.exports.fn(), value); - }); -}, "exports and imports: buffer argument"); - -promise_test(() => { - const [buffer, expected] = createModuleWithImports(); - const module = new WebAssembly.Module(buffer); - - const value = 102; - return WebAssembly.instantiate(module, { - "module": { - "global": value, - }, - }).then(instance => { - assert_Instance(instance, expected) - assert_equals(instance.exports.fn(), value); - }); -}, "exports and imports: Module argument"); + promise_test(() => { + const { buffer, args, exports, verify } = fn(); + const module = new WebAssembly.Module(buffer); + return WebAssembly.instantiate(module, ...args).then(instance => { + assert_Instance(instance, exports); + verify(instance); + }); + }, `${name}: Module argument`); +} promise_test(t => { const buffer = new Uint8Array(); return promise_rejects(t, new WebAssembly.CompileError(), WebAssembly.instantiate(buffer)); }, "Invalid code"); promise_test(() => { const buffer = new WasmModuleBuilder().toBuffer();
--- a/testing/web-platform/tests/wasm/jsapi/constructor/validate.any.js +++ b/testing/web-platform/tests/wasm/jsapi/constructor/validate.any.js @@ -89,8 +89,12 @@ for (const [module, expected] of modules test(() => { const bytes = new Uint8Array(module); const moduleBuffer = new bufferType(bytes.buffer); assert_equals(WebAssembly.validate(moduleBuffer), expected); }, `Validating module [${name}] in ${bufferType.name}`); } } } + +test(() => { + assert_true(WebAssembly.validate(emptyModuleBinary, {})); +}, "Stray argument");
--- a/testing/web-platform/tests/wasm/jsapi/global/constructor.any.js +++ b/testing/web-platform/tests/wasm/jsapi/global/constructor.any.js @@ -114,8 +114,14 @@ for (const type of ["i32", "f32", "f64"] for (const [value, expected, name = format_value(value)] of valueArguments) { test(() => { const argument = { "value": type }; const global = new WebAssembly.Global(argument, value); assert_Global(global, expected); }, `Explicit value ${name} for type ${type}`); } } + +test(() => { + const argument = { "value": "i32" }; + const global = new WebAssembly.Global(argument, 0, {}); + assert_Global(global, 0); +}, "Stray argument");
rename from testing/web-platform/tests/wasm/jsapi/global/value-set.any.js rename to testing/web-platform/tests/wasm/jsapi/global/value-get-set.any.js --- a/testing/web-platform/tests/wasm/jsapi/global/value-set.any.js +++ b/testing/web-platform/tests/wasm/jsapi/global/value-get-set.any.js @@ -87,8 +87,25 @@ test(() => { const desc = Object.getOwnPropertyDescriptor(WebAssembly.Global.prototype, "value"); assert_equals(typeof desc, "object"); const setter = desc.set; assert_equals(typeof setter, "function"); assert_throws(new TypeError(), () => setter.call(global)); }, "Calling setter without argument"); + +test(() => { + const argument = { "value": "i32", "mutable": true }; + const global = new WebAssembly.Global(argument); + const desc = Object.getOwnPropertyDescriptor(WebAssembly.Global.prototype, "value"); + assert_equals(typeof desc, "object"); + + const getter = desc.get; + assert_equals(typeof getter, "function"); + + const setter = desc.set; + assert_equals(typeof setter, "function"); + + assert_equals(getter.call(global, {}), 0); + assert_equals(setter.call(global, 1, {}), undefined); + assert_equals(global.value, 1); +}, "Stray argument");
--- a/testing/web-platform/tests/wasm/jsapi/global/valueOf.any.js +++ b/testing/web-platform/tests/wasm/jsapi/global/valueOf.any.js @@ -15,8 +15,14 @@ test(() => { ]; const fn = WebAssembly.Global.prototype.valueOf; for (const thisValue of thisValues) { assert_throws(new TypeError(), () => fn.call(thisValue), `this=${format_value(thisValue)}`); } }, "Branding"); + +test(() => { + const argument = { "value": "i32" }; + const global = new WebAssembly.Global(argument, 0); + assert_equals(global.valueOf({}), 0); +}, "Stray argument");
--- a/testing/web-platform/tests/wasm/jsapi/instance/constructor.any.js +++ b/testing/web-platform/tests/wasm/jsapi/instance/constructor.any.js @@ -1,12 +1,13 @@ // META: global=jsshell // META: script=/wasm/jsapi/wasm-constants.js // META: script=/wasm/jsapi/wasm-module-builder.js // META: script=/wasm/jsapi/assertions.js +// META: script=/wasm/jsapi/instanceTestFactory.js let emptyModuleBinary; setup(() => { emptyModuleBinary = new WasmModuleBuilder().toBuffer(); }); test(() => { assert_function_name(WebAssembly.Instance, "Instance", "WebAssembly.Instance"); @@ -35,187 +36,20 @@ test(() => { for (const argument of invalidArguments) { assert_throws(new TypeError(), () => new WebAssembly.Instance(argument), `new Instance(${format_value(argument)})`); } }, "Non-Module arguments"); test(() => { const module = new WebAssembly.Module(emptyModuleBinary); - const invalidArguments = [ - null, - true, - "", - Symbol(), - 1, - ]; - for (const argument of invalidArguments) { - assert_throws(new TypeError(), () => new WebAssembly.Instance(module, argument), - `new Instance(module, ${format_value(argument)})`); - } -}, "Non-object imports"); - -test(() => { - const module = new WebAssembly.Module(emptyModuleBinary); assert_throws(new TypeError(), () => WebAssembly.Instance(module)); }, "Calling"); -test(() => { - const module = new WebAssembly.Module(emptyModuleBinary); - const arguments = [ - [], - [undefined], - [{}], - ]; - for (const value of arguments) { - const instance = new WebAssembly.Instance(module, ...arguments); - assert_Instance(instance, {}); - } -}, "Empty module"); - -test(() => { - const builder = new WasmModuleBuilder(); - builder.addImportedGlobal("module", "global1", kWasmI32); - builder.addImportedGlobal("module2", "global3", kWasmI32); - builder.addImportedMemory("module", "memory", 0, 128); - builder.addImportedGlobal("module", "global2", kWasmI32); - const buffer = builder.toBuffer(); - const module = new WebAssembly.Module(buffer); - const order = []; - const imports = { - get module() { - order.push("module getter"); - return { - get global1() { - order.push("global1 getter"); - return 0; - }, - get global2() { - order.push("global2 getter"); - return 0; - }, - get memory() { - order.push("memory getter"); - return new WebAssembly.Memory({ "initial": 64, maximum: 128 }); - }, - } - }, - get module2() { - order.push("module2 getter"); - return { - get global3() { - order.push("global3 getter"); - return 0; - }, - } - }, - }; - new WebAssembly.Instance(module, imports); - const expected = [ - "module getter", - "global1 getter", - "module2 getter", - "global3 getter", - "module getter", - "memory getter", - "module getter", - "global2 getter", - ]; - assert_array_equals(order, expected); -}, "getter order for imports object"); - -test(() => { - const builder = new WasmModuleBuilder(); - - builder.addImport("module", "fn", kSig_v_v); - builder.addImportedGlobal("module", "global", kWasmI32); - builder.addImportedMemory("module", "memory", 0, 128); - builder.addImportedTable("module", "table", 0, 128); - - const buffer = builder.toBuffer(); - const module = new WebAssembly.Module(buffer); - const instance = new WebAssembly.Instance(module, { - "module": { - "fn": function() {}, - "global": 0, - "memory": new WebAssembly.Memory({ "initial": 64, maximum: 128 }), - "table": new WebAssembly.Table({ "element": "anyfunc", "initial": 64, maximum: 128 }), - }, - get "module2"() { - assert_unreached("Should not get modules that are not imported"); - }, - }); - assert_Instance(instance, {}); -}, "imports"); - -test(() => { - const builder = new WasmModuleBuilder(); - - builder - .addFunction("fn", kSig_v_d) - .addBody([ - kExprEnd - ]) - .exportFunc(); - builder - .addFunction("fn2", kSig_v_v) - .addBody([ - kExprEnd - ]) - .exportFunc(); - - builder.setFunctionTableLength(1); - builder.addExportOfKind("table", kExternalTable, 0); - - builder.addGlobal(kWasmI32, true) - .exportAs("global") - .init = 7; - builder.addGlobal(kWasmF64, true) - .exportAs("global2") - .init = 1.2; - - builder.addMemory(4, 8, true); - - const buffer = builder.toBuffer() - const module = new WebAssembly.Module(buffer); - - const instance = new WebAssembly.Instance(module, {}); - const expected = { - "fn": { "kind": "function", "name": "0", "length": 1 }, - "fn2": { "kind": "function", "name": "1", "length": 0 }, - "table": { "kind": "table", "length": 1 }, - "global": { "kind": "global", "value": 7 }, - "global2": { "kind": "global", "value": 1.2 }, - "memory": { "kind": "memory", "size": 4 }, - }; - assert_Instance(instance, expected); -}, "exports"); - -test(() => { - const value = 102; - - const builder = new WasmModuleBuilder(); - - builder.addImportedGlobal("module", "global", kWasmI32); - builder - .addFunction("fn", kSig_i_v) - .addBody([ - kExprGetGlobal, - 0, - kExprReturn, - kExprEnd, - ]) - .exportFunc(); - - const buffer = builder.toBuffer(); - const module = new WebAssembly.Module(buffer); - const instance = new WebAssembly.Instance(module, { - "module": { - "global": value, - }, - }); - const expected = { - "fn": { "kind": "function", "name": "0", "length": 0 }, - }; - assert_Instance(instance, expected); - - assert_equals(instance.exports.fn(), value); -}, "exports and imports"); +for (const [name, fn] of instanceTestFactory) { + test(() => { + const { buffer, args, exports, verify } = fn(); + const module = new WebAssembly.Module(buffer); + const instance = new WebAssembly.Instance(module, ...args); + assert_Instance(instance, exports); + verify(instance); + }, name); +}
--- a/testing/web-platform/tests/wasm/jsapi/instance/exports.any.js +++ b/testing/web-platform/tests/wasm/jsapi/instance/exports.any.js @@ -32,16 +32,30 @@ test(() => { assert_throws(new TypeError(), () => getter.call(thisValue), `this=${format_value(thisValue)}`); } }, "Branding"); test(() => { const module = new WebAssembly.Module(emptyModuleBinary); const instance = new WebAssembly.Instance(module); const exports = instance.exports; + + const desc = Object.getOwnPropertyDescriptor(WebAssembly.Instance.prototype, "exports"); + assert_equals(typeof desc, "object"); + + const getter = desc.get; + assert_equals(typeof getter, "function"); + + assert_equals(getter.call(instance, {}), exports); +}, "Stray argument"); + +test(() => { + const module = new WebAssembly.Module(emptyModuleBinary); + const instance = new WebAssembly.Instance(module); + const exports = instance.exports; instance.exports = {}; assert_equals(instance.exports, exports, "Should not change the exports"); }, "Setting (sloppy mode)"); test(() => { const module = new WebAssembly.Module(emptyModuleBinary); const instance = new WebAssembly.Instance(module); const exports = instance.exports;
new file mode 100644 --- /dev/null +++ b/testing/web-platform/tests/wasm/jsapi/instanceTestFactory.js @@ -0,0 +1,229 @@ +const instanceTestFactory = [ + [ + "Empty module without imports argument", + function() { + return { + buffer: emptyModuleBinary, + args: [], + exports: {}, + verify: () => {}, + }; + } + ], + + [ + "Empty module with undefined imports argument", + function() { + return { + buffer: emptyModuleBinary, + args: [undefined], + exports: {}, + verify: () => {}, + }; + } + ], + + [ + "Empty module with empty imports argument", + function() { + return { + buffer: emptyModuleBinary, + args: [{}], + exports: {}, + verify: () => {}, + }; + } + ], + + [ + "getter order for imports object", + function() { + const builder = new WasmModuleBuilder(); + builder.addImportedGlobal("module", "global1", kWasmI32); + builder.addImportedGlobal("module2", "global3", kWasmI32); + builder.addImportedMemory("module", "memory", 0, 128); + builder.addImportedGlobal("module", "global2", kWasmI32); + const buffer = builder.toBuffer(); + const order = []; + + const imports = { + get module() { + order.push("module getter"); + return { + get global1() { + order.push("global1 getter"); + return 0; + }, + get global2() { + order.push("global2 getter"); + return 0; + }, + get memory() { + order.push("memory getter"); + return new WebAssembly.Memory({ "initial": 64, maximum: 128 }); + }, + } + }, + get module2() { + order.push("module2 getter"); + return { + get global3() { + order.push("global3 getter"); + return 0; + }, + } + }, + }; + + const expected = [ + "module getter", + "global1 getter", + "module2 getter", + "global3 getter", + "module getter", + "memory getter", + "module getter", + "global2 getter", + ]; + return { + buffer, + args: [imports], + exports: {}, + verify: () => assert_array_equals(order, expected), + }; + } + ], + + [ + "imports", + function() { + const builder = new WasmModuleBuilder(); + + builder.addImport("module", "fn", kSig_v_v); + builder.addImportedGlobal("module", "global", kWasmI32); + builder.addImportedMemory("module", "memory", 0, 128); + builder.addImportedTable("module", "table", 0, 128); + + const buffer = builder.toBuffer(); + const imports = { + "module": { + "fn": function() {}, + "global": 0, + "memory": new WebAssembly.Memory({ "initial": 64, maximum: 128 }), + "table": new WebAssembly.Table({ "element": "anyfunc", "initial": 64, maximum: 128 }), + }, + get "module2"() { + assert_unreached("Should not get modules that are not imported"); + }, + }; + + return { + buffer, + args: [imports], + exports: {}, + verify: () => {}, + }; + } + ], + + [ + "No imports", + function() { + const builder = new WasmModuleBuilder(); + + builder + .addFunction("fn", kSig_v_d) + .addBody([ + kExprEnd + ]) + .exportFunc(); + builder + .addFunction("fn2", kSig_v_v) + .addBody([ + kExprEnd + ]) + .exportFunc(); + + builder.setFunctionTableLength(1); + builder.addExportOfKind("table", kExternalTable, 0); + + builder.addGlobal(kWasmI32, true) + .exportAs("global") + .init = 7; + builder.addGlobal(kWasmF64, true) + .exportAs("global2") + .init = 1.2; + + builder.addMemory(4, 8, true); + + const buffer = builder.toBuffer(); + + const exports = { + "fn": { "kind": "function", "name": "0", "length": 1 }, + "fn2": { "kind": "function", "name": "1", "length": 0 }, + "table": { "kind": "table", "length": 1 }, + "global": { "kind": "global", "value": 7 }, + "global2": { "kind": "global", "value": 1.2 }, + "memory": { "kind": "memory", "size": 4 }, + }; + + return { + buffer, + args: [], + exports, + verify: () => {}, + }; + } + ], + + [ + "exports and imports", + function() { + const value = 102; + + const builder = new WasmModuleBuilder(); + + const index = builder.addImportedGlobal("module", "global", kWasmI32); + builder + .addFunction("fn", kSig_i_v) + .addBody([ + kExprGetGlobal, + index, + kExprReturn, + kExprEnd, + ]) + .exportFunc(); + + const buffer = builder.toBuffer(); + + const imports = { + "module": { + "global": value, + }, + }; + + const exports = { + "fn": { "kind": "function", "name": "0", "length": 0 }, + }; + + return { + buffer, + args: [imports], + exports, + verify: instance => assert_equals(instance.exports.fn(), value) + }; + } + ], + + [ + "stray argument", + function() { + return { + buffer: emptyModuleBinary, + args: [{}, {}], + exports: {}, + verify: () => {} + }; + } + ], +];
--- a/testing/web-platform/tests/wasm/jsapi/interface.any.js +++ b/testing/web-platform/tests/wasm/jsapi/interface.any.js @@ -4,17 +4,17 @@ function test_operations(object, object_name, operations) { for (const [name, length] of operations) { test(() => { const propdesc = Object.getOwnPropertyDescriptor(object, name); assert_equals(typeof propdesc, "object"); assert_true(propdesc.writable, "writable"); assert_true(propdesc.enumerable, "enumerable"); assert_true(propdesc.configurable, "configurable"); - assert_equals(propdesc.value, WebAssembly[name]); + assert_equals(propdesc.value, object[name]); }, `${object_name}.${name}`); test(() => { assert_function_name(object[name], name, `${object_name}.${name}`); }, `${object_name}.${name}: name`); test(() => { assert_function_length(object[name], length, `${object_name}.${name}`);
--- a/testing/web-platform/tests/wasm/jsapi/memory/buffer.any.js +++ b/testing/web-platform/tests/wasm/jsapi/memory/buffer.any.js @@ -24,16 +24,30 @@ test(() => { for (const thisValue of thisValues) { assert_throws(new TypeError(), () => getter.call(thisValue), `this=${format_value(thisValue)}`); } }, "Branding"); test(() => { const argument = { "initial": 0 }; const memory = new WebAssembly.Memory(argument); + const buffer = memory.buffer; + + const desc = Object.getOwnPropertyDescriptor(WebAssembly.Memory.prototype, "buffer"); + assert_equals(typeof desc, "object"); + + const getter = desc.get; + assert_equals(typeof getter, "function"); + + assert_equals(getter.call(memory, {}), buffer); +}, "Stray argument"); + +test(() => { + const argument = { "initial": 0 }; + const memory = new WebAssembly.Memory(argument); const memory2 = new WebAssembly.Memory(argument); const buffer = memory.buffer; assert_not_equals(buffer, memory2.buffer, "Need two distinct buffers"); memory.buffer = memory2.buffer; assert_equals(memory.buffer, buffer, "Should not change the buffer"); }, "Setting (sloppy mode)"); test(() => {
--- a/testing/web-platform/tests/wasm/jsapi/memory/constructor.any.js +++ b/testing/web-platform/tests/wasm/jsapi/memory/constructor.any.js @@ -75,16 +75,20 @@ for (const value of outOfRangeValues) { }, `Out-of-range initial value in descriptor: ${format_value(value)}`); test(() => { assert_throws(new TypeError(), () => new WebAssembly.Memory({ "initial": 0, "maximum": value })); }, `Out-of-range maximum value in descriptor: ${format_value(value)}`); } test(() => { + assert_throws(new RangeError(), () => new WebAssembly.Memory({ "element": "anyfunc", "initial": 10, "maximum": 9 })); +}, "Initial value exceeds maximum"); + +test(() => { const proxy = new Proxy({}, { has(o, x) { assert_unreached(`Should not call [[HasProperty]] with ${x}`); }, get(o, x) { return 0; }, }); @@ -130,8 +134,14 @@ test(() => { assert_Memory(memory, { "size": 0 }); }, "Zero initial"); test(() => { const argument = { "initial": 4 }; const memory = new WebAssembly.Memory(argument); assert_Memory(memory, { "size": 4 }); }, "Non-zero initial"); + +test(() => { + const argument = { "initial": 0 }; + const memory = new WebAssembly.Memory(argument, {}); + assert_Memory(memory, { "size": 0 }); +}, "Stray argument");
--- a/testing/web-platform/tests/wasm/jsapi/memory/grow.any.js +++ b/testing/web-platform/tests/wasm/jsapi/memory/grow.any.js @@ -163,8 +163,23 @@ const outOfRangeValues = [ for (const value of outOfRangeValues) { test(() => { const argument = { "initial": 0 }; const memory = new WebAssembly.Memory(argument); assert_throws(new TypeError(), () => memory.grow(value)); }, `Out-of-range argument: ${format_value(value)}`); } + +test(() => { + const argument = { "initial": 0 }; + const memory = new WebAssembly.Memory(argument); + const oldMemory = memory.buffer; + assert_ArrayBuffer(oldMemory, { "size": 0 }, "Buffer before growing"); + + const result = memory.grow(2, {}); + assert_equals(result, 0); + + const newMemory = memory.buffer; + assert_not_equals(oldMemory, newMemory); + assert_ArrayBuffer(oldMemory, { "detached": true }, "Old buffer after growing"); + assert_ArrayBuffer(newMemory, { "size": 2 }, "New buffer after growing"); +}, "Stray argument");
--- a/testing/web-platform/tests/wasm/jsapi/module/constructor.any.js +++ b/testing/web-platform/tests/wasm/jsapi/module/constructor.any.js @@ -53,8 +53,13 @@ test(() => { const module = new WebAssembly.Module(emptyModuleBinary); assert_equals(Object.getPrototypeOf(module), WebAssembly.Module.prototype); }, "Prototype"); test(() => { const module = new WebAssembly.Module(emptyModuleBinary); assert_true(Object.isExtensible(module)); }, "Extensibility"); + +test(() => { + const module = new WebAssembly.Module(emptyModuleBinary, {}); + assert_equals(Object.getPrototypeOf(module), WebAssembly.Module.prototype); +}, "Stray argument");
--- a/testing/web-platform/tests/wasm/jsapi/module/customSections.any.js +++ b/testing/web-platform/tests/wasm/jsapi/module/customSections.any.js @@ -155,8 +155,13 @@ test(() => { assert_sections(WebAssembly.Module.customSections(module, "name"), []); assert_sections(WebAssembly.Module.customSections(module, "na\uFFFDme"), [ bytes, ]); assert_sections(WebAssembly.Module.customSections(module, "na\uDC01me"), [ bytes, ]); }, "Custom sections with U+FFFD"); + +test(() => { + const module = new WebAssembly.Module(emptyModuleBinary); + assert_sections(WebAssembly.Module.customSections(module, "", {}), []); +}, "Stray argument");
--- a/testing/web-platform/tests/wasm/jsapi/module/exports.any.js +++ b/testing/web-platform/tests/wasm/jsapi/module/exports.any.js @@ -123,8 +123,14 @@ test(() => { { "kind": "function", "name": "fn2" }, { "kind": "table", "name": "table" }, { "kind": "global", "name": "global" }, { "kind": "global", "name": "global2" }, { "kind": "memory", "name": "memory" }, ]; assert_exports(exports, expected); }, "exports"); + +test(() => { + const module = new WebAssembly.Module(emptyModuleBinary); + const exports = WebAssembly.Module.exports(module, {}); + assert_exports(exports, []); +}, "Stray argument");
--- a/testing/web-platform/tests/wasm/jsapi/module/imports.any.js +++ b/testing/web-platform/tests/wasm/jsapi/module/imports.any.js @@ -113,8 +113,14 @@ test(() => { const expected = [ { "module": "module", "kind": "function", "name": "fn" }, { "module": "module", "kind": "global", "name": "global" }, { "module": "module", "kind": "memory", "name": "memory" }, { "module": "module", "kind": "table", "name": "table" }, ]; assert_imports(imports, expected); }, "imports"); + +test(() => { + const module = new WebAssembly.Module(emptyModuleBinary); + const imports = WebAssembly.Module.imports(module, {}); + assert_imports(imports, []); +}, "Stray argument");
--- a/testing/web-platform/tests/wasm/jsapi/table/assertions.js +++ b/testing/web-platform/tests/wasm/jsapi/table/assertions.js @@ -1,11 +1,13 @@ function assert_equal_to_array(table, expected, message) { assert_equals(table.length, expected.length, `${message}: length`); - assert_throws(new RangeError(), () => table.get(-1), `${message}: table.get(-1)`); + // The argument check in get() happens before the range check, and negative numbers + // are illegal, hence will throw TypeError per spec. + assert_throws(new TypeError(), () => table.get(-1), `${message}: table.get(-1)`); for (let i = 0; i < expected.length; ++i) { assert_equals(table.get(i), expected[i], `${message}: table.get(${i} of ${expected.length})`); } assert_throws(new RangeError(), () => table.get(expected.length), `${message}: table.get(${expected.length} of ${expected.length})`); assert_throws(new RangeError(), () => table.get(expected.length + 1), `${message}: table.get(${expected.length + 1} of ${expected.length})`); }
--- a/testing/web-platform/tests/wasm/jsapi/table/constructor.any.js +++ b/testing/web-platform/tests/wasm/jsapi/table/constructor.any.js @@ -92,16 +92,22 @@ test(() => { test(() => { const argument = { "element": "anyfunc", "initial": 5 }; const table = new WebAssembly.Table(argument); assert_Table(table, { "length": 5 }); }, "Basic (non-zero)"); test(() => { + const argument = { "element": "anyfunc", "initial": 0 }; + const table = new WebAssembly.Table(argument, {}); + assert_Table(table, { "length": 0 }); +}, "Stray argument"); + +test(() => { const proxy = new Proxy({}, { has(o, x) { assert_unreached(`Should not call [[HasProperty]] with ${x}`); }, get(o, x) { switch (x) { case "element": return "anyfunc";
--- a/testing/web-platform/tests/wasm/jsapi/table/get-set.any.js +++ b/testing/web-platform/tests/wasm/jsapi/table/get-set.any.js @@ -126,17 +126,19 @@ test(() => { test(() => { const argument = { "element": "anyfunc", "initial": 5 }; const table = new WebAssembly.Table(argument); assert_equal_to_array(table, [null, null, null, null, null]); const {fn} = functions; - assert_throws(new RangeError(), () => table.set(-1, fn)); + // -1 is the wrong type hence the type check on entry gets this + // before the range check does. + assert_throws(new TypeError(), () => table.set(-1, fn)); assert_throws(new RangeError(), () => table.set(5, fn)); assert_equal_to_array(table, [null, null, null, null, null]); }, "Setting out-of-bounds"); test(() => { const argument = { "element": "anyfunc", "initial": 1 }; const table = new WebAssembly.Table(argument); assert_equal_to_array(table, [null]); @@ -213,8 +215,16 @@ test(() => { called++; return 0; }, }; assert_throws(new TypeError(), () => table.set(value, {})); assert_equals(called, 1); }, "Order of argument conversion"); +test(() => { + const {fn} = functions; + const argument = { "element": "anyfunc", "initial": 1 }; + const table = new WebAssembly.Table(argument); + + assert_equals(table.get(0, {}), null); + assert_equals(table.set(0, fn, {}), undefined); +}, "Stray argument");
--- a/testing/web-platform/tests/wasm/jsapi/table/grow.any.js +++ b/testing/web-platform/tests/wasm/jsapi/table/grow.any.js @@ -79,8 +79,18 @@ const outOfRangeValues = [ for (const value of outOfRangeValues) { test(() => { const argument = { "element": "anyfunc", "initial": 1 }; const table = new WebAssembly.Table(argument); assert_throws(new TypeError(), () => table.grow(value)); }, `Out-of-range argument: ${format_value(value)}`); } + +test(() => { + const argument = { "element": "anyfunc", "initial": 5 }; + const table = new WebAssembly.Table(argument); + assert_equal_to_array(table, nulls(5), "before"); + + const result = table.grow(3, {}); + assert_equals(result, 5); + assert_equal_to_array(table, nulls(8), "after"); +}, "Stray argument");
--- a/testing/web-platform/tests/wasm/jsapi/table/length.any.js +++ b/testing/web-platform/tests/wasm/jsapi/table/length.any.js @@ -25,16 +25,30 @@ test(() => { assert_throws(new TypeError(), () => getter.call(thisValue), `this=${format_value(thisValue)}`); } }, "Branding"); test(() => { const argument = { "element": "anyfunc", "initial": 2 }; const table = new WebAssembly.Table(argument); assert_equals(table.length, 2, "Initial length"); + + const desc = Object.getOwnPropertyDescriptor(WebAssembly.Table.prototype, "length"); + assert_equals(typeof desc, "object"); + + const getter = desc.get; + assert_equals(typeof getter, "function"); + + assert_equals(getter.call(table, {}), 2); +}, "Stray argument"); + +test(() => { + const argument = { "element": "anyfunc", "initial": 2 }; + const table = new WebAssembly.Table(argument); + assert_equals(table.length, 2, "Initial length"); table.length = 4; assert_equals(table.length, 2, "Should not change the length"); }, "Setting (sloppy mode)"); test(() => { const argument = { "element": "anyfunc", "initial": 2 }; const table = new WebAssembly.Table(argument); assert_equals(table.length, 2, "Initial length");
deleted file mode 100644 --- a/testing/webdriver/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -/target -/Cargo.lock -*~ -*.swp -*.swo
deleted file mode 100644 --- a/testing/webdriver/.hgignore +++ /dev/null @@ -1,2 +0,0 @@ -target/ -Cargo.lock
deleted file mode 100644 --- a/testing/webdriver/.travis.yml +++ /dev/null @@ -1,9 +0,0 @@ -language: rust - -rust: - - nightly - - stable - -script: - - cargo build --verbose - - cargo test --verbose \ No newline at end of file
--- a/toolkit/components/telemetry/app/TelemetryReportingPolicy.jsm +++ b/toolkit/components/telemetry/app/TelemetryReportingPolicy.jsm @@ -426,21 +426,18 @@ var TelemetryReportingPolicyImpl = { } let firstRunPolicyURL = Services.prefs.getStringPref(TelemetryUtils.Preferences.FirstRunURL, ""); if (!firstRunPolicyURL) { return false; } firstRunPolicyURL = Services.urlFormatter.formatURL(firstRunPolicyURL); - let win; - try { - const { BrowserWindowTracker } = ChromeUtils.import("resource:///modules/BrowserWindowTracker.jsm", {}); - win = BrowserWindowTracker.getTopWindow(); - } catch (e) {} + const { BrowserWindowTracker } = ChromeUtils.import("resource:///modules/BrowserWindowTracker.jsm", {}); + let win = BrowserWindowTracker.getTopWindow(); if (!win) { this._log.info("Couldn't find browser window to open first-run page. Falling back to infobar."); return false; } // We'll consider the user notified once the privacy policy has been loaded // in a background tab even if that tab hasn't been selected.