Bug Summary

File:var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h
Warning:line 578, column 17
Value stored to 'what' during its initialization is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name Unified_cpp_js_src_jit11.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/js/src/jit -fcoverage-compilation-dir=/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/js/src/jit -resource-dir /usr/lib/llvm-20/lib/clang/20 -include /var/lib/jenkins/workspace/firefox-scan-build/config/gcc_hidden.h -include /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D _GLIBCXX_ASSERTIONS -D DEBUG=1 -D WASM_SUPPORTS_HUGE_MEMORY -D JS_CACHEIR_SPEW -D JS_STRUCTURED_SPEW -D JS_HAS_CTYPES -D FFI_BUILDING -D EXPORT_JS_API -D MOZ_HAS_MOZGLUE -D MOZ_SUPPORT_LEAKCHECKING -I /var/lib/jenkins/workspace/firefox-scan-build/js/src/jit -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/js/src/jit -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/js/src -I /var/lib/jenkins/workspace/firefox-scan-build/js/src -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/x86_64-linux-gnu/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/backward -internal-isystem /usr/lib/llvm-20/lib/clang/20/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O3 -Wno-error=tautological-type-limit-compare -Wno-invalid-offsetof -Wno-range-loop-analysis -Wno-deprecated-anon-enum-enum-conversion -Wno-deprecated-enum-enum-conversion -Wno-deprecated-this-capture -Wno-inline-new-delete -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-vla-cxx-extension -Wno-unknown-warning-option -fdeprecated-macro -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fno-sized-deallocation -fno-aligned-allocation -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2025-01-20-090804-167946-1 -x c++ Unified_cpp_js_src_jit11.cpp
1/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7/*
8 * Everything needed to build actual MIR instructions: the actual opcodes and
9 * instructions, the instruction interface, and use chains.
10 */
11
12#ifndef jit_MIR_wasm_h
13#define jit_MIR_wasm_h
14
15#include "mozilla/Array.h"
16#include "mozilla/HashFunctions.h"
17#ifdef JS_JITSPEW1
18# include "mozilla/Sprintf.h"
19# include "mozilla/Vector.h"
20#endif
21
22#include <algorithm>
23#include <initializer_list>
24
25#include "jit/MIR.h"
26
27namespace js {
28
29class WasmInstanceObject;
30
31namespace wasm {
32class FuncExport;
33extern uint32_t MIRTypeToABIResultSize(jit::MIRType);
34} // namespace wasm
35
36namespace jit {
37
38class MWasmNullConstant : public MNullaryInstruction {
39 explicit MWasmNullConstant() : MNullaryInstruction(classOpcode) {
40 setResultType(MIRType::WasmAnyRef);
41 setMovable();
42 }
43
44 public:
45 INSTRUCTION_HEADER(WasmNullConstant)
46 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
47
48 HashNumber valueHash() const override;
49 bool congruentTo(const MDefinition* ins) const override {
50 return ins->isWasmNullConstant();
51 }
52 AliasSet getAliasSet() const override { return AliasSet::None(); }
53
54 ALLOW_CLONE(MWasmNullConstant)bool canClone() const override { return true; } MInstruction*
clone(TempAllocator& alloc, const MDefinitionVector&
inputs) const override { MInstruction* res = new (alloc) MWasmNullConstant
(*this); for (size_t i = 0; i < numOperands(); i++) res->
replaceOperand(i, inputs[i]); return res; }
55};
56
57// Floating-point value as created by wasm. Just a constant value, used to
58// effectively inhibit all the MIR optimizations. This uses the same LIR nodes
59// as a MConstant of the same type would.
60class MWasmFloatConstant : public MNullaryInstruction {
61 union {
62 float f32_;
63 double f64_;
64#ifdef ENABLE_WASM_SIMD1
65 int8_t s128_[16];
66 uint64_t bits_[2];
67#else
68 uint64_t bits_[1];
69#endif
70 } u;
71
72 explicit MWasmFloatConstant(MIRType type) : MNullaryInstruction(classOpcode) {
73 u.bits_[0] = 0;
74#ifdef ENABLE_WASM_SIMD1
75 u.bits_[1] = 0;
76#endif
77 setResultType(type);
78 }
79
80 public:
81 INSTRUCTION_HEADER(WasmFloatConstant)
82
83 static MWasmFloatConstant* NewDouble(TempAllocator& alloc, double d) {
84 auto* ret = new (alloc) MWasmFloatConstant(MIRType::Double);
85 ret->u.f64_ = d;
86 return ret;
87 }
88
89 static MWasmFloatConstant* NewFloat32(TempAllocator& alloc, float f) {
90 auto* ret = new (alloc) MWasmFloatConstant(MIRType::Float32);
91 ret->u.f32_ = f;
92 return ret;
93 }
94
95#ifdef ENABLE_WASM_SIMD1
96 static MWasmFloatConstant* NewSimd128(TempAllocator& alloc,
97 const SimdConstant& s) {
98 auto* ret = new (alloc) MWasmFloatConstant(MIRType::Simd128);
99 memcpy(ret->u.s128_, s.bytes(), 16);
100 return ret;
101 }
102#endif
103
104 HashNumber valueHash() const override;
105 bool congruentTo(const MDefinition* ins) const override;
106 AliasSet getAliasSet() const override { return AliasSet::None(); }
107
108 const double& toDouble() const {
109 MOZ_ASSERT(type() == MIRType::Double)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(type() == MIRType::Double)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(type() == MIRType::Double)))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("type() == MIRType::Double"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 109); AnnotateMozCrashReason("MOZ_ASSERT" "(" "type() == MIRType::Double"
")"); do { *((volatile int*)__null) = 109; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
110 return u.f64_;
111 }
112 const float& toFloat32() const {
113 MOZ_ASSERT(type() == MIRType::Float32)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(type() == MIRType::Float32)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(type() == MIRType::Float32))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("type() == MIRType::Float32"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 113); AnnotateMozCrashReason("MOZ_ASSERT" "(" "type() == MIRType::Float32"
")"); do { *((volatile int*)__null) = 113; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
114 return u.f32_;
115 }
116#ifdef ENABLE_WASM_SIMD1
117 const SimdConstant toSimd128() const {
118 MOZ_ASSERT(type() == MIRType::Simd128)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(type() == MIRType::Simd128)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(type() == MIRType::Simd128))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("type() == MIRType::Simd128"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 118); AnnotateMozCrashReason("MOZ_ASSERT" "(" "type() == MIRType::Simd128"
")"); do { *((volatile int*)__null) = 118; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
119 return SimdConstant::CreateX16(u.s128_);
120 }
121#endif
122#ifdef JS_JITSPEW1
123 void getExtras(ExtrasCollector* extras) const override {
124 char buf[64];
125 switch (type()) {
126 case MIRType::Float32:
127 SprintfLiteral(buf, "f32{%e}", (double)u.f32_);
128 break;
129 case MIRType::Double:
130 SprintfLiteral(buf, "f64{%e}", u.f64_);
131 break;
132# ifdef ENABLE_WASM_SIMD1
133 case MIRType::Simd128:
134 SprintfLiteral(buf, "v128{[1]=%016llx:[0]=%016llx}",
135 (unsigned long long int)u.bits_[1],
136 (unsigned long long int)u.bits_[0]);
137 break;
138# endif
139 default:
140 SprintfLiteral(buf, "!!getExtras: missing case!!");
141 break;
142 }
143 extras->add(buf);
144 }
145#endif
146};
147
148// Converts a uint32 to a float32 (coming from wasm).
149class MWasmUnsignedToFloat32 : public MUnaryInstruction,
150 public NoTypePolicy::Data {
151 explicit MWasmUnsignedToFloat32(MDefinition* def)
152 : MUnaryInstruction(classOpcode, def) {
153 setResultType(MIRType::Float32);
154 setMovable();
155 }
156
157 public:
158 INSTRUCTION_HEADER(WasmUnsignedToFloat32)
159 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
160
161 MDefinition* foldsTo(TempAllocator& alloc) override;
162 bool congruentTo(const MDefinition* ins) const override {
163 return congruentIfOperandsEqual(ins);
164 }
165 AliasSet getAliasSet() const override { return AliasSet::None(); }
166
167 bool canProduceFloat32() const override { return true; }
168};
169
170// The same as MWasmTruncateToInt64 but with the Instance dependency.
171// It used only for arm now because on arm we need to call builtin to truncate
172// to i64.
173class MWasmBuiltinTruncateToInt64 : public MAryInstruction<2>,
174 public NoTypePolicy::Data {
175 TruncFlags flags_;
176 wasm::TrapSiteDesc trapSiteDesc_;
177
178 MWasmBuiltinTruncateToInt64(MDefinition* def, MDefinition* instance,
179 TruncFlags flags,
180 const wasm::TrapSiteDesc& trapSiteDesc)
181 : MAryInstruction(classOpcode),
182 flags_(flags),
183 trapSiteDesc_(trapSiteDesc) {
184 initOperand(0, def);
185 initOperand(1, instance);
186
187 setResultType(MIRType::Int64);
188 setGuard(); // neither removable nor movable because of possible
189 // side-effects.
190 }
191
192 public:
193 INSTRUCTION_HEADER(WasmBuiltinTruncateToInt64)
194 NAMED_OPERANDS((0, input), (1, instance))MDefinition* input() const { return getOperand(0); } MDefinition
* instance() const { return getOperand(1); }
;
195 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
196
197 bool isUnsigned() const { return flags_ & TRUNC_UNSIGNED; }
198 bool isSaturating() const { return flags_ & TRUNC_SATURATING; }
199 TruncFlags flags() const { return flags_; }
200 const wasm::TrapSiteDesc& trapSiteDesc() const { return trapSiteDesc_; }
201
202 bool congruentTo(const MDefinition* ins) const override {
203 return congruentIfOperandsEqual(ins) &&
204 ins->toWasmBuiltinTruncateToInt64()->flags() == flags_;
205 }
206 AliasSet getAliasSet() const override { return AliasSet::None(); }
207};
208
209class MWasmTruncateToInt64 : public MUnaryInstruction,
210 public NoTypePolicy::Data {
211 TruncFlags flags_;
212 wasm::TrapSiteDesc trapSiteDesc_;
213
214 MWasmTruncateToInt64(MDefinition* def, TruncFlags flags,
215 const wasm::TrapSiteDesc& trapSiteDesc)
216 : MUnaryInstruction(classOpcode, def),
217 flags_(flags),
218 trapSiteDesc_(trapSiteDesc) {
219 setResultType(MIRType::Int64);
220 setGuard(); // neither removable nor movable because of possible
221 // side-effects.
222 }
223
224 public:
225 INSTRUCTION_HEADER(WasmTruncateToInt64)
226 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
227
228 bool isUnsigned() const { return flags_ & TRUNC_UNSIGNED; }
229 bool isSaturating() const { return flags_ & TRUNC_SATURATING; }
230 TruncFlags flags() const { return flags_; }
231 const wasm::TrapSiteDesc& trapSiteDesc() const { return trapSiteDesc_; }
232
233 bool congruentTo(const MDefinition* ins) const override {
234 return congruentIfOperandsEqual(ins) &&
235 ins->toWasmTruncateToInt64()->flags() == flags_;
236 }
237 AliasSet getAliasSet() const override { return AliasSet::None(); }
238};
239
240// Truncate a value to an int32, with wasm semantics: this will trap when the
241// value is out of range.
242class MWasmTruncateToInt32 : public MUnaryInstruction,
243 public NoTypePolicy::Data {
244 TruncFlags flags_;
245 wasm::TrapSiteDesc trapSiteDesc_;
246
247 explicit MWasmTruncateToInt32(MDefinition* def, TruncFlags flags,
248 const wasm::TrapSiteDesc& trapSiteDesc)
249 : MUnaryInstruction(classOpcode, def),
250 flags_(flags),
251 trapSiteDesc_(trapSiteDesc) {
252 setResultType(MIRType::Int32);
253 setGuard(); // neither removable nor movable because of possible
254 // side-effects.
255 }
256
257 public:
258 INSTRUCTION_HEADER(WasmTruncateToInt32)
259 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
260
261 bool isUnsigned() const { return flags_ & TRUNC_UNSIGNED; }
262 bool isSaturating() const { return flags_ & TRUNC_SATURATING; }
263 TruncFlags flags() const { return flags_; }
264 const wasm::TrapSiteDesc& trapSiteDesc() const { return trapSiteDesc_; }
265
266 MDefinition* foldsTo(TempAllocator& alloc) override;
267
268 bool congruentTo(const MDefinition* ins) const override {
269 return congruentIfOperandsEqual(ins) &&
270 ins->toWasmTruncateToInt32()->flags() == flags_;
271 }
272
273 AliasSet getAliasSet() const override { return AliasSet::None(); }
274};
275
276// It is like MTruncateToInt32 but with instance dependency.
277class MWasmBuiltinTruncateToInt32 : public MAryInstruction<2>,
278 public ToInt32Policy::Data {
279 wasm::TrapSiteDesc trapSiteDesc_;
280
281 MWasmBuiltinTruncateToInt32(
282 MDefinition* def, MDefinition* instance,
283 wasm::TrapSiteDesc trapSiteDesc = wasm::TrapSiteDesc())
284 : MAryInstruction(classOpcode), trapSiteDesc_(trapSiteDesc) {
285 initOperand(0, def);
286 initOperand(1, instance);
287 setResultType(MIRType::Int32);
288 setMovable();
289
290 // Guard unless the conversion is known to be non-effectful & non-throwing.
291 if (MTruncateToInt32::mightHaveSideEffects(def)) {
292 setGuard();
293 }
294 }
295
296 public:
297 INSTRUCTION_HEADER(WasmBuiltinTruncateToInt32)
298 NAMED_OPERANDS((0, input), (1, instance))MDefinition* input() const { return getOperand(0); } MDefinition
* instance() const { return getOperand(1); }
299 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
300
301 bool congruentTo(const MDefinition* ins) const override {
302 return congruentIfOperandsEqual(ins);
303 }
304 AliasSet getAliasSet() const override { return AliasSet::None(); }
305
306 const wasm::TrapSiteDesc& trapSiteDesc() const { return trapSiteDesc_; }
307
308 ALLOW_CLONE(MWasmBuiltinTruncateToInt32)bool canClone() const override { return true; } MInstruction*
clone(TempAllocator& alloc, const MDefinitionVector&
inputs) const override { MInstruction* res = new (alloc) MWasmBuiltinTruncateToInt32
(*this); for (size_t i = 0; i < numOperands(); i++) res->
replaceOperand(i, inputs[i]); return res; }
309};
310
311class MWasmBuiltinDivI64 : public MAryInstruction<3>, public ArithPolicy::Data {
312 bool canBeNegativeZero_;
313 bool canBeNegativeOverflow_;
314 bool canBeDivideByZero_;
315 bool canBeNegativeDividend_;
316 bool unsigned_; // If false, signedness will be derived from operands
317 bool trapOnError_;
318 wasm::TrapSiteDesc trapSiteDesc_;
319
320 MWasmBuiltinDivI64(MDefinition* left, MDefinition* right,
321 MDefinition* instance)
322 : MAryInstruction(classOpcode),
323 canBeNegativeZero_(true),
324 canBeNegativeOverflow_(true),
325 canBeDivideByZero_(true),
326 canBeNegativeDividend_(true),
327 unsigned_(false),
328 trapOnError_(false) {
329 initOperand(0, left);
330 initOperand(1, right);
331 initOperand(2, instance);
332
333 setResultType(MIRType::Int64);
334 setMovable();
335 }
336
337 public:
338 INSTRUCTION_HEADER(WasmBuiltinDivI64)
339
340 NAMED_OPERANDS((0, lhs), (1, rhs), (2, instance))MDefinition* lhs() const { return getOperand(0); } MDefinition
* rhs() const { return getOperand(1); } MDefinition* instance
() const { return getOperand(2); }
341
342 static MWasmBuiltinDivI64* New(
343 TempAllocator& alloc, MDefinition* left, MDefinition* right,
344 MDefinition* instance, bool unsignd, bool trapOnError = false,
345 wasm::TrapSiteDesc trapSiteDesc = wasm::TrapSiteDesc()) {
346 auto* wasm64Div = new (alloc) MWasmBuiltinDivI64(left, right, instance);
347 wasm64Div->unsigned_ = unsignd;
348 wasm64Div->trapOnError_ = trapOnError;
349 wasm64Div->trapSiteDesc_ = trapSiteDesc;
350 if (trapOnError) {
351 wasm64Div->setGuard(); // not removable because of possible side-effects.
352 wasm64Div->setNotMovable();
353 }
354 return wasm64Div;
355 }
356
357 bool canBeNegativeZero() const { return canBeNegativeZero_; }
358 void setCanBeNegativeZero(bool negativeZero) {
359 canBeNegativeZero_ = negativeZero;
360 }
361
362 bool canBeNegativeOverflow() const { return canBeNegativeOverflow_; }
363
364 bool canBeDivideByZero() const { return canBeDivideByZero_; }
365
366 bool canBeNegativeDividend() const {
367 // "Dividend" is an ambiguous concept for unsigned truncated
368 // division, because of the truncation procedure:
369 // ((x>>>0)/2)|0, for example, gets transformed in
370 // MWasmDiv::truncate into a node with lhs representing x (not
371 // x>>>0) and rhs representing the constant 2; in other words,
372 // the MIR node corresponds to "cast operands to unsigned and
373 // divide" operation. In this case, is the dividend x or is it
374 // x>>>0? In order to resolve such ambiguities, we disallow
375 // the usage of this method for unsigned division.
376 MOZ_ASSERT(!unsigned_)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!unsigned_)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!unsigned_))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("!unsigned_", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 376); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!unsigned_" ")"
); do { *((volatile int*)__null) = 376; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
377 return canBeNegativeDividend_;
378 }
379
380 bool isUnsigned() const { return unsigned_; }
381
382 bool trapOnError() const { return trapOnError_; }
383 const wasm::TrapSiteDesc& trapSiteDesc() const {
384 MOZ_ASSERT(trapSiteDesc_.isValid())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(trapSiteDesc_.isValid())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(trapSiteDesc_.isValid()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("trapSiteDesc_.isValid()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 384); AnnotateMozCrashReason("MOZ_ASSERT" "(" "trapSiteDesc_.isValid()"
")"); do { *((volatile int*)__null) = 384; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
385 return trapSiteDesc_;
386 }
387
388 ALLOW_CLONE(MWasmBuiltinDivI64)bool canClone() const override { return true; } MInstruction*
clone(TempAllocator& alloc, const MDefinitionVector&
inputs) const override { MInstruction* res = new (alloc) MWasmBuiltinDivI64
(*this); for (size_t i = 0; i < numOperands(); i++) res->
replaceOperand(i, inputs[i]); return res; }
389};
390
391class MWasmBuiltinModD : public MAryInstruction<3>, public ArithPolicy::Data {
392 wasm::BytecodeOffset bytecodeOffset_;
393
394 MWasmBuiltinModD(MDefinition* left, MDefinition* right, MDefinition* instance,
395 MIRType type)
396 : MAryInstruction(classOpcode) {
397 initOperand(0, left);
398 initOperand(1, right);
399 initOperand(2, instance);
400
401 setResultType(type);
402 setMovable();
403 }
404
405 public:
406 INSTRUCTION_HEADER(WasmBuiltinModD)
407 NAMED_OPERANDS((0, lhs), (1, rhs), (2, instance))MDefinition* lhs() const { return getOperand(0); } MDefinition
* rhs() const { return getOperand(1); } MDefinition* instance
() const { return getOperand(2); }
408
409 static MWasmBuiltinModD* New(
410 TempAllocator& alloc, MDefinition* left, MDefinition* right,
411 MDefinition* instance, MIRType type,
412 wasm::BytecodeOffset bytecodeOffset = wasm::BytecodeOffset()) {
413 auto* wasmBuiltinModD =
414 new (alloc) MWasmBuiltinModD(left, right, instance, type);
415 wasmBuiltinModD->bytecodeOffset_ = bytecodeOffset;
416 return wasmBuiltinModD;
417 }
418
419 wasm::BytecodeOffset bytecodeOffset() const {
420 MOZ_ASSERT(bytecodeOffset_.isValid())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(bytecodeOffset_.isValid())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(bytecodeOffset_.isValid())))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("bytecodeOffset_.isValid()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 420); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bytecodeOffset_.isValid()"
")"); do { *((volatile int*)__null) = 420; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
421 return bytecodeOffset_;
422 }
423
424 ALLOW_CLONE(MWasmBuiltinModD)bool canClone() const override { return true; } MInstruction*
clone(TempAllocator& alloc, const MDefinitionVector&
inputs) const override { MInstruction* res = new (alloc) MWasmBuiltinModD
(*this); for (size_t i = 0; i < numOperands(); i++) res->
replaceOperand(i, inputs[i]); return res; }
425};
426
427class MWasmBuiltinModI64 : public MAryInstruction<3>, public ArithPolicy::Data {
428 bool unsigned_; // If false, signedness will be derived from operands
429 bool canBeNegativeDividend_;
430 bool canBeDivideByZero_;
431 bool trapOnError_;
432 wasm::TrapSiteDesc trapSiteDesc_;
433
434 MWasmBuiltinModI64(MDefinition* left, MDefinition* right,
435 MDefinition* instance)
436 : MAryInstruction(classOpcode),
437 unsigned_(false),
438 canBeNegativeDividend_(true),
439 canBeDivideByZero_(true),
440 trapOnError_(false) {
441 initOperand(0, left);
442 initOperand(1, right);
443 initOperand(2, instance);
444
445 setResultType(MIRType::Int64);
446 setMovable();
447 }
448
449 public:
450 INSTRUCTION_HEADER(WasmBuiltinModI64)
451
452 NAMED_OPERANDS((0, lhs), (1, rhs), (2, instance))MDefinition* lhs() const { return getOperand(0); } MDefinition
* rhs() const { return getOperand(1); } MDefinition* instance
() const { return getOperand(2); }
453
454 static MWasmBuiltinModI64* New(
455 TempAllocator& alloc, MDefinition* left, MDefinition* right,
456 MDefinition* instance, bool unsignd, bool trapOnError = false,
457 wasm::TrapSiteDesc trapSiteDesc = wasm::TrapSiteDesc()) {
458 auto* mod = new (alloc) MWasmBuiltinModI64(left, right, instance);
459 mod->unsigned_ = unsignd;
460 mod->trapOnError_ = trapOnError;
461 mod->trapSiteDesc_ = trapSiteDesc;
462 if (trapOnError) {
463 mod->setGuard(); // not removable because of possible side-effects.
464 mod->setNotMovable();
465 }
466 return mod;
467 }
468
469 bool canBeNegativeDividend() const {
470 MOZ_ASSERT(!unsigned_)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!unsigned_)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!unsigned_))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("!unsigned_", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 470); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!unsigned_" ")"
); do { *((volatile int*)__null) = 470; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
471 return canBeNegativeDividend_;
472 }
473
474 bool canBeDivideByZero() const { return canBeDivideByZero_; }
475
476 bool isUnsigned() const { return unsigned_; }
477
478 bool trapOnError() const { return trapOnError_; }
479 const wasm::TrapSiteDesc& trapSiteDesc() const {
480 MOZ_ASSERT(trapSiteDesc_.isValid())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(trapSiteDesc_.isValid())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(trapSiteDesc_.isValid()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("trapSiteDesc_.isValid()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 480); AnnotateMozCrashReason("MOZ_ASSERT" "(" "trapSiteDesc_.isValid()"
")"); do { *((volatile int*)__null) = 480; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
481 return trapSiteDesc_;
482 }
483
484 ALLOW_CLONE(MWasmBuiltinModI64)bool canClone() const override { return true; } MInstruction*
clone(TempAllocator& alloc, const MDefinitionVector&
inputs) const override { MInstruction* res = new (alloc) MWasmBuiltinModI64
(*this); for (size_t i = 0; i < numOperands(); i++) res->
replaceOperand(i, inputs[i]); return res; }
485};
486
487// Check whether we need to fire the interrupt handler (in wasm code).
488class MWasmInterruptCheck : public MUnaryInstruction,
489 public NoTypePolicy::Data {
490 wasm::TrapSiteDesc trapSiteDesc_;
491
492 MWasmInterruptCheck(MDefinition* instance,
493 const wasm::TrapSiteDesc& trapSiteDesc)
494 : MUnaryInstruction(classOpcode, instance), trapSiteDesc_(trapSiteDesc) {
495 setGuard();
496 }
497
498 public:
499 INSTRUCTION_HEADER(WasmInterruptCheck)
500 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
501 NAMED_OPERANDS((0, instance))MDefinition* instance() const { return getOperand(0); }
502
503 AliasSet getAliasSet() const override { return AliasSet::None(); }
504 const wasm::TrapSiteDesc& trapSiteDesc() const { return trapSiteDesc_; }
505};
506
507// Directly jumps to the indicated trap, leaving Wasm code and reporting a
508// runtime error.
509
510class MWasmTrap : public MAryControlInstruction<0, 0>,
511 public NoTypePolicy::Data {
512 wasm::Trap trap_;
513 wasm::TrapSiteDesc trapSiteDesc_;
514
515 explicit MWasmTrap(wasm::Trap trap, const wasm::TrapSiteDesc& trapSiteDesc)
516 : MAryControlInstruction(classOpcode),
517 trap_(trap),
518 trapSiteDesc_(trapSiteDesc) {}
519
520 public:
521 INSTRUCTION_HEADER(WasmTrap)
522 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
523
524 AliasSet getAliasSet() const override { return AliasSet::None(); }
525
526 wasm::Trap trap() const { return trap_; }
527 const wasm::TrapSiteDesc& trapSiteDesc() const { return trapSiteDesc_; }
528};
529
530// Flips the input's sign bit, independently of the rest of the number's
531// payload. Note this is different from multiplying by minus-one, which has
532// side-effects for e.g. NaNs.
533class MWasmNeg : public MUnaryInstruction, public NoTypePolicy::Data {
534 MWasmNeg(MDefinition* op, MIRType type) : MUnaryInstruction(classOpcode, op) {
535 setResultType(type);
536 setMovable();
537 }
538
539 public:
540 INSTRUCTION_HEADER(WasmNeg)
541 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
542};
543
544// Machine-level bitwise AND/OR/XOR, avoiding all JS-level complexity embodied
545// in MBinaryBitwiseInstruction.
546class MWasmBinaryBitwise : public MBinaryInstruction,
547 public NoTypePolicy::Data {
548 public:
549 enum class SubOpcode { And, Or, Xor };
550
551 protected:
552 MWasmBinaryBitwise(MDefinition* left, MDefinition* right, MIRType type,
553 SubOpcode subOpcode)
554 : MBinaryInstruction(classOpcode, left, right), subOpcode_(subOpcode) {
555 MOZ_ASSERT(type == MIRType::Int32 || type == MIRType::Int64)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(type == MIRType::Int32 || type == MIRType::Int64)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(type == MIRType::Int32 || type == MIRType::Int64))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("type == MIRType::Int32 || type == MIRType::Int64"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 555); AnnotateMozCrashReason("MOZ_ASSERT" "(" "type == MIRType::Int32 || type == MIRType::Int64"
")"); do { *((volatile int*)__null) = 555; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
556 setResultType(type);
557 setMovable();
558 setCommutative();
559 }
560
561 public:
562 INSTRUCTION_HEADER(WasmBinaryBitwise)
563 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
564
565 SubOpcode subOpcode() const { return subOpcode_; }
566 MDefinition* foldsTo(TempAllocator& alloc) override;
567
568 bool congruentTo(const MDefinition* ins) const override {
569 return ins->isWasmBinaryBitwise() &&
570 ins->toWasmBinaryBitwise()->subOpcode() == subOpcode() &&
571 binaryCongruentTo(ins);
572 }
573
574 AliasSet getAliasSet() const override { return AliasSet::None(); }
575
576#ifdef JS_JITSPEW1
577 void getExtras(ExtrasCollector* extras) const override {
578 const char* what = "!!unknown!!";
Value stored to 'what' during its initialization is never read
579 switch (subOpcode()) {
580 case SubOpcode::And:
581 what = "And";
582 break;
583 case SubOpcode::Or:
584 what = "Or";
585 break;
586 case SubOpcode::Xor:
587 what = "Xor";
588 break;
589 }
590 extras->add(what);
591 }
592#endif
593
594 private:
595 SubOpcode subOpcode_;
596
597 ALLOW_CLONE(MWasmBinaryBitwise)bool canClone() const override { return true; } MInstruction*
clone(TempAllocator& alloc, const MDefinitionVector&
inputs) const override { MInstruction* res = new (alloc) MWasmBinaryBitwise
(*this); for (size_t i = 0; i < numOperands(); i++) res->
replaceOperand(i, inputs[i]); return res; }
598};
599
600class MWasmLoadInstance : public MUnaryInstruction, public NoTypePolicy::Data {
601 uint32_t offset_;
602 AliasSet aliases_;
603
604 explicit MWasmLoadInstance(MDefinition* instance, uint32_t offset,
605 MIRType type, AliasSet aliases)
606 : MUnaryInstruction(classOpcode, instance),
607 offset_(offset),
608 aliases_(aliases) {
609 // Different instance data have different alias classes and only those
610 // classes are allowed.
611 MOZ_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases_.flags() == AliasSet::Load(AliasSet::WasmHeapMeta
).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmTableMeta
).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmPendingException
).flags() || aliases_.flags() == AliasSet::None().flags())>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(aliases_.flags() == AliasSet::Load(AliasSet::WasmHeapMeta
).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmTableMeta
).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmPendingException
).flags() || aliases_.flags() == AliasSet::None().flags()))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("aliases_.flags() == AliasSet::Load(AliasSet::WasmHeapMeta).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmTableMeta).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmPendingException).flags() || aliases_.flags() == AliasSet::None().flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 616); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases_.flags() == AliasSet::Load(AliasSet::WasmHeapMeta).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmTableMeta).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmPendingException).flags() || aliases_.flags() == AliasSet::None().flags()"
")"); do { *((volatile int*)__null) = 616; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
612 aliases_.flags() == AliasSet::Load(AliasSet::WasmHeapMeta).flags() ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases_.flags() == AliasSet::Load(AliasSet::WasmHeapMeta
).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmTableMeta
).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmPendingException
).flags() || aliases_.flags() == AliasSet::None().flags())>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(aliases_.flags() == AliasSet::Load(AliasSet::WasmHeapMeta
).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmTableMeta
).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmPendingException
).flags() || aliases_.flags() == AliasSet::None().flags()))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("aliases_.flags() == AliasSet::Load(AliasSet::WasmHeapMeta).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmTableMeta).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmPendingException).flags() || aliases_.flags() == AliasSet::None().flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 616); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases_.flags() == AliasSet::Load(AliasSet::WasmHeapMeta).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmTableMeta).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmPendingException).flags() || aliases_.flags() == AliasSet::None().flags()"
")"); do { *((volatile int*)__null) = 616; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
613 aliases_.flags() == AliasSet::Load(AliasSet::WasmTableMeta).flags() ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases_.flags() == AliasSet::Load(AliasSet::WasmHeapMeta
).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmTableMeta
).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmPendingException
).flags() || aliases_.flags() == AliasSet::None().flags())>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(aliases_.flags() == AliasSet::Load(AliasSet::WasmHeapMeta
).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmTableMeta
).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmPendingException
).flags() || aliases_.flags() == AliasSet::None().flags()))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("aliases_.flags() == AliasSet::Load(AliasSet::WasmHeapMeta).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmTableMeta).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmPendingException).flags() || aliases_.flags() == AliasSet::None().flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 616); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases_.flags() == AliasSet::Load(AliasSet::WasmHeapMeta).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmTableMeta).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmPendingException).flags() || aliases_.flags() == AliasSet::None().flags()"
")"); do { *((volatile int*)__null) = 616; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
614 aliases_.flags() ==do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases_.flags() == AliasSet::Load(AliasSet::WasmHeapMeta
).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmTableMeta
).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmPendingException
).flags() || aliases_.flags() == AliasSet::None().flags())>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(aliases_.flags() == AliasSet::Load(AliasSet::WasmHeapMeta
).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmTableMeta
).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmPendingException
).flags() || aliases_.flags() == AliasSet::None().flags()))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("aliases_.flags() == AliasSet::Load(AliasSet::WasmHeapMeta).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmTableMeta).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmPendingException).flags() || aliases_.flags() == AliasSet::None().flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 616); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases_.flags() == AliasSet::Load(AliasSet::WasmHeapMeta).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmTableMeta).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmPendingException).flags() || aliases_.flags() == AliasSet::None().flags()"
")"); do { *((volatile int*)__null) = 616; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
615 AliasSet::Load(AliasSet::WasmPendingException).flags() ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases_.flags() == AliasSet::Load(AliasSet::WasmHeapMeta
).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmTableMeta
).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmPendingException
).flags() || aliases_.flags() == AliasSet::None().flags())>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(aliases_.flags() == AliasSet::Load(AliasSet::WasmHeapMeta
).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmTableMeta
).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmPendingException
).flags() || aliases_.flags() == AliasSet::None().flags()))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("aliases_.flags() == AliasSet::Load(AliasSet::WasmHeapMeta).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmTableMeta).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmPendingException).flags() || aliases_.flags() == AliasSet::None().flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 616); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases_.flags() == AliasSet::Load(AliasSet::WasmHeapMeta).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmTableMeta).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmPendingException).flags() || aliases_.flags() == AliasSet::None().flags()"
")"); do { *((volatile int*)__null) = 616; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
616 aliases_.flags() == AliasSet::None().flags())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases_.flags() == AliasSet::Load(AliasSet::WasmHeapMeta
).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmTableMeta
).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmPendingException
).flags() || aliases_.flags() == AliasSet::None().flags())>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(aliases_.flags() == AliasSet::Load(AliasSet::WasmHeapMeta
).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmTableMeta
).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmPendingException
).flags() || aliases_.flags() == AliasSet::None().flags()))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("aliases_.flags() == AliasSet::Load(AliasSet::WasmHeapMeta).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmTableMeta).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmPendingException).flags() || aliases_.flags() == AliasSet::None().flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 616); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases_.flags() == AliasSet::Load(AliasSet::WasmHeapMeta).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmTableMeta).flags() || aliases_.flags() == AliasSet::Load(AliasSet::WasmPendingException).flags() || aliases_.flags() == AliasSet::None().flags()"
")"); do { *((volatile int*)__null) = 616; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
617
618 // The only types supported at the moment.
619 MOZ_ASSERT(type == MIRType::Pointer || type == MIRType::Int32 ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(type == MIRType::Pointer || type == MIRType::Int32 ||
type == MIRType::Int64 || type == MIRType::WasmAnyRef)>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(type == MIRType::Pointer || type == MIRType::Int32 ||
type == MIRType::Int64 || type == MIRType::WasmAnyRef))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("type == MIRType::Pointer || type == MIRType::Int32 || type == MIRType::Int64 || type == MIRType::WasmAnyRef"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 620); AnnotateMozCrashReason("MOZ_ASSERT" "(" "type == MIRType::Pointer || type == MIRType::Int32 || type == MIRType::Int64 || type == MIRType::WasmAnyRef"
")"); do { *((volatile int*)__null) = 620; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
620 type == MIRType::Int64 || type == MIRType::WasmAnyRef)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(type == MIRType::Pointer || type == MIRType::Int32 ||
type == MIRType::Int64 || type == MIRType::WasmAnyRef)>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(type == MIRType::Pointer || type == MIRType::Int32 ||
type == MIRType::Int64 || type == MIRType::WasmAnyRef))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("type == MIRType::Pointer || type == MIRType::Int32 || type == MIRType::Int64 || type == MIRType::WasmAnyRef"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 620); AnnotateMozCrashReason("MOZ_ASSERT" "(" "type == MIRType::Pointer || type == MIRType::Int32 || type == MIRType::Int64 || type == MIRType::WasmAnyRef"
")"); do { *((volatile int*)__null) = 620; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
621
622 setMovable();
623 setResultType(type);
624 }
625
626 public:
627 INSTRUCTION_HEADER(WasmLoadInstance)
628 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
629 NAMED_OPERANDS((0, instance))MDefinition* instance() const { return getOperand(0); }
630
631 uint32_t offset() const { return offset_; }
632
633 bool congruentTo(const MDefinition* ins) const override {
634 return op() == ins->op() &&
635 offset() == ins->toWasmLoadInstance()->offset() &&
636 type() == ins->type();
637 }
638
639 HashNumber valueHash() const override {
640 return addU32ToHash(HashNumber(op()), offset());
641 }
642
643 AliasSet getAliasSet() const override { return aliases_; }
644};
645
646class MWasmStoreInstance : public MBinaryInstruction,
647 public NoTypePolicy::Data {
648 uint32_t offset_;
649 AliasSet aliases_;
650
651 explicit MWasmStoreInstance(MDefinition* instance, MDefinition* value,
652 uint32_t offset, MIRType type, AliasSet aliases)
653 : MBinaryInstruction(classOpcode, instance, value),
654 offset_(offset),
655 aliases_(aliases) {
656 // Different instance data have different alias classes and only those
657 // classes are allowed.
658 MOZ_ASSERT(aliases_.flags() ==do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases_.flags() == AliasSet::Store(AliasSet::WasmPendingException
).flags())>::isValid, "invalid assertion condition"); if (
(__builtin_expect(!!(!(!!(aliases_.flags() == AliasSet::Store
(AliasSet::WasmPendingException).flags()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aliases_.flags() == AliasSet::Store(AliasSet::WasmPendingException).flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 659); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases_.flags() == AliasSet::Store(AliasSet::WasmPendingException).flags()"
")"); do { *((volatile int*)__null) = 659; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
659 AliasSet::Store(AliasSet::WasmPendingException).flags())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases_.flags() == AliasSet::Store(AliasSet::WasmPendingException
).flags())>::isValid, "invalid assertion condition"); if (
(__builtin_expect(!!(!(!!(aliases_.flags() == AliasSet::Store
(AliasSet::WasmPendingException).flags()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aliases_.flags() == AliasSet::Store(AliasSet::WasmPendingException).flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 659); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases_.flags() == AliasSet::Store(AliasSet::WasmPendingException).flags()"
")"); do { *((volatile int*)__null) = 659; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
660
661 // The only types supported at the moment.
662 MOZ_ASSERT(type == MIRType::Pointer || type == MIRType::Int32 ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(type == MIRType::Pointer || type == MIRType::Int32 ||
type == MIRType::Int64 || type == MIRType::WasmAnyRef)>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(type == MIRType::Pointer || type == MIRType::Int32 ||
type == MIRType::Int64 || type == MIRType::WasmAnyRef))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("type == MIRType::Pointer || type == MIRType::Int32 || type == MIRType::Int64 || type == MIRType::WasmAnyRef"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 663); AnnotateMozCrashReason("MOZ_ASSERT" "(" "type == MIRType::Pointer || type == MIRType::Int32 || type == MIRType::Int64 || type == MIRType::WasmAnyRef"
")"); do { *((volatile int*)__null) = 663; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
663 type == MIRType::Int64 || type == MIRType::WasmAnyRef)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(type == MIRType::Pointer || type == MIRType::Int32 ||
type == MIRType::Int64 || type == MIRType::WasmAnyRef)>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(type == MIRType::Pointer || type == MIRType::Int32 ||
type == MIRType::Int64 || type == MIRType::WasmAnyRef))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("type == MIRType::Pointer || type == MIRType::Int32 || type == MIRType::Int64 || type == MIRType::WasmAnyRef"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 663); AnnotateMozCrashReason("MOZ_ASSERT" "(" "type == MIRType::Pointer || type == MIRType::Int32 || type == MIRType::Int64 || type == MIRType::WasmAnyRef"
")"); do { *((volatile int*)__null) = 663; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
664 }
665
666 public:
667 INSTRUCTION_HEADER(WasmStoreInstance)
668 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
669 NAMED_OPERANDS((0, instance), (1, value))MDefinition* instance() const { return getOperand(0); } MDefinition
* value() const { return getOperand(1); }
670
671 uint32_t offset() const { return offset_; }
672
673 AliasSet getAliasSet() const override { return aliases_; }
674};
675
676class MWasmHeapReg : public MNullaryInstruction {
677 AliasSet aliases_;
678
679 explicit MWasmHeapReg(AliasSet aliases)
680 : MNullaryInstruction(classOpcode), aliases_(aliases) {
681 setMovable();
682 setResultType(MIRType::Pointer);
683 }
684
685 public:
686 INSTRUCTION_HEADER(WasmHeapReg)
687 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
688
689 bool congruentTo(const MDefinition* ins) const override {
690 return ins->isWasmHeapReg();
691 }
692
693 AliasSet getAliasSet() const override { return aliases_; }
694};
695
696// For memory32, bounds check nodes are of type Int32 on 32-bit systems for both
697// wasm and asm.js code, as well as on 64-bit systems for asm.js code and for
698// wasm code that is known to have a bounds check limit that fits into 32 bits.
699// They are of type Int64 only on 64-bit systems for wasm code with 4GB heaps.
700// There is no way for nodes of both types to be present in the same function.
701// Should this change, then BCE must be updated to take type into account.
702//
703// For memory64, bounds check nodes are always of type Int64.
704
705class MWasmBoundsCheck : public MBinaryInstruction, public NoTypePolicy::Data {
706 public:
707 enum Target {
708 // Linear memory at index zero, which is the only memory allowed so far.
709 Memory0,
710 // Everything else. Currently comprises tables, and arrays in the GC
711 // proposal.
712 Unknown
713 };
714
715 private:
716 wasm::TrapSiteDesc trapSiteDesc_;
717 Target target_;
718
719 explicit MWasmBoundsCheck(MDefinition* index, MDefinition* boundsCheckLimit,
720 const wasm::TrapSiteDesc& trapSiteDesc,
721 Target target)
722 : MBinaryInstruction(classOpcode, index, boundsCheckLimit),
723 trapSiteDesc_(trapSiteDesc),
724 target_(target) {
725 MOZ_ASSERT(index->type() == boundsCheckLimit->type())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(index->type() == boundsCheckLimit->type())>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(index->type() == boundsCheckLimit->type()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("index->type() == boundsCheckLimit->type()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 725); AnnotateMozCrashReason("MOZ_ASSERT" "(" "index->type() == boundsCheckLimit->type()"
")"); do { *((volatile int*)__null) = 725; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
726
727 // Bounds check is effectful: it throws for OOB.
728 setGuard();
729
730 if (JitOptions.spectreIndexMasking) {
731 setResultType(index->type());
732 }
733 }
734
735 public:
736 INSTRUCTION_HEADER(WasmBoundsCheck)
737 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
738 NAMED_OPERANDS((0, index), (1, boundsCheckLimit))MDefinition* index() const { return getOperand(0); } MDefinition
* boundsCheckLimit() const { return getOperand(1); }
739
740 AliasSet getAliasSet() const override { return AliasSet::None(); }
741
742 bool isMemory0() const { return target_ == MWasmBoundsCheck::Memory0; }
743
744 bool isRedundant() const { return !isGuard(); }
745
746 void setRedundant() { setNotGuard(); }
747
748 const wasm::TrapSiteDesc& trapSiteDesc() const { return trapSiteDesc_; }
749};
750
751class MWasmAddOffset : public MUnaryInstruction, public NoTypePolicy::Data {
752 uint64_t offset_;
753 wasm::TrapSiteDesc trapSiteDesc_;
754
755 MWasmAddOffset(MDefinition* base, uint64_t offset,
756 const wasm::TrapSiteDesc& trapSiteDesc)
757 : MUnaryInstruction(classOpcode, base),
758 offset_(offset),
759 trapSiteDesc_(trapSiteDesc) {
760 setGuard();
761 MOZ_ASSERT(base->type() == MIRType::Int32 ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(base->type() == MIRType::Int32 || base->type()
== MIRType::Int64)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(base->type() == MIRType::
Int32 || base->type() == MIRType::Int64))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("base->type() == MIRType::Int32 || base->type() == MIRType::Int64"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 762); AnnotateMozCrashReason("MOZ_ASSERT" "(" "base->type() == MIRType::Int32 || base->type() == MIRType::Int64"
")"); do { *((volatile int*)__null) = 762; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
762 base->type() == MIRType::Int64)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(base->type() == MIRType::Int32 || base->type()
== MIRType::Int64)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(base->type() == MIRType::
Int32 || base->type() == MIRType::Int64))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("base->type() == MIRType::Int32 || base->type() == MIRType::Int64"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 762); AnnotateMozCrashReason("MOZ_ASSERT" "(" "base->type() == MIRType::Int32 || base->type() == MIRType::Int64"
")"); do { *((volatile int*)__null) = 762; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
763 setResultType(base->type());
764 }
765
766 public:
767 INSTRUCTION_HEADER(WasmAddOffset)
768 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
769 NAMED_OPERANDS((0, base))MDefinition* base() const { return getOperand(0); }
770
771 MDefinition* foldsTo(TempAllocator& alloc) override;
772
773 AliasSet getAliasSet() const override { return AliasSet::None(); }
774
775 uint64_t offset() const { return offset_; }
776 const wasm::TrapSiteDesc& trapSiteDesc() const { return trapSiteDesc_; }
777};
778
779class MWasmAlignmentCheck : public MUnaryInstruction,
780 public NoTypePolicy::Data {
781 uint32_t byteSize_;
782 wasm::TrapSiteDesc trapSiteDesc_;
783
784 explicit MWasmAlignmentCheck(MDefinition* index, uint32_t byteSize,
785 const wasm::TrapSiteDesc& trapSiteDesc)
786 : MUnaryInstruction(classOpcode, index),
787 byteSize_(byteSize),
788 trapSiteDesc_(trapSiteDesc) {
789 MOZ_ASSERT(mozilla::IsPowerOfTwo(byteSize))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mozilla::IsPowerOfTwo(byteSize))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mozilla::IsPowerOfTwo(byteSize
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("mozilla::IsPowerOfTwo(byteSize)", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 789); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mozilla::IsPowerOfTwo(byteSize)"
")"); do { *((volatile int*)__null) = 789; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
790 // Alignment check is effectful: it throws for unaligned.
791 setGuard();
792 }
793
794 public:
795 INSTRUCTION_HEADER(WasmAlignmentCheck)
796 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
797 NAMED_OPERANDS((0, index))MDefinition* index() const { return getOperand(0); }
798
799 bool congruentTo(const MDefinition* ins) const override;
800
801 AliasSet getAliasSet() const override { return AliasSet::None(); }
802
803 uint32_t byteSize() const { return byteSize_; }
804
805 const wasm::TrapSiteDesc& trapSiteDesc() const { return trapSiteDesc_; }
806};
807
808class MWasmLoad
809 : public MVariadicInstruction, // memoryBase is nullptr on some platforms
810 public NoTypePolicy::Data {
811 wasm::MemoryAccessDesc access_;
812
813 explicit MWasmLoad(const wasm::MemoryAccessDesc& access, MIRType resultType)
814 : MVariadicInstruction(classOpcode), access_(access) {
815 setGuard();
816 setResultType(resultType);
817 }
818
819 public:
820 INSTRUCTION_HEADER(WasmLoad)
821 NAMED_OPERANDS((0, base), (1, memoryBase))MDefinition* base() const { return getOperand(0); } MDefinition
* memoryBase() const { return getOperand(1); }
;
822
823 static MWasmLoad* New(TempAllocator& alloc, MDefinition* memoryBase,
824 MDefinition* base, const wasm::MemoryAccessDesc& access,
825 MIRType resultType) {
826 MWasmLoad* load = new (alloc) MWasmLoad(access, resultType);
827 if (!load->init(alloc, 1 + !!memoryBase)) {
828 return nullptr;
829 }
830
831 load->initOperand(0, base);
832 if (memoryBase) {
833 load->initOperand(1, memoryBase);
834 }
835
836 return load;
837 }
838
839 const wasm::MemoryAccessDesc& access() const { return access_; }
840
841 AliasSet getAliasSet() const override {
842 // When a barrier is needed, make the instruction effectful by giving
843 // it a "store" effect.
844 if (access_.isAtomic()) {
845 return AliasSet::Store(AliasSet::WasmHeap);
846 }
847 return AliasSet::Load(AliasSet::WasmHeap);
848 }
849
850 bool hasMemoryBase() const { return numOperands() > 1; }
851
852#ifdef JS_JITSPEW1
853 void getExtras(ExtrasCollector* extras) const override {
854 char buf[64];
855 SprintfLiteral(buf, "(offs=%lld)", (long long int)access().offset64());
856 extras->add(buf);
857 }
858#endif
859};
860
861class MWasmStore : public MVariadicInstruction, public NoTypePolicy::Data {
862 wasm::MemoryAccessDesc access_;
863
864 explicit MWasmStore(const wasm::MemoryAccessDesc& access)
865 : MVariadicInstruction(classOpcode), access_(access) {
866 setGuard();
867 }
868
869 public:
870 INSTRUCTION_HEADER(WasmStore)
871 NAMED_OPERANDS((0, base), (1, value), (2, memoryBase))MDefinition* base() const { return getOperand(0); } MDefinition
* value() const { return getOperand(1); } MDefinition* memoryBase
() const { return getOperand(2); }
872
873 static MWasmStore* New(TempAllocator& alloc, MDefinition* memoryBase,
874 MDefinition* base,
875 const wasm::MemoryAccessDesc& access,
876 MDefinition* value) {
877 MWasmStore* store = new (alloc) MWasmStore(access);
878 if (!store->init(alloc, 2 + !!memoryBase)) {
879 return nullptr;
880 }
881
882 store->initOperand(0, base);
883 store->initOperand(1, value);
884 if (memoryBase) {
885 store->initOperand(2, memoryBase);
886 }
887
888 return store;
889 }
890
891 const wasm::MemoryAccessDesc& access() const { return access_; }
892
893 AliasSet getAliasSet() const override {
894 return AliasSet::Store(AliasSet::WasmHeap);
895 }
896
897 bool hasMemoryBase() const { return numOperands() > 2; }
898
899#ifdef JS_JITSPEW1
900 void getExtras(ExtrasCollector* extras) const override {
901 char buf[64];
902 SprintfLiteral(buf, "(offs=%lld)", (long long int)access().offset64());
903 extras->add(buf);
904 }
905#endif
906};
907
908class MAsmJSMemoryAccess {
909 Scalar::Type accessType_;
910 bool needsBoundsCheck_;
911
912 public:
913 explicit MAsmJSMemoryAccess(Scalar::Type accessType)
914 : accessType_(accessType), needsBoundsCheck_(true) {
915 MOZ_ASSERT(accessType != Scalar::Uint8Clamped)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(accessType != Scalar::Uint8Clamped)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(accessType != Scalar::Uint8Clamped
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"accessType != Scalar::Uint8Clamped", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 915); AnnotateMozCrashReason("MOZ_ASSERT" "(" "accessType != Scalar::Uint8Clamped"
")"); do { *((volatile int*)__null) = 915; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
916 }
917
918 Scalar::Type accessType() const { return accessType_; }
919 unsigned byteSize() const { return TypedArrayElemSize(accessType()); }
920 bool needsBoundsCheck() const { return needsBoundsCheck_; }
921
922 wasm::MemoryAccessDesc access() const {
923 return wasm::MemoryAccessDesc(0, accessType_, Scalar::byteSize(accessType_),
924 0, wasm::TrapSiteDesc(), false);
925 }
926
927 void removeBoundsCheck() { needsBoundsCheck_ = false; }
928};
929
930class MAsmJSLoadHeap
931 : public MVariadicInstruction, // 1 plus optional memoryBase and
932 // boundsCheckLimit
933 public MAsmJSMemoryAccess,
934 public NoTypePolicy::Data {
935 uint32_t memoryBaseIndex_;
936
937 explicit MAsmJSLoadHeap(uint32_t memoryBaseIndex, Scalar::Type accessType)
938 : MVariadicInstruction(classOpcode),
939 MAsmJSMemoryAccess(accessType),
940 memoryBaseIndex_(memoryBaseIndex) {
941 setResultType(ScalarTypeToMIRType(accessType));
942 }
943
944 public:
945 INSTRUCTION_HEADER(AsmJSLoadHeap)
946 NAMED_OPERANDS((0, base), (1, boundsCheckLimit))MDefinition* base() const { return getOperand(0); } MDefinition
* boundsCheckLimit() const { return getOperand(1); }
947
948 static MAsmJSLoadHeap* New(TempAllocator& alloc, MDefinition* memoryBase,
949 MDefinition* base, MDefinition* boundsCheckLimit,
950 Scalar::Type accessType) {
951 uint32_t nextIndex = 2;
952 uint32_t memoryBaseIndex = memoryBase ? nextIndex++ : UINT32_MAX(4294967295U);
953
954 MAsmJSLoadHeap* load =
955 new (alloc) MAsmJSLoadHeap(memoryBaseIndex, accessType);
956 if (!load->init(alloc, nextIndex)) {
957 return nullptr;
958 }
959
960 load->initOperand(0, base);
961 load->initOperand(1, boundsCheckLimit);
962 if (memoryBase) {
963 load->initOperand(memoryBaseIndex, memoryBase);
964 }
965
966 return load;
967 }
968
969 bool hasMemoryBase() const { return memoryBaseIndex_ != UINT32_MAX(4294967295U); }
970 MDefinition* memoryBase() const {
971 MOZ_ASSERT(hasMemoryBase())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(hasMemoryBase())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(hasMemoryBase()))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("hasMemoryBase()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 971); AnnotateMozCrashReason("MOZ_ASSERT" "(" "hasMemoryBase()"
")"); do { *((volatile int*)__null) = 971; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
972 return getOperand(memoryBaseIndex_);
973 }
974
975 bool congruentTo(const MDefinition* ins) const override;
976 AliasSet getAliasSet() const override {
977 return AliasSet::Load(AliasSet::WasmHeap);
978 }
979 AliasType mightAlias(const MDefinition* def) const override;
980};
981
982class MAsmJSStoreHeap
983 : public MVariadicInstruction, // 2 plus optional memoryBase and
984 // boundsCheckLimit
985 public MAsmJSMemoryAccess,
986 public NoTypePolicy::Data {
987 uint32_t memoryBaseIndex_;
988
989 explicit MAsmJSStoreHeap(uint32_t memoryBaseIndex, Scalar::Type accessType)
990 : MVariadicInstruction(classOpcode),
991 MAsmJSMemoryAccess(accessType),
992 memoryBaseIndex_(memoryBaseIndex) {}
993
994 public:
995 INSTRUCTION_HEADER(AsmJSStoreHeap)
996 NAMED_OPERANDS((0, base), (1, value), (2, boundsCheckLimit))MDefinition* base() const { return getOperand(0); } MDefinition
* value() const { return getOperand(1); } MDefinition* boundsCheckLimit
() const { return getOperand(2); }
997
998 static MAsmJSStoreHeap* New(TempAllocator& alloc, MDefinition* memoryBase,
999 MDefinition* base, MDefinition* boundsCheckLimit,
1000 Scalar::Type accessType, MDefinition* v) {
1001 uint32_t nextIndex = 3;
1002 uint32_t memoryBaseIndex = memoryBase ? nextIndex++ : UINT32_MAX(4294967295U);
1003
1004 MAsmJSStoreHeap* store =
1005 new (alloc) MAsmJSStoreHeap(memoryBaseIndex, accessType);
1006 if (!store->init(alloc, nextIndex)) {
1007 return nullptr;
1008 }
1009
1010 store->initOperand(0, base);
1011 store->initOperand(1, v);
1012 store->initOperand(2, boundsCheckLimit);
1013 if (memoryBase) {
1014 store->initOperand(memoryBaseIndex, memoryBase);
1015 }
1016
1017 return store;
1018 }
1019
1020 bool hasMemoryBase() const { return memoryBaseIndex_ != UINT32_MAX(4294967295U); }
1021 MDefinition* memoryBase() const {
1022 MOZ_ASSERT(hasMemoryBase())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(hasMemoryBase())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(hasMemoryBase()))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("hasMemoryBase()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 1022); AnnotateMozCrashReason("MOZ_ASSERT" "(" "hasMemoryBase()"
")"); do { *((volatile int*)__null) = 1022; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1023 return getOperand(memoryBaseIndex_);
1024 }
1025
1026 AliasSet getAliasSet() const override {
1027 return AliasSet::Store(AliasSet::WasmHeap);
1028 }
1029};
1030
1031class MWasmCompareExchangeHeap : public MVariadicInstruction,
1032 public NoTypePolicy::Data {
1033 wasm::MemoryAccessDesc access_;
1034 wasm::BytecodeOffset bytecodeOffset_;
1035
1036 explicit MWasmCompareExchangeHeap(const wasm::MemoryAccessDesc& access,
1037 wasm::BytecodeOffset bytecodeOffset)
1038 : MVariadicInstruction(classOpcode),
1039 access_(access),
1040 bytecodeOffset_(bytecodeOffset) {
1041 setGuard(); // Not removable
1042 setResultType(ScalarTypeToMIRType(access.type()));
1043 }
1044
1045 public:
1046 INSTRUCTION_HEADER(WasmCompareExchangeHeap)
1047 NAMED_OPERANDS((0, base), (1, oldValue), (2, newValue), (3, instance),MDefinition* base() const { return getOperand(0); } MDefinition
* oldValue() const { return getOperand(1); } MDefinition* newValue
() const { return getOperand(2); } MDefinition* instance() const
{ return getOperand(3); } MDefinition* memoryBase() const { return
getOperand(4); }
1048 (4, memoryBase))MDefinition* base() const { return getOperand(0); } MDefinition
* oldValue() const { return getOperand(1); } MDefinition* newValue
() const { return getOperand(2); } MDefinition* instance() const
{ return getOperand(3); } MDefinition* memoryBase() const { return
getOperand(4); }
1049
1050 static MWasmCompareExchangeHeap* New(TempAllocator& alloc,
1051 wasm::BytecodeOffset bytecodeOffset,
1052 MDefinition* memoryBase,
1053 MDefinition* base,
1054 const wasm::MemoryAccessDesc& access,
1055 MDefinition* oldv, MDefinition* newv,
1056 MDefinition* instance) {
1057 MWasmCompareExchangeHeap* cas =
1058 new (alloc) MWasmCompareExchangeHeap(access, bytecodeOffset);
1059 if (!cas->init(alloc, 4 + !!memoryBase)) {
1060 return nullptr;
1061 }
1062 cas->initOperand(0, base);
1063 cas->initOperand(1, oldv);
1064 cas->initOperand(2, newv);
1065 cas->initOperand(3, instance);
1066 if (memoryBase) {
1067 cas->initOperand(4, memoryBase);
1068 }
1069 return cas;
1070 }
1071
1072 const wasm::MemoryAccessDesc& access() const { return access_; }
1073 wasm::BytecodeOffset bytecodeOffset() const { return bytecodeOffset_; }
1074
1075 AliasSet getAliasSet() const override {
1076 return AliasSet::Store(AliasSet::WasmHeap);
1077 }
1078
1079 bool hasMemoryBase() const { return numOperands() > 4; }
1080};
1081
1082class MWasmAtomicExchangeHeap : public MVariadicInstruction,
1083 public NoTypePolicy::Data {
1084 wasm::MemoryAccessDesc access_;
1085 wasm::BytecodeOffset bytecodeOffset_;
1086
1087 explicit MWasmAtomicExchangeHeap(const wasm::MemoryAccessDesc& access,
1088 wasm::BytecodeOffset bytecodeOffset)
1089 : MVariadicInstruction(classOpcode),
1090 access_(access),
1091 bytecodeOffset_(bytecodeOffset) {
1092 setGuard(); // Not removable
1093 setResultType(ScalarTypeToMIRType(access.type()));
1094 }
1095
1096 public:
1097 INSTRUCTION_HEADER(WasmAtomicExchangeHeap)
1098 NAMED_OPERANDS((0, base), (1, value), (2, instance), (3, memoryBase))MDefinition* base() const { return getOperand(0); } MDefinition
* value() const { return getOperand(1); } MDefinition* instance
() const { return getOperand(2); } MDefinition* memoryBase() const
{ return getOperand(3); }
1099
1100 static MWasmAtomicExchangeHeap* New(TempAllocator& alloc,
1101 wasm::BytecodeOffset bytecodeOffset,
1102 MDefinition* memoryBase,
1103 MDefinition* base,
1104 const wasm::MemoryAccessDesc& access,
1105 MDefinition* value,
1106 MDefinition* instance) {
1107 MWasmAtomicExchangeHeap* xchg =
1108 new (alloc) MWasmAtomicExchangeHeap(access, bytecodeOffset);
1109 if (!xchg->init(alloc, 3 + !!memoryBase)) {
1110 return nullptr;
1111 }
1112
1113 xchg->initOperand(0, base);
1114 xchg->initOperand(1, value);
1115 xchg->initOperand(2, instance);
1116 if (memoryBase) {
1117 xchg->initOperand(3, memoryBase);
1118 }
1119
1120 return xchg;
1121 }
1122
1123 const wasm::MemoryAccessDesc& access() const { return access_; }
1124 wasm::BytecodeOffset bytecodeOffset() const { return bytecodeOffset_; }
1125
1126 AliasSet getAliasSet() const override {
1127 return AliasSet::Store(AliasSet::WasmHeap);
1128 }
1129
1130 bool hasMemoryBase() const { return numOperands() > 3; }
1131};
1132
1133class MWasmAtomicBinopHeap : public MVariadicInstruction,
1134 public NoTypePolicy::Data {
1135 AtomicOp op_;
1136 wasm::MemoryAccessDesc access_;
1137 wasm::BytecodeOffset bytecodeOffset_;
1138
1139 explicit MWasmAtomicBinopHeap(AtomicOp op,
1140 const wasm::MemoryAccessDesc& access,
1141 wasm::BytecodeOffset bytecodeOffset)
1142 : MVariadicInstruction(classOpcode),
1143 op_(op),
1144 access_(access),
1145 bytecodeOffset_(bytecodeOffset) {
1146 setGuard(); // Not removable
1147 setResultType(ScalarTypeToMIRType(access.type()));
1148 }
1149
1150 public:
1151 INSTRUCTION_HEADER(WasmAtomicBinopHeap)
1152 NAMED_OPERANDS((0, base), (1, value), (2, instance), (3, memoryBase))MDefinition* base() const { return getOperand(0); } MDefinition
* value() const { return getOperand(1); } MDefinition* instance
() const { return getOperand(2); } MDefinition* memoryBase() const
{ return getOperand(3); }
1153
1154 static MWasmAtomicBinopHeap* New(TempAllocator& alloc,
1155 wasm::BytecodeOffset bytecodeOffset,
1156 AtomicOp op, MDefinition* memoryBase,
1157 MDefinition* base,
1158 const wasm::MemoryAccessDesc& access,
1159 MDefinition* v, MDefinition* instance) {
1160 MWasmAtomicBinopHeap* binop =
1161 new (alloc) MWasmAtomicBinopHeap(op, access, bytecodeOffset);
1162 if (!binop->init(alloc, 3 + !!memoryBase)) {
1163 return nullptr;
1164 }
1165
1166 binop->initOperand(0, base);
1167 binop->initOperand(1, v);
1168 binop->initOperand(2, instance);
1169 if (memoryBase) {
1170 binop->initOperand(3, memoryBase);
1171 }
1172
1173 return binop;
1174 }
1175
1176 AtomicOp operation() const { return op_; }
1177 const wasm::MemoryAccessDesc& access() const { return access_; }
1178 wasm::BytecodeOffset bytecodeOffset() const { return bytecodeOffset_; }
1179
1180 AliasSet getAliasSet() const override {
1181 return AliasSet::Store(AliasSet::WasmHeap);
1182 }
1183
1184 bool hasMemoryBase() const { return numOperands() > 3; }
1185};
1186
1187class MWasmLoadInstanceDataField : public MUnaryInstruction,
1188 public NoTypePolicy::Data {
1189 MWasmLoadInstanceDataField(MIRType type, unsigned instanceDataOffset,
1190 bool isConstant, MDefinition* instance)
1191 : MUnaryInstruction(classOpcode, instance),
1192 instanceDataOffset_(instanceDataOffset),
1193 isConstant_(isConstant) {
1194 MOZ_ASSERT(IsNumberType(type) || type == MIRType::Simd128 ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(IsNumberType(type) || type == MIRType::Simd128 || type
== MIRType::Pointer || type == MIRType::WasmAnyRef)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(IsNumberType(type) || type == MIRType::Simd128 || type == MIRType
::Pointer || type == MIRType::WasmAnyRef))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("IsNumberType(type) || type == MIRType::Simd128 || type == MIRType::Pointer || type == MIRType::WasmAnyRef"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 1195); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsNumberType(type) || type == MIRType::Simd128 || type == MIRType::Pointer || type == MIRType::WasmAnyRef"
")"); do { *((volatile int*)__null) = 1195; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1195 type == MIRType::Pointer || type == MIRType::WasmAnyRef)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(IsNumberType(type) || type == MIRType::Simd128 || type
== MIRType::Pointer || type == MIRType::WasmAnyRef)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(IsNumberType(type) || type == MIRType::Simd128 || type == MIRType
::Pointer || type == MIRType::WasmAnyRef))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("IsNumberType(type) || type == MIRType::Simd128 || type == MIRType::Pointer || type == MIRType::WasmAnyRef"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 1195); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsNumberType(type) || type == MIRType::Simd128 || type == MIRType::Pointer || type == MIRType::WasmAnyRef"
")"); do { *((volatile int*)__null) = 1195; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1196 setResultType(type);
1197 setMovable();
1198 }
1199
1200 unsigned instanceDataOffset_;
1201 bool isConstant_;
1202
1203 public:
1204 INSTRUCTION_HEADER(WasmLoadInstanceDataField)
1205 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
1206 NAMED_OPERANDS((0, instance))MDefinition* instance() const { return getOperand(0); }
1207
1208 unsigned instanceDataOffset() const { return instanceDataOffset_; }
1209
1210 HashNumber valueHash() const override;
1211 bool congruentTo(const MDefinition* ins) const override;
1212 MDefinition* foldsTo(TempAllocator& alloc) override;
1213
1214 AliasSet getAliasSet() const override {
1215 return isConstant_ ? AliasSet::None()
1216 : AliasSet::Load(AliasSet::WasmInstanceData);
1217 }
1218
1219 AliasType mightAlias(const MDefinition* def) const override;
1220
1221#ifdef JS_JITSPEW1
1222 void getExtras(ExtrasCollector* extras) const override {
1223 char buf[96];
1224 SprintfLiteral(buf, "(offs=%lld, isConst=%s)",
1225 (long long int)instanceDataOffset_,
1226 isConstant_ ? "true" : "false");
1227 extras->add(buf);
1228 }
1229#endif
1230};
1231
1232class MWasmLoadGlobalCell : public MUnaryInstruction,
1233 public NoTypePolicy::Data {
1234 MWasmLoadGlobalCell(MIRType type, MDefinition* cellPtr)
1235 : MUnaryInstruction(classOpcode, cellPtr) {
1236 setResultType(type);
1237 setMovable();
1238 }
1239
1240 public:
1241 INSTRUCTION_HEADER(WasmLoadGlobalCell)
1242 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
1243 NAMED_OPERANDS((0, cellPtr))MDefinition* cellPtr() const { return getOperand(0); }
1244
1245 // The default valueHash is good enough, because there are no non-operand
1246 // fields.
1247 bool congruentTo(const MDefinition* ins) const override;
1248
1249 AliasSet getAliasSet() const override {
1250 return AliasSet::Load(AliasSet::WasmGlobalCell);
1251 }
1252
1253 AliasType mightAlias(const MDefinition* def) const override;
1254};
1255
1256class MWasmLoadTableElement : public MBinaryInstruction,
1257 public NoTypePolicy::Data {
1258 MWasmLoadTableElement(MDefinition* elements, MDefinition* index)
1259 : MBinaryInstruction(classOpcode, elements, index) {
1260 setResultType(MIRType::WasmAnyRef);
1261 setMovable();
1262 }
1263
1264 public:
1265 INSTRUCTION_HEADER(WasmLoadTableElement)
1266 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
1267 NAMED_OPERANDS((0, elements))MDefinition* elements() const { return getOperand(0); }
1268 NAMED_OPERANDS((1, index))MDefinition* index() const { return getOperand(1); }
1269
1270 AliasSet getAliasSet() const override {
1271 return AliasSet::Load(AliasSet::WasmTableElement);
1272 }
1273};
1274
1275class MWasmStoreInstanceDataField : public MBinaryInstruction,
1276 public NoTypePolicy::Data {
1277 MWasmStoreInstanceDataField(unsigned instanceDataOffset, MDefinition* value,
1278 MDefinition* instance)
1279 : MBinaryInstruction(classOpcode, value, instance),
1280 instanceDataOffset_(instanceDataOffset) {}
1281
1282 unsigned instanceDataOffset_;
1283
1284 public:
1285 INSTRUCTION_HEADER(WasmStoreInstanceDataField)
1286 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
1287 NAMED_OPERANDS((0, value), (1, instance))MDefinition* value() const { return getOperand(0); } MDefinition
* instance() const { return getOperand(1); }
1288
1289 unsigned instanceDataOffset() const { return instanceDataOffset_; }
1290
1291 AliasSet getAliasSet() const override {
1292 return AliasSet::Store(AliasSet::WasmInstanceData);
1293 }
1294};
1295
1296class MWasmStoreGlobalCell : public MBinaryInstruction,
1297 public NoTypePolicy::Data {
1298 MWasmStoreGlobalCell(MDefinition* value, MDefinition* cellPtr)
1299 : MBinaryInstruction(classOpcode, value, cellPtr) {}
1300
1301 public:
1302 INSTRUCTION_HEADER(WasmStoreGlobalCell)
1303 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
1304 NAMED_OPERANDS((0, value), (1, cellPtr))MDefinition* value() const { return getOperand(0); } MDefinition
* cellPtr() const { return getOperand(1); }
1305
1306 AliasSet getAliasSet() const override {
1307 return AliasSet::Store(AliasSet::WasmGlobalCell);
1308 }
1309};
1310
1311class MWasmStoreStackResult : public MBinaryInstruction,
1312 public NoTypePolicy::Data {
1313 MWasmStoreStackResult(MDefinition* stackResultArea, uint32_t offset,
1314 MDefinition* value)
1315 : MBinaryInstruction(classOpcode, stackResultArea, value),
1316 offset_(offset) {}
1317
1318 uint32_t offset_;
1319
1320 public:
1321 INSTRUCTION_HEADER(WasmStoreStackResult)
1322 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
1323 NAMED_OPERANDS((0, stackResultArea), (1, value))MDefinition* stackResultArea() const { return getOperand(0); }
MDefinition* value() const { return getOperand(1); }
1324
1325 uint32_t offset() const { return offset_; }
1326
1327 AliasSet getAliasSet() const override {
1328 return AliasSet::Store(AliasSet::WasmStackResult);
1329 }
1330};
1331
1332// Represents a known-good derived pointer into an object or memory region (in
1333// the most general sense) that will not move while the derived pointer is live.
1334// The `offset` *must* be a valid offset into the object represented by `base`;
1335// hence overflow in the address calculation will never be an issue. `offset`
1336// must be representable as a 31-bit unsigned integer.
1337//
1338// DO NOT use this with a base value of any JS-heap-resident object type.
1339// Such a value would need to be adjusted during GC, yet we have no mechanism
1340// to do that. See bug 1810090.
1341
1342class MWasmDerivedPointer : public MUnaryInstruction,
1343 public NoTypePolicy::Data {
1344 MWasmDerivedPointer(MDefinition* base, size_t offset)
1345 : MUnaryInstruction(classOpcode, base), offset_(uint32_t(offset)) {
1346 MOZ_ASSERT(offset <= INT32_MAX)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(offset <= (2147483647))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(offset <= (2147483647))))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("offset <= (2147483647)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 1346); AnnotateMozCrashReason("MOZ_ASSERT" "(" "offset <= (2147483647)"
")"); do { *((volatile int*)__null) = 1346; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1347 // Do not change this to allow `base` to be a GC-heap allocated type.
1348 MOZ_ASSERT(base->type() == MIRType::Pointer ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(base->type() == MIRType::Pointer || base->type
() == TargetWordMIRType())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(base->type() == MIRType::
Pointer || base->type() == TargetWordMIRType()))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("base->type() == MIRType::Pointer || base->type() == TargetWordMIRType()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 1349); AnnotateMozCrashReason("MOZ_ASSERT" "(" "base->type() == MIRType::Pointer || base->type() == TargetWordMIRType()"
")"); do { *((volatile int*)__null) = 1349; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1349 base->type() == TargetWordMIRType())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(base->type() == MIRType::Pointer || base->type
() == TargetWordMIRType())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(base->type() == MIRType::
Pointer || base->type() == TargetWordMIRType()))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("base->type() == MIRType::Pointer || base->type() == TargetWordMIRType()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 1349); AnnotateMozCrashReason("MOZ_ASSERT" "(" "base->type() == MIRType::Pointer || base->type() == TargetWordMIRType()"
")"); do { *((volatile int*)__null) = 1349; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1350 setResultType(MIRType::Pointer);
1351 setMovable();
1352 }
1353
1354 uint32_t offset_;
1355
1356 public:
1357 INSTRUCTION_HEADER(WasmDerivedPointer)
1358 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
1359 NAMED_OPERANDS((0, base))MDefinition* base() const { return getOperand(0); }
1360
1361 uint32_t offset() const { return offset_; }
1362
1363 AliasSet getAliasSet() const override { return AliasSet::None(); }
1364
1365 bool congruentTo(const MDefinition* ins) const override {
1366 return congruentIfOperandsEqual(ins) &&
1367 ins->toWasmDerivedPointer()->offset() == offset();
1368 }
1369
1370#ifdef JS_JITSPEW1
1371 void getExtras(ExtrasCollector* extras) const override {
1372 char buf[64];
1373 SprintfLiteral(buf, "(offs=%lld)", (long long int)offset_);
1374 extras->add(buf);
1375 }
1376#endif
1377
1378 ALLOW_CLONE(MWasmDerivedPointer)bool canClone() const override { return true; } MInstruction*
clone(TempAllocator& alloc, const MDefinitionVector&
inputs) const override { MInstruction* res = new (alloc) MWasmDerivedPointer
(*this); for (size_t i = 0; i < numOperands(); i++) res->
replaceOperand(i, inputs[i]); return res; }
1379};
1380
1381// As with MWasmDerivedPointer, DO NOT use this with a base value of any
1382// JS-heap-resident object type.
1383class MWasmDerivedIndexPointer : public MBinaryInstruction,
1384 public NoTypePolicy::Data {
1385 MWasmDerivedIndexPointer(MDefinition* base, MDefinition* index, Scale scale)
1386 : MBinaryInstruction(classOpcode, base, index), scale_(scale) {
1387 // Do not change this to allow `base` to be a GC-heap allocated type.
1388 MOZ_ASSERT(base->type() == MIRType::Pointer)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(base->type() == MIRType::Pointer)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(base->type() == MIRType::
Pointer))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("base->type() == MIRType::Pointer", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 1388); AnnotateMozCrashReason("MOZ_ASSERT" "(" "base->type() == MIRType::Pointer"
")"); do { *((volatile int*)__null) = 1388; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1389 setResultType(MIRType::Pointer);
1390 setMovable();
1391 }
1392
1393 Scale scale_;
1394
1395 public:
1396 INSTRUCTION_HEADER(WasmDerivedIndexPointer)
1397 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
1398 NAMED_OPERANDS((0, base))MDefinition* base() const { return getOperand(0); }
1399 NAMED_OPERANDS((1, index))MDefinition* index() const { return getOperand(1); }
1400
1401 Scale scale() const { return scale_; }
1402
1403 AliasSet getAliasSet() const override { return AliasSet::None(); }
1404
1405 bool congruentTo(const MDefinition* ins) const override {
1406 return congruentIfOperandsEqual(ins) &&
1407 ins->toWasmDerivedIndexPointer()->scale() == scale();
1408 }
1409
1410 ALLOW_CLONE(MWasmDerivedIndexPointer)bool canClone() const override { return true; } MInstruction*
clone(TempAllocator& alloc, const MDefinitionVector&
inputs) const override { MInstruction* res = new (alloc) MWasmDerivedIndexPointer
(*this); for (size_t i = 0; i < numOperands(); i++) res->
replaceOperand(i, inputs[i]); return res; }
1411};
1412
1413// Whether to perform a pre-write barrier for a wasm store reference.
1414enum class WasmPreBarrierKind : uint8_t { None, Normal };
1415
1416// Stores a reference to an address. This performs a pre-barrier on the address,
1417// but not a post-barrier. A post-barrier must be performed separately, if it's
1418// required. The accessed location is `valueBase + valueOffset`. The latter
1419// must be be representable as a 31-bit unsigned integer.
1420
1421class MWasmStoreRef : public MAryInstruction<3>, public NoTypePolicy::Data {
1422 uint32_t offset_;
1423 AliasSet::Flag aliasSet_;
1424 WasmPreBarrierKind preBarrierKind_;
1425
1426 MWasmStoreRef(MDefinition* instance, MDefinition* valueBase,
1427 size_t valueOffset, MDefinition* value, AliasSet::Flag aliasSet,
1428 WasmPreBarrierKind preBarrierKind)
1429 : MAryInstruction<3>(classOpcode),
1430 offset_(uint32_t(valueOffset)),
1431 aliasSet_(aliasSet),
1432 preBarrierKind_(preBarrierKind) {
1433 MOZ_ASSERT(valueOffset <= INT32_MAX)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(valueOffset <= (2147483647))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(valueOffset <= (2147483647
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("valueOffset <= (2147483647)", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 1433); AnnotateMozCrashReason("MOZ_ASSERT" "(" "valueOffset <= (2147483647)"
")"); do { *((volatile int*)__null) = 1433; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1434 MOZ_ASSERT(valueBase->type() == MIRType::Pointer ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(valueBase->type() == MIRType::Pointer || valueBase
->type() == MIRType::StackResults)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(valueBase->type() == MIRType
::Pointer || valueBase->type() == MIRType::StackResults)))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("valueBase->type() == MIRType::Pointer || valueBase->type() == MIRType::StackResults"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 1435); AnnotateMozCrashReason("MOZ_ASSERT" "(" "valueBase->type() == MIRType::Pointer || valueBase->type() == MIRType::StackResults"
")"); do { *((volatile int*)__null) = 1435; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1435 valueBase->type() == MIRType::StackResults)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(valueBase->type() == MIRType::Pointer || valueBase
->type() == MIRType::StackResults)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(valueBase->type() == MIRType
::Pointer || valueBase->type() == MIRType::StackResults)))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("valueBase->type() == MIRType::Pointer || valueBase->type() == MIRType::StackResults"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 1435); AnnotateMozCrashReason("MOZ_ASSERT" "(" "valueBase->type() == MIRType::Pointer || valueBase->type() == MIRType::StackResults"
")"); do { *((volatile int*)__null) = 1435; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1436 MOZ_ASSERT(value->type() == MIRType::WasmAnyRef)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(value->type() == MIRType::WasmAnyRef)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(value->type() == MIRType::WasmAnyRef))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("value->type() == MIRType::WasmAnyRef"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 1436); AnnotateMozCrashReason("MOZ_ASSERT" "(" "value->type() == MIRType::WasmAnyRef"
")"); do { *((volatile int*)__null) = 1436; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1437 initOperand(0, instance);
1438 initOperand(1, valueBase);
1439 initOperand(2, value);
1440 }
1441
1442 public:
1443 INSTRUCTION_HEADER(WasmStoreRef)
1444 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
1445 NAMED_OPERANDS((0, instance), (1, valueBase), (2, value))MDefinition* instance() const { return getOperand(0); } MDefinition
* valueBase() const { return getOperand(1); } MDefinition* value
() const { return getOperand(2); }
1446
1447 uint32_t offset() const { return offset_; }
1448 AliasSet getAliasSet() const override { return AliasSet::Store(aliasSet_); }
1449 WasmPreBarrierKind preBarrierKind() const { return preBarrierKind_; }
1450
1451#ifdef JS_JITSPEW1
1452 void getExtras(ExtrasCollector* extras) const override {
1453 char buf[64];
1454 SprintfLiteral(buf, "(offs=%lld)", (long long int)offset_);
1455 extras->add(buf);
1456 }
1457#endif
1458};
1459
1460// Given a value being written to another object, update the generational store
1461// buffer if the value is in the nursery and object is in the tenured heap.
1462class MWasmPostWriteBarrierImmediate : public MQuaternaryInstruction,
1463 public NoTypePolicy::Data {
1464 uint32_t valueOffset_;
1465
1466 MWasmPostWriteBarrierImmediate(MDefinition* instance, MDefinition* object,
1467 MDefinition* valueBase, uint32_t valueOffset,
1468 MDefinition* value)
1469 : MQuaternaryInstruction(classOpcode, instance, object, valueBase, value),
1470 valueOffset_(valueOffset) {
1471 setGuard();
1472 }
1473
1474 public:
1475 INSTRUCTION_HEADER(WasmPostWriteBarrierImmediate)
1476 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
1477 NAMED_OPERANDS((0, instance), (1, object), (2, valueBase), (3, value))MDefinition* instance() const { return getOperand(0); } MDefinition
* object() const { return getOperand(1); } MDefinition* valueBase
() const { return getOperand(2); } MDefinition* value() const
{ return getOperand(3); }
1478
1479 AliasSet getAliasSet() const override { return AliasSet::None(); }
1480 uint32_t valueOffset() const { return valueOffset_; }
1481
1482 ALLOW_CLONE(MWasmPostWriteBarrierImmediate)bool canClone() const override { return true; } MInstruction*
clone(TempAllocator& alloc, const MDefinitionVector&
inputs) const override { MInstruction* res = new (alloc) MWasmPostWriteBarrierImmediate
(*this); for (size_t i = 0; i < numOperands(); i++) res->
replaceOperand(i, inputs[i]); return res; }
1483};
1484
1485// Given a value being written to another object, update the generational store
1486// buffer if the value is in the nursery and object is in the tenured heap.
1487class MWasmPostWriteBarrierIndex : public MAryInstruction<5>,
1488 public NoTypePolicy::Data {
1489 uint32_t elemSize_;
1490
1491 MWasmPostWriteBarrierIndex(MDefinition* instance, MDefinition* object,
1492 MDefinition* valueBase, MDefinition* index,
1493 uint32_t scale, MDefinition* value)
1494 : MAryInstruction<5>(classOpcode), elemSize_(scale) {
1495 initOperand(0, instance);
1496 initOperand(1, object);
1497 initOperand(2, valueBase);
1498 initOperand(3, index);
1499 initOperand(4, value);
1500 setGuard();
1501 }
1502
1503 public:
1504 INSTRUCTION_HEADER(WasmPostWriteBarrierIndex)
1505 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
1506 NAMED_OPERANDS((0, instance), (1, object), (2, valueBase), (3, index),MDefinition* instance() const { return getOperand(0); } MDefinition
* object() const { return getOperand(1); } MDefinition* valueBase
() const { return getOperand(2); } MDefinition* index() const
{ return getOperand(3); } MDefinition* value() const { return
getOperand(4); }
1507 (4, value))MDefinition* instance() const { return getOperand(0); } MDefinition
* object() const { return getOperand(1); } MDefinition* valueBase
() const { return getOperand(2); } MDefinition* index() const
{ return getOperand(3); } MDefinition* value() const { return
getOperand(4); }
1508
1509 AliasSet getAliasSet() const override { return AliasSet::None(); }
1510 uint32_t elemSize() const { return elemSize_; }
1511
1512 ALLOW_CLONE(MWasmPostWriteBarrierIndex)bool canClone() const override { return true; } MInstruction*
clone(TempAllocator& alloc, const MDefinitionVector&
inputs) const override { MInstruction* res = new (alloc) MWasmPostWriteBarrierIndex
(*this); for (size_t i = 0; i < numOperands(); i++) res->
replaceOperand(i, inputs[i]); return res; }
1513};
1514
1515class MWasmParameter : public MNullaryInstruction {
1516 ABIArg abi_;
1517
1518 MWasmParameter(ABIArg abi, MIRType mirType)
1519 : MNullaryInstruction(classOpcode), abi_(abi) {
1520 setResultType(mirType);
1521 }
1522
1523 public:
1524 INSTRUCTION_HEADER(WasmParameter)
1525 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
1526
1527 ABIArg abi() const { return abi_; }
1528};
1529
1530class MWasmReturn : public MAryControlInstruction<2, 0>,
1531 public NoTypePolicy::Data {
1532 MWasmReturn(MDefinition* ins, MDefinition* instance)
1533 : MAryControlInstruction(classOpcode) {
1534 initOperand(0, ins);
1535 initOperand(1, instance);
1536 }
1537
1538 public:
1539 INSTRUCTION_HEADER(WasmReturn)
1540 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
1541
1542 AliasSet getAliasSet() const override { return AliasSet::None(); }
1543};
1544
1545class MWasmReturnVoid : public MAryControlInstruction<1, 0>,
1546 public NoTypePolicy::Data {
1547 explicit MWasmReturnVoid(MDefinition* instance)
1548 : MAryControlInstruction(classOpcode) {
1549 initOperand(0, instance);
1550 }
1551
1552 public:
1553 INSTRUCTION_HEADER(WasmReturnVoid)
1554 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
1555
1556 AliasSet getAliasSet() const override { return AliasSet::None(); }
1557};
1558
1559class MWasmStackArg : public MUnaryInstruction, public NoTypePolicy::Data {
1560 MWasmStackArg(uint32_t spOffset, MDefinition* ins)
1561 : MUnaryInstruction(classOpcode, ins), spOffset_(spOffset) {}
1562
1563 uint32_t spOffset_;
1564
1565 public:
1566 INSTRUCTION_HEADER(WasmStackArg)
1567 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
1568 NAMED_OPERANDS((0, arg))MDefinition* arg() const { return getOperand(0); }
1569
1570 uint32_t spOffset() const { return spOffset_; }
1571 void incrementOffset(uint32_t inc) { spOffset_ += inc; }
1572};
1573
1574template <typename Location>
1575class MWasmResultBase : public MNullaryInstruction {
1576 Location loc_;
1577
1578 protected:
1579 MWasmResultBase(Opcode op, MIRType type, Location loc)
1580 : MNullaryInstruction(op), loc_(loc) {
1581 setResultType(type);
1582 setCallResultCapture();
1583 }
1584
1585 public:
1586 Location loc() { return loc_; }
1587};
1588
1589class MWasmRegisterResult : public MWasmResultBase<Register> {
1590 MWasmRegisterResult(MIRType type, Register reg)
1591 : MWasmResultBase(classOpcode, type, reg) {}
1592
1593 public:
1594 INSTRUCTION_HEADER(WasmRegisterResult)
1595 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
1596};
1597
1598class MWasmFloatRegisterResult : public MWasmResultBase<FloatRegister> {
1599 MWasmFloatRegisterResult(MIRType type, FloatRegister reg)
1600 : MWasmResultBase(classOpcode, type, reg) {}
1601
1602 public:
1603 INSTRUCTION_HEADER(WasmFloatRegisterResult)
1604 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
1605};
1606
1607class MWasmRegister64Result : public MWasmResultBase<Register64> {
1608 explicit MWasmRegister64Result(Register64 reg)
1609 : MWasmResultBase(classOpcode, MIRType::Int64, reg) {}
1610
1611 public:
1612 INSTRUCTION_HEADER(WasmRegister64Result)
1613 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
1614};
1615
1616class MWasmStackResultArea : public MNullaryInstruction {
1617 public:
1618 class StackResult {
1619 // Offset in bytes from lowest address of stack result area.
1620 uint32_t offset_;
1621 MIRType type_;
1622
1623 public:
1624 StackResult() : type_(MIRType::Undefined) {}
1625 StackResult(uint32_t offset, MIRType type) : offset_(offset), type_(type) {}
1626
1627 bool initialized() const { return type_ != MIRType::Undefined; }
1628 uint32_t offset() const {
1629 MOZ_ASSERT(initialized())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(initialized())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(initialized()))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("initialized()",
"/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 1629); AnnotateMozCrashReason("MOZ_ASSERT" "(" "initialized()"
")"); do { *((volatile int*)__null) = 1629; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1630 return offset_;
1631 }
1632 MIRType type() const {
1633 MOZ_ASSERT(initialized())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(initialized())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(initialized()))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("initialized()",
"/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 1633); AnnotateMozCrashReason("MOZ_ASSERT" "(" "initialized()"
")"); do { *((volatile int*)__null) = 1633; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1634 return type_;
1635 }
1636 uint32_t endOffset() const {
1637 return offset() + wasm::MIRTypeToABIResultSize(type());
1638 }
1639 };
1640
1641 private:
1642 FixedList<StackResult> results_;
1643 uint32_t base_;
1644
1645 explicit MWasmStackResultArea()
1646 : MNullaryInstruction(classOpcode), base_(UINT32_MAX(4294967295U)) {
1647 setResultType(MIRType::StackResults);
1648 }
1649
1650 void assertInitialized() const {
1651 MOZ_ASSERT(results_.length() != 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(results_.length() != 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(results_.length() != 0))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("results_.length() != 0"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 1651); AnnotateMozCrashReason("MOZ_ASSERT" "(" "results_.length() != 0"
")"); do { *((volatile int*)__null) = 1651; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1652#ifdef DEBUG1
1653 for (size_t i = 0; i < results_.length(); i++) {
1654 MOZ_ASSERT(results_[i].initialized())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(results_[i].initialized())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(results_[i].initialized())))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("results_[i].initialized()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 1654); AnnotateMozCrashReason("MOZ_ASSERT" "(" "results_[i].initialized()"
")"); do { *((volatile int*)__null) = 1654; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1655 }
1656#endif
1657 }
1658
1659 bool baseInitialized() const { return base_ != UINT32_MAX(4294967295U); }
1660
1661 public:
1662 INSTRUCTION_HEADER(WasmStackResultArea)
1663 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
1664
1665 [[nodiscard]] bool init(TempAllocator& alloc, size_t stackResultCount) {
1666 MOZ_ASSERT(results_.length() == 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(results_.length() == 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(results_.length() == 0))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("results_.length() == 0"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 1666); AnnotateMozCrashReason("MOZ_ASSERT" "(" "results_.length() == 0"
")"); do { *((volatile int*)__null) = 1666; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1667 MOZ_ASSERT(stackResultCount > 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(stackResultCount > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(stackResultCount > 0))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("stackResultCount > 0"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 1667); AnnotateMozCrashReason("MOZ_ASSERT" "(" "stackResultCount > 0"
")"); do { *((volatile int*)__null) = 1667; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1668 if (!results_.init(alloc, stackResultCount)) {
1669 return false;
1670 }
1671 for (size_t n = 0; n < stackResultCount; n++) {
1672 results_[n] = StackResult();
1673 }
1674 return true;
1675 }
1676
1677 size_t resultCount() const { return results_.length(); }
1678 const StackResult& result(size_t n) const {
1679 MOZ_ASSERT(results_[n].initialized())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(results_[n].initialized())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(results_[n].initialized())))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("results_[n].initialized()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 1679); AnnotateMozCrashReason("MOZ_ASSERT" "(" "results_[n].initialized()"
")"); do { *((volatile int*)__null) = 1679; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1680 return results_[n];
1681 }
1682 void initResult(size_t n, const StackResult& loc) {
1683 MOZ_ASSERT(!results_[n].initialized())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!results_[n].initialized())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!results_[n].initialized()))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!results_[n].initialized()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 1683); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!results_[n].initialized()"
")"); do { *((volatile int*)__null) = 1683; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1684 MOZ_ASSERT((n == 0) == (loc.offset() == 0))do { static_assert( mozilla::detail::AssertionConditionType<
decltype((n == 0) == (loc.offset() == 0))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!((n == 0) == (loc.offset() ==
0)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("(n == 0) == (loc.offset() == 0)", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 1684); AnnotateMozCrashReason("MOZ_ASSERT" "(" "(n == 0) == (loc.offset() == 0)"
")"); do { *((volatile int*)__null) = 1684; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1685 MOZ_ASSERT_IF(n > 0, loc.offset() >= result(n - 1).endOffset())do { if (n > 0) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(loc.offset() >= result(n - 1).endOffset())>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(loc.offset() >= result(n - 1).endOffset()))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("loc.offset() >= result(n - 1).endOffset()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 1685); AnnotateMozCrashReason("MOZ_ASSERT" "(" "loc.offset() >= result(n - 1).endOffset()"
")"); do { *((volatile int*)__null) = 1685; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
1686 results_[n] = loc;
1687 }
1688
1689 uint32_t byteSize() const {
1690 assertInitialized();
1691 return result(resultCount() - 1).endOffset();
1692 }
1693
1694 // Stack index indicating base of stack area.
1695 uint32_t base() const {
1696 MOZ_ASSERT(baseInitialized())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(baseInitialized())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(baseInitialized()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("baseInitialized()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 1696); AnnotateMozCrashReason("MOZ_ASSERT" "(" "baseInitialized()"
")"); do { *((volatile int*)__null) = 1696; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1697 return base_;
1698 }
1699 void setBase(uint32_t base) {
1700 MOZ_ASSERT(!baseInitialized())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!baseInitialized())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!baseInitialized()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("!baseInitialized()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 1700); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!baseInitialized()"
")"); do { *((volatile int*)__null) = 1700; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1701 base_ = base;
1702 MOZ_ASSERT(baseInitialized())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(baseInitialized())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(baseInitialized()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("baseInitialized()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 1702); AnnotateMozCrashReason("MOZ_ASSERT" "(" "baseInitialized()"
")"); do { *((volatile int*)__null) = 1702; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1703 }
1704};
1705
1706class MWasmStackResult : public MUnaryInstruction, public NoTypePolicy::Data {
1707 uint32_t resultIdx_;
1708
1709 MWasmStackResult(MWasmStackResultArea* resultArea, size_t idx)
1710 : MUnaryInstruction(classOpcode, resultArea), resultIdx_(idx) {
1711 setResultType(result().type());
1712 setCallResultCapture();
1713 }
1714
1715 public:
1716 INSTRUCTION_HEADER(WasmStackResult)
1717 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
1718 NAMED_OPERANDS((0, resultArea))MDefinition* resultArea() const { return getOperand(0); }
1719
1720 const MWasmStackResultArea::StackResult& result() const {
1721 return resultArea()->toWasmStackResultArea()->result(resultIdx_);
1722 }
1723};
1724
1725// Mixin class for wasm calls that may or may not be catchable.
1726class MWasmCallBase {
1727 public:
1728 struct Arg {
1729 AnyRegister reg;
1730 MDefinition* def;
1731 Arg(AnyRegister reg, MDefinition* def) : reg(reg), def(def) {}
1732 };
1733 using Args = Vector<Arg, 8, SystemAllocPolicy>;
1734
1735 protected:
1736 wasm::CallSiteDesc desc_;
1737 wasm::CalleeDesc callee_;
1738 wasm::FailureMode builtinMethodFailureMode_;
1739 FixedList<AnyRegister> argRegs_;
1740 uint32_t stackArgAreaSizeUnaligned_;
1741 ABIArg instanceArg_;
1742 bool inTry_;
1743 size_t tryNoteIndex_;
1744
1745 MWasmCallBase(const wasm::CallSiteDesc& desc, const wasm::CalleeDesc& callee,
1746 uint32_t stackArgAreaSizeUnaligned, bool inTry,
1747 size_t tryNoteIndex)
1748 : desc_(desc),
1749 callee_(callee),
1750 builtinMethodFailureMode_(wasm::FailureMode::Infallible),
1751 stackArgAreaSizeUnaligned_(stackArgAreaSizeUnaligned),
1752 inTry_(inTry),
1753 tryNoteIndex_(tryNoteIndex) {}
1754
1755 template <class MVariadicT>
1756 [[nodiscard]] bool initWithArgs(TempAllocator& alloc, MVariadicT* ins,
1757 const Args& args,
1758 MDefinition* tableAddressOrRef) {
1759 if (!argRegs_.init(alloc, args.length())) {
1760 return false;
1761 }
1762 for (size_t i = 0; i < argRegs_.length(); i++) {
1763 argRegs_[i] = args[i].reg;
1764 }
1765
1766 if (!ins->init(alloc, argRegs_.length() + (tableAddressOrRef ? 1 : 0))) {
1767 return false;
1768 }
1769 // FixedList doesn't initialize its elements, so do an unchecked init.
1770 for (size_t i = 0; i < argRegs_.length(); i++) {
1771 ins->initOperand(i, args[i].def);
1772 }
1773 if (tableAddressOrRef) {
1774 ins->initOperand(argRegs_.length(), tableAddressOrRef);
1775 }
1776 return true;
1777 }
1778
1779 public:
1780 static bool IsWasmCall(MDefinition* def) {
1781 return def->isWasmCallCatchable() || def->isWasmCallUncatchable() ||
1782 def->isWasmReturnCall();
1783 }
1784
1785 size_t numArgs() const { return argRegs_.length(); }
1786 AnyRegister registerForArg(size_t index) const {
1787 MOZ_ASSERT(index < numArgs())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(index < numArgs())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(index < numArgs()))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("index < numArgs()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 1787); AnnotateMozCrashReason("MOZ_ASSERT" "(" "index < numArgs()"
")"); do { *((volatile int*)__null) = 1787; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1788 return argRegs_[index];
1789 }
1790 const wasm::CallSiteDesc& desc() const { return desc_; }
1791 const wasm::CalleeDesc& callee() const { return callee_; }
1792 wasm::FailureMode builtinMethodFailureMode() const {
1793 MOZ_ASSERT(callee_.which() == wasm::CalleeDesc::BuiltinInstanceMethod)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(callee_.which() == wasm::CalleeDesc::BuiltinInstanceMethod
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(callee_.which() == wasm::CalleeDesc::BuiltinInstanceMethod
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"callee_.which() == wasm::CalleeDesc::BuiltinInstanceMethod",
"/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 1793); AnnotateMozCrashReason("MOZ_ASSERT" "(" "callee_.which() == wasm::CalleeDesc::BuiltinInstanceMethod"
")"); do { *((volatile int*)__null) = 1793; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1794 return builtinMethodFailureMode_;
1795 }
1796 uint32_t stackArgAreaSizeUnaligned() const {
1797 return stackArgAreaSizeUnaligned_;
1798 }
1799
1800 const ABIArg& instanceArg() const { return instanceArg_; }
1801
1802 bool inTry() const { return inTry_; }
1803 size_t tryNoteIndex() const { return tryNoteIndex_; }
1804
1805 static AliasSet wasmCallAliasSet() {
1806 // This is ok because:
1807 // - numElements is immutable
1808 // - the GC will rewrite any array data pointers on move
1809 AliasSet exclude = AliasSet(AliasSet::WasmArrayNumElements) |
1810 AliasSet(AliasSet::WasmArrayDataPointer);
1811 return AliasSet::Store(AliasSet::Any) & ~exclude;
1812 }
1813};
1814
1815// A wasm call that is catchable. This instruction is a control instruction,
1816// and terminates the block it is on. A normal return will proceed in a the
1817// fallthrough block. An exceptional return will unwind into the landing pad
1818// block for this call. The landing pad block must begin with an
1819// MWasmCallLandingPrePad.
1820class MWasmCallCatchable final : public MVariadicControlInstruction<2>,
1821 public MWasmCallBase,
1822 public NoTypePolicy::Data {
1823 MWasmCallCatchable(const wasm::CallSiteDesc& desc,
1824 const wasm::CalleeDesc& callee,
1825 uint32_t stackArgAreaSizeUnaligned, size_t tryNoteIndex)
1826 : MVariadicControlInstruction(classOpcode),
1827 MWasmCallBase(desc, callee, stackArgAreaSizeUnaligned, true,
1828 tryNoteIndex) {}
1829
1830 public:
1831 INSTRUCTION_HEADER(WasmCallCatchable)
1832
1833 static MWasmCallCatchable* New(
1834 TempAllocator& alloc, const wasm::CallSiteDesc& desc,
1835 const wasm::CalleeDesc& callee, const Args& args,
1836 uint32_t stackArgAreaSizeUnaligned, uint32_t tryNoteIndex,
1837 MBasicBlock* fallthroughBlock, MBasicBlock* prePadBlock,
1838 MDefinition* tableAddressOrRef = nullptr);
1839
1840 static MWasmCallCatchable* NewBuiltinInstanceMethodCall(
1841 TempAllocator& alloc, const wasm::CallSiteDesc& desc,
1842 const wasm::SymbolicAddress builtin, wasm::FailureMode failureMode,
1843 const ABIArg& instanceArg, const Args& args,
1844 uint32_t stackArgAreaSizeUnaligned, uint32_t tryNoteIndex,
1845 MBasicBlock* fallthroughBlock, MBasicBlock* prePadBlock);
1846
1847 bool possiblyCalls() const override { return true; }
1848 AliasSet getAliasSet() const override { return wasmCallAliasSet(); }
1849
1850 static const size_t FallthroughBranchIndex = 0;
1851 static const size_t PrePadBranchIndex = 1;
1852};
1853
1854// A wasm call that is not catchable. This instruction is not a control
1855// instruction, and therefore is not a block terminator.
1856class MWasmCallUncatchable final : public MVariadicInstruction,
1857 public MWasmCallBase,
1858 public NoTypePolicy::Data {
1859 MWasmCallUncatchable(const wasm::CallSiteDesc& desc,
1860 const wasm::CalleeDesc& callee,
1861 uint32_t stackArgAreaSizeUnaligned)
1862 : MVariadicInstruction(classOpcode),
1863 MWasmCallBase(desc, callee, stackArgAreaSizeUnaligned, false, 0) {}
1864
1865 public:
1866 INSTRUCTION_HEADER(WasmCallUncatchable)
1867
1868 static MWasmCallUncatchable* New(TempAllocator& alloc,
1869 const wasm::CallSiteDesc& desc,
1870 const wasm::CalleeDesc& callee,
1871 const Args& args,
1872 uint32_t stackArgAreaSizeUnaligned,
1873 MDefinition* tableAddressOrRef = nullptr);
1874
1875 static MWasmCallUncatchable* NewBuiltinInstanceMethodCall(
1876 TempAllocator& alloc, const wasm::CallSiteDesc& desc,
1877 const wasm::SymbolicAddress builtin, wasm::FailureMode failureMode,
1878 const ABIArg& instanceArg, const Args& args,
1879 uint32_t stackArgAreaSizeUnaligned);
1880
1881 bool possiblyCalls() const override { return true; }
1882 AliasSet getAliasSet() const override { return wasmCallAliasSet(); }
1883};
1884
1885class MWasmReturnCall final : public MVariadicControlInstruction<0>,
1886 public MWasmCallBase,
1887 public NoTypePolicy::Data {
1888 MWasmReturnCall(const wasm::CallSiteDesc& desc,
1889 const wasm::CalleeDesc& callee,
1890 uint32_t stackArgAreaSizeUnaligned)
1891 : MVariadicControlInstruction(classOpcode),
1892 MWasmCallBase(desc, callee, stackArgAreaSizeUnaligned, false, 0) {}
1893
1894 public:
1895 INSTRUCTION_HEADER(WasmReturnCall)
1896
1897 static MWasmReturnCall* New(TempAllocator& alloc,
1898 const wasm::CallSiteDesc& desc,
1899 const wasm::CalleeDesc& callee, const Args& args,
1900 uint32_t stackArgAreaSizeUnaligned,
1901 MDefinition* tableAddressOrRef = nullptr);
1902
1903 bool possiblyCalls() const override { return true; }
1904};
1905
1906// A marker instruction for a block which is the landing pad for a catchable
1907// wasm call. This instruction does not emit any code, only filling in
1908// metadata. This instruction must be the first instruction added to the
1909// landing pad block.
1910class MWasmCallLandingPrePad : public MNullaryInstruction {
1911 // The block of the call that may unwind to this landing pad.
1912 MBasicBlock* callBlock_;
1913 // The index of the try note to initialize a landing pad for.
1914 size_t tryNoteIndex_;
1915
1916 explicit MWasmCallLandingPrePad(MBasicBlock* callBlock, size_t tryNoteIndex)
1917 : MNullaryInstruction(classOpcode),
1918 callBlock_(callBlock),
1919 tryNoteIndex_(tryNoteIndex) {
1920 setGuard();
1921 }
1922
1923 public:
1924 INSTRUCTION_HEADER(WasmCallLandingPrePad)
1925 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
1926
1927 AliasSet getAliasSet() const override { return AliasSet::None(); }
1928
1929 size_t tryNoteIndex() { return tryNoteIndex_; }
1930 MBasicBlock* callBlock() { return callBlock_; }
1931};
1932
1933class MWasmSelect : public MTernaryInstruction, public NoTypePolicy::Data {
1934 MWasmSelect(MDefinition* trueExpr, MDefinition* falseExpr,
1935 MDefinition* condExpr)
1936 : MTernaryInstruction(classOpcode, trueExpr, falseExpr, condExpr) {
1937 MOZ_ASSERT(condExpr->type() == MIRType::Int32)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(condExpr->type() == MIRType::Int32)>::isValid,
"invalid assertion condition"); if ((__builtin_expect(!!(!(!
!(condExpr->type() == MIRType::Int32))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("condExpr->type() == MIRType::Int32"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 1937); AnnotateMozCrashReason("MOZ_ASSERT" "(" "condExpr->type() == MIRType::Int32"
")"); do { *((volatile int*)__null) = 1937; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1938 MOZ_ASSERT(trueExpr->type() == falseExpr->type())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(trueExpr->type() == falseExpr->type())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(trueExpr->type() == falseExpr->type()))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("trueExpr->type() == falseExpr->type()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 1938); AnnotateMozCrashReason("MOZ_ASSERT" "(" "trueExpr->type() == falseExpr->type()"
")"); do { *((volatile int*)__null) = 1938; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1939 setResultType(trueExpr->type());
1940 setMovable();
1941 }
1942
1943 public:
1944 INSTRUCTION_HEADER(WasmSelect)
1945 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
1946 NAMED_OPERANDS((0, trueExpr), (1, falseExpr), (2, condExpr))MDefinition* trueExpr() const { return getOperand(0); } MDefinition
* falseExpr() const { return getOperand(1); } MDefinition* condExpr
() const { return getOperand(2); }
1947
1948 AliasSet getAliasSet() const override { return AliasSet::None(); }
1949
1950 bool congruentTo(const MDefinition* ins) const override {
1951 return congruentIfOperandsEqual(ins);
1952 }
1953
1954 ALLOW_CLONE(MWasmSelect)bool canClone() const override { return true; } MInstruction*
clone(TempAllocator& alloc, const MDefinitionVector&
inputs) const override { MInstruction* res = new (alloc) MWasmSelect
(*this); for (size_t i = 0; i < numOperands(); i++) res->
replaceOperand(i, inputs[i]); return res; }
1955};
1956
1957// Wasm SIMD.
1958//
1959// See comment in WasmIonCompile.cpp for a justification for these nodes.
1960
1961// (v128, v128, v128) -> v128 effect-free operation.
1962class MWasmTernarySimd128 : public MTernaryInstruction,
1963 public NoTypePolicy::Data {
1964 wasm::SimdOp simdOp_;
1965
1966 MWasmTernarySimd128(MDefinition* v0, MDefinition* v1, MDefinition* v2,
1967 wasm::SimdOp simdOp)
1968 : MTernaryInstruction(classOpcode, v0, v1, v2), simdOp_(simdOp) {
1969 setMovable();
1970 setResultType(MIRType::Simd128);
1971 }
1972
1973 public:
1974 INSTRUCTION_HEADER(WasmTernarySimd128)
1975 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
1976 NAMED_OPERANDS((0, v0), (1, v1), (2, v2))MDefinition* v0() const { return getOperand(0); } MDefinition
* v1() const { return getOperand(1); } MDefinition* v2() const
{ return getOperand(2); }
1977
1978 AliasSet getAliasSet() const override { return AliasSet::None(); }
1979 bool congruentTo(const MDefinition* ins) const override {
1980 return congruentIfOperandsEqual(ins) &&
1981 simdOp() == ins->toWasmTernarySimd128()->simdOp();
1982 }
1983#ifdef ENABLE_WASM_SIMD1
1984 MDefinition* foldsTo(TempAllocator& alloc) override;
1985
1986 // If the control mask of a bitselect allows the operation to be specialized
1987 // as a shuffle and it is profitable to specialize it on this platform, return
1988 // true and the appropriate shuffle mask.
1989 bool specializeBitselectConstantMaskAsShuffle(int8_t shuffle[16]);
1990 // Checks if more relaxed version of lane select can be used. It returns true
1991 // if a bit mask input expected to be all 0s or 1s for entire 8-bit lanes,
1992 // false otherwise.
1993 bool canRelaxBitselect();
1994#endif
1995
1996 wasm::SimdOp simdOp() const { return simdOp_; }
1997
1998 ALLOW_CLONE(MWasmTernarySimd128)bool canClone() const override { return true; } MInstruction*
clone(TempAllocator& alloc, const MDefinitionVector&
inputs) const override { MInstruction* res = new (alloc) MWasmTernarySimd128
(*this); for (size_t i = 0; i < numOperands(); i++) res->
replaceOperand(i, inputs[i]); return res; }
1999};
2000
2001// (v128, v128) -> v128 effect-free operations.
2002class MWasmBinarySimd128 : public MBinaryInstruction,
2003 public NoTypePolicy::Data {
2004 wasm::SimdOp simdOp_;
2005
2006 MWasmBinarySimd128(MDefinition* lhs, MDefinition* rhs, bool commutative,
2007 wasm::SimdOp simdOp)
2008 : MBinaryInstruction(classOpcode, lhs, rhs), simdOp_(simdOp) {
2009 setMovable();
2010 setResultType(MIRType::Simd128);
2011 if (commutative) {
2012 setCommutative();
2013 }
2014 }
2015
2016 public:
2017 INSTRUCTION_HEADER(WasmBinarySimd128)
2018 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
2019
2020 AliasSet getAliasSet() const override { return AliasSet::None(); }
2021 bool congruentTo(const MDefinition* ins) const override {
2022 return congruentIfOperandsEqual(ins) &&
2023 ins->toWasmBinarySimd128()->simdOp() == simdOp_;
2024 }
2025#ifdef ENABLE_WASM_SIMD1
2026 MDefinition* foldsTo(TempAllocator& alloc) override;
2027
2028 // Checks if pmaddubsw operation is supported.
2029 bool canPmaddubsw();
2030#endif
2031
2032 wasm::SimdOp simdOp() const { return simdOp_; }
2033
2034 // Platform-dependent specialization.
2035 bool specializeForConstantRhs();
2036
2037 ALLOW_CLONE(MWasmBinarySimd128)bool canClone() const override { return true; } MInstruction*
clone(TempAllocator& alloc, const MDefinitionVector&
inputs) const override { MInstruction* res = new (alloc) MWasmBinarySimd128
(*this); for (size_t i = 0; i < numOperands(); i++) res->
replaceOperand(i, inputs[i]); return res; }
2038};
2039
2040// (v128, const) -> v128 effect-free operations.
2041class MWasmBinarySimd128WithConstant : public MUnaryInstruction,
2042 public NoTypePolicy::Data {
2043 SimdConstant rhs_;
2044 wasm::SimdOp simdOp_;
2045
2046 MWasmBinarySimd128WithConstant(MDefinition* lhs, const SimdConstant& rhs,
2047 wasm::SimdOp simdOp)
2048 : MUnaryInstruction(classOpcode, lhs), rhs_(rhs), simdOp_(simdOp) {
2049 setMovable();
2050 setResultType(MIRType::Simd128);
2051 }
2052
2053 public:
2054 INSTRUCTION_HEADER(WasmBinarySimd128WithConstant)
2055 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
2056
2057 AliasSet getAliasSet() const override { return AliasSet::None(); }
2058 bool congruentTo(const MDefinition* ins) const override {
2059 return congruentIfOperandsEqual(ins) &&
2060 ins->toWasmBinarySimd128WithConstant()->simdOp() == simdOp_ &&
2061 rhs_.bitwiseEqual(ins->toWasmBinarySimd128WithConstant()->rhs());
2062 }
2063
2064 wasm::SimdOp simdOp() const { return simdOp_; }
2065 MDefinition* lhs() const { return input(); }
2066 const SimdConstant& rhs() const { return rhs_; }
2067
2068 ALLOW_CLONE(MWasmBinarySimd128WithConstant)bool canClone() const override { return true; } MInstruction*
clone(TempAllocator& alloc, const MDefinitionVector&
inputs) const override { MInstruction* res = new (alloc) MWasmBinarySimd128WithConstant
(*this); for (size_t i = 0; i < numOperands(); i++) res->
replaceOperand(i, inputs[i]); return res; }
2069};
2070
2071// (v128, scalar, imm) -> v128 effect-free operations.
2072class MWasmReplaceLaneSimd128 : public MBinaryInstruction,
2073 public NoTypePolicy::Data {
2074 uint32_t laneIndex_;
2075 wasm::SimdOp simdOp_;
2076
2077 MWasmReplaceLaneSimd128(MDefinition* lhs, MDefinition* rhs,
2078 uint32_t laneIndex, wasm::SimdOp simdOp)
2079 : MBinaryInstruction(classOpcode, lhs, rhs),
2080 laneIndex_(laneIndex),
2081 simdOp_(simdOp) {
2082 setMovable();
2083 setResultType(MIRType::Simd128);
2084 }
2085
2086 public:
2087 INSTRUCTION_HEADER(WasmReplaceLaneSimd128)
2088 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
2089
2090 AliasSet getAliasSet() const override { return AliasSet::None(); }
2091 bool congruentTo(const MDefinition* ins) const override {
2092 return congruentIfOperandsEqual(ins) &&
2093 ins->toWasmReplaceLaneSimd128()->simdOp() == simdOp_ &&
2094 ins->toWasmReplaceLaneSimd128()->laneIndex() == laneIndex_;
2095 }
2096
2097 uint32_t laneIndex() const { return laneIndex_; }
2098 wasm::SimdOp simdOp() const { return simdOp_; }
2099
2100 ALLOW_CLONE(MWasmReplaceLaneSimd128)bool canClone() const override { return true; } MInstruction*
clone(TempAllocator& alloc, const MDefinitionVector&
inputs) const override { MInstruction* res = new (alloc) MWasmReplaceLaneSimd128
(*this); for (size_t i = 0; i < numOperands(); i++) res->
replaceOperand(i, inputs[i]); return res; }
2101};
2102
2103// (scalar) -> v128 effect-free operations.
2104class MWasmScalarToSimd128 : public MUnaryInstruction,
2105 public NoTypePolicy::Data {
2106 wasm::SimdOp simdOp_;
2107
2108 MWasmScalarToSimd128(MDefinition* src, wasm::SimdOp simdOp)
2109 : MUnaryInstruction(classOpcode, src), simdOp_(simdOp) {
2110 setMovable();
2111 setResultType(MIRType::Simd128);
2112 }
2113
2114 public:
2115 INSTRUCTION_HEADER(WasmScalarToSimd128)
2116 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
2117
2118 AliasSet getAliasSet() const override { return AliasSet::None(); }
2119 bool congruentTo(const MDefinition* ins) const override {
2120 return congruentIfOperandsEqual(ins) &&
2121 ins->toWasmScalarToSimd128()->simdOp() == simdOp_;
2122 }
2123#ifdef ENABLE_WASM_SIMD1
2124 MDefinition* foldsTo(TempAllocator& alloc) override;
2125#endif
2126
2127 wasm::SimdOp simdOp() const { return simdOp_; }
2128
2129 ALLOW_CLONE(MWasmScalarToSimd128)bool canClone() const override { return true; } MInstruction*
clone(TempAllocator& alloc, const MDefinitionVector&
inputs) const override { MInstruction* res = new (alloc) MWasmScalarToSimd128
(*this); for (size_t i = 0; i < numOperands(); i++) res->
replaceOperand(i, inputs[i]); return res; }
2130};
2131
2132// (v128, imm) -> scalar effect-free operations.
2133class MWasmReduceSimd128 : public MUnaryInstruction, public NoTypePolicy::Data {
2134 wasm::SimdOp simdOp_;
2135 uint32_t imm_;
2136
2137 MWasmReduceSimd128(MDefinition* src, wasm::SimdOp simdOp, MIRType outType,
2138 uint32_t imm)
2139 : MUnaryInstruction(classOpcode, src), simdOp_(simdOp), imm_(imm) {
2140 setMovable();
2141 setResultType(outType);
2142 }
2143
2144 public:
2145 INSTRUCTION_HEADER(WasmReduceSimd128)
2146 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
2147
2148 AliasSet getAliasSet() const override { return AliasSet::None(); }
2149 bool congruentTo(const MDefinition* ins) const override {
2150 return congruentIfOperandsEqual(ins) &&
2151 ins->toWasmReduceSimd128()->simdOp() == simdOp_ &&
2152 ins->toWasmReduceSimd128()->imm() == imm_;
2153 }
2154#ifdef ENABLE_WASM_SIMD1
2155 MDefinition* foldsTo(TempAllocator& alloc) override;
2156#endif
2157
2158 uint32_t imm() const { return imm_; }
2159 wasm::SimdOp simdOp() const { return simdOp_; }
2160
2161 ALLOW_CLONE(MWasmReduceSimd128)bool canClone() const override { return true; } MInstruction*
clone(TempAllocator& alloc, const MDefinitionVector&
inputs) const override { MInstruction* res = new (alloc) MWasmReduceSimd128
(*this); for (size_t i = 0; i < numOperands(); i++) res->
replaceOperand(i, inputs[i]); return res; }
2162};
2163
2164class MWasmLoadLaneSimd128
2165 : public MVariadicInstruction, // memoryBase is nullptr on some platforms
2166 public NoTypePolicy::Data {
2167 wasm::MemoryAccessDesc access_;
2168 uint32_t laneSize_;
2169 uint32_t laneIndex_;
2170 uint32_t memoryBaseIndex_;
2171
2172 MWasmLoadLaneSimd128(const wasm::MemoryAccessDesc& access, uint32_t laneSize,
2173 uint32_t laneIndex, uint32_t memoryBaseIndex)
2174 : MVariadicInstruction(classOpcode),
2175 access_(access),
2176 laneSize_(laneSize),
2177 laneIndex_(laneIndex),
2178 memoryBaseIndex_(memoryBaseIndex) {
2179 MOZ_ASSERT(!access_.isAtomic())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!access_.isAtomic())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!access_.isAtomic()))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("!access_.isAtomic()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2179); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!access_.isAtomic()"
")"); do { *((volatile int*)__null) = 2179; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2180 setGuard();
2181 setResultType(MIRType::Simd128);
2182 }
2183
2184 public:
2185 INSTRUCTION_HEADER(WasmLoadLaneSimd128)
2186 NAMED_OPERANDS((0, base), (1, value))MDefinition* base() const { return getOperand(0); } MDefinition
* value() const { return getOperand(1); }
;
2187
2188 static MWasmLoadLaneSimd128* New(TempAllocator& alloc,
2189 MDefinition* memoryBase, MDefinition* base,
2190 const wasm::MemoryAccessDesc& access,
2191 uint32_t laneSize, uint32_t laneIndex,
2192 MDefinition* value) {
2193 uint32_t nextIndex = 2;
2194 uint32_t memoryBaseIndex = memoryBase ? nextIndex++ : UINT32_MAX(4294967295U);
2195
2196 MWasmLoadLaneSimd128* load = new (alloc)
2197 MWasmLoadLaneSimd128(access, laneSize, laneIndex, memoryBaseIndex);
2198 if (!load->init(alloc, nextIndex)) {
2199 return nullptr;
2200 }
2201
2202 load->initOperand(0, base);
2203 load->initOperand(1, value);
2204 if (memoryBase) {
2205 load->initOperand(memoryBaseIndex, memoryBase);
2206 }
2207
2208 return load;
2209 }
2210
2211 const wasm::MemoryAccessDesc& access() const { return access_; }
2212 uint32_t laneSize() const { return laneSize_; }
2213 uint32_t laneIndex() const { return laneIndex_; }
2214 bool hasMemoryBase() const { return memoryBaseIndex_ != UINT32_MAX(4294967295U); }
2215 MDefinition* memoryBase() const {
2216 MOZ_ASSERT(hasMemoryBase())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(hasMemoryBase())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(hasMemoryBase()))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("hasMemoryBase()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2216); AnnotateMozCrashReason("MOZ_ASSERT" "(" "hasMemoryBase()"
")"); do { *((volatile int*)__null) = 2216; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2217 return getOperand(memoryBaseIndex_);
2218 }
2219
2220 AliasSet getAliasSet() const override {
2221 return AliasSet::Load(AliasSet::WasmHeap);
2222 }
2223};
2224
2225class MWasmStoreLaneSimd128 : public MVariadicInstruction,
2226 public NoTypePolicy::Data {
2227 wasm::MemoryAccessDesc access_;
2228 uint32_t laneSize_;
2229 uint32_t laneIndex_;
2230 uint32_t memoryBaseIndex_;
2231
2232 explicit MWasmStoreLaneSimd128(const wasm::MemoryAccessDesc& access,
2233 uint32_t laneSize, uint32_t laneIndex,
2234 uint32_t memoryBaseIndex)
2235 : MVariadicInstruction(classOpcode),
2236 access_(access),
2237 laneSize_(laneSize),
2238 laneIndex_(laneIndex),
2239 memoryBaseIndex_(memoryBaseIndex) {
2240 MOZ_ASSERT(!access_.isAtomic())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!access_.isAtomic())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!access_.isAtomic()))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("!access_.isAtomic()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2240); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!access_.isAtomic()"
")"); do { *((volatile int*)__null) = 2240; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2241 setGuard();
2242 setResultType(MIRType::Simd128);
2243 }
2244
2245 public:
2246 INSTRUCTION_HEADER(WasmStoreLaneSimd128)
2247 NAMED_OPERANDS((0, base), (1, value))MDefinition* base() const { return getOperand(0); } MDefinition
* value() const { return getOperand(1); }
2248
2249 static MWasmStoreLaneSimd128* New(TempAllocator& alloc,
2250 MDefinition* memoryBase, MDefinition* base,
2251 const wasm::MemoryAccessDesc& access,
2252 uint32_t laneSize, uint32_t laneIndex,
2253 MDefinition* value) {
2254 uint32_t nextIndex = 2;
2255 uint32_t memoryBaseIndex = memoryBase ? nextIndex++ : UINT32_MAX(4294967295U);
2256
2257 MWasmStoreLaneSimd128* store = new (alloc)
2258 MWasmStoreLaneSimd128(access, laneSize, laneIndex, memoryBaseIndex);
2259 if (!store->init(alloc, nextIndex)) {
2260 return nullptr;
2261 }
2262
2263 store->initOperand(0, base);
2264 store->initOperand(1, value);
2265 if (memoryBase) {
2266 store->initOperand(memoryBaseIndex, memoryBase);
2267 }
2268
2269 return store;
2270 }
2271
2272 const wasm::MemoryAccessDesc& access() const { return access_; }
2273 uint32_t laneSize() const { return laneSize_; }
2274 uint32_t laneIndex() const { return laneIndex_; }
2275 bool hasMemoryBase() const { return memoryBaseIndex_ != UINT32_MAX(4294967295U); }
2276 MDefinition* memoryBase() const {
2277 MOZ_ASSERT(hasMemoryBase())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(hasMemoryBase())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(hasMemoryBase()))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("hasMemoryBase()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2277); AnnotateMozCrashReason("MOZ_ASSERT" "(" "hasMemoryBase()"
")"); do { *((volatile int*)__null) = 2277; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2278 return getOperand(memoryBaseIndex_);
2279 }
2280
2281 AliasSet getAliasSet() const override {
2282 return AliasSet::Store(AliasSet::WasmHeap);
2283 }
2284};
2285
2286// End Wasm SIMD
2287
2288class MIonToWasmCall final : public MVariadicInstruction,
2289 public NoTypePolicy::Data {
2290 CompilerGCPointer<WasmInstanceObject*> instanceObj_;
2291 const wasm::FuncExport& funcExport_;
2292
2293 MIonToWasmCall(WasmInstanceObject* instanceObj, MIRType resultType,
2294 const wasm::FuncExport& funcExport)
2295 : MVariadicInstruction(classOpcode),
2296 instanceObj_(instanceObj),
2297 funcExport_(funcExport) {
2298 setResultType(resultType);
2299 }
2300
2301 public:
2302 INSTRUCTION_HEADER(IonToWasmCall);
2303
2304 static MIonToWasmCall* New(TempAllocator& alloc,
2305 WasmInstanceObject* instanceObj,
2306 const wasm::FuncExport& funcExport);
2307
2308 void initArg(size_t i, MDefinition* arg) { initOperand(i, arg); }
2309
2310 WasmInstanceObject* instanceObject() const { return instanceObj_; }
2311 wasm::Instance* instance() const { return &instanceObj_->instance(); }
2312 const wasm::FuncExport& funcExport() const { return funcExport_; }
2313 bool possiblyCalls() const override { return true; }
2314#ifdef DEBUG1
2315 bool isConsistentFloat32Use(MUse* use) const override;
2316#endif
2317};
2318
2319// For accesses to wasm object fields, we need to be able to describe 8- and
2320// 16-bit accesses. But MIRType can't represent those. Hence these two
2321// supplemental enums, used for reading and writing fields respectively.
2322
2323// Indicates how to widen an 8- or 16-bit value (when it is read from memory).
2324enum class MWideningOp : uint8_t { None, FromU16, FromS16, FromU8, FromS8 };
2325
2326#ifdef JS_JITSPEW1
2327static inline const char* StringFromMWideningOp(MWideningOp op) {
2328 switch (op) {
2329 case MWideningOp::None:
2330 return "None";
2331 case MWideningOp::FromU16:
2332 return "FromU16";
2333 case MWideningOp::FromS16:
2334 return "FromS16";
2335 case MWideningOp::FromU8:
2336 return "FromU8";
2337 case MWideningOp::FromS8:
2338 return "FromS8";
2339 default:
2340 break;
2341 }
2342 MOZ_CRASH("Unknown MWideningOp")do { do { } while (false); MOZ_ReportCrash("" "Unknown MWideningOp"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2342); AnnotateMozCrashReason("MOZ_CRASH(" "Unknown MWideningOp"
")"); do { *((volatile int*)__null) = 2342; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
2343}
2344#endif
2345
2346// Indicates how to narrow a 32-bit value (when it is written to memory). The
2347// operation is a simple truncate.
2348enum class MNarrowingOp : uint8_t { None, To16, To8 };
2349
2350#ifdef JS_JITSPEW1
2351static inline const char* StringFromMNarrowingOp(MNarrowingOp op) {
2352 switch (op) {
2353 case MNarrowingOp::None:
2354 return "None";
2355 case MNarrowingOp::To16:
2356 return "To16";
2357 case MNarrowingOp::To8:
2358 return "To8";
2359 default:
2360 break;
2361 }
2362 MOZ_CRASH("Unknown MNarrowingOp")do { do { } while (false); MOZ_ReportCrash("" "Unknown MNarrowingOp"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2362); AnnotateMozCrashReason("MOZ_CRASH(" "Unknown MNarrowingOp"
")"); do { *((volatile int*)__null) = 2362; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
2363}
2364#endif
2365
2366// Load an object field stored at a fixed offset from a base pointer. This
2367// field may be any value type, including references. No barriers are
2368// performed. The offset must be representable as a 31-bit unsigned integer.
2369class MWasmLoadField : public MUnaryInstruction, public NoTypePolicy::Data {
2370 uint32_t offset_;
2371 MWideningOp wideningOp_;
2372 AliasSet aliases_;
2373 wasm::MaybeTrapSiteDesc maybeTrap_;
2374
2375 MWasmLoadField(MDefinition* obj, uint32_t offset, MIRType type,
2376 MWideningOp wideningOp, AliasSet aliases,
2377 wasm::MaybeTrapSiteDesc maybeTrap = mozilla::Nothing())
2378 : MUnaryInstruction(classOpcode, obj),
2379 offset_(uint32_t(offset)),
2380 wideningOp_(wideningOp),
2381 aliases_(aliases),
2382 maybeTrap_(maybeTrap) {
2383 MOZ_ASSERT(offset <= INT32_MAX)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(offset <= (2147483647))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(offset <= (2147483647))))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("offset <= (2147483647)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2383); AnnotateMozCrashReason("MOZ_ASSERT" "(" "offset <= (2147483647)"
")"); do { *((volatile int*)__null) = 2383; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2384 // "if you want to widen the value when it is loaded, the destination type
2385 // must be Int32".
2386 MOZ_ASSERT_IF(wideningOp != MWideningOp::None, type == MIRType::Int32)do { if (wideningOp != MWideningOp::None) { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(type ==
MIRType::Int32)>::isValid, "invalid assertion condition")
; if ((__builtin_expect(!!(!(!!(type == MIRType::Int32))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("type == MIRType::Int32"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2386); AnnotateMozCrashReason("MOZ_ASSERT" "(" "type == MIRType::Int32"
")"); do { *((volatile int*)__null) = 2386; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2387 MOZ_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataPointer
).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayNumElements
).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataPointer
).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any)
.flags())>::isValid, "invalid assertion condition"); if ((
__builtin_expect(!!(!(!!(aliases.flags() == AliasSet::Load(AliasSet
::WasmStructOutlineDataPointer).flags() || aliases.flags() ==
AliasSet::Load(AliasSet::WasmArrayNumElements).flags() || aliases
.flags() == AliasSet::Load(AliasSet::WasmArrayDataPointer).flags
() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags(
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataPointer).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayNumElements).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataPointer).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2394); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataPointer).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayNumElements).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataPointer).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2394; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2388 aliases.flags() ==do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataPointer
).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayNumElements
).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataPointer
).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any)
.flags())>::isValid, "invalid assertion condition"); if ((
__builtin_expect(!!(!(!!(aliases.flags() == AliasSet::Load(AliasSet
::WasmStructOutlineDataPointer).flags() || aliases.flags() ==
AliasSet::Load(AliasSet::WasmArrayNumElements).flags() || aliases
.flags() == AliasSet::Load(AliasSet::WasmArrayDataPointer).flags
() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags(
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataPointer).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayNumElements).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataPointer).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2394); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataPointer).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayNumElements).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataPointer).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2394; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2389 AliasSet::Load(AliasSet::WasmStructOutlineDataPointer).flags() ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataPointer
).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayNumElements
).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataPointer
).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any)
.flags())>::isValid, "invalid assertion condition"); if ((
__builtin_expect(!!(!(!!(aliases.flags() == AliasSet::Load(AliasSet
::WasmStructOutlineDataPointer).flags() || aliases.flags() ==
AliasSet::Load(AliasSet::WasmArrayNumElements).flags() || aliases
.flags() == AliasSet::Load(AliasSet::WasmArrayDataPointer).flags
() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags(
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataPointer).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayNumElements).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataPointer).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2394); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataPointer).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayNumElements).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataPointer).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2394; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2390 aliases.flags() ==do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataPointer
).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayNumElements
).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataPointer
).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any)
.flags())>::isValid, "invalid assertion condition"); if ((
__builtin_expect(!!(!(!!(aliases.flags() == AliasSet::Load(AliasSet
::WasmStructOutlineDataPointer).flags() || aliases.flags() ==
AliasSet::Load(AliasSet::WasmArrayNumElements).flags() || aliases
.flags() == AliasSet::Load(AliasSet::WasmArrayDataPointer).flags
() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags(
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataPointer).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayNumElements).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataPointer).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2394); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataPointer).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayNumElements).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataPointer).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2394; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2391 AliasSet::Load(AliasSet::WasmArrayNumElements).flags() ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataPointer
).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayNumElements
).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataPointer
).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any)
.flags())>::isValid, "invalid assertion condition"); if ((
__builtin_expect(!!(!(!!(aliases.flags() == AliasSet::Load(AliasSet
::WasmStructOutlineDataPointer).flags() || aliases.flags() ==
AliasSet::Load(AliasSet::WasmArrayNumElements).flags() || aliases
.flags() == AliasSet::Load(AliasSet::WasmArrayDataPointer).flags
() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags(
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataPointer).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayNumElements).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataPointer).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2394); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataPointer).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayNumElements).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataPointer).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2394; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2392 aliases.flags() ==do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataPointer
).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayNumElements
).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataPointer
).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any)
.flags())>::isValid, "invalid assertion condition"); if ((
__builtin_expect(!!(!(!!(aliases.flags() == AliasSet::Load(AliasSet
::WasmStructOutlineDataPointer).flags() || aliases.flags() ==
AliasSet::Load(AliasSet::WasmArrayNumElements).flags() || aliases
.flags() == AliasSet::Load(AliasSet::WasmArrayDataPointer).flags
() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags(
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataPointer).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayNumElements).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataPointer).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2394); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataPointer).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayNumElements).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataPointer).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2394; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2393 AliasSet::Load(AliasSet::WasmArrayDataPointer).flags() ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataPointer
).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayNumElements
).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataPointer
).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any)
.flags())>::isValid, "invalid assertion condition"); if ((
__builtin_expect(!!(!(!!(aliases.flags() == AliasSet::Load(AliasSet
::WasmStructOutlineDataPointer).flags() || aliases.flags() ==
AliasSet::Load(AliasSet::WasmArrayNumElements).flags() || aliases
.flags() == AliasSet::Load(AliasSet::WasmArrayDataPointer).flags
() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags(
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataPointer).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayNumElements).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataPointer).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2394); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataPointer).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayNumElements).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataPointer).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2394; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2394 aliases.flags() == AliasSet::Load(AliasSet::Any).flags())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataPointer
).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayNumElements
).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataPointer
).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any)
.flags())>::isValid, "invalid assertion condition"); if ((
__builtin_expect(!!(!(!!(aliases.flags() == AliasSet::Load(AliasSet
::WasmStructOutlineDataPointer).flags() || aliases.flags() ==
AliasSet::Load(AliasSet::WasmArrayNumElements).flags() || aliases
.flags() == AliasSet::Load(AliasSet::WasmArrayDataPointer).flags
() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags(
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataPointer).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayNumElements).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataPointer).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2394); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataPointer).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayNumElements).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataPointer).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2394; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2395 setResultType(type);
2396 if (maybeTrap_) {
2397 setGuard();
2398 }
2399 }
2400
2401 public:
2402 INSTRUCTION_HEADER(WasmLoadField)
2403 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
2404 NAMED_OPERANDS((0, obj))MDefinition* obj() const { return getOperand(0); }
2405
2406 uint32_t offset() const { return offset_; }
2407 MWideningOp wideningOp() const { return wideningOp_; }
2408 AliasSet getAliasSet() const override { return aliases_; }
2409 wasm::MaybeTrapSiteDesc maybeTrap() const { return maybeTrap_; }
2410
2411 bool congruentTo(const MDefinition* ins) const override {
2412 // In the limited case where this insn is used to read
2413 // WasmStructObject::outlineData_ (the field itself, not what it points
2414 // at), we allow commoning up to happen. This is OK because
2415 // WasmStructObject::outlineData_ is readonly for the life of the
2416 // WasmStructObject.
2417 if (!ins->isWasmLoadField()) {
2418 return false;
2419 }
2420 const MWasmLoadField* other = ins->toWasmLoadField();
2421 return ins->isWasmLoadField() && congruentIfOperandsEqual(ins) &&
2422 offset() == other->offset() && wideningOp() == other->wideningOp() &&
2423 getAliasSet().flags() == other->getAliasSet().flags();
2424 }
2425
2426#ifdef JS_JITSPEW1
2427 void getExtras(ExtrasCollector* extras) const override {
2428 char buf[96];
2429 SprintfLiteral(buf, "(offs=%lld, wideningOp=%s)", (long long int)offset_,
2430 StringFromMWideningOp(wideningOp_));
2431 extras->add(buf);
2432 }
2433#endif
2434};
2435
2436// Loads a value from a location, denoted as a fixed offset from a base
2437// pointer, which (it is assumed) is within a wasm object. This field may be
2438// any value type, including references. No barriers are performed.
2439//
2440// This instruction takes a pointer to a second object `ka`, which it is
2441// necessary to keep alive. It is expected that `ka` holds a reference to
2442// `obj`, but this is not enforced and no code is generated to access `ka`.
2443// This instruction extends the lifetime of `ka` so that it, and hence `obj`,
2444// cannot be collected while `obj` is live. This is necessary if `obj` does
2445// not point to a GC-managed object. `offset` must be representable as a
2446// 31-bit unsigned integer.
2447class MWasmLoadFieldKA : public MBinaryInstruction, public NoTypePolicy::Data {
2448 uint32_t offset_;
2449 uint32_t fieldIndex_;
2450 MWideningOp wideningOp_;
2451 AliasSet aliases_;
2452 wasm::MaybeTrapSiteDesc maybeTrap_;
2453
2454 MWasmLoadFieldKA(MDefinition* ka, MDefinition* obj, size_t offset,
2455 uint32_t fieldIndex, MIRType type, MWideningOp wideningOp,
2456 AliasSet aliases,
2457 wasm::MaybeTrapSiteDesc maybeTrap = mozilla::Nothing())
2458 : MBinaryInstruction(classOpcode, ka, obj),
2459 offset_(uint32_t(offset)),
2460 fieldIndex_(fieldIndex),
2461 wideningOp_(wideningOp),
2462 aliases_(aliases),
2463 maybeTrap_(maybeTrap) {
2464 MOZ_ASSERT(offset <= INT32_MAX)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(offset <= (2147483647))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(offset <= (2147483647))))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("offset <= (2147483647)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2464); AnnotateMozCrashReason("MOZ_ASSERT" "(" "offset <= (2147483647)"
")"); do { *((volatile int*)__null) = 2464; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2465 MOZ_ASSERT_IF(wideningOp != MWideningOp::None, type == MIRType::Int32)do { if (wideningOp != MWideningOp::None) { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(type ==
MIRType::Int32)>::isValid, "invalid assertion condition")
; if ((__builtin_expect(!!(!(!!(type == MIRType::Int32))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("type == MIRType::Int32"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2465); AnnotateMozCrashReason("MOZ_ASSERT" "(" "type == MIRType::Int32"
")"); do { *((volatile int*)__null) = 2465; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2466 MOZ_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases.flags() == AliasSet::Load(AliasSet::WasmStructInlineDataArea
).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataArea
).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any)
.flags())>::isValid, "invalid assertion condition"); if ((
__builtin_expect(!!(!(!!(aliases.flags() == AliasSet::Load(AliasSet
::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet
::Load(AliasSet::WasmStructOutlineDataArea).flags() || aliases
.flags() == AliasSet::Load(AliasSet::WasmArrayDataArea).flags
() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags(
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aliases.flags() == AliasSet::Load(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2473); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Load(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2473; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2467 aliases.flags() ==do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases.flags() == AliasSet::Load(AliasSet::WasmStructInlineDataArea
).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataArea
).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any)
.flags())>::isValid, "invalid assertion condition"); if ((
__builtin_expect(!!(!(!!(aliases.flags() == AliasSet::Load(AliasSet
::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet
::Load(AliasSet::WasmStructOutlineDataArea).flags() || aliases
.flags() == AliasSet::Load(AliasSet::WasmArrayDataArea).flags
() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags(
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aliases.flags() == AliasSet::Load(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2473); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Load(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2473; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2468 AliasSet::Load(AliasSet::WasmStructInlineDataArea).flags() ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases.flags() == AliasSet::Load(AliasSet::WasmStructInlineDataArea
).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataArea
).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any)
.flags())>::isValid, "invalid assertion condition"); if ((
__builtin_expect(!!(!(!!(aliases.flags() == AliasSet::Load(AliasSet
::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet
::Load(AliasSet::WasmStructOutlineDataArea).flags() || aliases
.flags() == AliasSet::Load(AliasSet::WasmArrayDataArea).flags
() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags(
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aliases.flags() == AliasSet::Load(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2473); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Load(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2473; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2469 aliases.flags() ==do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases.flags() == AliasSet::Load(AliasSet::WasmStructInlineDataArea
).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataArea
).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any)
.flags())>::isValid, "invalid assertion condition"); if ((
__builtin_expect(!!(!(!!(aliases.flags() == AliasSet::Load(AliasSet
::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet
::Load(AliasSet::WasmStructOutlineDataArea).flags() || aliases
.flags() == AliasSet::Load(AliasSet::WasmArrayDataArea).flags
() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags(
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aliases.flags() == AliasSet::Load(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2473); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Load(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2473; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2470 AliasSet::Load(AliasSet::WasmStructOutlineDataArea).flags() ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases.flags() == AliasSet::Load(AliasSet::WasmStructInlineDataArea
).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataArea
).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any)
.flags())>::isValid, "invalid assertion condition"); if ((
__builtin_expect(!!(!(!!(aliases.flags() == AliasSet::Load(AliasSet
::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet
::Load(AliasSet::WasmStructOutlineDataArea).flags() || aliases
.flags() == AliasSet::Load(AliasSet::WasmArrayDataArea).flags
() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags(
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aliases.flags() == AliasSet::Load(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2473); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Load(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2473; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2471 aliases.flags() ==do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases.flags() == AliasSet::Load(AliasSet::WasmStructInlineDataArea
).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataArea
).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any)
.flags())>::isValid, "invalid assertion condition"); if ((
__builtin_expect(!!(!(!!(aliases.flags() == AliasSet::Load(AliasSet
::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet
::Load(AliasSet::WasmStructOutlineDataArea).flags() || aliases
.flags() == AliasSet::Load(AliasSet::WasmArrayDataArea).flags
() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags(
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aliases.flags() == AliasSet::Load(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2473); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Load(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2473; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2472 AliasSet::Load(AliasSet::WasmArrayDataArea).flags() ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases.flags() == AliasSet::Load(AliasSet::WasmStructInlineDataArea
).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataArea
).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any)
.flags())>::isValid, "invalid assertion condition"); if ((
__builtin_expect(!!(!(!!(aliases.flags() == AliasSet::Load(AliasSet
::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet
::Load(AliasSet::WasmStructOutlineDataArea).flags() || aliases
.flags() == AliasSet::Load(AliasSet::WasmArrayDataArea).flags
() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags(
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aliases.flags() == AliasSet::Load(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2473); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Load(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2473; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2473 aliases.flags() == AliasSet::Load(AliasSet::Any).flags())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases.flags() == AliasSet::Load(AliasSet::WasmStructInlineDataArea
).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataArea
).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any)
.flags())>::isValid, "invalid assertion condition"); if ((
__builtin_expect(!!(!(!!(aliases.flags() == AliasSet::Load(AliasSet
::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet
::Load(AliasSet::WasmStructOutlineDataArea).flags() || aliases
.flags() == AliasSet::Load(AliasSet::WasmArrayDataArea).flags
() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags(
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aliases.flags() == AliasSet::Load(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2473); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Load(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2473; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2474 setResultType(type);
2475 if (maybeTrap_) {
2476 setGuard();
2477 }
2478 }
2479
2480 public:
2481 INSTRUCTION_HEADER(WasmLoadFieldKA)
2482 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
2483 NAMED_OPERANDS((0, ka), (1, obj))MDefinition* ka() const { return getOperand(0); } MDefinition
* obj() const { return getOperand(1); }
2484
2485 uint32_t offset() const { return offset_; }
2486 uint32_t fieldIndex() const { return fieldIndex_; }
2487 MWideningOp wideningOp() const { return wideningOp_; }
2488 AliasSet getAliasSet() const override { return aliases_; }
2489 wasm::MaybeTrapSiteDesc maybeTrap() const { return maybeTrap_; }
2490
2491#ifdef JS_JITSPEW1
2492 void getExtras(ExtrasCollector* extras) const override {
2493 char buf[96];
2494 SprintfLiteral(buf, "(offs=%lld, wideningOp=%s)", (long long int)offset_,
2495 StringFromMWideningOp(wideningOp_));
2496 extras->add(buf);
2497 }
2498#endif
2499};
2500
2501// Loads a value from base pointer, given an index and element size. This field
2502// may be any value type, including references. No barriers are performed.
2503//
2504// The element size is implicitly defined by MIRType and MWideningOp. For
2505// example, MIRType::Float32 indicates an element size of 32 bits, and
2506// MIRType::Int32 and MWideningOp::FromU16 together indicate an element size of
2507// 16 bits.
2508//
2509// This instruction takes a second object `ka` that must be kept alive, as
2510// described for MWasmLoadFieldKA above.
2511class MWasmLoadElementKA : public MTernaryInstruction,
2512 public NoTypePolicy::Data {
2513 MWideningOp wideningOp_;
2514 Scale scale_;
2515 AliasSet aliases_;
2516 wasm::MaybeTrapSiteDesc maybeTrap_;
2517
2518 MWasmLoadElementKA(MDefinition* ka, MDefinition* base, MDefinition* index,
2519 MIRType type, MWideningOp wideningOp, Scale scale,
2520 AliasSet aliases,
2521 wasm::MaybeTrapSiteDesc maybeTrap = mozilla::Nothing())
2522 : MTernaryInstruction(classOpcode, ka, base, index),
2523 wideningOp_(wideningOp),
2524 scale_(scale),
2525 aliases_(aliases),
2526 maybeTrap_(maybeTrap) {
2527 MOZ_ASSERT(base->type() == MIRType::WasmArrayData)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(base->type() == MIRType::WasmArrayData)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(base->type() == MIRType::WasmArrayData))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("base->type() == MIRType::WasmArrayData"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2527); AnnotateMozCrashReason("MOZ_ASSERT" "(" "base->type() == MIRType::WasmArrayData"
")"); do { *((volatile int*)__null) = 2527; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2528 MOZ_ASSERT(aliases.flags() ==do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any)
.flags())>::isValid, "invalid assertion condition"); if ((
__builtin_expect(!!(!(!!(aliases.flags() == AliasSet::Load(AliasSet
::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::
Load(AliasSet::Any).flags()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2530); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2530; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2529 AliasSet::Load(AliasSet::WasmArrayDataArea).flags() ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any)
.flags())>::isValid, "invalid assertion condition"); if ((
__builtin_expect(!!(!(!!(aliases.flags() == AliasSet::Load(AliasSet
::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::
Load(AliasSet::Any).flags()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2530); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2530; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2530 aliases.flags() == AliasSet::Load(AliasSet::Any).flags())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any)
.flags())>::isValid, "invalid assertion condition"); if ((
__builtin_expect(!!(!(!!(aliases.flags() == AliasSet::Load(AliasSet
::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::
Load(AliasSet::Any).flags()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2530); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2530; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2531 setResultType(type);
2532 if (maybeTrap_) {
2533 setGuard();
2534 }
2535 }
2536
2537 public:
2538 INSTRUCTION_HEADER(WasmLoadElementKA)
2539 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
2540 NAMED_OPERANDS((0, ka), (1, base), (2, index))MDefinition* ka() const { return getOperand(0); } MDefinition
* base() const { return getOperand(1); } MDefinition* index()
const { return getOperand(2); }
2541
2542 MWideningOp wideningOp() const { return wideningOp_; }
2543 Scale scale() const { return scale_; }
2544 AliasSet getAliasSet() const override { return aliases_; }
2545 wasm::MaybeTrapSiteDesc maybeTrap() const { return maybeTrap_; }
2546
2547#ifdef JS_JITSPEW1
2548 void getExtras(ExtrasCollector* extras) const override {
2549 char buf[96];
2550 SprintfLiteral(buf, "(wideningOp=%s, scale=%s)",
2551 StringFromMWideningOp(wideningOp_), StringFromScale(scale_));
2552 extras->add(buf);
2553 }
2554#endif
2555};
2556
2557// Stores a non-reference value to anlocation, denoted as a fixed offset from
2558// a base pointer, which (it is assumed) is within a wasm object. This field
2559// may be any value type, _excluding_ references. References _must_ use the
2560// 'Ref' variant of this instruction. The offset must be representable as a
2561// 31-bit unsigned integer.
2562//
2563// This instruction takes a second object `ka` that must be kept alive, as
2564// described for MWasmLoadFieldKA above.
2565class MWasmStoreFieldKA : public MTernaryInstruction,
2566 public NoTypePolicy::Data {
2567 uint32_t offset_;
2568 uint32_t fieldIndex_;
2569 MNarrowingOp narrowingOp_;
2570 AliasSet aliases_;
2571 wasm::MaybeTrapSiteDesc maybeTrap_;
2572
2573 MWasmStoreFieldKA(MDefinition* ka, MDefinition* obj, size_t offset,
2574 uint32_t fieldIndex, MDefinition* value,
2575 MNarrowingOp narrowingOp, AliasSet aliases,
2576 wasm::MaybeTrapSiteDesc maybeTrap = mozilla::Nothing())
2577 : MTernaryInstruction(classOpcode, ka, obj, value),
2578 offset_(uint32_t(offset)),
2579 fieldIndex_(fieldIndex),
2580 narrowingOp_(narrowingOp),
2581 aliases_(aliases),
2582 maybeTrap_(maybeTrap) {
2583 MOZ_ASSERT(offset <= INT32_MAX)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(offset <= (2147483647))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(offset <= (2147483647))))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("offset <= (2147483647)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2583); AnnotateMozCrashReason("MOZ_ASSERT" "(" "offset <= (2147483647)"
")"); do { *((volatile int*)__null) = 2583; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2584 MOZ_ASSERT(value->type() != MIRType::WasmAnyRef)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(value->type() != MIRType::WasmAnyRef)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(value->type() != MIRType::WasmAnyRef))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("value->type() != MIRType::WasmAnyRef"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2584); AnnotateMozCrashReason("MOZ_ASSERT" "(" "value->type() != MIRType::WasmAnyRef"
")"); do { *((volatile int*)__null) = 2584; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2585 // "if you want to narrow the value when it is stored, the source type
2586 // must be Int32".
2587 MOZ_ASSERT_IF(narrowingOp != MNarrowingOp::None,do { if (narrowingOp != MNarrowingOp::None) { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(value->
type() == MIRType::Int32)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(value->type() == MIRType::
Int32))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("value->type() == MIRType::Int32", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2588); AnnotateMozCrashReason("MOZ_ASSERT" "(" "value->type() == MIRType::Int32"
")"); do { *((volatile int*)__null) = 2588; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
2588 value->type() == MIRType::Int32)do { if (narrowingOp != MNarrowingOp::None) { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(value->
type() == MIRType::Int32)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(value->type() == MIRType::
Int32))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("value->type() == MIRType::Int32", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2588); AnnotateMozCrashReason("MOZ_ASSERT" "(" "value->type() == MIRType::Int32"
")"); do { *((volatile int*)__null) = 2588; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2589 MOZ_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any
).flags())>::isValid, "invalid assertion condition"); if (
(__builtin_expect(!!(!(!!(aliases.flags() == AliasSet::Store(
AliasSet::WasmStructInlineDataArea).flags() || aliases.flags(
) == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags
() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any
).flags()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2596); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2596; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2590 aliases.flags() ==do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any
).flags())>::isValid, "invalid assertion condition"); if (
(__builtin_expect(!!(!(!!(aliases.flags() == AliasSet::Store(
AliasSet::WasmStructInlineDataArea).flags() || aliases.flags(
) == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags
() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any
).flags()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2596); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2596; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2591 AliasSet::Store(AliasSet::WasmStructInlineDataArea).flags() ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any
).flags())>::isValid, "invalid assertion condition"); if (
(__builtin_expect(!!(!(!!(aliases.flags() == AliasSet::Store(
AliasSet::WasmStructInlineDataArea).flags() || aliases.flags(
) == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags
() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any
).flags()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2596); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2596; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2592 aliases.flags() ==do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any
).flags())>::isValid, "invalid assertion condition"); if (
(__builtin_expect(!!(!(!!(aliases.flags() == AliasSet::Store(
AliasSet::WasmStructInlineDataArea).flags() || aliases.flags(
) == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags
() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any
).flags()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2596); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2596; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2593 AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags() ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any
).flags())>::isValid, "invalid assertion condition"); if (
(__builtin_expect(!!(!(!!(aliases.flags() == AliasSet::Store(
AliasSet::WasmStructInlineDataArea).flags() || aliases.flags(
) == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags
() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any
).flags()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2596); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2596; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2594 aliases.flags() ==do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any
).flags())>::isValid, "invalid assertion condition"); if (
(__builtin_expect(!!(!(!!(aliases.flags() == AliasSet::Store(
AliasSet::WasmStructInlineDataArea).flags() || aliases.flags(
) == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags
() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any
).flags()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2596); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2596; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2595 AliasSet::Store(AliasSet::WasmArrayDataArea).flags() ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any
).flags())>::isValid, "invalid assertion condition"); if (
(__builtin_expect(!!(!(!!(aliases.flags() == AliasSet::Store(
AliasSet::WasmStructInlineDataArea).flags() || aliases.flags(
) == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags
() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any
).flags()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2596); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2596; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2596 aliases.flags() == AliasSet::Store(AliasSet::Any).flags())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any
).flags())>::isValid, "invalid assertion condition"); if (
(__builtin_expect(!!(!(!!(aliases.flags() == AliasSet::Store(
AliasSet::WasmStructInlineDataArea).flags() || aliases.flags(
) == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags
() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any
).flags()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2596); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2596; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2597 if (maybeTrap_) {
2598 setGuard();
2599 }
2600 }
2601
2602 public:
2603 INSTRUCTION_HEADER(WasmStoreFieldKA)
2604 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
2605 NAMED_OPERANDS((0, ka), (1, obj), (2, value))MDefinition* ka() const { return getOperand(0); } MDefinition
* obj() const { return getOperand(1); } MDefinition* value() const
{ return getOperand(2); }
2606
2607 uint32_t offset() const { return offset_; }
2608 uint32_t fieldIndex() const { return fieldIndex_; }
2609 MNarrowingOp narrowingOp() const { return narrowingOp_; }
2610 AliasSet getAliasSet() const override { return aliases_; }
2611 wasm::MaybeTrapSiteDesc maybeTrap() const { return maybeTrap_; }
2612
2613#ifdef JS_JITSPEW1
2614 void getExtras(ExtrasCollector* extras) const override {
2615 char buf[96];
2616 SprintfLiteral(buf, "(offs=%lld, narrowingOp=%s)", (long long int)offset_,
2617 StringFromMNarrowingOp(narrowingOp_));
2618 extras->add(buf);
2619 }
2620#endif
2621};
2622
2623// Stores a reference value to a location, denoted as a fixed offset from a
2624// base pointer, which (it is assumed) is within a wasm object. This
2625// instruction emits a pre-barrier. A post barrier _must_ be performed
2626// separately. The offset must be representable as a 31-bit unsigned integer.
2627//
2628// This instruction takes a second object `ka` that must be kept alive, as
2629// described for MWasmLoadFieldKA above.
2630class MWasmStoreFieldRefKA : public MAryInstruction<4>,
2631 public NoTypePolicy::Data {
2632 uint32_t offset_;
2633 uint32_t fieldIndex_;
2634 AliasSet aliases_;
2635 wasm::MaybeTrapSiteDesc maybeTrap_;
2636 WasmPreBarrierKind preBarrierKind_;
2637
2638 MWasmStoreFieldRefKA(MDefinition* instance, MDefinition* ka, MDefinition* obj,
2639 size_t offset, uint32_t fieldIndex, MDefinition* value,
2640 AliasSet aliases, wasm::MaybeTrapSiteDesc maybeTrap,
2641 WasmPreBarrierKind preBarrierKind)
2642 : MAryInstruction<4>(classOpcode),
2643 offset_(uint32_t(offset)),
2644 fieldIndex_(fieldIndex),
2645 aliases_(aliases),
2646 maybeTrap_(maybeTrap),
2647 preBarrierKind_(preBarrierKind) {
2648 MOZ_ASSERT(obj->type() == TargetWordMIRType() ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(obj->type() == TargetWordMIRType() || obj->type
() == MIRType::Pointer || obj->type() == MIRType::WasmAnyRef
|| obj->type() == MIRType::WasmArrayData)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(obj->type() == TargetWordMIRType
() || obj->type() == MIRType::Pointer || obj->type() ==
MIRType::WasmAnyRef || obj->type() == MIRType::WasmArrayData
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"obj->type() == TargetWordMIRType() || obj->type() == MIRType::Pointer || obj->type() == MIRType::WasmAnyRef || obj->type() == MIRType::WasmArrayData"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2651); AnnotateMozCrashReason("MOZ_ASSERT" "(" "obj->type() == TargetWordMIRType() || obj->type() == MIRType::Pointer || obj->type() == MIRType::WasmAnyRef || obj->type() == MIRType::WasmArrayData"
")"); do { *((volatile int*)__null) = 2651; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2649 obj->type() == MIRType::Pointer ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(obj->type() == TargetWordMIRType() || obj->type
() == MIRType::Pointer || obj->type() == MIRType::WasmAnyRef
|| obj->type() == MIRType::WasmArrayData)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(obj->type() == TargetWordMIRType
() || obj->type() == MIRType::Pointer || obj->type() ==
MIRType::WasmAnyRef || obj->type() == MIRType::WasmArrayData
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"obj->type() == TargetWordMIRType() || obj->type() == MIRType::Pointer || obj->type() == MIRType::WasmAnyRef || obj->type() == MIRType::WasmArrayData"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2651); AnnotateMozCrashReason("MOZ_ASSERT" "(" "obj->type() == TargetWordMIRType() || obj->type() == MIRType::Pointer || obj->type() == MIRType::WasmAnyRef || obj->type() == MIRType::WasmArrayData"
")"); do { *((volatile int*)__null) = 2651; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2650 obj->type() == MIRType::WasmAnyRef ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(obj->type() == TargetWordMIRType() || obj->type
() == MIRType::Pointer || obj->type() == MIRType::WasmAnyRef
|| obj->type() == MIRType::WasmArrayData)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(obj->type() == TargetWordMIRType
() || obj->type() == MIRType::Pointer || obj->type() ==
MIRType::WasmAnyRef || obj->type() == MIRType::WasmArrayData
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"obj->type() == TargetWordMIRType() || obj->type() == MIRType::Pointer || obj->type() == MIRType::WasmAnyRef || obj->type() == MIRType::WasmArrayData"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2651); AnnotateMozCrashReason("MOZ_ASSERT" "(" "obj->type() == TargetWordMIRType() || obj->type() == MIRType::Pointer || obj->type() == MIRType::WasmAnyRef || obj->type() == MIRType::WasmArrayData"
")"); do { *((volatile int*)__null) = 2651; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2651 obj->type() == MIRType::WasmArrayData)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(obj->type() == TargetWordMIRType() || obj->type
() == MIRType::Pointer || obj->type() == MIRType::WasmAnyRef
|| obj->type() == MIRType::WasmArrayData)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(obj->type() == TargetWordMIRType
() || obj->type() == MIRType::Pointer || obj->type() ==
MIRType::WasmAnyRef || obj->type() == MIRType::WasmArrayData
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"obj->type() == TargetWordMIRType() || obj->type() == MIRType::Pointer || obj->type() == MIRType::WasmAnyRef || obj->type() == MIRType::WasmArrayData"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2651); AnnotateMozCrashReason("MOZ_ASSERT" "(" "obj->type() == TargetWordMIRType() || obj->type() == MIRType::Pointer || obj->type() == MIRType::WasmAnyRef || obj->type() == MIRType::WasmArrayData"
")"); do { *((volatile int*)__null) = 2651; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2652 MOZ_ASSERT(offset <= INT32_MAX)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(offset <= (2147483647))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(offset <= (2147483647))))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("offset <= (2147483647)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2652); AnnotateMozCrashReason("MOZ_ASSERT" "(" "offset <= (2147483647)"
")"); do { *((volatile int*)__null) = 2652; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2653 MOZ_ASSERT(value->type() == MIRType::WasmAnyRef)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(value->type() == MIRType::WasmAnyRef)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(value->type() == MIRType::WasmAnyRef))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("value->type() == MIRType::WasmAnyRef"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2653); AnnotateMozCrashReason("MOZ_ASSERT" "(" "value->type() == MIRType::WasmAnyRef"
")"); do { *((volatile int*)__null) = 2653; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2654 MOZ_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any
).flags())>::isValid, "invalid assertion condition"); if (
(__builtin_expect(!!(!(!!(aliases.flags() == AliasSet::Store(
AliasSet::WasmStructInlineDataArea).flags() || aliases.flags(
) == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags
() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any
).flags()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2661); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2661; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2655 aliases.flags() ==do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any
).flags())>::isValid, "invalid assertion condition"); if (
(__builtin_expect(!!(!(!!(aliases.flags() == AliasSet::Store(
AliasSet::WasmStructInlineDataArea).flags() || aliases.flags(
) == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags
() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any
).flags()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2661); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2661; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2656 AliasSet::Store(AliasSet::WasmStructInlineDataArea).flags() ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any
).flags())>::isValid, "invalid assertion condition"); if (
(__builtin_expect(!!(!(!!(aliases.flags() == AliasSet::Store(
AliasSet::WasmStructInlineDataArea).flags() || aliases.flags(
) == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags
() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any
).flags()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2661); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2661; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2657 aliases.flags() ==do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any
).flags())>::isValid, "invalid assertion condition"); if (
(__builtin_expect(!!(!(!!(aliases.flags() == AliasSet::Store(
AliasSet::WasmStructInlineDataArea).flags() || aliases.flags(
) == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags
() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any
).flags()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2661); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2661; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2658 AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags() ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any
).flags())>::isValid, "invalid assertion condition"); if (
(__builtin_expect(!!(!(!!(aliases.flags() == AliasSet::Store(
AliasSet::WasmStructInlineDataArea).flags() || aliases.flags(
) == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags
() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any
).flags()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2661); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2661; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2659 aliases.flags() ==do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any
).flags())>::isValid, "invalid assertion condition"); if (
(__builtin_expect(!!(!(!!(aliases.flags() == AliasSet::Store(
AliasSet::WasmStructInlineDataArea).flags() || aliases.flags(
) == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags
() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any
).flags()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2661); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2661; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2660 AliasSet::Store(AliasSet::WasmArrayDataArea).flags() ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any
).flags())>::isValid, "invalid assertion condition"); if (
(__builtin_expect(!!(!(!!(aliases.flags() == AliasSet::Store(
AliasSet::WasmStructInlineDataArea).flags() || aliases.flags(
) == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags
() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any
).flags()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2661); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2661; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2661 aliases.flags() == AliasSet::Store(AliasSet::Any).flags())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any
).flags())>::isValid, "invalid assertion condition"); if (
(__builtin_expect(!!(!(!!(aliases.flags() == AliasSet::Store(
AliasSet::WasmStructInlineDataArea).flags() || aliases.flags(
) == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags
() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any
).flags()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2661); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Store(AliasSet::WasmStructInlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmStructOutlineDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2661; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2662 initOperand(0, instance);
2663 initOperand(1, ka);
2664 initOperand(2, obj);
2665 initOperand(3, value);
2666 if (maybeTrap_) {
2667 setGuard();
2668 }
2669 }
2670
2671 public:
2672 INSTRUCTION_HEADER(WasmStoreFieldRefKA)
2673 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
2674 NAMED_OPERANDS((0, instance), (1, ka), (2, obj), (3, value))MDefinition* instance() const { return getOperand(0); } MDefinition
* ka() const { return getOperand(1); } MDefinition* obj() const
{ return getOperand(2); } MDefinition* value() const { return
getOperand(3); }
2675
2676 uint32_t offset() const { return offset_; }
2677 uint32_t fieldIndex() const { return fieldIndex_; }
2678 AliasSet getAliasSet() const override { return aliases_; }
2679 wasm::MaybeTrapSiteDesc maybeTrap() const { return maybeTrap_; }
2680 WasmPreBarrierKind preBarrierKind() const { return preBarrierKind_; }
2681
2682#ifdef JS_JITSPEW1
2683 void getExtras(ExtrasCollector* extras) const override {
2684 char buf[64];
2685 SprintfLiteral(buf, "(offs=%lld)", (long long int)offset_);
2686 extras->add(buf);
2687 }
2688#endif
2689};
2690
2691// Stores a non-reference value to a base pointer, given an index and element
2692// size. This field may be any value type, excluding references. References MUST
2693// use the 'Ref' variant of this instruction.
2694//
2695// The element size is implicitly defined by MIRType and MNarrowingOp. For
2696// example, MIRType::Float32 indicates an element size of 32 bits, and
2697// MIRType::Int32 and MNarrowingOp::To16 together indicate an element size of 16
2698// bits.
2699//
2700// This instruction takes a second object `ka` that must be kept alive, as
2701// described for MWasmLoadFieldKA above.
2702class MWasmStoreElementKA : public MQuaternaryInstruction,
2703 public NoTypePolicy::Data {
2704 MNarrowingOp narrowingOp_;
2705 Scale scale_;
2706 AliasSet aliases_;
2707 wasm::MaybeTrapSiteDesc maybeTrap_;
2708
2709 MWasmStoreElementKA(MDefinition* ka, MDefinition* base, MDefinition* index,
2710 MDefinition* value, MNarrowingOp narrowingOp, Scale scale,
2711 AliasSet aliases,
2712 wasm::MaybeTrapSiteDesc maybeTrap = mozilla::Nothing())
2713 : MQuaternaryInstruction(classOpcode, ka, base, index, value),
2714 narrowingOp_(narrowingOp),
2715 scale_(scale),
2716 aliases_(aliases),
2717 maybeTrap_(maybeTrap) {
2718 MOZ_ASSERT(base->type() == MIRType::WasmArrayData)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(base->type() == MIRType::WasmArrayData)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(base->type() == MIRType::WasmArrayData))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("base->type() == MIRType::WasmArrayData"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2718); AnnotateMozCrashReason("MOZ_ASSERT" "(" "base->type() == MIRType::WasmArrayData"
")"); do { *((volatile int*)__null) = 2718; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2719 MOZ_ASSERT(value->type() != MIRType::WasmAnyRef)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(value->type() != MIRType::WasmAnyRef)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(value->type() != MIRType::WasmAnyRef))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("value->type() != MIRType::WasmAnyRef"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2719); AnnotateMozCrashReason("MOZ_ASSERT" "(" "value->type() != MIRType::WasmAnyRef"
")"); do { *((volatile int*)__null) = 2719; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2720 // "if you want to narrow the value when it is stored, the source type
2721 // must be Int32".
2722 MOZ_ASSERT_IF(narrowingOp != MNarrowingOp::None,do { if (narrowingOp != MNarrowingOp::None) { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(value->
type() == MIRType::Int32)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(value->type() == MIRType::
Int32))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("value->type() == MIRType::Int32", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2723); AnnotateMozCrashReason("MOZ_ASSERT" "(" "value->type() == MIRType::Int32"
")"); do { *((volatile int*)__null) = 2723; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
2723 value->type() == MIRType::Int32)do { if (narrowingOp != MNarrowingOp::None) { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(value->
type() == MIRType::Int32)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(value->type() == MIRType::
Int32))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("value->type() == MIRType::Int32", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2723); AnnotateMozCrashReason("MOZ_ASSERT" "(" "value->type() == MIRType::Int32"
")"); do { *((volatile int*)__null) = 2723; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2724 MOZ_ASSERT(aliases.flags() ==do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any
).flags())>::isValid, "invalid assertion condition"); if (
(__builtin_expect(!!(!(!!(aliases.flags() == AliasSet::Store(
AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet
::Store(AliasSet::Any).flags()))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2726); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2726; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2725 AliasSet::Store(AliasSet::WasmArrayDataArea).flags() ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any
).flags())>::isValid, "invalid assertion condition"); if (
(__builtin_expect(!!(!(!!(aliases.flags() == AliasSet::Store(
AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet
::Store(AliasSet::Any).flags()))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2726); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2726; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2726 aliases.flags() == AliasSet::Store(AliasSet::Any).flags())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any
).flags())>::isValid, "invalid assertion condition"); if (
(__builtin_expect(!!(!(!!(aliases.flags() == AliasSet::Store(
AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet
::Store(AliasSet::Any).flags()))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2726); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2726; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2727 if (maybeTrap_) {
2728 setGuard();
2729 }
2730 }
2731
2732 public:
2733 INSTRUCTION_HEADER(WasmStoreElementKA)
2734 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
2735 NAMED_OPERANDS((0, ka), (1, base), (2, index), (3, value))MDefinition* ka() const { return getOperand(0); } MDefinition
* base() const { return getOperand(1); } MDefinition* index()
const { return getOperand(2); } MDefinition* value() const {
return getOperand(3); }
2736
2737 MNarrowingOp narrowingOp() const { return narrowingOp_; }
2738 Scale scale() const { return scale_; }
2739 AliasSet getAliasSet() const override { return aliases_; }
2740 wasm::MaybeTrapSiteDesc maybeTrap() const { return maybeTrap_; }
2741
2742#ifdef JS_JITSPEW1
2743 void getExtras(ExtrasCollector* extras) const override {
2744 char buf[96];
2745 SprintfLiteral(buf, "(narrowingOp=%s, scale=%s)",
2746 StringFromMNarrowingOp(narrowingOp_),
2747 StringFromScale(scale_));
2748 extras->add(buf);
2749 }
2750#endif
2751};
2752
2753// Stores a reference value to a base pointer, given an index and element size.
2754// This instruction emits a pre-barrier. A post barrier MUST be performed
2755// separately.
2756//
2757// The element size is implicitly defined by MIRType and MNarrowingOp, as
2758// described for MWasmStoreElementKA above.
2759//
2760// This instruction takes a second object `ka` that must be kept alive, as
2761// described for MWasmLoadFieldKA above.
2762class MWasmStoreElementRefKA : public MAryInstruction<5>,
2763 public NoTypePolicy::Data {
2764 AliasSet aliases_;
2765 wasm::MaybeTrapSiteDesc maybeTrap_;
2766 WasmPreBarrierKind preBarrierKind_;
2767
2768 MWasmStoreElementRefKA(MDefinition* instance, MDefinition* ka,
2769 MDefinition* base, MDefinition* index,
2770 MDefinition* value, AliasSet aliases,
2771 wasm::MaybeTrapSiteDesc maybeTrap,
2772 WasmPreBarrierKind preBarrierKind)
2773 : MAryInstruction<5>(classOpcode),
2774 aliases_(aliases),
2775 maybeTrap_(maybeTrap),
2776 preBarrierKind_(preBarrierKind) {
2777 MOZ_ASSERT(base->type() == MIRType::WasmArrayData)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(base->type() == MIRType::WasmArrayData)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(base->type() == MIRType::WasmArrayData))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("base->type() == MIRType::WasmArrayData"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2777); AnnotateMozCrashReason("MOZ_ASSERT" "(" "base->type() == MIRType::WasmArrayData"
")"); do { *((volatile int*)__null) = 2777; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2778 MOZ_ASSERT(value->type() == MIRType::WasmAnyRef)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(value->type() == MIRType::WasmAnyRef)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(value->type() == MIRType::WasmAnyRef))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("value->type() == MIRType::WasmAnyRef"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2778); AnnotateMozCrashReason("MOZ_ASSERT" "(" "value->type() == MIRType::WasmAnyRef"
")"); do { *((volatile int*)__null) = 2778; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2779 MOZ_ASSERT(aliases.flags() ==do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any
).flags())>::isValid, "invalid assertion condition"); if (
(__builtin_expect(!!(!(!!(aliases.flags() == AliasSet::Store(
AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet
::Store(AliasSet::Any).flags()))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2781); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2781; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2780 AliasSet::Store(AliasSet::WasmArrayDataArea).flags() ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any
).flags())>::isValid, "invalid assertion condition"); if (
(__builtin_expect(!!(!(!!(aliases.flags() == AliasSet::Store(
AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet
::Store(AliasSet::Any).flags()))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2781); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2781; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2781 aliases.flags() == AliasSet::Store(AliasSet::Any).flags())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea
).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any
).flags())>::isValid, "invalid assertion condition"); if (
(__builtin_expect(!!(!(!!(aliases.flags() == AliasSet::Store(
AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet
::Store(AliasSet::Any).flags()))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2781); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2781; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2782 initOperand(0, instance);
2783 initOperand(1, ka);
2784 initOperand(2, base);
2785 initOperand(3, index);
2786 initOperand(4, value);
2787 if (maybeTrap_) {
2788 setGuard();
2789 }
2790 }
2791
2792 public:
2793 INSTRUCTION_HEADER(WasmStoreElementRefKA)
2794 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
2795 NAMED_OPERANDS((0, instance), (1, ka), (2, base), (3, index), (4, value))MDefinition* instance() const { return getOperand(0); } MDefinition
* ka() const { return getOperand(1); } MDefinition* base() const
{ return getOperand(2); } MDefinition* index() const { return
getOperand(3); } MDefinition* value() const { return getOperand
(4); }
2796
2797 AliasSet getAliasSet() const override { return aliases_; }
2798 wasm::MaybeTrapSiteDesc maybeTrap() const { return maybeTrap_; }
2799 WasmPreBarrierKind preBarrierKind() const { return preBarrierKind_; }
2800};
2801
2802class MWasmRefIsSubtypeOfAbstract : public MUnaryInstruction,
2803 public NoTypePolicy::Data {
2804 wasm::RefType sourceType_;
2805 wasm::RefType destType_;
2806
2807 MWasmRefIsSubtypeOfAbstract(MDefinition* ref, wasm::RefType sourceType,
2808 wasm::RefType destType)
2809 : MUnaryInstruction(classOpcode, ref),
2810 sourceType_(sourceType),
2811 destType_(destType) {
2812 MOZ_ASSERT(!destType.isTypeRef())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!destType.isTypeRef())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!destType.isTypeRef()))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("!destType.isTypeRef()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2812); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!destType.isTypeRef()"
")"); do { *((volatile int*)__null) = 2812; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2813 setResultType(MIRType::Int32);
2814 setMovable();
2815 }
2816
2817 public:
2818 INSTRUCTION_HEADER(WasmRefIsSubtypeOfAbstract)
2819 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
2820 NAMED_OPERANDS((0, ref))MDefinition* ref() const { return getOperand(0); }
2821
2822 wasm::RefType sourceType() const { return sourceType_; };
2823 wasm::RefType destType() const { return destType_; };
2824
2825 bool congruentTo(const MDefinition* ins) const override {
2826 return congruentIfOperandsEqual(ins) &&
2827 sourceType() == ins->toWasmRefIsSubtypeOfAbstract()->sourceType() &&
2828 destType() == ins->toWasmRefIsSubtypeOfAbstract()->destType();
2829 }
2830
2831 HashNumber valueHash() const override {
2832 HashNumber hn = MUnaryInstruction::valueHash();
2833 hn = addU64ToHash(hn, sourceType().packed().bits());
2834 hn = addU64ToHash(hn, destType().packed().bits());
2835 return hn;
2836 }
2837
2838 MDefinition* foldsTo(TempAllocator& alloc) override;
2839};
2840
2841// Represents the contents of all fields of a wasm struct.
2842// This class will be used for scalar replacement of wasm structs.
2843class MWasmStructState : public TempObject {
2844 private:
2845 MDefinition* wasmStruct_;
2846 // Represents the fields of this struct.
2847 Vector<MDefinition*, 0, JitAllocPolicy> fields_;
2848
2849 explicit MWasmStructState(TempAllocator& alloc, MDefinition* structObject)
2850 : wasmStruct_(structObject), fields_(alloc) {}
2851
2852 public:
2853 static MWasmStructState* New(TempAllocator& alloc, MDefinition* structObject);
2854 static MWasmStructState* Copy(TempAllocator& alloc, MWasmStructState* state);
2855
2856 // Init the fields_ vector.
2857 [[nodiscard]] bool init();
2858
2859 size_t numFields() const { return fields_.length(); }
2860 MDefinition* wasmStruct() const { return wasmStruct_; }
2861
2862 // Get the field value based on the position of the field in the struct.
2863 MDefinition* getField(uint32_t index) const { return fields_[index]; }
2864 // Set the field offset based on the position of the field in the struct.
2865 void setField(uint32_t index, MDefinition* def) { fields_[index] = def; }
2866};
2867
2868// Tests if the wasm ref `ref` is a subtype of `superSTV`.
2869// The actual super type definition must be known at compile time, so that the
2870// subtyping depth of super type depth can be used.
2871class MWasmRefIsSubtypeOfConcrete : public MBinaryInstruction,
2872 public NoTypePolicy::Data {
2873 wasm::RefType sourceType_;
2874 wasm::RefType destType_;
2875
2876 MWasmRefIsSubtypeOfConcrete(MDefinition* ref, MDefinition* superSTV,
2877 wasm::RefType sourceType, wasm::RefType destType)
2878 : MBinaryInstruction(classOpcode, ref, superSTV),
2879 sourceType_(sourceType),
2880 destType_(destType) {
2881 MOZ_ASSERT(destType.isTypeRef())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(destType.isTypeRef())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(destType.isTypeRef()))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("destType.isTypeRef()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 2881); AnnotateMozCrashReason("MOZ_ASSERT" "(" "destType.isTypeRef()"
")"); do { *((volatile int*)__null) = 2881; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2882 setResultType(MIRType::Int32);
2883 setMovable();
2884 }
2885
2886 public:
2887 INSTRUCTION_HEADER(WasmRefIsSubtypeOfConcrete)
2888 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
2889 NAMED_OPERANDS((0, ref), (1, superSTV))MDefinition* ref() const { return getOperand(0); } MDefinition
* superSTV() const { return getOperand(1); }
2890
2891 wasm::RefType sourceType() const { return sourceType_; };
2892 wasm::RefType destType() const { return destType_; };
2893
2894 bool congruentTo(const MDefinition* ins) const override {
2895 return congruentIfOperandsEqual(ins) &&
2896 sourceType() == ins->toWasmRefIsSubtypeOfConcrete()->sourceType() &&
2897 destType() == ins->toWasmRefIsSubtypeOfConcrete()->destType();
2898 }
2899
2900 HashNumber valueHash() const override {
2901 HashNumber hn = MBinaryInstruction::valueHash();
2902 hn = addU64ToHash(hn, sourceType().packed().bits());
2903 hn = addU64ToHash(hn, destType().packed().bits());
2904 return hn;
2905 }
2906
2907 MDefinition* foldsTo(TempAllocator& alloc) override;
2908};
2909
2910class MWasmNewStructObject : public MBinaryInstruction,
2911 public NoTypePolicy::Data {
2912 private:
2913 bool isOutline_;
2914 bool zeroFields_;
2915 gc::AllocKind allocKind_;
2916 const wasm::StructType& structType_;
2917 wasm::TrapSiteDesc trapSiteDesc_;
2918
2919 MWasmNewStructObject(MDefinition* instance, MDefinition* typeDefData,
2920 const wasm::StructType& structType_, bool isOutline,
2921 bool zeroFields, gc::AllocKind allocKind,
2922 const wasm::TrapSiteDesc& trapSiteDesc)
2923 : MBinaryInstruction(classOpcode, instance, typeDefData),
2924 isOutline_(isOutline),
2925 zeroFields_(zeroFields),
2926 allocKind_(allocKind),
2927 structType_(structType_),
2928 trapSiteDesc_(trapSiteDesc) {
2929 setResultType(MIRType::WasmAnyRef);
2930 }
2931
2932 public:
2933 INSTRUCTION_HEADER(WasmNewStructObject)
2934 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
2935 NAMED_OPERANDS((0, instance), (1, typeDefData))MDefinition* instance() const { return getOperand(0); } MDefinition
* typeDefData() const { return getOperand(1); }
2936
2937 AliasSet getAliasSet() const override {
2938 if (js::SupportDifferentialTesting()) {
2939 // Consider allocations effectful for differential testing.
2940 return MDefinition::getAliasSet();
2941 }
2942 return AliasSet::None();
2943 }
2944 bool isOutline() const { return isOutline_; }
2945 bool zeroFields() const { return zeroFields_; }
2946 gc::AllocKind allocKind() const { return allocKind_; }
2947 const wasm::TrapSiteDesc& trapSiteDesc() const { return trapSiteDesc_; }
2948 const wasm::StructType& structType() { return structType_; }
2949};
2950
2951class MWasmNewArrayObject : public MTernaryInstruction,
2952 public NoTypePolicy::Data {
2953 private:
2954 uint32_t elemSize_;
2955 bool zeroFields_;
2956 wasm::TrapSiteDesc trapSiteDesc_;
2957
2958 MWasmNewArrayObject(MDefinition* instance, MDefinition* numElements,
2959 MDefinition* typeDefData, uint32_t elemSize,
2960 bool zeroFields, const wasm::TrapSiteDesc& trapSiteDesc)
2961 : MTernaryInstruction(classOpcode, instance, numElements, typeDefData),
2962 elemSize_(elemSize),
2963 zeroFields_(zeroFields),
2964 trapSiteDesc_(trapSiteDesc) {
2965 setResultType(MIRType::WasmAnyRef);
2966 }
2967
2968 public:
2969 INSTRUCTION_HEADER(WasmNewArrayObject)
2970 TRIVIAL_NEW_WRAPPERStemplate <typename... Args> static MThisOpcode* New(TempAllocator
& alloc, Args&&... args) { return new (alloc) MThisOpcode
(std::forward<Args>(args)...); } template <typename...
Args> static MThisOpcode* New(TempAllocator::Fallible alloc
, Args&&... args) { return new (alloc) MThisOpcode(std
::forward<Args>(args)...); }
2971 NAMED_OPERANDS((0, instance), (1, numElements), (2, typeDefData))MDefinition* instance() const { return getOperand(0); } MDefinition
* numElements() const { return getOperand(1); } MDefinition* typeDefData
() const { return getOperand(2); }
2972
2973 AliasSet getAliasSet() const override {
2974 if (js::SupportDifferentialTesting()) {
2975 // Consider allocations effectful for differential testing.
2976 return MDefinition::getAliasSet();
2977 }
2978 return AliasSet::None();
2979 }
2980 uint32_t elemSize() const { return elemSize_; }
2981 bool zeroFields() const { return zeroFields_; }
2982 const wasm::TrapSiteDesc& trapSiteDesc() const { return trapSiteDesc_; }
2983};
2984
2985#undef INSTRUCTION_HEADER
2986
2987#ifdef ENABLE_WASM_SIMD1
2988MWasmShuffleSimd128* BuildWasmShuffleSimd128(TempAllocator& alloc,
2989 const int8_t* control,
2990 MDefinition* lhs,
2991 MDefinition* rhs);
2992#endif // ENABLE_WASM_SIMD
2993
2994} // namespace jit
2995} // namespace js
2996
2997#endif /* jit_MIR_wasm_h */