зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset aca2e6cff6b9 (bug 1578418) for bustages complaining about WasmBaselineCompile.cpp CLOSED TREE
This commit is contained in:
Родитель
f16e836b61
Коммит
8fb59cb8ed
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1764,13 +1764,11 @@ static bool EmitF64Const(FunctionCompiler& f) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool EmitBlock(FunctionCompiler& f) {
|
static bool EmitBlock(FunctionCompiler& f) {
|
||||||
ResultType params;
|
return f.iter().readBlock() && f.startBlock();
|
||||||
return f.iter().readBlock(¶ms) && f.startBlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool EmitLoop(FunctionCompiler& f) {
|
static bool EmitLoop(FunctionCompiler& f) {
|
||||||
ResultType params;
|
if (!f.iter().readLoop()) {
|
||||||
if (!f.iter().readLoop(¶ms)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1786,9 +1784,8 @@ static bool EmitLoop(FunctionCompiler& f) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool EmitIf(FunctionCompiler& f) {
|
static bool EmitIf(FunctionCompiler& f) {
|
||||||
ResultType params;
|
|
||||||
MDefinition* condition = nullptr;
|
MDefinition* condition = nullptr;
|
||||||
if (!f.iter().readIf(¶ms, &condition)) {
|
if (!f.iter().readIf(&condition)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1802,10 +1799,9 @@ static bool EmitIf(FunctionCompiler& f) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool EmitElse(FunctionCompiler& f) {
|
static bool EmitElse(FunctionCompiler& f) {
|
||||||
ResultType paramType;
|
ResultType thenType;
|
||||||
ResultType resultType;
|
|
||||||
DefVector thenValues;
|
DefVector thenValues;
|
||||||
if (!f.iter().readElse(¶mType, &resultType, &thenValues)) {
|
if (!f.iter().readElse(&thenType, &thenValues)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -720,11 +720,10 @@ class MOZ_STACK_CLASS OpIter : private Policy {
|
||||||
MOZ_MUST_USE bool readFunctionStart(uint32_t funcIndex);
|
MOZ_MUST_USE bool readFunctionStart(uint32_t funcIndex);
|
||||||
MOZ_MUST_USE bool readFunctionEnd(const uint8_t* bodyEnd);
|
MOZ_MUST_USE bool readFunctionEnd(const uint8_t* bodyEnd);
|
||||||
MOZ_MUST_USE bool readReturn(ValueVector* values);
|
MOZ_MUST_USE bool readReturn(ValueVector* values);
|
||||||
MOZ_MUST_USE bool readBlock(ResultType* paramType);
|
MOZ_MUST_USE bool readBlock();
|
||||||
MOZ_MUST_USE bool readLoop(ResultType* paramType);
|
MOZ_MUST_USE bool readLoop();
|
||||||
MOZ_MUST_USE bool readIf(ResultType* paramType, Value* condition);
|
MOZ_MUST_USE bool readIf(Value* condition);
|
||||||
MOZ_MUST_USE bool readElse(ResultType* paramType, ResultType* resultType,
|
MOZ_MUST_USE bool readElse(ResultType* thenType, ValueVector* thenValues);
|
||||||
ValueVector* thenValues);
|
|
||||||
MOZ_MUST_USE bool readEnd(LabelKind* kind, ResultType* type,
|
MOZ_MUST_USE bool readEnd(LabelKind* kind, ResultType* type,
|
||||||
ValueVector* values);
|
ValueVector* values);
|
||||||
void popEnd();
|
void popEnd();
|
||||||
|
@ -1263,7 +1262,7 @@ inline bool OpIter<Policy>::readReturn(ValueVector* values) {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Policy>
|
template <typename Policy>
|
||||||
inline bool OpIter<Policy>::readBlock(ResultType* paramType) {
|
inline bool OpIter<Policy>::readBlock() {
|
||||||
MOZ_ASSERT(Classify(op_) == OpKind::Block);
|
MOZ_ASSERT(Classify(op_) == OpKind::Block);
|
||||||
|
|
||||||
BlockType type;
|
BlockType type;
|
||||||
|
@ -1271,12 +1270,11 @@ inline bool OpIter<Policy>::readBlock(ResultType* paramType) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
*paramType = type.params();
|
|
||||||
return pushControl(LabelKind::Block, type);
|
return pushControl(LabelKind::Block, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Policy>
|
template <typename Policy>
|
||||||
inline bool OpIter<Policy>::readLoop(ResultType* paramType) {
|
inline bool OpIter<Policy>::readLoop() {
|
||||||
MOZ_ASSERT(Classify(op_) == OpKind::Loop);
|
MOZ_ASSERT(Classify(op_) == OpKind::Loop);
|
||||||
|
|
||||||
BlockType type;
|
BlockType type;
|
||||||
|
@ -1284,12 +1282,11 @@ inline bool OpIter<Policy>::readLoop(ResultType* paramType) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
*paramType = type.params();
|
|
||||||
return pushControl(LabelKind::Loop, type);
|
return pushControl(LabelKind::Loop, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Policy>
|
template <typename Policy>
|
||||||
inline bool OpIter<Policy>::readIf(ResultType* paramType, Value* condition) {
|
inline bool OpIter<Policy>::readIf(Value* condition) {
|
||||||
MOZ_ASSERT(Classify(op_) == OpKind::If);
|
MOZ_ASSERT(Classify(op_) == OpKind::If);
|
||||||
|
|
||||||
BlockType type;
|
BlockType type;
|
||||||
|
@ -1305,14 +1302,12 @@ inline bool OpIter<Policy>::readIf(ResultType* paramType, Value* condition) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
*paramType = type.params();
|
|
||||||
size_t paramsLength = type.params().length();
|
size_t paramsLength = type.params().length();
|
||||||
return thenParamStack_.append(valueStack_.end() - paramsLength, paramsLength);
|
return thenParamStack_.append(valueStack_.end() - paramsLength, paramsLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Policy>
|
template <typename Policy>
|
||||||
inline bool OpIter<Policy>::readElse(ResultType* paramType,
|
inline bool OpIter<Policy>::readElse(ResultType* thenType,
|
||||||
ResultType* resultType,
|
|
||||||
ValueVector* values) {
|
ValueVector* values) {
|
||||||
MOZ_ASSERT(Classify(op_) == OpKind::Else);
|
MOZ_ASSERT(Classify(op_) == OpKind::Else);
|
||||||
|
|
||||||
|
@ -1321,8 +1316,7 @@ inline bool OpIter<Policy>::readElse(ResultType* paramType,
|
||||||
return fail("else can only be used within an if");
|
return fail("else can only be used within an if");
|
||||||
}
|
}
|
||||||
|
|
||||||
*paramType = block.type().params();
|
if (!checkStackAtEndOfBlock(thenType, values)) {
|
||||||
if (!checkStackAtEndOfBlock(resultType, values)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1353,8 +1347,7 @@ inline bool OpIter<Policy>::readEnd(LabelKind* kind, ResultType* type,
|
||||||
|
|
||||||
// If an `if` block ends with `end` instead of `else`, then we must
|
// If an `if` block ends with `end` instead of `else`, then we must
|
||||||
// additionally validate that the then-block doesn't push anything.
|
// additionally validate that the then-block doesn't push anything.
|
||||||
if (block.kind() == LabelKind::Then &&
|
if (block.kind() == LabelKind::Then && !block.resultType().empty()) {
|
||||||
block.type().params() != block.type().results()) {
|
|
||||||
return fail("if without else with a result value");
|
return fail("if without else with a result value");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,93 +39,6 @@ typedef Vector<jit::MIRType, 8, SystemAllocPolicy> MIRTypeVector;
|
||||||
typedef jit::ABIArgIter<MIRTypeVector> ABIArgMIRTypeIter;
|
typedef jit::ABIArgIter<MIRTypeVector> ABIArgMIRTypeIter;
|
||||||
typedef jit::ABIArgIter<ValTypeVector> ABIArgValTypeIter;
|
typedef jit::ABIArgIter<ValTypeVector> ABIArgValTypeIter;
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
// ABIResultIter implementation
|
|
||||||
|
|
||||||
static uint32_t ResultStackSize(ValType type) {
|
|
||||||
switch (type.code()) {
|
|
||||||
case ValType::I32:
|
|
||||||
return ABIResult::StackSizeOfInt32;
|
|
||||||
case ValType::I64:
|
|
||||||
return ABIResult::StackSizeOfInt64;
|
|
||||||
case ValType::F32:
|
|
||||||
return ABIResult::StackSizeOfFloat;
|
|
||||||
case ValType::F64:
|
|
||||||
return ABIResult::StackSizeOfDouble;
|
|
||||||
case ValType::Ref:
|
|
||||||
case ValType::FuncRef:
|
|
||||||
case ValType::AnyRef:
|
|
||||||
return ABIResult::StackSizeOfPtr;
|
|
||||||
case ValType::NullRef:
|
|
||||||
default:
|
|
||||||
MOZ_CRASH("Unexpected result type");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t ABIResult::size() const { return ResultStackSize(type()); }
|
|
||||||
|
|
||||||
void ABIResultIter::settleRegister(ValType type) {
|
|
||||||
MOZ_ASSERT(!done());
|
|
||||||
MOZ_ASSERT(index() < RegisterResultCount);
|
|
||||||
static_assert(RegisterResultCount == 1, "expected a single register result");
|
|
||||||
|
|
||||||
switch (type.code()) {
|
|
||||||
case ValType::I32:
|
|
||||||
cur_ = ABIResult(type, ReturnReg);
|
|
||||||
break;
|
|
||||||
case ValType::I64:
|
|
||||||
cur_ = ABIResult(type, ReturnReg64);
|
|
||||||
break;
|
|
||||||
case ValType::F32:
|
|
||||||
cur_ = ABIResult(type, ReturnFloat32Reg);
|
|
||||||
break;
|
|
||||||
case ValType::F64:
|
|
||||||
cur_ = ABIResult(type, ReturnDoubleReg);
|
|
||||||
break;
|
|
||||||
case ValType::Ref:
|
|
||||||
case ValType::FuncRef:
|
|
||||||
case ValType::AnyRef:
|
|
||||||
cur_ = ABIResult(type, ReturnReg);
|
|
||||||
break;
|
|
||||||
case ValType::NullRef:
|
|
||||||
default:
|
|
||||||
MOZ_CRASH("Unexpected result type");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABIResultIter::settleNext() {
|
|
||||||
MOZ_ASSERT(direction_ == Next);
|
|
||||||
MOZ_ASSERT(!done());
|
|
||||||
|
|
||||||
uint32_t typeIndex = count_ - index_ - 1;
|
|
||||||
ValType type = type_[typeIndex];
|
|
||||||
|
|
||||||
if (index_ < RegisterResultCount) {
|
|
||||||
settleRegister(type);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
cur_ = ABIResult(type, nextStackOffset_);
|
|
||||||
nextStackOffset_ += ResultStackSize(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABIResultIter::settlePrev() {
|
|
||||||
MOZ_ASSERT(direction_ == Prev);
|
|
||||||
MOZ_ASSERT(!done());
|
|
||||||
uint32_t typeIndex = index_;
|
|
||||||
ValType type = type_[typeIndex];
|
|
||||||
|
|
||||||
if (count_ - index_ - 1 < RegisterResultCount) {
|
|
||||||
settleRegister(type);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t size = ResultStackSize(type);
|
|
||||||
MOZ_ASSERT(nextStackOffset_ >= size);
|
|
||||||
nextStackOffset_ -= size;
|
|
||||||
cur_ = ABIResult(type, nextStackOffset_);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef WASM_CODEGEN_DEBUG
|
#ifdef WASM_CODEGEN_DEBUG
|
||||||
template <class Closure>
|
template <class Closure>
|
||||||
static void GenPrint(DebugChannel channel, MacroAssembler& masm,
|
static void GenPrint(DebugChannel channel, MacroAssembler& masm,
|
||||||
|
|
|
@ -20,227 +20,10 @@
|
||||||
#define wasm_stubs_h
|
#define wasm_stubs_h
|
||||||
|
|
||||||
#include "wasm/WasmGenerator.h"
|
#include "wasm/WasmGenerator.h"
|
||||||
#include "wasm/WasmOpIter.h"
|
|
||||||
|
|
||||||
namespace js {
|
namespace js {
|
||||||
namespace wasm {
|
namespace wasm {
|
||||||
|
|
||||||
// ValType and location for a single result: either in a register or on the
|
|
||||||
// stack.
|
|
||||||
|
|
||||||
class ABIResult {
|
|
||||||
ValType type_;
|
|
||||||
enum class Location { Gpr, Gpr64, Fpr, Stack } loc_;
|
|
||||||
union {
|
|
||||||
Register gpr_;
|
|
||||||
Register64 gpr64_;
|
|
||||||
FloatRegister fpr_;
|
|
||||||
uint32_t stackOffset_;
|
|
||||||
};
|
|
||||||
|
|
||||||
void validate() {
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (onStack()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
MOZ_ASSERT(inRegister());
|
|
||||||
switch (type_.code()) {
|
|
||||||
case ValType::I32:
|
|
||||||
MOZ_ASSERT(loc_ == Location::Gpr);
|
|
||||||
break;
|
|
||||||
case ValType::I64:
|
|
||||||
MOZ_ASSERT(loc_ == Location::Gpr64);
|
|
||||||
break;
|
|
||||||
case ValType::F32:
|
|
||||||
case ValType::F64:
|
|
||||||
MOZ_ASSERT(loc_ == Location::Fpr);
|
|
||||||
break;
|
|
||||||
case ValType::AnyRef:
|
|
||||||
case ValType::FuncRef:
|
|
||||||
case ValType::Ref:
|
|
||||||
MOZ_ASSERT(loc_ == Location::Gpr);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
MOZ_CRASH("bad value type");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
friend class ABIResultIter;
|
|
||||||
ABIResult(){};
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Sizes of items in the stack area.
|
|
||||||
//
|
|
||||||
// The size values come from the implementations of Push() in
|
|
||||||
// MacroAssembler-x86-shared.cpp and MacroAssembler-arm-shared.cpp, and from
|
|
||||||
// VFPRegister::size() in Architecture-arm.h.
|
|
||||||
//
|
|
||||||
// On ARM unlike on x86 we push a single for float.
|
|
||||||
|
|
||||||
static constexpr size_t StackSizeOfPtr = sizeof(intptr_t);
|
|
||||||
static constexpr size_t StackSizeOfInt32 = StackSizeOfPtr;
|
|
||||||
static constexpr size_t StackSizeOfInt64 = sizeof(int64_t);
|
|
||||||
#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS32)
|
|
||||||
static constexpr size_t StackSizeOfFloat = sizeof(float);
|
|
||||||
#else
|
|
||||||
static constexpr size_t StackSizeOfFloat = sizeof(double);
|
|
||||||
#endif
|
|
||||||
static constexpr size_t StackSizeOfDouble = sizeof(double);
|
|
||||||
|
|
||||||
ABIResult(ValType type, Register gpr)
|
|
||||||
: type_(type), loc_(Location::Gpr), gpr_(gpr) {
|
|
||||||
validate();
|
|
||||||
}
|
|
||||||
ABIResult(ValType type, Register64 gpr64)
|
|
||||||
: type_(type), loc_(Location::Gpr64), gpr64_(gpr64) {
|
|
||||||
validate();
|
|
||||||
}
|
|
||||||
ABIResult(ValType type, FloatRegister fpr)
|
|
||||||
: type_(type), loc_(Location::Fpr), fpr_(fpr) {
|
|
||||||
validate();
|
|
||||||
}
|
|
||||||
ABIResult(ValType type, uint32_t stackOffset)
|
|
||||||
: type_(type), loc_(Location::Stack), stackOffset_(stackOffset) {
|
|
||||||
validate();
|
|
||||||
}
|
|
||||||
|
|
||||||
ValType type() const { return type_; }
|
|
||||||
bool onStack() const { return loc_ == Location::Stack; }
|
|
||||||
bool inRegister() const { return !onStack(); }
|
|
||||||
Register gpr() const {
|
|
||||||
MOZ_ASSERT(loc_ == Location::Gpr);
|
|
||||||
return gpr_;
|
|
||||||
}
|
|
||||||
Register64 gpr64() const {
|
|
||||||
MOZ_ASSERT(loc_ == Location::Gpr64);
|
|
||||||
return gpr64_;
|
|
||||||
}
|
|
||||||
FloatRegister fpr() const {
|
|
||||||
MOZ_ASSERT(loc_ == Location::Fpr);
|
|
||||||
return fpr_;
|
|
||||||
}
|
|
||||||
// Offset from SP.
|
|
||||||
uint32_t stackOffset() const {
|
|
||||||
MOZ_ASSERT(loc_ == Location::Stack);
|
|
||||||
return stackOffset_;
|
|
||||||
}
|
|
||||||
uint32_t size() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Just as WebAssembly functions can take multiple arguments, they can also
|
|
||||||
// return multiple results. As with a call, a limited number of results will be
|
|
||||||
// located in registers, and the rest will be stored in a stack area. The
|
|
||||||
// |ABIResultIter| computes result locations, given a |ResultType|.
|
|
||||||
//
|
|
||||||
// Recall that a |ResultType| represents a sequence of value types t1..tN,
|
|
||||||
// indexed from 1 to N. In principle it doesn't matter how we decide which
|
|
||||||
// results get to be in registers and which go to the stack. To better
|
|
||||||
// harmonize with WebAssembly's abstract stack machine, whose properties are
|
|
||||||
// taken advantage of by the baseline compiler, our strategy is to start
|
|
||||||
// allocating result locations in "reverse" order: from result N down to 1.
|
|
||||||
//
|
|
||||||
// If a result with index I is in a register, then all results with index J > I
|
|
||||||
// are also in registers. If a result I is on the stack, then all results with
|
|
||||||
// index K < I are also on the stack, farther away from the stack pointer than
|
|
||||||
// result I.
|
|
||||||
//
|
|
||||||
// Currently only a single result is ever stored in a register, though this may
|
|
||||||
// change in the future on register-rich platforms.
|
|
||||||
//
|
|
||||||
// NB: The baseline compiler also uses thie ABI for locations of block
|
|
||||||
// parameters and return values, within individual WebAssembly functions.
|
|
||||||
|
|
||||||
class ABIResultIter {
|
|
||||||
ResultType type_;
|
|
||||||
uint32_t count_;
|
|
||||||
uint32_t index_;
|
|
||||||
uint32_t nextStackOffset_;
|
|
||||||
enum { Next, Prev } direction_;
|
|
||||||
ABIResult cur_;
|
|
||||||
|
|
||||||
void settleRegister(ValType type);
|
|
||||||
void settleNext();
|
|
||||||
void settlePrev();
|
|
||||||
|
|
||||||
static constexpr size_t RegisterResultCount = 1;
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit ABIResultIter(const ResultType& type)
|
|
||||||
: type_(type), count_(type.length()) {
|
|
||||||
reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset() {
|
|
||||||
index_ = nextStackOffset_ = 0;
|
|
||||||
direction_ = Next;
|
|
||||||
if (!done()) {
|
|
||||||
settleNext();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bool done() const { return index_ == count_; }
|
|
||||||
uint32_t index() const { return index_; }
|
|
||||||
uint32_t count() const { return count_; }
|
|
||||||
uint32_t remaining() const { return count_ - index_; }
|
|
||||||
void switchToNext() {
|
|
||||||
MOZ_ASSERT(direction_ == Prev);
|
|
||||||
if (!done() && cur().onStack()) {
|
|
||||||
nextStackOffset_ += cur().size();
|
|
||||||
}
|
|
||||||
index_ = count_ - index_;
|
|
||||||
direction_ = Next;
|
|
||||||
if (!done()) {
|
|
||||||
settleNext();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void switchToPrev() {
|
|
||||||
MOZ_ASSERT(direction_ == Next);
|
|
||||||
if (!done() && cur().onStack()) {
|
|
||||||
nextStackOffset_ -= cur().size();
|
|
||||||
}
|
|
||||||
index_ = count_ - index_;
|
|
||||||
direction_ = Prev;
|
|
||||||
if (!done()) settlePrev();
|
|
||||||
}
|
|
||||||
void next() {
|
|
||||||
MOZ_ASSERT(direction_ == Next);
|
|
||||||
MOZ_ASSERT(!done());
|
|
||||||
index_++;
|
|
||||||
if (!done()) {
|
|
||||||
settleNext();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void prev() {
|
|
||||||
MOZ_ASSERT(direction_ == Prev);
|
|
||||||
MOZ_ASSERT(!done());
|
|
||||||
index_++;
|
|
||||||
if (!done()) {
|
|
||||||
settlePrev();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const ABIResult& cur() const {
|
|
||||||
MOZ_ASSERT(!done());
|
|
||||||
return cur_;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t stackBytesConsumedSoFar() const { return nextStackOffset_; }
|
|
||||||
|
|
||||||
static inline bool HasStackResults(const ResultType& type) {
|
|
||||||
return type.length() > RegisterResultCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t MeasureStackBytes(const ResultType& type) {
|
|
||||||
if (!HasStackResults(type)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
ABIResultIter iter(type);
|
|
||||||
while (!iter.done()) {
|
|
||||||
iter.next();
|
|
||||||
}
|
|
||||||
return iter.stackBytesConsumedSoFar();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
extern bool GenerateBuiltinThunk(jit::MacroAssembler& masm,
|
extern bool GenerateBuiltinThunk(jit::MacroAssembler& masm,
|
||||||
jit::ABIFunctionType abiType,
|
jit::ABIFunctionType abiType,
|
||||||
ExitReason exitReason, void* funcPtr,
|
ExitReason exitReason, void* funcPtr,
|
||||||
|
|
|
@ -578,13 +578,13 @@ static bool DecodeFunctionBodyExprs(const ModuleEnvironment& env,
|
||||||
¬hing));
|
¬hing));
|
||||||
}
|
}
|
||||||
case uint16_t(Op::Block):
|
case uint16_t(Op::Block):
|
||||||
CHECK(iter.readBlock(&unusedType));
|
CHECK(iter.readBlock());
|
||||||
case uint16_t(Op::Loop):
|
case uint16_t(Op::Loop):
|
||||||
CHECK(iter.readLoop(&unusedType));
|
CHECK(iter.readLoop());
|
||||||
case uint16_t(Op::If):
|
case uint16_t(Op::If):
|
||||||
CHECK(iter.readIf(&unusedType, ¬hing));
|
CHECK(iter.readIf(¬hing));
|
||||||
case uint16_t(Op::Else):
|
case uint16_t(Op::Else):
|
||||||
CHECK(iter.readElse(&unusedType, &unusedType, ¬hings));
|
CHECK(iter.readElse(&unusedType, ¬hings));
|
||||||
case uint16_t(Op::I32Clz):
|
case uint16_t(Op::I32Clz):
|
||||||
case uint16_t(Op::I32Ctz):
|
case uint16_t(Op::I32Ctz):
|
||||||
case uint16_t(Op::I32Popcnt):
|
case uint16_t(Op::I32Popcnt):
|
||||||
|
|
Загрузка…
Ссылка в новой задаче