Bug Summary

File:var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h
Warning:line 579, 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_jit0.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-19/lib/clang/19 -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 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-19/lib/clang/19/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-2024-09-18-050813-4143630-1 -x c++ Unified_cpp_js_src_jit0.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) 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::BytecodeOffset bytecodeOffset_;
177
178 MWasmBuiltinTruncateToInt64(MDefinition* def, MDefinition* instance,
179 TruncFlags flags,
180 wasm::BytecodeOffset bytecodeOffset)
181 : MAryInstruction(classOpcode),
182 flags_(flags),
183 bytecodeOffset_(bytecodeOffset) {
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 wasm::BytecodeOffset bytecodeOffset() const { return bytecodeOffset_; }
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::BytecodeOffset bytecodeOffset_;
213
214 MWasmTruncateToInt64(MDefinition* def, TruncFlags flags,
215 wasm::BytecodeOffset bytecodeOffset)
216 : MUnaryInstruction(classOpcode, def),
217 flags_(flags),
218 bytecodeOffset_(bytecodeOffset) {
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 wasm::BytecodeOffset bytecodeOffset() const { return bytecodeOffset_; }
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::BytecodeOffset bytecodeOffset_;
246
247 explicit MWasmTruncateToInt32(MDefinition* def, TruncFlags flags,
248 wasm::BytecodeOffset bytecodeOffset)
249 : MUnaryInstruction(classOpcode, def),
250 flags_(flags),
251 bytecodeOffset_(bytecodeOffset) {
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 wasm::BytecodeOffset bytecodeOffset() const { return bytecodeOffset_; }
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::BytecodeOffset bytecodeOffset_;
280
281 MWasmBuiltinTruncateToInt32(
282 MDefinition* def, MDefinition* instance,
283 wasm::BytecodeOffset bytecodeOffset = wasm::BytecodeOffset())
284 : MAryInstruction(classOpcode), bytecodeOffset_(bytecodeOffset) {
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 wasm::BytecodeOffset bytecodeOffset() const { return bytecodeOffset_; }
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::BytecodeOffset bytecodeOffset_;
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::BytecodeOffset bytecodeOffset = wasm::BytecodeOffset()) {
346 auto* wasm64Div = new (alloc) MWasmBuiltinDivI64(left, right, instance);
347 wasm64Div->unsigned_ = unsignd;
348 wasm64Div->trapOnError_ = trapOnError;
349 wasm64Div->bytecodeOffset_ = bytecodeOffset;
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 wasm::BytecodeOffset bytecodeOffset() const {
384 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"
, 384); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bytecodeOffset_.isValid()"
")"); do { *((volatile int*)__null) = 384; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
385 return bytecodeOffset_;
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::BytecodeOffset bytecodeOffset_;
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::BytecodeOffset bytecodeOffset = wasm::BytecodeOffset()) {
458 auto* mod = new (alloc) MWasmBuiltinModI64(left, right, instance);
459 mod->unsigned_ = unsignd;
460 mod->trapOnError_ = trapOnError;
461 mod->bytecodeOffset_ = bytecodeOffset;
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 wasm::BytecodeOffset bytecodeOffset() const {
480 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"
, 480); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bytecodeOffset_.isValid()"
")"); do { *((volatile int*)__null) = 480; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
481 return bytecodeOffset_;
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::BytecodeOffset bytecodeOffset_;
491
492 MWasmInterruptCheck(MDefinition* instance,
493 wasm::BytecodeOffset bytecodeOffset)
494 : MUnaryInstruction(classOpcode, instance),
495 bytecodeOffset_(bytecodeOffset) {
496 setGuard();
497 }
498
499 public:
500 INSTRUCTION_HEADER(WasmInterruptCheck)
501 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)...); }
502 NAMED_OPERANDS((0, instance))MDefinition* instance() const { return getOperand(0); }
503
504 AliasSet getAliasSet() const override { return AliasSet::None(); }
505 wasm::BytecodeOffset bytecodeOffset() const { return bytecodeOffset_; }
506};
507
508// Directly jumps to the indicated trap, leaving Wasm code and reporting a
509// runtime error.
510
511class MWasmTrap : public MAryControlInstruction<0, 0>,
512 public NoTypePolicy::Data {
513 wasm::Trap trap_;
514 wasm::BytecodeOffset bytecodeOffset_;
515
516 explicit MWasmTrap(wasm::Trap trap, wasm::BytecodeOffset bytecodeOffset)
517 : MAryControlInstruction(classOpcode),
518 trap_(trap),
519 bytecodeOffset_(bytecodeOffset) {}
520
521 public:
522 INSTRUCTION_HEADER(WasmTrap)
523 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)...); }
524
525 AliasSet getAliasSet() const override { return AliasSet::None(); }
526
527 wasm::Trap trap() const { return trap_; }
528 wasm::BytecodeOffset bytecodeOffset() const { return bytecodeOffset_; }
529};
530
531// Flips the input's sign bit, independently of the rest of the number's
532// payload. Note this is different from multiplying by minus-one, which has
533// side-effects for e.g. NaNs.
534class MWasmNeg : public MUnaryInstruction, public NoTypePolicy::Data {
535 MWasmNeg(MDefinition* op, MIRType type) : MUnaryInstruction(classOpcode, op) {
536 setResultType(type);
537 setMovable();
538 }
539
540 public:
541 INSTRUCTION_HEADER(WasmNeg)
542 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)...); }
543};
544
545// Machine-level bitwise AND/OR/XOR, avoiding all JS-level complexity embodied
546// in MBinaryBitwiseInstruction.
547class MWasmBinaryBitwise : public MBinaryInstruction,
548 public NoTypePolicy::Data {
549 public:
550 enum class SubOpcode { And, Or, Xor };
551
552 protected:
553 MWasmBinaryBitwise(MDefinition* left, MDefinition* right, MIRType type,
554 SubOpcode subOpcode)
555 : MBinaryInstruction(classOpcode, left, right), subOpcode_(subOpcode) {
556 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"
, 556); AnnotateMozCrashReason("MOZ_ASSERT" "(" "type == MIRType::Int32 || type == MIRType::Int64"
")"); do { *((volatile int*)__null) = 556; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
557 setResultType(type);
558 setMovable();
559 setCommutative();
560 }
561
562 public:
563 INSTRUCTION_HEADER(WasmBinaryBitwise)
564 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)...); }
565
566 SubOpcode subOpcode() const { return subOpcode_; }
567 MDefinition* foldsTo(TempAllocator& alloc) override;
568
569 bool congruentTo(const MDefinition* ins) const override {
570 return ins->isWasmBinaryBitwise() &&
571 ins->toWasmBinaryBitwise()->subOpcode() == subOpcode() &&
572 binaryCongruentTo(ins);
573 }
574
575 AliasSet getAliasSet() const override { return AliasSet::None(); }
576
577#ifdef JS_JITSPEW1
578 void getExtras(ExtrasCollector* extras) override {
579 const char* what = "!!unknown!!";
Value stored to 'what' during its initialization is never read
580 switch (subOpcode()) {
581 case SubOpcode::And:
582 what = "And";
583 break;
584 case SubOpcode::Or:
585 what = "Or";
586 break;
587 case SubOpcode::Xor:
588 what = "Xor";
589 break;
590 }
591 extras->add(what);
592 }
593#endif
594
595 private:
596 SubOpcode subOpcode_;
597
598 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; }
599};
600
601class MWasmLoadInstance : public MUnaryInstruction, public NoTypePolicy::Data {
602 uint32_t offset_;
603 AliasSet aliases_;
604
605 explicit MWasmLoadInstance(MDefinition* instance, uint32_t offset,
606 MIRType type, AliasSet aliases)
607 : MUnaryInstruction(classOpcode, instance),
608 offset_(offset),
609 aliases_(aliases) {
610 // Different instance data have different alias classes and only those
611 // classes are allowed.
612 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"
, 617); 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) = 617; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
613 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"
, 617); 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) = 617; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
614 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"
, 617); 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) = 617; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
615 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"
, 617); 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) = 617; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
616 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"
, 617); 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) = 617; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
617 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"
, 617); 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) = 617; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
618
619 // The only types supported at the moment.
620 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"
, 621); AnnotateMozCrashReason("MOZ_ASSERT" "(" "type == MIRType::Pointer || type == MIRType::Int32 || type == MIRType::Int64 || type == MIRType::WasmAnyRef"
")"); do { *((volatile int*)__null) = 621; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
621 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"
, 621); AnnotateMozCrashReason("MOZ_ASSERT" "(" "type == MIRType::Pointer || type == MIRType::Int32 || type == MIRType::Int64 || type == MIRType::WasmAnyRef"
")"); do { *((volatile int*)__null) = 621; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
622
623 setMovable();
624 setResultType(type);
625 }
626
627 public:
628 INSTRUCTION_HEADER(WasmLoadInstance)
629 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)...); }
630 NAMED_OPERANDS((0, instance))MDefinition* instance() const { return getOperand(0); }
631
632 uint32_t offset() const { return offset_; }
633
634 bool congruentTo(const MDefinition* ins) const override {
635 return op() == ins->op() &&
636 offset() == ins->toWasmLoadInstance()->offset() &&
637 type() == ins->type();
638 }
639
640 HashNumber valueHash() const override {
641 return addU32ToHash(HashNumber(op()), offset());
642 }
643
644 AliasSet getAliasSet() const override { return aliases_; }
645};
646
647class MWasmStoreInstance : public MBinaryInstruction,
648 public NoTypePolicy::Data {
649 uint32_t offset_;
650 AliasSet aliases_;
651
652 explicit MWasmStoreInstance(MDefinition* instance, MDefinition* value,
653 uint32_t offset, MIRType type, AliasSet aliases)
654 : MBinaryInstruction(classOpcode, instance, value),
655 offset_(offset),
656 aliases_(aliases) {
657 // Different instance data have different alias classes and only those
658 // classes are allowed.
659 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"
, 660); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases_.flags() == AliasSet::Store(AliasSet::WasmPendingException).flags()"
")"); do { *((volatile int*)__null) = 660; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
660 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"
, 660); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases_.flags() == AliasSet::Store(AliasSet::WasmPendingException).flags()"
")"); do { *((volatile int*)__null) = 660; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
661
662 // The only types supported at the moment.
663 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"
, 664); AnnotateMozCrashReason("MOZ_ASSERT" "(" "type == MIRType::Pointer || type == MIRType::Int32 || type == MIRType::Int64 || type == MIRType::WasmAnyRef"
")"); do { *((volatile int*)__null) = 664; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
664 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"
, 664); AnnotateMozCrashReason("MOZ_ASSERT" "(" "type == MIRType::Pointer || type == MIRType::Int32 || type == MIRType::Int64 || type == MIRType::WasmAnyRef"
")"); do { *((volatile int*)__null) = 664; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
665 }
666
667 public:
668 INSTRUCTION_HEADER(WasmStoreInstance)
669 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)...); }
670 NAMED_OPERANDS((0, instance), (1, value))MDefinition* instance() const { return getOperand(0); } MDefinition
* value() const { return getOperand(1); }
671
672 uint32_t offset() const { return offset_; }
673
674 AliasSet getAliasSet() const override { return aliases_; }
675};
676
677class MWasmHeapReg : public MNullaryInstruction {
678 AliasSet aliases_;
679
680 explicit MWasmHeapReg(AliasSet aliases)
681 : MNullaryInstruction(classOpcode), aliases_(aliases) {
682 setMovable();
683 setResultType(MIRType::Pointer);
684 }
685
686 public:
687 INSTRUCTION_HEADER(WasmHeapReg)
688 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)...); }
689
690 bool congruentTo(const MDefinition* ins) const override {
691 return ins->isWasmHeapReg();
692 }
693
694 AliasSet getAliasSet() const override { return aliases_; }
695};
696
697// For memory32, bounds check nodes are of type Int32 on 32-bit systems for both
698// wasm and asm.js code, as well as on 64-bit systems for asm.js code and for
699// wasm code that is known to have a bounds check limit that fits into 32 bits.
700// They are of type Int64 only on 64-bit systems for wasm code with 4GB heaps.
701// There is no way for nodes of both types to be present in the same function.
702// Should this change, then BCE must be updated to take type into account.
703//
704// For memory64, bounds check nodes are always of type Int64.
705
706class MWasmBoundsCheck : public MBinaryInstruction, public NoTypePolicy::Data {
707 public:
708 enum Target {
709 // Linear memory at index zero, which is the only memory allowed so far.
710 Memory0,
711 // Everything else. Currently comprises tables, and arrays in the GC
712 // proposal.
713 Unknown
714 };
715
716 private:
717 wasm::BytecodeOffset bytecodeOffset_;
718 Target target_;
719
720 explicit MWasmBoundsCheck(MDefinition* index, MDefinition* boundsCheckLimit,
721 wasm::BytecodeOffset bytecodeOffset, Target target)
722 : MBinaryInstruction(classOpcode, index, boundsCheckLimit),
723 bytecodeOffset_(bytecodeOffset),
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 wasm::BytecodeOffset bytecodeOffset() const { return bytecodeOffset_; }
749};
750
751class MWasmAddOffset : public MUnaryInstruction, public NoTypePolicy::Data {
752 uint64_t offset_;
753 wasm::BytecodeOffset bytecodeOffset_;
754
755 MWasmAddOffset(MDefinition* base, uint64_t offset,
756 wasm::BytecodeOffset bytecodeOffset)
757 : MUnaryInstruction(classOpcode, base),
758 offset_(offset),
759 bytecodeOffset_(bytecodeOffset) {
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 wasm::BytecodeOffset bytecodeOffset() const { return bytecodeOffset_; }
777};
778
779class MWasmAlignmentCheck : public MUnaryInstruction,
780 public NoTypePolicy::Data {
781 uint32_t byteSize_;
782 wasm::BytecodeOffset bytecodeOffset_;
783
784 explicit MWasmAlignmentCheck(MDefinition* index, uint32_t byteSize,
785 wasm::BytecodeOffset bytecodeOffset)
786 : MUnaryInstruction(classOpcode, index),
787 byteSize_(byteSize),
788 bytecodeOffset_(bytecodeOffset) {
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 wasm::BytecodeOffset bytecodeOffset() const { return bytecodeOffset_; }
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) 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) 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::BytecodeOffset(), 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) 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) 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) 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// Arguments for constructing a catchable wasm call inside of a try block.
1726struct MWasmCallTryDesc {
1727 bool inTry;
1728 uint32_t relativeTryDepth;
1729 size_t tryNoteIndex;
1730 MBasicBlock* fallthroughBlock;
1731 MBasicBlock* prePadBlock;
1732
1733 MWasmCallTryDesc()
1734 : inTry(false),
1735 relativeTryDepth(0),
1736 tryNoteIndex(0),
1737 fallthroughBlock(nullptr),
1738 prePadBlock(nullptr) {}
1739};
1740
1741// Mixin class for wasm calls that may or may not be catchable.
1742class MWasmCallBase {
1743 public:
1744 struct Arg {
1745 AnyRegister reg;
1746 MDefinition* def;
1747 Arg(AnyRegister reg, MDefinition* def) : reg(reg), def(def) {}
1748 };
1749 using Args = Vector<Arg, 8, SystemAllocPolicy>;
1750
1751 protected:
1752 wasm::CallSiteDesc desc_;
1753 wasm::CalleeDesc callee_;
1754 wasm::FailureMode builtinMethodFailureMode_;
1755 FixedList<AnyRegister> argRegs_;
1756 uint32_t stackArgAreaSizeUnaligned_;
1757 ABIArg instanceArg_;
1758 bool inTry_;
1759 size_t tryNoteIndex_;
1760
1761 MWasmCallBase(const wasm::CallSiteDesc& desc, const wasm::CalleeDesc& callee,
1762 uint32_t stackArgAreaSizeUnaligned, bool inTry,
1763 size_t tryNoteIndex)
1764 : desc_(desc),
1765 callee_(callee),
1766 builtinMethodFailureMode_(wasm::FailureMode::Infallible),
1767 stackArgAreaSizeUnaligned_(stackArgAreaSizeUnaligned),
1768 inTry_(inTry),
1769 tryNoteIndex_(tryNoteIndex) {}
1770
1771 template <class MVariadicT>
1772 [[nodiscard]] bool initWithArgs(TempAllocator& alloc, MVariadicT* ins,
1773 const Args& args,
1774 MDefinition* tableIndexOrRef) {
1775 if (!argRegs_.init(alloc, args.length())) {
1776 return false;
1777 }
1778 for (size_t i = 0; i < argRegs_.length(); i++) {
1779 argRegs_[i] = args[i].reg;
1780 }
1781
1782 if (!ins->init(alloc, argRegs_.length() + (tableIndexOrRef ? 1 : 0))) {
1783 return false;
1784 }
1785 // FixedList doesn't initialize its elements, so do an unchecked init.
1786 for (size_t i = 0; i < argRegs_.length(); i++) {
1787 ins->initOperand(i, args[i].def);
1788 }
1789 if (tableIndexOrRef) {
1790 ins->initOperand(argRegs_.length(), tableIndexOrRef);
1791 }
1792 return true;
1793 }
1794
1795 public:
1796 static bool IsWasmCall(MDefinition* def) {
1797 return def->isWasmCallCatchable() || def->isWasmCallUncatchable() ||
1798 def->isWasmReturnCall();
1799 }
1800
1801 size_t numArgs() const { return argRegs_.length(); }
1802 AnyRegister registerForArg(size_t index) const {
1803 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"
, 1803); AnnotateMozCrashReason("MOZ_ASSERT" "(" "index < numArgs()"
")"); do { *((volatile int*)__null) = 1803; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1804 return argRegs_[index];
1805 }
1806 const wasm::CallSiteDesc& desc() const { return desc_; }
1807 const wasm::CalleeDesc& callee() const { return callee_; }
1808 wasm::FailureMode builtinMethodFailureMode() const {
1809 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"
, 1809); AnnotateMozCrashReason("MOZ_ASSERT" "(" "callee_.which() == wasm::CalleeDesc::BuiltinInstanceMethod"
")"); do { *((volatile int*)__null) = 1809; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1810 return builtinMethodFailureMode_;
1811 }
1812 uint32_t stackArgAreaSizeUnaligned() const {
1813 return stackArgAreaSizeUnaligned_;
1814 }
1815
1816 const ABIArg& instanceArg() const { return instanceArg_; }
1817
1818 bool inTry() const { return inTry_; }
1819 size_t tryNoteIndex() const { return tryNoteIndex_; }
1820
1821 static AliasSet wasmCallAliasSet() {
1822 // This is ok because:
1823 // - numElements is immutable
1824 // - the GC will rewrite any array data pointers on move
1825 AliasSet exclude = AliasSet(AliasSet::WasmArrayNumElements) |
1826 AliasSet(AliasSet::WasmArrayDataPointer);
1827 return AliasSet::Store(AliasSet::Any) & ~exclude;
1828 }
1829};
1830
1831// A wasm call that is catchable. This instruction is a control instruction,
1832// and terminates the block it is on. A normal return will proceed in a the
1833// fallthrough block. An exceptional return will unwind into the landing pad
1834// block for this call. The landing pad block must begin with an
1835// MWasmCallLandingPrePad.
1836class MWasmCallCatchable final : public MVariadicControlInstruction<2>,
1837 public MWasmCallBase,
1838 public NoTypePolicy::Data {
1839 MWasmCallCatchable(const wasm::CallSiteDesc& desc,
1840 const wasm::CalleeDesc& callee,
1841 uint32_t stackArgAreaSizeUnaligned, size_t tryNoteIndex)
1842 : MVariadicControlInstruction(classOpcode),
1843 MWasmCallBase(desc, callee, stackArgAreaSizeUnaligned, true,
1844 tryNoteIndex) {}
1845
1846 public:
1847 INSTRUCTION_HEADER(WasmCallCatchable)
1848
1849 static MWasmCallCatchable* New(TempAllocator& alloc,
1850 const wasm::CallSiteDesc& desc,
1851 const wasm::CalleeDesc& callee,
1852 const Args& args,
1853 uint32_t stackArgAreaSizeUnaligned,
1854 const MWasmCallTryDesc& tryDesc,
1855 MDefinition* tableIndexOrRef = nullptr);
1856
1857 static MWasmCallCatchable* NewBuiltinInstanceMethodCall(
1858 TempAllocator& alloc, const wasm::CallSiteDesc& desc,
1859 const wasm::SymbolicAddress builtin, wasm::FailureMode failureMode,
1860 const ABIArg& instanceArg, const Args& args,
1861 uint32_t stackArgAreaSizeUnaligned, const MWasmCallTryDesc& tryDesc);
1862
1863 bool possiblyCalls() const override { return true; }
1864 AliasSet getAliasSet() const override { return wasmCallAliasSet(); }
1865
1866 static const size_t FallthroughBranchIndex = 0;
1867 static const size_t PrePadBranchIndex = 1;
1868};
1869
1870// A wasm call that is not catchable. This instruction is not a control
1871// instruction, and therefore is not a block terminator.
1872class MWasmCallUncatchable final : public MVariadicInstruction,
1873 public MWasmCallBase,
1874 public NoTypePolicy::Data {
1875 MWasmCallUncatchable(const wasm::CallSiteDesc& desc,
1876 const wasm::CalleeDesc& callee,
1877 uint32_t stackArgAreaSizeUnaligned)
1878 : MVariadicInstruction(classOpcode),
1879 MWasmCallBase(desc, callee, stackArgAreaSizeUnaligned, false, 0) {}
1880
1881 public:
1882 INSTRUCTION_HEADER(WasmCallUncatchable)
1883
1884 static MWasmCallUncatchable* New(TempAllocator& alloc,
1885 const wasm::CallSiteDesc& desc,
1886 const wasm::CalleeDesc& callee,
1887 const Args& args,
1888 uint32_t stackArgAreaSizeUnaligned,
1889 MDefinition* tableIndexOrRef = nullptr);
1890
1891 static MWasmCallUncatchable* NewBuiltinInstanceMethodCall(
1892 TempAllocator& alloc, const wasm::CallSiteDesc& desc,
1893 const wasm::SymbolicAddress builtin, wasm::FailureMode failureMode,
1894 const ABIArg& instanceArg, const Args& args,
1895 uint32_t stackArgAreaSizeUnaligned);
1896
1897 bool possiblyCalls() const override { return true; }
1898 AliasSet getAliasSet() const override { return wasmCallAliasSet(); }
1899};
1900
1901class MWasmReturnCall final : public MVariadicControlInstruction<0>,
1902 public MWasmCallBase,
1903 public NoTypePolicy::Data {
1904 MWasmReturnCall(const wasm::CallSiteDesc& desc,
1905 const wasm::CalleeDesc& callee,
1906 uint32_t stackArgAreaSizeUnaligned)
1907 : MVariadicControlInstruction(classOpcode),
1908 MWasmCallBase(desc, callee, stackArgAreaSizeUnaligned, false, 0) {}
1909
1910 public:
1911 INSTRUCTION_HEADER(WasmReturnCall)
1912
1913 static MWasmReturnCall* New(TempAllocator& alloc,
1914 const wasm::CallSiteDesc& desc,
1915 const wasm::CalleeDesc& callee, const Args& args,
1916 uint32_t stackArgAreaSizeUnaligned,
1917 MDefinition* tableIndexOrRef = nullptr);
1918
1919 bool possiblyCalls() const override { return true; }
1920};
1921
1922// A marker instruction for a block which is the landing pad for a catchable
1923// wasm call. This instruction does not emit any code, only filling in
1924// metadata. This instruction must be the first instruction added to the
1925// landing pad block.
1926class MWasmCallLandingPrePad : public MNullaryInstruction {
1927 // The block of the call that may unwind to this landing pad.
1928 MBasicBlock* callBlock_;
1929 // The index of the try note to initialize a landing pad for.
1930 size_t tryNoteIndex_;
1931
1932 explicit MWasmCallLandingPrePad(MBasicBlock* callBlock, size_t tryNoteIndex)
1933 : MNullaryInstruction(classOpcode),
1934 callBlock_(callBlock),
1935 tryNoteIndex_(tryNoteIndex) {
1936 setGuard();
1937 }
1938
1939 public:
1940 INSTRUCTION_HEADER(WasmCallLandingPrePad)
1941 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)...); }
1942
1943 AliasSet getAliasSet() const override { return AliasSet::None(); }
1944
1945 size_t tryNoteIndex() { return tryNoteIndex_; }
1946 MBasicBlock* callBlock() { return callBlock_; }
1947};
1948
1949class MWasmSelect : public MTernaryInstruction, public NoTypePolicy::Data {
1950 MWasmSelect(MDefinition* trueExpr, MDefinition* falseExpr,
1951 MDefinition* condExpr)
1952 : MTernaryInstruction(classOpcode, trueExpr, falseExpr, condExpr) {
1953 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"
, 1953); AnnotateMozCrashReason("MOZ_ASSERT" "(" "condExpr->type() == MIRType::Int32"
")"); do { *((volatile int*)__null) = 1953; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1954 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"
, 1954); AnnotateMozCrashReason("MOZ_ASSERT" "(" "trueExpr->type() == falseExpr->type()"
")"); do { *((volatile int*)__null) = 1954; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1955 setResultType(trueExpr->type());
1956 setMovable();
1957 }
1958
1959 public:
1960 INSTRUCTION_HEADER(WasmSelect)
1961 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)...); }
1962 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); }
1963
1964 AliasSet getAliasSet() const override { return AliasSet::None(); }
1965
1966 bool congruentTo(const MDefinition* ins) const override {
1967 return congruentIfOperandsEqual(ins);
1968 }
1969
1970 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; }
1971};
1972
1973class MWasmReinterpret : public MUnaryInstruction, public NoTypePolicy::Data {
1974 MWasmReinterpret(MDefinition* val, MIRType toType)
1975 : MUnaryInstruction(classOpcode, val) {
1976 switch (val->type()) {
1977 case MIRType::Int32:
1978 MOZ_ASSERT(toType == MIRType::Float32)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(toType == MIRType::Float32)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(toType == MIRType::Float32))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("toType == MIRType::Float32"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 1978); AnnotateMozCrashReason("MOZ_ASSERT" "(" "toType == MIRType::Float32"
")"); do { *((volatile int*)__null) = 1978; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1979 break;
1980 case MIRType::Float32:
1981 MOZ_ASSERT(toType == MIRType::Int32)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(toType == MIRType::Int32)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(toType == MIRType::Int32))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("toType == MIRType::Int32"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 1981); AnnotateMozCrashReason("MOZ_ASSERT" "(" "toType == MIRType::Int32"
")"); do { *((volatile int*)__null) = 1981; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1982 break;
1983 case MIRType::Double:
1984 MOZ_ASSERT(toType == MIRType::Int64)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(toType == MIRType::Int64)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(toType == MIRType::Int64))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("toType == MIRType::Int64"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 1984); AnnotateMozCrashReason("MOZ_ASSERT" "(" "toType == MIRType::Int64"
")"); do { *((volatile int*)__null) = 1984; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1985 break;
1986 case MIRType::Int64:
1987 MOZ_ASSERT(toType == MIRType::Double)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(toType == MIRType::Double)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(toType == MIRType::Double)))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("toType == MIRType::Double"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 1987); AnnotateMozCrashReason("MOZ_ASSERT" "(" "toType == MIRType::Double"
")"); do { *((volatile int*)__null) = 1987; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1988 break;
1989 default:
1990 MOZ_CRASH("unexpected reinterpret conversion")do { do { } while (false); MOZ_ReportCrash("" "unexpected reinterpret conversion"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/jit/MIR-wasm.h"
, 1990); AnnotateMozCrashReason("MOZ_CRASH(" "unexpected reinterpret conversion"
")"); do { *((volatile int*)__null) = 1990; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
1991 }
1992 setMovable();
1993 setResultType(toType);
1994 }
1995
1996 public:
1997 INSTRUCTION_HEADER(WasmReinterpret)
1998 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)...); }
1999
2000 AliasSet getAliasSet() const override { return AliasSet::None(); }
2001 bool congruentTo(const MDefinition* ins) const override {
2002 // No need to check type() here, because congruentIfOperandsEqual will
2003 // check it.
2004 return congruentIfOperandsEqual(ins);
2005 }
2006
2007 ALLOW_CLONE(MWasmReinterpret)bool canClone() const override { return true; } MInstruction*
clone(TempAllocator& alloc, const MDefinitionVector&
inputs) const override { MInstruction* res = new (alloc) MWasmReinterpret
(*this); for (size_t i = 0; i < numOperands(); i++) res->
replaceOperand(i, inputs[i]); return res; }
2008};
2009
2010// Wasm SIMD.
2011//
2012// See comment in WasmIonCompile.cpp for a justification for these nodes.
2013
2014// (v128, v128, v128) -> v128 effect-free operation.
2015class MWasmTernarySimd128 : public MTernaryInstruction,
2016 public NoTypePolicy::Data {
2017 wasm::SimdOp simdOp_;
2018
2019 MWasmTernarySimd128(MDefinition* v0, MDefinition* v1, MDefinition* v2,
2020 wasm::SimdOp simdOp)
2021 : MTernaryInstruction(classOpcode, v0, v1, v2), simdOp_(simdOp) {
2022 setMovable();
2023 setResultType(MIRType::Simd128);
2024 }
2025
2026 public:
2027 INSTRUCTION_HEADER(WasmTernarySimd128)
2028 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)...); }
2029 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); }
2030
2031 AliasSet getAliasSet() const override { return AliasSet::None(); }
2032 bool congruentTo(const MDefinition* ins) const override {
2033 return congruentIfOperandsEqual(ins) &&
2034 simdOp() == ins->toWasmTernarySimd128()->simdOp();
2035 }
2036#ifdef ENABLE_WASM_SIMD1
2037 MDefinition* foldsTo(TempAllocator& alloc) override;
2038
2039 // If the control mask of a bitselect allows the operation to be specialized
2040 // as a shuffle and it is profitable to specialize it on this platform, return
2041 // true and the appropriate shuffle mask.
2042 bool specializeBitselectConstantMaskAsShuffle(int8_t shuffle[16]);
2043 // Checks if more relaxed version of lane select can be used. It returns true
2044 // if a bit mask input expected to be all 0s or 1s for entire 8-bit lanes,
2045 // false otherwise.
2046 bool canRelaxBitselect();
2047#endif
2048
2049 wasm::SimdOp simdOp() const { return simdOp_; }
2050
2051 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; }
2052};
2053
2054// (v128, v128) -> v128 effect-free operations.
2055class MWasmBinarySimd128 : public MBinaryInstruction,
2056 public NoTypePolicy::Data {
2057 wasm::SimdOp simdOp_;
2058
2059 MWasmBinarySimd128(MDefinition* lhs, MDefinition* rhs, bool commutative,
2060 wasm::SimdOp simdOp)
2061 : MBinaryInstruction(classOpcode, lhs, rhs), simdOp_(simdOp) {
2062 setMovable();
2063 setResultType(MIRType::Simd128);
2064 if (commutative) {
2065 setCommutative();
2066 }
2067 }
2068
2069 public:
2070 INSTRUCTION_HEADER(WasmBinarySimd128)
2071 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)...); }
2072
2073 AliasSet getAliasSet() const override { return AliasSet::None(); }
2074 bool congruentTo(const MDefinition* ins) const override {
2075 return congruentIfOperandsEqual(ins) &&
2076 ins->toWasmBinarySimd128()->simdOp() == simdOp_;
2077 }
2078#ifdef ENABLE_WASM_SIMD1
2079 MDefinition* foldsTo(TempAllocator& alloc) override;
2080
2081 // Checks if pmaddubsw operation is supported.
2082 bool canPmaddubsw();
2083#endif
2084
2085 wasm::SimdOp simdOp() const { return simdOp_; }
2086
2087 // Platform-dependent specialization.
2088 bool specializeForConstantRhs();
2089
2090 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; }
2091};
2092
2093// (v128, const) -> v128 effect-free operations.
2094class MWasmBinarySimd128WithConstant : public MUnaryInstruction,
2095 public NoTypePolicy::Data {
2096 SimdConstant rhs_;
2097 wasm::SimdOp simdOp_;
2098
2099 MWasmBinarySimd128WithConstant(MDefinition* lhs, const SimdConstant& rhs,
2100 wasm::SimdOp simdOp)
2101 : MUnaryInstruction(classOpcode, lhs), rhs_(rhs), simdOp_(simdOp) {
2102 setMovable();
2103 setResultType(MIRType::Simd128);
2104 }
2105
2106 public:
2107 INSTRUCTION_HEADER(WasmBinarySimd128WithConstant)
2108 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)...); }
2109
2110 AliasSet getAliasSet() const override { return AliasSet::None(); }
2111 bool congruentTo(const MDefinition* ins) const override {
2112 return congruentIfOperandsEqual(ins) &&
2113 ins->toWasmBinarySimd128WithConstant()->simdOp() == simdOp_ &&
2114 rhs_.bitwiseEqual(ins->toWasmBinarySimd128WithConstant()->rhs());
2115 }
2116
2117 wasm::SimdOp simdOp() const { return simdOp_; }
2118 MDefinition* lhs() const { return input(); }
2119 const SimdConstant& rhs() const { return rhs_; }
2120
2121 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; }
2122};
2123
2124// (v128, scalar, imm) -> v128 effect-free operations.
2125class MWasmReplaceLaneSimd128 : public MBinaryInstruction,
2126 public NoTypePolicy::Data {
2127 uint32_t laneIndex_;
2128 wasm::SimdOp simdOp_;
2129
2130 MWasmReplaceLaneSimd128(MDefinition* lhs, MDefinition* rhs,
2131 uint32_t laneIndex, wasm::SimdOp simdOp)
2132 : MBinaryInstruction(classOpcode, lhs, rhs),
2133 laneIndex_(laneIndex),
2134 simdOp_(simdOp) {
2135 setMovable();
2136 setResultType(MIRType::Simd128);
2137 }
2138
2139 public:
2140 INSTRUCTION_HEADER(WasmReplaceLaneSimd128)
2141 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)...); }
2142
2143 AliasSet getAliasSet() const override { return AliasSet::None(); }
2144 bool congruentTo(const MDefinition* ins) const override {
2145 return congruentIfOperandsEqual(ins) &&
2146 ins->toWasmReplaceLaneSimd128()->simdOp() == simdOp_ &&
2147 ins->toWasmReplaceLaneSimd128()->laneIndex() == laneIndex_;
2148 }
2149
2150 uint32_t laneIndex() const { return laneIndex_; }
2151 wasm::SimdOp simdOp() const { return simdOp_; }
2152
2153 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; }
2154};
2155
2156// (scalar) -> v128 effect-free operations.
2157class MWasmScalarToSimd128 : public MUnaryInstruction,
2158 public NoTypePolicy::Data {
2159 wasm::SimdOp simdOp_;
2160
2161 MWasmScalarToSimd128(MDefinition* src, wasm::SimdOp simdOp)
2162 : MUnaryInstruction(classOpcode, src), simdOp_(simdOp) {
2163 setMovable();
2164 setResultType(MIRType::Simd128);
2165 }
2166
2167 public:
2168 INSTRUCTION_HEADER(WasmScalarToSimd128)
2169 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)...); }
2170
2171 AliasSet getAliasSet() const override { return AliasSet::None(); }
2172 bool congruentTo(const MDefinition* ins) const override {
2173 return congruentIfOperandsEqual(ins) &&
2174 ins->toWasmScalarToSimd128()->simdOp() == simdOp_;
2175 }
2176#ifdef ENABLE_WASM_SIMD1
2177 MDefinition* foldsTo(TempAllocator& alloc) override;
2178#endif
2179
2180 wasm::SimdOp simdOp() const { return simdOp_; }
2181
2182 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; }
2183};
2184
2185// (v128, imm) -> scalar effect-free operations.
2186class MWasmReduceSimd128 : public MUnaryInstruction, public NoTypePolicy::Data {
2187 wasm::SimdOp simdOp_;
2188 uint32_t imm_;
2189
2190 MWasmReduceSimd128(MDefinition* src, wasm::SimdOp simdOp, MIRType outType,
2191 uint32_t imm)
2192 : MUnaryInstruction(classOpcode, src), simdOp_(simdOp), imm_(imm) {
2193 setMovable();
2194 setResultType(outType);
2195 }
2196
2197 public:
2198 INSTRUCTION_HEADER(WasmReduceSimd128)
2199 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)...); }
2200
2201 AliasSet getAliasSet() const override { return AliasSet::None(); }
2202 bool congruentTo(const MDefinition* ins) const override {
2203 return congruentIfOperandsEqual(ins) &&
2204 ins->toWasmReduceSimd128()->simdOp() == simdOp_ &&
2205 ins->toWasmReduceSimd128()->imm() == imm_;
2206 }
2207#ifdef ENABLE_WASM_SIMD1
2208 MDefinition* foldsTo(TempAllocator& alloc) override;
2209#endif
2210
2211 uint32_t imm() const { return imm_; }
2212 wasm::SimdOp simdOp() const { return simdOp_; }
2213
2214 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; }
2215};
2216
2217class MWasmLoadLaneSimd128
2218 : public MVariadicInstruction, // memoryBase is nullptr on some platforms
2219 public NoTypePolicy::Data {
2220 wasm::MemoryAccessDesc access_;
2221 uint32_t laneSize_;
2222 uint32_t laneIndex_;
2223 uint32_t memoryBaseIndex_;
2224
2225 MWasmLoadLaneSimd128(const wasm::MemoryAccessDesc& access, uint32_t laneSize,
2226 uint32_t laneIndex, uint32_t memoryBaseIndex)
2227 : MVariadicInstruction(classOpcode),
2228 access_(access),
2229 laneSize_(laneSize),
2230 laneIndex_(laneIndex),
2231 memoryBaseIndex_(memoryBaseIndex) {
2232 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"
, 2232); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!access_.isAtomic()"
")"); do { *((volatile int*)__null) = 2232; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2233 setGuard();
2234 setResultType(MIRType::Simd128);
2235 }
2236
2237 public:
2238 INSTRUCTION_HEADER(WasmLoadLaneSimd128)
2239 NAMED_OPERANDS((0, base), (1, value))MDefinition* base() const { return getOperand(0); } MDefinition
* value() const { return getOperand(1); }
;
2240
2241 static MWasmLoadLaneSimd128* New(TempAllocator& alloc,
2242 MDefinition* memoryBase, MDefinition* base,
2243 const wasm::MemoryAccessDesc& access,
2244 uint32_t laneSize, uint32_t laneIndex,
2245 MDefinition* value) {
2246 uint32_t nextIndex = 2;
2247 uint32_t memoryBaseIndex = memoryBase ? nextIndex++ : UINT32_MAX(4294967295U);
2248
2249 MWasmLoadLaneSimd128* load = new (alloc)
2250 MWasmLoadLaneSimd128(access, laneSize, laneIndex, memoryBaseIndex);
2251 if (!load->init(alloc, nextIndex)) {
2252 return nullptr;
2253 }
2254
2255 load->initOperand(0, base);
2256 load->initOperand(1, value);
2257 if (memoryBase) {
2258 load->initOperand(memoryBaseIndex, memoryBase);
2259 }
2260
2261 return load;
2262 }
2263
2264 const wasm::MemoryAccessDesc& access() const { return access_; }
2265 uint32_t laneSize() const { return laneSize_; }
2266 uint32_t laneIndex() const { return laneIndex_; }
2267 bool hasMemoryBase() const { return memoryBaseIndex_ != UINT32_MAX(4294967295U); }
2268 MDefinition* memoryBase() const {
2269 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"
, 2269); AnnotateMozCrashReason("MOZ_ASSERT" "(" "hasMemoryBase()"
")"); do { *((volatile int*)__null) = 2269; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2270 return getOperand(memoryBaseIndex_);
2271 }
2272
2273 AliasSet getAliasSet() const override {
2274 return AliasSet::Load(AliasSet::WasmHeap);
2275 }
2276};
2277
2278class MWasmStoreLaneSimd128 : public MVariadicInstruction,
2279 public NoTypePolicy::Data {
2280 wasm::MemoryAccessDesc access_;
2281 uint32_t laneSize_;
2282 uint32_t laneIndex_;
2283 uint32_t memoryBaseIndex_;
2284
2285 explicit MWasmStoreLaneSimd128(const wasm::MemoryAccessDesc& access,
2286 uint32_t laneSize, uint32_t laneIndex,
2287 uint32_t memoryBaseIndex)
2288 : MVariadicInstruction(classOpcode),
2289 access_(access),
2290 laneSize_(laneSize),
2291 laneIndex_(laneIndex),
2292 memoryBaseIndex_(memoryBaseIndex) {
2293 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"
, 2293); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!access_.isAtomic()"
")"); do { *((volatile int*)__null) = 2293; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2294 setGuard();
2295 setResultType(MIRType::Simd128);
2296 }
2297
2298 public:
2299 INSTRUCTION_HEADER(WasmStoreLaneSimd128)
2300 NAMED_OPERANDS((0, base), (1, value))MDefinition* base() const { return getOperand(0); } MDefinition
* value() const { return getOperand(1); }
2301
2302 static MWasmStoreLaneSimd128* New(TempAllocator& alloc,
2303 MDefinition* memoryBase, MDefinition* base,
2304 const wasm::MemoryAccessDesc& access,
2305 uint32_t laneSize, uint32_t laneIndex,
2306 MDefinition* value) {
2307 uint32_t nextIndex = 2;
2308 uint32_t memoryBaseIndex = memoryBase ? nextIndex++ : UINT32_MAX(4294967295U);
2309
2310 MWasmStoreLaneSimd128* store = new (alloc)
2311 MWasmStoreLaneSimd128(access, laneSize, laneIndex, memoryBaseIndex);
2312 if (!store->init(alloc, nextIndex)) {
2313 return nullptr;
2314 }
2315
2316 store->initOperand(0, base);
2317 store->initOperand(1, value);
2318 if (memoryBase) {
2319 store->initOperand(memoryBaseIndex, memoryBase);
2320 }
2321
2322 return store;
2323 }
2324
2325 const wasm::MemoryAccessDesc& access() const { return access_; }
2326 uint32_t laneSize() const { return laneSize_; }
2327 uint32_t laneIndex() const { return laneIndex_; }
2328 bool hasMemoryBase() const { return memoryBaseIndex_ != UINT32_MAX(4294967295U); }
2329 MDefinition* memoryBase() const {
2330 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"
, 2330); AnnotateMozCrashReason("MOZ_ASSERT" "(" "hasMemoryBase()"
")"); do { *((volatile int*)__null) = 2330; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2331 return getOperand(memoryBaseIndex_);
2332 }
2333
2334 AliasSet getAliasSet() const override {
2335 return AliasSet::Store(AliasSet::WasmHeap);
2336 }
2337};
2338
2339// End Wasm SIMD
2340
2341class MIonToWasmCall final : public MVariadicInstruction,
2342 public NoTypePolicy::Data {
2343 CompilerGCPointer<WasmInstanceObject*> instanceObj_;
2344 const wasm::FuncExport& funcExport_;
2345
2346 MIonToWasmCall(WasmInstanceObject* instanceObj, MIRType resultType,
2347 const wasm::FuncExport& funcExport)
2348 : MVariadicInstruction(classOpcode),
2349 instanceObj_(instanceObj),
2350 funcExport_(funcExport) {
2351 setResultType(resultType);
2352 }
2353
2354 public:
2355 INSTRUCTION_HEADER(IonToWasmCall);
2356
2357 static MIonToWasmCall* New(TempAllocator& alloc,
2358 WasmInstanceObject* instanceObj,
2359 const wasm::FuncExport& funcExport);
2360
2361 void initArg(size_t i, MDefinition* arg) { initOperand(i, arg); }
2362
2363 WasmInstanceObject* instanceObject() const { return instanceObj_; }
2364 wasm::Instance* instance() const { return &instanceObj_->instance(); }
2365 const wasm::FuncExport& funcExport() const { return funcExport_; }
2366 bool possiblyCalls() const override { return true; }
2367#ifdef DEBUG1
2368 bool isConsistentFloat32Use(MUse* use) const override;
2369#endif
2370};
2371
2372// For accesses to wasm object fields, we need to be able to describe 8- and
2373// 16-bit accesses. But MIRType can't represent those. Hence these two
2374// supplemental enums, used for reading and writing fields respectively.
2375
2376// Indicates how to widen an 8- or 16-bit value (when it is read from memory).
2377enum class MWideningOp : uint8_t { None, FromU16, FromS16, FromU8, FromS8 };
2378
2379#ifdef JS_JITSPEW1
2380static inline const char* StringFromMWideningOp(MWideningOp op) {
2381 switch (op) {
2382 case MWideningOp::None:
2383 return "None";
2384 case MWideningOp::FromU16:
2385 return "FromU16";
2386 case MWideningOp::FromS16:
2387 return "FromS16";
2388 case MWideningOp::FromU8:
2389 return "FromU8";
2390 case MWideningOp::FromS8:
2391 return "FromS8";
2392 default:
2393 break;
2394 }
2395 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"
, 2395); AnnotateMozCrashReason("MOZ_CRASH(" "Unknown MWideningOp"
")"); do { *((volatile int*)__null) = 2395; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
2396}
2397#endif
2398
2399// Indicates how to narrow a 32-bit value (when it is written to memory). The
2400// operation is a simple truncate.
2401enum class MNarrowingOp : uint8_t { None, To16, To8 };
2402
2403#ifdef JS_JITSPEW1
2404static inline const char* StringFromMNarrowingOp(MNarrowingOp op) {
2405 switch (op) {
2406 case MNarrowingOp::None:
2407 return "None";
2408 case MNarrowingOp::To16:
2409 return "To16";
2410 case MNarrowingOp::To8:
2411 return "To8";
2412 default:
2413 break;
2414 }
2415 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"
, 2415); AnnotateMozCrashReason("MOZ_CRASH(" "Unknown MNarrowingOp"
")"); do { *((volatile int*)__null) = 2415; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
2416}
2417#endif
2418
2419// Provide information about potential trap at the instruction machine code,
2420// e.g. null pointer dereference.
2421struct TrapSiteInfo {
2422 wasm::BytecodeOffset offset;
2423 explicit TrapSiteInfo(wasm::BytecodeOffset offset_) : offset(offset_) {}
2424};
2425
2426using MaybeTrapSiteInfo = mozilla::Maybe<TrapSiteInfo>;
2427
2428// Load an object field stored at a fixed offset from a base pointer. This
2429// field may be any value type, including references. No barriers are
2430// performed. The offset must be representable as a 31-bit unsigned integer.
2431class MWasmLoadField : public MUnaryInstruction, public NoTypePolicy::Data {
2432 uint32_t offset_;
2433 MWideningOp wideningOp_;
2434 AliasSet aliases_;
2435 MaybeTrapSiteInfo maybeTrap_;
2436
2437 MWasmLoadField(MDefinition* obj, uint32_t offset, MIRType type,
2438 MWideningOp wideningOp, AliasSet aliases,
2439 MaybeTrapSiteInfo maybeTrap = mozilla::Nothing())
2440 : MUnaryInstruction(classOpcode, obj),
2441 offset_(uint32_t(offset)),
2442 wideningOp_(wideningOp),
2443 aliases_(aliases),
2444 maybeTrap_(maybeTrap) {
2445 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"
, 2445); AnnotateMozCrashReason("MOZ_ASSERT" "(" "offset <= (2147483647)"
")"); do { *((volatile int*)__null) = 2445; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2446 // "if you want to widen the value when it is loaded, the destination type
2447 // must be Int32".
2448 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"
, 2448); AnnotateMozCrashReason("MOZ_ASSERT" "(" "type == MIRType::Int32"
")"); do { *((volatile int*)__null) = 2448; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2449 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"
, 2456); 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) = 2456; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2450 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"
, 2456); 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) = 2456; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2451 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"
, 2456); 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) = 2456; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2452 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"
, 2456); 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) = 2456; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2453 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"
, 2456); 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) = 2456; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2454 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"
, 2456); 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) = 2456; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2455 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"
, 2456); 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) = 2456; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2456 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"
, 2456); 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) = 2456; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2457 setResultType(type);
2458 if (maybeTrap_) {
2459 setGuard();
2460 }
2461 }
2462
2463 public:
2464 INSTRUCTION_HEADER(WasmLoadField)
2465 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)...); }
2466 NAMED_OPERANDS((0, obj))MDefinition* obj() const { return getOperand(0); }
2467
2468 uint32_t offset() const { return offset_; }
2469 MWideningOp wideningOp() const { return wideningOp_; }
2470 AliasSet getAliasSet() const override { return aliases_; }
2471 MaybeTrapSiteInfo maybeTrap() const { return maybeTrap_; }
2472
2473 bool congruentTo(const MDefinition* ins) const override {
2474 // In the limited case where this insn is used to read
2475 // WasmStructObject::outlineData_ (the field itself, not what it points
2476 // at), we allow commoning up to happen. This is OK because
2477 // WasmStructObject::outlineData_ is readonly for the life of the
2478 // WasmStructObject.
2479 if (!ins->isWasmLoadField()) {
2480 return false;
2481 }
2482 const MWasmLoadField* other = ins->toWasmLoadField();
2483 return ins->isWasmLoadField() && congruentIfOperandsEqual(ins) &&
2484 offset() == other->offset() && wideningOp() == other->wideningOp() &&
2485 getAliasSet().flags() == other->getAliasSet().flags();
2486 }
2487
2488#ifdef JS_JITSPEW1
2489 void getExtras(ExtrasCollector* extras) override {
2490 char buf[96];
2491 SprintfLiteral(buf, "(offs=%lld, wideningOp=%s)", (long long int)offset_,
2492 StringFromMWideningOp(wideningOp_));
2493 extras->add(buf);
2494 }
2495#endif
2496};
2497
2498// Loads a value from a location, denoted as a fixed offset from a base
2499// pointer, which (it is assumed) is within a wasm object. This field may be
2500// any value type, including references. No barriers are performed.
2501//
2502// This instruction takes a pointer to a second object `ka`, which it is
2503// necessary to keep alive. It is expected that `ka` holds a reference to
2504// `obj`, but this is not enforced and no code is generated to access `ka`.
2505// This instruction extends the lifetime of `ka` so that it, and hence `obj`,
2506// cannot be collected while `obj` is live. This is necessary if `obj` does
2507// not point to a GC-managed object. `offset` must be representable as a
2508// 31-bit unsigned integer.
2509class MWasmLoadFieldKA : public MBinaryInstruction, public NoTypePolicy::Data {
2510 uint32_t offset_;
2511 MWideningOp wideningOp_;
2512 AliasSet aliases_;
2513 MaybeTrapSiteInfo maybeTrap_;
2514
2515 MWasmLoadFieldKA(MDefinition* ka, MDefinition* obj, size_t offset,
2516 MIRType type, MWideningOp wideningOp, AliasSet aliases,
2517 MaybeTrapSiteInfo maybeTrap = mozilla::Nothing())
2518 : MBinaryInstruction(classOpcode, ka, obj),
2519 offset_(uint32_t(offset)),
2520 wideningOp_(wideningOp),
2521 aliases_(aliases),
2522 maybeTrap_(maybeTrap) {
2523 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"
, 2523); AnnotateMozCrashReason("MOZ_ASSERT" "(" "offset <= (2147483647)"
")"); do { *((volatile int*)__null) = 2523; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2524 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"
, 2524); AnnotateMozCrashReason("MOZ_ASSERT" "(" "type == MIRType::Int32"
")"); do { *((volatile int*)__null) = 2524; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2525 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"
, 2532); 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) = 2532; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2526 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"
, 2532); 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) = 2532; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2527 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"
, 2532); 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) = 2532; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2528 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"
, 2532); 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) = 2532; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2529 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"
, 2532); 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) = 2532; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2530 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"
, 2532); 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) = 2532; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2531 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"
, 2532); 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) = 2532; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2532 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"
, 2532); 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) = 2532; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2533 setResultType(type);
2534 if (maybeTrap_) {
2535 setGuard();
2536 }
2537 }
2538
2539 public:
2540 INSTRUCTION_HEADER(WasmLoadFieldKA)
2541 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)...); }
2542 NAMED_OPERANDS((0, ka), (1, obj))MDefinition* ka() const { return getOperand(0); } MDefinition
* obj() const { return getOperand(1); }
2543
2544 uint32_t offset() const { return offset_; }
2545 MWideningOp wideningOp() const { return wideningOp_; }
2546 AliasSet getAliasSet() const override { return aliases_; }
2547 MaybeTrapSiteInfo maybeTrap() const { return maybeTrap_; }
2548
2549#ifdef JS_JITSPEW1
2550 void getExtras(ExtrasCollector* extras) override {
2551 char buf[96];
2552 SprintfLiteral(buf, "(offs=%lld, wideningOp=%s)", (long long int)offset_,
2553 StringFromMWideningOp(wideningOp_));
2554 extras->add(buf);
2555 }
2556#endif
2557};
2558
2559// Loads a value from base pointer, given an index and element size. This field
2560// may be any value type, including references. No barriers are performed.
2561//
2562// The element size is implicitly defined by MIRType and MWideningOp. For
2563// example, MIRType::Float32 indicates an element size of 32 bits, and
2564// MIRType::Int32 and MWideningOp::FromU16 together indicate an element size of
2565// 16 bits.
2566//
2567// This instruction takes a second object `ka` that must be kept alive, as
2568// described for MWasmLoadFieldKA above.
2569class MWasmLoadElementKA : public MTernaryInstruction,
2570 public NoTypePolicy::Data {
2571 MWideningOp wideningOp_;
2572 Scale scale_;
2573 AliasSet aliases_;
2574 MaybeTrapSiteInfo maybeTrap_;
2575
2576 MWasmLoadElementKA(MDefinition* ka, MDefinition* base, MDefinition* index,
2577 MIRType type, MWideningOp wideningOp, Scale scale,
2578 AliasSet aliases,
2579 MaybeTrapSiteInfo maybeTrap = mozilla::Nothing())
2580 : MTernaryInstruction(classOpcode, ka, base, index),
2581 wideningOp_(wideningOp),
2582 scale_(scale),
2583 aliases_(aliases),
2584 maybeTrap_(maybeTrap) {
2585 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"
, 2585); AnnotateMozCrashReason("MOZ_ASSERT" "(" "base->type() == MIRType::WasmArrayData"
")"); do { *((volatile int*)__null) = 2585; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2586 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"
, 2588); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2588; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2587 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"
, 2588); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2588; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2588 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"
, 2588); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Load(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Load(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2588; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2589 setResultType(type);
2590 if (maybeTrap_) {
2591 setGuard();
2592 }
2593 }
2594
2595 public:
2596 INSTRUCTION_HEADER(WasmLoadElementKA)
2597 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)...); }
2598 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); }
2599
2600 MWideningOp wideningOp() const { return wideningOp_; }
2601 Scale scale() const { return scale_; }
2602 AliasSet getAliasSet() const override { return aliases_; }
2603 MaybeTrapSiteInfo maybeTrap() const { return maybeTrap_; }
2604
2605#ifdef JS_JITSPEW1
2606 void getExtras(ExtrasCollector* extras) override {
2607 char buf[96];
2608 SprintfLiteral(buf, "(wideningOp=%s, scale=%s)",
2609 StringFromMWideningOp(wideningOp_), StringFromScale(scale_));
2610 extras->add(buf);
2611 }
2612#endif
2613};
2614
2615// Stores a non-reference value to anlocation, denoted as a fixed offset from
2616// a base pointer, which (it is assumed) is within a wasm object. This field
2617// may be any value type, _excluding_ references. References _must_ use the
2618// 'Ref' variant of this instruction. The offset must be representable as a
2619// 31-bit unsigned integer.
2620//
2621// This instruction takes a second object `ka` that must be kept alive, as
2622// described for MWasmLoadFieldKA above.
2623class MWasmStoreFieldKA : public MTernaryInstruction,
2624 public NoTypePolicy::Data {
2625 uint32_t offset_;
2626 MNarrowingOp narrowingOp_;
2627 AliasSet aliases_;
2628 MaybeTrapSiteInfo maybeTrap_;
2629
2630 MWasmStoreFieldKA(MDefinition* ka, MDefinition* obj, size_t offset,
2631 MDefinition* value, MNarrowingOp narrowingOp,
2632 AliasSet aliases,
2633 MaybeTrapSiteInfo maybeTrap = mozilla::Nothing())
2634 : MTernaryInstruction(classOpcode, ka, obj, value),
2635 offset_(uint32_t(offset)),
2636 narrowingOp_(narrowingOp),
2637 aliases_(aliases),
2638 maybeTrap_(maybeTrap) {
2639 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"
, 2639); AnnotateMozCrashReason("MOZ_ASSERT" "(" "offset <= (2147483647)"
")"); do { *((volatile int*)__null) = 2639; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2640 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"
, 2640); AnnotateMozCrashReason("MOZ_ASSERT" "(" "value->type() != MIRType::WasmAnyRef"
")"); do { *((volatile int*)__null) = 2640; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2641 // "if you want to narrow the value when it is stored, the source type
2642 // must be Int32".
2643 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"
, 2644); AnnotateMozCrashReason("MOZ_ASSERT" "(" "value->type() == MIRType::Int32"
")"); do { *((volatile int*)__null) = 2644; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
2644 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"
, 2644); AnnotateMozCrashReason("MOZ_ASSERT" "(" "value->type() == MIRType::Int32"
")"); do { *((volatile int*)__null) = 2644; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2645 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"
, 2652); 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) = 2652; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2646 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"
, 2652); 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) = 2652; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2647 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"
, 2652); 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) = 2652; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2648 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"
, 2652); 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) = 2652; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2649 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"
, 2652); 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) = 2652; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2650 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"
, 2652); 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) = 2652; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2651 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"
, 2652); 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) = 2652; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2652 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"
, 2652); 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) = 2652; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2653 if (maybeTrap_) {
2654 setGuard();
2655 }
2656 }
2657
2658 public:
2659 INSTRUCTION_HEADER(WasmStoreFieldKA)
2660 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)...); }
2661 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); }
2662
2663 uint32_t offset() const { return offset_; }
2664 MNarrowingOp narrowingOp() const { return narrowingOp_; }
2665 AliasSet getAliasSet() const override { return aliases_; }
2666 MaybeTrapSiteInfo maybeTrap() const { return maybeTrap_; }
2667
2668#ifdef JS_JITSPEW1
2669 void getExtras(ExtrasCollector* extras) override {
2670 char buf[96];
2671 SprintfLiteral(buf, "(offs=%lld, narrowingOp=%s)", (long long int)offset_,
2672 StringFromMNarrowingOp(narrowingOp_));
2673 extras->add(buf);
2674 }
2675#endif
2676};
2677
2678// Stores a reference value to a location, denoted as a fixed offset from a
2679// base pointer, which (it is assumed) is within a wasm object. This
2680// instruction emits a pre-barrier. A post barrier _must_ be performed
2681// separately. The offset must be representable as a 31-bit unsigned integer.
2682//
2683// This instruction takes a second object `ka` that must be kept alive, as
2684// described for MWasmLoadFieldKA above.
2685class MWasmStoreFieldRefKA : public MAryInstruction<4>,
2686 public NoTypePolicy::Data {
2687 uint32_t offset_;
2688 AliasSet aliases_;
2689 MaybeTrapSiteInfo maybeTrap_;
2690 WasmPreBarrierKind preBarrierKind_;
2691
2692 MWasmStoreFieldRefKA(MDefinition* instance, MDefinition* ka, MDefinition* obj,
2693 size_t offset, MDefinition* value, AliasSet aliases,
2694 MaybeTrapSiteInfo maybeTrap,
2695 WasmPreBarrierKind preBarrierKind)
2696 : MAryInstruction<4>(classOpcode),
2697 offset_(uint32_t(offset)),
2698 aliases_(aliases),
2699 maybeTrap_(maybeTrap),
2700 preBarrierKind_(preBarrierKind) {
2701 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"
, 2704); AnnotateMozCrashReason("MOZ_ASSERT" "(" "obj->type() == TargetWordMIRType() || obj->type() == MIRType::Pointer || obj->type() == MIRType::WasmAnyRef || obj->type() == MIRType::WasmArrayData"
")"); do { *((volatile int*)__null) = 2704; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2702 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"
, 2704); AnnotateMozCrashReason("MOZ_ASSERT" "(" "obj->type() == TargetWordMIRType() || obj->type() == MIRType::Pointer || obj->type() == MIRType::WasmAnyRef || obj->type() == MIRType::WasmArrayData"
")"); do { *((volatile int*)__null) = 2704; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2703 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"
, 2704); AnnotateMozCrashReason("MOZ_ASSERT" "(" "obj->type() == TargetWordMIRType() || obj->type() == MIRType::Pointer || obj->type() == MIRType::WasmAnyRef || obj->type() == MIRType::WasmArrayData"
")"); do { *((volatile int*)__null) = 2704; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2704 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"
, 2704); AnnotateMozCrashReason("MOZ_ASSERT" "(" "obj->type() == TargetWordMIRType() || obj->type() == MIRType::Pointer || obj->type() == MIRType::WasmAnyRef || obj->type() == MIRType::WasmArrayData"
")"); do { *((volatile int*)__null) = 2704; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2705 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"
, 2705); AnnotateMozCrashReason("MOZ_ASSERT" "(" "offset <= (2147483647)"
")"); do { *((volatile int*)__null) = 2705; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2706 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"
, 2706); AnnotateMozCrashReason("MOZ_ASSERT" "(" "value->type() == MIRType::WasmAnyRef"
")"); do { *((volatile int*)__null) = 2706; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2707 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"
, 2714); 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) = 2714; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2708 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"
, 2714); 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) = 2714; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2709 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"
, 2714); 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) = 2714; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2710 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"
, 2714); 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) = 2714; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2711 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"
, 2714); 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) = 2714; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2712 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"
, 2714); 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) = 2714; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2713 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"
, 2714); 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) = 2714; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2714 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"
, 2714); 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) = 2714; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2715 initOperand(0, instance);
2716 initOperand(1, ka);
2717 initOperand(2, obj);
2718 initOperand(3, value);
2719 if (maybeTrap_) {
2720 setGuard();
2721 }
2722 }
2723
2724 public:
2725 INSTRUCTION_HEADER(WasmStoreFieldRefKA)
2726 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)...); }
2727 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); }
2728
2729 uint32_t offset() const { return offset_; }
2730 AliasSet getAliasSet() const override { return aliases_; }
2731 MaybeTrapSiteInfo maybeTrap() const { return maybeTrap_; }
2732 WasmPreBarrierKind preBarrierKind() const { return preBarrierKind_; }
2733
2734#ifdef JS_JITSPEW1
2735 void getExtras(ExtrasCollector* extras) override {
2736 char buf[64];
2737 SprintfLiteral(buf, "(offs=%lld)", (long long int)offset_);
2738 extras->add(buf);
2739 }
2740#endif
2741};
2742
2743// Stores a non-reference value to a base pointer, given an index and element
2744// size. This field may be any value type, excluding references. References MUST
2745// use the 'Ref' variant of this instruction.
2746//
2747// The element size is implicitly defined by MIRType and MNarrowingOp. For
2748// example, MIRType::Float32 indicates an element size of 32 bits, and
2749// MIRType::Int32 and MNarrowingOp::To16 together indicate an element size of 16
2750// bits.
2751//
2752// This instruction takes a second object `ka` that must be kept alive, as
2753// described for MWasmLoadFieldKA above.
2754class MWasmStoreElementKA : public MQuaternaryInstruction,
2755 public NoTypePolicy::Data {
2756 MNarrowingOp narrowingOp_;
2757 Scale scale_;
2758 AliasSet aliases_;
2759 MaybeTrapSiteInfo maybeTrap_;
2760
2761 MWasmStoreElementKA(MDefinition* ka, MDefinition* base, MDefinition* index,
2762 MDefinition* value, MNarrowingOp narrowingOp, Scale scale,
2763 AliasSet aliases,
2764 MaybeTrapSiteInfo maybeTrap = mozilla::Nothing())
2765 : MQuaternaryInstruction(classOpcode, ka, base, index, value),
2766 narrowingOp_(narrowingOp),
2767 scale_(scale),
2768 aliases_(aliases),
2769 maybeTrap_(maybeTrap) {
2770 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"
, 2770); AnnotateMozCrashReason("MOZ_ASSERT" "(" "base->type() == MIRType::WasmArrayData"
")"); do { *((volatile int*)__null) = 2770; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2771 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"
, 2771); AnnotateMozCrashReason("MOZ_ASSERT" "(" "value->type() != MIRType::WasmAnyRef"
")"); do { *((volatile int*)__null) = 2771; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2772 // "if you want to narrow the value when it is stored, the source type
2773 // must be Int32".
2774 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"
, 2775); AnnotateMozCrashReason("MOZ_ASSERT" "(" "value->type() == MIRType::Int32"
")"); do { *((volatile int*)__null) = 2775; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
2775 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"
, 2775); AnnotateMozCrashReason("MOZ_ASSERT" "(" "value->type() == MIRType::Int32"
")"); do { *((volatile int*)__null) = 2775; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2776 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"
, 2778); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2778; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2777 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"
, 2778); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2778; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2778 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"
, 2778); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2778; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2779 if (maybeTrap_) {
2780 setGuard();
2781 }
2782 }
2783
2784 public:
2785 INSTRUCTION_HEADER(WasmStoreElementKA)
2786 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)...); }
2787 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); }
2788
2789 MNarrowingOp narrowingOp() const { return narrowingOp_; }
2790 Scale scale() const { return scale_; }
2791 AliasSet getAliasSet() const override { return aliases_; }
2792 MaybeTrapSiteInfo maybeTrap() const { return maybeTrap_; }
2793
2794#ifdef JS_JITSPEW1
2795 void getExtras(ExtrasCollector* extras) override {
2796 char buf[96];
2797 SprintfLiteral(buf, "(narrowingOp=%s, scale=%s)",
2798 StringFromMNarrowingOp(narrowingOp_),
2799 StringFromScale(scale_));
2800 extras->add(buf);
2801 }
2802#endif
2803};
2804
2805// Stores a reference value to a base pointer, given an index and element size.
2806// This instruction emits a pre-barrier. A post barrier MUST be performed
2807// separately.
2808//
2809// The element size is implicitly defined by MIRType and MNarrowingOp, as
2810// described for MWasmStoreElementKA above.
2811//
2812// This instruction takes a second object `ka` that must be kept alive, as
2813// described for MWasmLoadFieldKA above.
2814class MWasmStoreElementRefKA : public MAryInstruction<5>,
2815 public NoTypePolicy::Data {
2816 AliasSet aliases_;
2817 MaybeTrapSiteInfo maybeTrap_;
2818 WasmPreBarrierKind preBarrierKind_;
2819
2820 MWasmStoreElementRefKA(MDefinition* instance, MDefinition* ka,
2821 MDefinition* base, MDefinition* index,
2822 MDefinition* value, AliasSet aliases,
2823 MaybeTrapSiteInfo maybeTrap,
2824 WasmPreBarrierKind preBarrierKind)
2825 : MAryInstruction<5>(classOpcode),
2826 aliases_(aliases),
2827 maybeTrap_(maybeTrap),
2828 preBarrierKind_(preBarrierKind) {
2829 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"
, 2829); AnnotateMozCrashReason("MOZ_ASSERT" "(" "base->type() == MIRType::WasmArrayData"
")"); do { *((volatile int*)__null) = 2829; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2830 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"
, 2830); AnnotateMozCrashReason("MOZ_ASSERT" "(" "value->type() == MIRType::WasmAnyRef"
")"); do { *((volatile int*)__null) = 2830; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2831 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"
, 2833); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2833; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2832 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"
, 2833); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2833; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2833 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"
, 2833); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aliases.flags() == AliasSet::Store(AliasSet::WasmArrayDataArea).flags() || aliases.flags() == AliasSet::Store(AliasSet::Any).flags()"
")"); do { *((volatile int*)__null) = 2833; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2834 initOperand(0, instance);
2835 initOperand(1, ka);
2836 initOperand(2, base);
2837 initOperand(3, index);
2838 initOperand(4, value);
2839 if (maybeTrap_) {
2840 setGuard();
2841 }
2842 }
2843
2844 public:
2845 INSTRUCTION_HEADER(WasmStoreElementRefKA)
2846 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)...); }
2847 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); }
2848
2849 AliasSet getAliasSet() const override { return aliases_; }
2850 MaybeTrapSiteInfo maybeTrap() const { return maybeTrap_; }
2851 WasmPreBarrierKind preBarrierKind() const { return preBarrierKind_; }
2852};
2853
2854class MWasmRefIsSubtypeOfAbstract : public MUnaryInstruction,
2855 public NoTypePolicy::Data {
2856 wasm::RefType sourceType_;
2857 wasm::RefType destType_;
2858
2859 MWasmRefIsSubtypeOfAbstract(MDefinition* ref, wasm::RefType sourceType,
2860 wasm::RefType destType)
2861 : MUnaryInstruction(classOpcode, ref),
2862 sourceType_(sourceType),
2863 destType_(destType) {
2864 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"
, 2864); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!destType.isTypeRef()"
")"); do { *((volatile int*)__null) = 2864; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2865 setResultType(MIRType::Int32);
2866 setMovable();
2867 }
2868
2869 public:
2870 INSTRUCTION_HEADER(WasmRefIsSubtypeOfAbstract)
2871 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)...); }
2872 NAMED_OPERANDS((0, ref))MDefinition* ref() const { return getOperand(0); }
2873
2874 wasm::RefType sourceType() const { return sourceType_; };
2875 wasm::RefType destType() const { return destType_; };
2876
2877 bool congruentTo(const MDefinition* ins) const override {
2878 return congruentIfOperandsEqual(ins) &&
2879 sourceType() == ins->toWasmRefIsSubtypeOfAbstract()->sourceType() &&
2880 destType() == ins->toWasmRefIsSubtypeOfAbstract()->destType();
2881 }
2882
2883 HashNumber valueHash() const override {
2884 HashNumber hn = MUnaryInstruction::valueHash();
2885 hn = addU64ToHash(hn, sourceType().packed().bits());
2886 hn = addU64ToHash(hn, destType().packed().bits());
2887 return hn;
2888 }
2889
2890 MDefinition* foldsTo(TempAllocator& alloc) override;
2891};
2892
2893// Tests if the wasm ref `ref` is a subtype of `superSTV`.
2894// The actual super type definition must be known at compile time, so that the
2895// subtyping depth of super type depth can be used.
2896class MWasmRefIsSubtypeOfConcrete : public MBinaryInstruction,
2897 public NoTypePolicy::Data {
2898 wasm::RefType sourceType_;
2899 wasm::RefType destType_;
2900
2901 MWasmRefIsSubtypeOfConcrete(MDefinition* ref, MDefinition* superSTV,
2902 wasm::RefType sourceType, wasm::RefType destType)
2903 : MBinaryInstruction(classOpcode, ref, superSTV),
2904 sourceType_(sourceType),
2905 destType_(destType) {
2906 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"
, 2906); AnnotateMozCrashReason("MOZ_ASSERT" "(" "destType.isTypeRef()"
")"); do { *((volatile int*)__null) = 2906; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2907 setResultType(MIRType::Int32);
2908 setMovable();
2909 }
2910
2911 public:
2912 INSTRUCTION_HEADER(WasmRefIsSubtypeOfConcrete)
2913 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)...); }
2914 NAMED_OPERANDS((0, ref), (1, superSTV))MDefinition* ref() const { return getOperand(0); } MDefinition
* superSTV() const { return getOperand(1); }
2915
2916 wasm::RefType sourceType() const { return sourceType_; };
2917 wasm::RefType destType() const { return destType_; };
2918
2919 bool congruentTo(const MDefinition* ins) const override {
2920 return congruentIfOperandsEqual(ins) &&
2921 sourceType() == ins->toWasmRefIsSubtypeOfConcrete()->sourceType() &&
2922 destType() == ins->toWasmRefIsSubtypeOfConcrete()->destType();
2923 }
2924
2925 HashNumber valueHash() const override {
2926 HashNumber hn = MBinaryInstruction::valueHash();
2927 hn = addU64ToHash(hn, sourceType().packed().bits());
2928 hn = addU64ToHash(hn, destType().packed().bits());
2929 return hn;
2930 }
2931
2932 MDefinition* foldsTo(TempAllocator& alloc) override;
2933};
2934
2935class MWasmNewStructObject : public MBinaryInstruction,
2936 public NoTypePolicy::Data {
2937 private:
2938 bool isOutline_;
2939 bool zeroFields_;
2940 gc::AllocKind allocKind_;
2941
2942 MWasmNewStructObject(MDefinition* instance, MDefinition* typeDefData,
2943 bool isOutline, bool zeroFields, gc::AllocKind allocKind)
2944 : MBinaryInstruction(classOpcode, instance, typeDefData),
2945 isOutline_(isOutline),
2946 zeroFields_(zeroFields),
2947 allocKind_(allocKind) {
2948 setResultType(MIRType::WasmAnyRef);
2949 }
2950
2951 public:
2952 INSTRUCTION_HEADER(WasmNewStructObject)
2953 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)...); }
2954 NAMED_OPERANDS((0, instance), (1, typeDefData))MDefinition* instance() const { return getOperand(0); } MDefinition
* typeDefData() const { return getOperand(1); }
2955
2956 AliasSet getAliasSet() const override {
2957 if (js::SupportDifferentialTesting()) {
2958 // Consider allocations effectful for differential testing.
2959 return MDefinition::getAliasSet();
2960 }
2961 return AliasSet::None();
2962 }
2963 bool isOutline() const { return isOutline_; }
2964 bool zeroFields() const { return zeroFields_; }
2965 gc::AllocKind allocKind() const { return allocKind_; }
2966};
2967
2968class MWasmNewArrayObject : public MTernaryInstruction,
2969 public NoTypePolicy::Data {
2970 private:
2971 uint32_t elemSize_;
2972 bool zeroFields_;
2973 wasm::BytecodeOffset bytecodeOffset_;
2974
2975 MWasmNewArrayObject(MDefinition* instance, MDefinition* numElements,
2976 MDefinition* typeDefData, uint32_t elemSize,
2977 bool zeroFields, wasm::BytecodeOffset bytecodeOffset)
2978 : MTernaryInstruction(classOpcode, instance, numElements, typeDefData),
2979 elemSize_(elemSize),
2980 zeroFields_(zeroFields),
2981 bytecodeOffset_(bytecodeOffset) {
2982 setResultType(MIRType::WasmAnyRef);
2983 }
2984
2985 public:
2986 INSTRUCTION_HEADER(WasmNewArrayObject)
2987 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)...); }
2988 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); }
2989
2990 AliasSet getAliasSet() const override {
2991 if (js::SupportDifferentialTesting()) {
2992 // Consider allocations effectful for differential testing.
2993 return MDefinition::getAliasSet();
2994 }
2995 return AliasSet::None();
2996 }
2997 uint32_t elemSize() const { return elemSize_; }
2998 bool zeroFields() const { return zeroFields_; }
2999 wasm::BytecodeOffset bytecodeOffset() const { return bytecodeOffset_; }
3000};
3001
3002#undef INSTRUCTION_HEADER
3003
3004#ifdef ENABLE_WASM_SIMD1
3005MWasmShuffleSimd128* BuildWasmShuffleSimd128(TempAllocator& alloc,
3006 const int8_t* control,
3007 MDefinition* lhs,
3008 MDefinition* rhs);
3009#endif // ENABLE_WASM_SIMD
3010
3011} // namespace jit
3012} // namespace js
3013
3014#endif /* jit_MIR_wasm_h */