diff --git a/src/interpreter/ByteCode.h b/src/interpreter/ByteCode.h index cb9a7c2d0..78f5c8462 100644 --- a/src/interpreter/ByteCode.h +++ b/src/interpreter/ByteCode.h @@ -47,11 +47,18 @@ class FunctionType; F(CallRef) \ F(Select) \ F(MemorySize) \ + F(MemorySizeM64) \ F(MemoryGrow) \ + F(MemoryGrowM64) \ F(MemoryInit) \ + F(MemoryInitM64) \ F(DataDrop) \ F(MemoryCopy) \ + F(MemoryCopyM64) \ + F(MemoryCopyM64M32) \ + F(MemoryCopyM32M64) \ F(MemoryFill) \ + F(MemoryFillM64) \ F(TableInit) \ F(ElemDrop) \ F(TableCopy) \ @@ -2658,36 +2665,66 @@ class BrTable : public ByteCode { uint32_t m_tableSize; }; -class MemorySize : public ByteCode { +class ByteCodeOffsetMemIndex : public ByteCode { public: - MemorySize(uint32_t index, ByteCodeStackOffset dstOffset) - : ByteCode(Opcode::MemorySizeOpcode) - , m_dstOffset(dstOffset) + ByteCodeOffsetMemIndex(Opcode opcode, uint32_t index, ByteCodeStackOffset dstOffset) + : ByteCode(opcode) + , m_stackOffset(dstOffset) , m_memIndex(index) { } - ByteCodeStackOffset dstOffset() const { return m_dstOffset; } + ByteCodeStackOffset stackOffset1() const { return m_stackOffset; } uint16_t memIndex() const { return m_memIndex; } + +protected: + ByteCodeStackOffset m_stackOffset; + uint16_t m_memIndex; +}; + +class MemorySize : public ByteCodeOffsetMemIndex { +public: + MemorySize(uint32_t index, ByteCodeStackOffset dstOffset) + : ByteCodeOffsetMemIndex(Opcode::MemorySizeOpcode, index, dstOffset) + { + } + + ByteCodeStackOffset dstOffset() const { return stackOffset1(); } + #if !defined(NDEBUG) void dump(size_t pos) { - printf("memory.size "); - DUMP_BYTECODE_OFFSET(dstOffset); - printf("memIndex: %" PRIu16, m_memIndex); + printf("MemorySize "); + DUMP_BYTECODE_OFFSET(stackOffset); + printf("memIndex: %" PRIu16, memIndex()); } #endif +}; -protected: - ByteCodeStackOffset m_dstOffset; - uint16_t m_memIndex; +class MemorySizeM64 : public ByteCodeOffsetMemIndex { +public: + MemorySizeM64(uint32_t index, ByteCodeStackOffset dstOffset) + : ByteCodeOffsetMemIndex(Opcode::MemorySizeM64Opcode, index, dstOffset) + { + } + + ByteCodeStackOffset dstOffset() const { return stackOffset1(); } + +#if !defined(NDEBUG) + void dump(size_t pos) + { + printf("MemorySizeM64 "); + DUMP_BYTECODE_OFFSET(stackOffset); + printf("memIndex: %" PRIu16, memIndex()); + } +#endif }; -class MemoryInit : public ByteCode { +class ByteCodeOffset3MemIndexSegmentIndex : public ByteCode { public: - MemoryInit(uint32_t index, uint32_t segmentIndex, ByteCodeStackOffset src0, ByteCodeStackOffset src1, ByteCodeStackOffset src2) - : ByteCode(Opcode::MemoryInitOpcode) + ByteCodeOffset3MemIndexSegmentIndex(Opcode opcode, uint32_t index, uint32_t segmentIndex, ByteCodeStackOffset src0, ByteCodeStackOffset src1, ByteCodeStackOffset src2) + : ByteCode(opcode) , m_segmentIndex(segmentIndex) , m_memIndex(index) , m_srcOffsets{ src0, src1, src2 } @@ -2706,137 +2743,312 @@ class MemoryInit : public ByteCode { uint16_t memIndex() const { return m_memIndex; } +protected: + uint32_t m_segmentIndex; + uint16_t m_memIndex; + ByteCodeStackOffset m_srcOffsets[3]; +}; + +class MemoryInit : public ByteCodeOffset3MemIndexSegmentIndex { +public: + MemoryInit(uint32_t index, uint32_t segmentIndex, ByteCodeStackOffset src0, ByteCodeStackOffset src1, ByteCodeStackOffset src2) + : ByteCodeOffset3MemIndexSegmentIndex(Opcode::MemoryInitOpcode, index, segmentIndex, src0, src1, src2) + { + } + #if !defined(NDEBUG) void dump(size_t pos) { - printf("memory.init "); + printf("MemoryInit "); DUMP_BYTECODE_OFFSET(srcOffsets[0]); DUMP_BYTECODE_OFFSET(srcOffsets[1]); DUMP_BYTECODE_OFFSET(srcOffsets[2]); - printf("segmentIndex: %" PRIu32, m_segmentIndex); - printf("memIndex: %" PRIu16, m_memIndex); + printf("segmentIndex: %" PRIu32, segmentIndex()); + printf("memIndex: %" PRIu16, memIndex()); + } +#endif +}; + +class MemoryInitM64 : public ByteCodeOffset3MemIndexSegmentIndex { +public: + MemoryInitM64(uint32_t index, uint32_t segmentIndex, ByteCodeStackOffset src0, ByteCodeStackOffset src1, ByteCodeStackOffset src2) + : ByteCodeOffset3MemIndexSegmentIndex(Opcode::MemoryInitM64Opcode, index, segmentIndex, src0, src1, src2) + { + } + +#if !defined(NDEBUG) + void dump(size_t pos) + { + printf("MemoryInitM64 "); + DUMP_BYTECODE_OFFSET(srcOffsets[0]); + DUMP_BYTECODE_OFFSET(srcOffsets[1]); + DUMP_BYTECODE_OFFSET(srcOffsets[2]); + printf("segmentIndex: %" PRIu32, segmentIndex()); + printf("memIndex: %" PRIu16, memIndex()); } #endif +}; + +class ByteCodeOffset3MemIndex2 : public ByteCode { +public: + ByteCodeOffset3MemIndex2(Opcode opcode, uint32_t memIndex1, uint32_t memIndex2, ByteCodeStackOffset src0, ByteCodeStackOffset src1, ByteCodeStackOffset src2) + : ByteCode(opcode) + , m_memIndex1(memIndex1) + , m_memIndex2(memIndex2) + , m_srcOffsets{ src0, src1, src2 } + { + } + + const ByteCodeStackOffset* srcOffsets() const + { + return m_srcOffsets; + } + + uint16_t memIndex1() const { return m_memIndex1; } + uint16_t memIndex2() const { return m_memIndex2; } protected: - uint32_t m_segmentIndex; - uint16_t m_memIndex; + uint16_t m_memIndex1; + uint16_t m_memIndex2; ByteCodeStackOffset m_srcOffsets[3]; }; -class MemoryCopy : public ByteCodeOffset3 { +class MemoryCopy : public ByteCodeOffset3MemIndex2 { public: MemoryCopy(uint32_t srcIndex, uint32_t dstIndex, ByteCodeStackOffset src0, ByteCodeStackOffset src1, ByteCodeStackOffset src2) - : ByteCodeOffset3(Opcode::MemoryCopyOpcode, src0, src1, src2) - , m_srcMemIndex(srcIndex) - , m_dstMemIndex(dstIndex) + : ByteCodeOffset3MemIndex2(Opcode::MemoryCopyOpcode, srcIndex, dstIndex, src0, src1, src2) { } - const ByteCodeStackOffset* srcOffsets() const + uint16_t srcMemIndex() const { return memIndex1(); } + uint16_t dstMemIndex() const { return memIndex2(); } + +#if !defined(NDEBUG) + void dump(size_t pos) + { + printf("MemoryCopy "); + DUMP_BYTECODE_OFFSET(srcOffsets[0]); + DUMP_BYTECODE_OFFSET(srcOffsets[1]); + DUMP_BYTECODE_OFFSET(srcOffsets[2]); + printf("srcMemIndex: %" PRIu16, srcMemIndex()); + printf("dstMemIndex: %" PRIu16, dstMemIndex()); + } +#endif +}; + +class MemoryCopyM64 : public ByteCodeOffset3MemIndex2 { +public: + MemoryCopyM64(uint32_t srcIndex, uint32_t dstIndex, ByteCodeStackOffset src0, ByteCodeStackOffset src1, ByteCodeStackOffset src2) + : ByteCodeOffset3MemIndex2(Opcode::MemoryCopyM64Opcode, srcIndex, dstIndex, src0, src1, src2) { - return stackOffsets(); } - uint16_t srcMemIndex() const { return m_srcMemIndex; } - uint16_t dstMemIndex() const { return m_dstMemIndex; } + uint16_t srcMemIndex() const { return memIndex1(); } + uint16_t dstMemIndex() const { return memIndex2(); } #if !defined(NDEBUG) void dump(size_t pos) { - printf("memory.copy "); - DUMP_BYTECODE_OFFSET(stackOffsets[0]); - DUMP_BYTECODE_OFFSET(stackOffsets[1]); - DUMP_BYTECODE_OFFSET(stackOffsets[2]); - printf("srcMemIndex: %" PRIu16, m_srcMemIndex); - printf("dstMemIndex: %" PRIu16, m_dstMemIndex); + printf("MemoryCopyM64 "); + DUMP_BYTECODE_OFFSET(srcOffsets[0]); + DUMP_BYTECODE_OFFSET(srcOffsets[1]); + DUMP_BYTECODE_OFFSET(srcOffsets[2]); + printf("srcMemIndex: %" PRIu16, srcMemIndex()); + printf("dstMemIndex: %" PRIu16, dstMemIndex()); } #endif - -protected: - uint16_t m_srcMemIndex; - uint16_t m_dstMemIndex; }; -class MemoryFill : public ByteCodeOffset3 { +class MemoryCopyM32M64 : public ByteCodeOffset3MemIndex2 { public: - MemoryFill(uint32_t memIdx, ByteCodeStackOffset src0, ByteCodeStackOffset src1, ByteCodeStackOffset src2) - : ByteCodeOffset3(Opcode::MemoryFillOpcode, src0, src1, src2) - , m_memIndex(memIdx) + MemoryCopyM32M64(uint32_t srcIndex, uint32_t dstIndex, ByteCodeStackOffset src0, ByteCodeStackOffset src1, ByteCodeStackOffset src2) + : ByteCodeOffset3MemIndex2(Opcode::MemoryCopyM32M64Opcode, srcIndex, dstIndex, src0, src1, src2) { } - const ByteCodeStackOffset* srcOffsets() const + uint16_t srcMemIndex() const { return memIndex1(); } + uint16_t dstMemIndex() const { return memIndex2(); } + +#if !defined(NDEBUG) + void dump(size_t pos) { - return stackOffsets(); + printf("MemoryCopyM32M64 "); + DUMP_BYTECODE_OFFSET(srcOffsets[0]); + DUMP_BYTECODE_OFFSET(srcOffsets[1]); + DUMP_BYTECODE_OFFSET(srcOffsets[2]); + printf("srcMemIndex: %" PRIu16, srcMemIndex()); + printf("dstMemIndex: %" PRIu16, dstMemIndex()); } +#endif +}; - uint16_t memIndex() const { return m_memIndex; } +class MemoryCopyM64M32 : public ByteCodeOffset3MemIndex2 { +public: + MemoryCopyM64M32(uint32_t srcIndex, uint32_t dstIndex, ByteCodeStackOffset src0, ByteCodeStackOffset src1, ByteCodeStackOffset src2) + : ByteCodeOffset3MemIndex2(Opcode::MemoryCopyM64M32Opcode, srcIndex, dstIndex, src0, src1, src2) + { + } + + uint16_t srcMemIndex() const { return memIndex1(); } + uint16_t dstMemIndex() const { return memIndex2(); } #if !defined(NDEBUG) void dump(size_t pos) { - printf("memory.fill "); - DUMP_BYTECODE_OFFSET(stackOffsets[0]); - DUMP_BYTECODE_OFFSET(stackOffsets[1]); - DUMP_BYTECODE_OFFSET(stackOffsets[2]); - printf("memIndex: %" PRIu16, m_memIndex); + printf("MemoryCopyM64M32 "); + DUMP_BYTECODE_OFFSET(srcOffsets[0]); + DUMP_BYTECODE_OFFSET(srcOffsets[1]); + DUMP_BYTECODE_OFFSET(srcOffsets[2]); + printf("srcMemIndex: %" PRIu16, srcMemIndex()); + printf("dstMemIndex: %" PRIu16, dstMemIndex()); } #endif +}; + +class ByteCodeOffset3MemIndex : public ByteCode { +public: + ByteCodeOffset3MemIndex(Opcode opcode, uint32_t memIndex, ByteCodeStackOffset src0, ByteCodeStackOffset src1, ByteCodeStackOffset src2) + : ByteCode(opcode) + , m_memIndex(memIndex) + , m_srcOffsets{ src0, src1, src2 } + { + } + + const ByteCodeStackOffset* srcOffsets() const + { + return m_srcOffsets; + } + + uint16_t memIndex() const { return m_memIndex; } protected: uint16_t m_memIndex; + ByteCodeStackOffset m_srcOffsets[3]; }; -class DataDrop : public ByteCode { +class MemoryFill : public ByteCodeOffset3MemIndex { public: - DataDrop(uint32_t segmentIndex) - : ByteCode(Opcode::DataDropOpcode) - , m_segmentIndex(segmentIndex) + MemoryFill(uint32_t memIndex, ByteCodeStackOffset src0, ByteCodeStackOffset src1, ByteCodeStackOffset src2) + : ByteCodeOffset3MemIndex(Opcode::MemoryFillOpcode, memIndex, src0, src1, src2) { } - uint32_t segmentIndex() const +#if !defined(NDEBUG) + void dump(size_t pos) + { + printf("MemoryFill "); + DUMP_BYTECODE_OFFSET(srcOffsets[0]); + DUMP_BYTECODE_OFFSET(srcOffsets[1]); + DUMP_BYTECODE_OFFSET(srcOffsets[2]); + printf("memIndex: %" PRIu16, m_memIndex); + } +#endif +}; + +class MemoryFillM64 : public ByteCodeOffset3MemIndex { +public: + MemoryFillM64(uint32_t memIndex, ByteCodeStackOffset src0, ByteCodeStackOffset src1, ByteCodeStackOffset src2) + : ByteCodeOffset3MemIndex(Opcode::MemoryFillM64Opcode, memIndex, src0, src1, src2) { - return m_segmentIndex; } #if !defined(NDEBUG) void dump(size_t pos) { - printf("data.drop "); - printf("segmentIndex: %" PRIu32, m_segmentIndex); + printf("MemoryFillM64 "); + DUMP_BYTECODE_OFFSET(srcOffsets[0]); + DUMP_BYTECODE_OFFSET(srcOffsets[1]); + DUMP_BYTECODE_OFFSET(srcOffsets[2]); + printf("memIndex: %" PRIu16, memIndex()); } #endif +}; + +class ByteCodeOffset2MemIndex : public ByteCode { +public: + ByteCodeOffset2MemIndex(Opcode opcode, uint32_t memIndex, ByteCodeStackOffset stackOffset1, ByteCodeStackOffset stackOffset2) + : ByteCode(opcode) + , m_memIndex(memIndex) + , m_stackOffset1(stackOffset1) + , m_stackOffset2(stackOffset2) + { + } + + ByteCodeStackOffset stackOffset1() const { return m_stackOffset1; } + ByteCodeStackOffset stackOffset2() const { return m_stackOffset2; } + uint16_t memIndex() const { return m_memIndex; } protected: - uint32_t m_segmentIndex; + uint16_t m_memIndex; + ByteCodeStackOffset m_stackOffset1; + ByteCodeStackOffset m_stackOffset2; }; -class MemoryGrow : public ByteCodeOffset2 { +class MemoryGrow : public ByteCodeOffset2MemIndex { public: - MemoryGrow(uint32_t index, ByteCodeStackOffset srcOffset, ByteCodeStackOffset dstOffset) - : ByteCodeOffset2(Opcode::MemoryGrowOpcode, srcOffset, dstOffset) - , m_memIndex(index) + MemoryGrow(uint32_t memIndex, ByteCodeStackOffset srcOffset, ByteCodeStackOffset dstOffset) + : ByteCodeOffset2MemIndex(Opcode::MemoryGrowOpcode, memIndex, srcOffset, dstOffset) { } ByteCodeStackOffset srcOffset() const { return stackOffset1(); } ByteCodeStackOffset dstOffset() const { return stackOffset2(); } - uint16_t memIndex() const { return m_memIndex; } #if !defined(NDEBUG) void dump(size_t pos) { - printf("memory.grow "); + printf("MemoryGrow "); DUMP_BYTECODE_OFFSET(stackOffset1); DUMP_BYTECODE_OFFSET(stackOffset2); - printf("memIndex: %" PRIu16, m_memIndex); + printf("memIndex: %" PRIu16, memIndex()); + } +#endif +}; + +class MemoryGrowM64 : public ByteCodeOffset2MemIndex { +public: + MemoryGrowM64(uint32_t memIndex, ByteCodeStackOffset srcOffset, ByteCodeStackOffset dstOffset) + : ByteCodeOffset2MemIndex(Opcode::MemoryGrowM64Opcode, memIndex, srcOffset, dstOffset) + { + } + + ByteCodeStackOffset srcOffset() const { return stackOffset1(); } + ByteCodeStackOffset dstOffset() const { return stackOffset2(); } + +#if !defined(NDEBUG) + void dump(size_t pos) + { + printf("MemoryGrowM64 "); + DUMP_BYTECODE_OFFSET(stackOffset1); + DUMP_BYTECODE_OFFSET(stackOffset2); + printf("memIndex: %" PRIu16, memIndex()); + } +#endif +}; + +class DataDrop : public ByteCode { +public: + DataDrop(uint32_t segmentIndex) + : ByteCode(Opcode::DataDropOpcode) + , m_segmentIndex(segmentIndex) + { + } + + uint32_t segmentIndex() const + { + return m_segmentIndex; + } + +#if !defined(NDEBUG) + void dump(size_t pos) + { + printf("data.drop "); + printf("segmentIndex: %" PRIu32, m_segmentIndex); } #endif protected: - uint16_t m_memIndex; + uint32_t m_segmentIndex; }; // dummy ByteCode for memory load operation diff --git a/src/interpreter/Interpreter.cpp b/src/interpreter/Interpreter.cpp index 6fce0bda3..e9459938b 100644 --- a/src/interpreter/Interpreter.cpp +++ b/src/interpreter/Interpreter.cpp @@ -2190,67 +2190,161 @@ ByteCodeStackOffset* Interpreter::interpret(ExecutionState& state, : { MemorySize* code = (MemorySize*)programCounter; - writeValue(bp, code->dstOffset(), memories[code->memIndex()]->sizeInPageSize()); + writeValue(bp, code->dstOffset(), memories[code->memIndex()]->sizeInPageSize()); ADD_PROGRAM_COUNTER(MemorySize); NEXT_INSTRUCTION(); } + DEFINE_OPCODE(MemorySizeM64) + : + { + MemorySizeM64* code = (MemorySizeM64*)programCounter; + writeValue(bp, code->dstOffset(), memories[code->memIndex()]->sizeInPageSize()); + ADD_PROGRAM_COUNTER(MemorySizeM64); + NEXT_INSTRUCTION(); + } + DEFINE_OPCODE(MemoryGrow) : { MemoryGrow* code = (MemoryGrow*)programCounter; Memory* m = memories[code->memIndex()]; auto oldSize = m->sizeInPageSize(); - if (m->grow(readValue(bp, code->srcOffset()) * (uint64_t)Memory::s_memoryPageSize)) { - writeValue(bp, code->dstOffset(), oldSize); + if (m->grow(readValue(bp, code->srcOffset()) * (uint64_t)Memory::s_memoryPageSize)) { + writeValue(bp, code->dstOffset(), oldSize); } else { - writeValue(bp, code->dstOffset(), -1); + writeValue(bp, code->dstOffset(), -1); } ADD_PROGRAM_COUNTER(MemoryGrow); NEXT_INSTRUCTION(); } + DEFINE_OPCODE(MemoryGrowM64) + : + { + MemoryGrowM64* code = (MemoryGrowM64*)programCounter; + Memory* m = memories[code->memIndex()]; + auto oldSize = m->sizeInPageSize(); + uint64_t value = readValue(bp, code->srcOffset()); + if (value < Memory::s_maxMemory64Grow && m->grow(value * (uint64_t)Memory::s_memoryPageSize)) { + writeValue(bp, code->dstOffset(), oldSize); + } else { + writeValue(bp, code->dstOffset(), -1); + } + ADD_PROGRAM_COUNTER(MemoryGrowM64); + NEXT_INSTRUCTION(); + } + DEFINE_OPCODE(MemoryInit) : { MemoryInit* code = (MemoryInit*)programCounter; Memory* m = memories[code->memIndex()]; DataSegment* sg = instance->dataSegment(code->segmentIndex()); - auto dstStart = readValue(bp, code->srcOffsets()[0]); - auto srcStart = readValue(bp, code->srcOffsets()[1]); - auto size = readValue(bp, code->srcOffsets()[2]); + auto dstStart = readValue(bp, code->srcOffsets()[0]); + auto srcStart = readValue(bp, code->srcOffsets()[1]); + auto size = readValue(bp, code->srcOffsets()[2]); m->init(state, sg, dstStart, srcStart, size); ADD_PROGRAM_COUNTER(MemoryInit); NEXT_INSTRUCTION(); } + DEFINE_OPCODE(MemoryInitM64) + : + { + MemoryInitM64* code = (MemoryInitM64*)programCounter; + Memory* m = memories[code->memIndex()]; + DataSegment* sg = instance->dataSegment(code->segmentIndex()); + auto dstStart = readValue(bp, code->srcOffsets()[0]); + auto srcStart = readValue(bp, code->srcOffsets()[1]); + auto size = readValue(bp, code->srcOffsets()[2]); + m->init(state, sg, dstStart, srcStart, size); + ADD_PROGRAM_COUNTER(MemoryInitM64); + NEXT_INSTRUCTION(); + } + DEFINE_OPCODE(MemoryCopy) : { MemoryCopy* code = (MemoryCopy*)programCounter; Memory* srcMem = memories[code->srcMemIndex()]; Memory* dstMem = memories[code->dstMemIndex()]; - auto dstStart = readValue(bp, code->srcOffsets()[0]); - auto srcStart = readValue(bp, code->srcOffsets()[1]); - auto size = readValue(bp, code->srcOffsets()[2]); + auto dstStart = readValue(bp, code->srcOffsets()[0]); + auto srcStart = readValue(bp, code->srcOffsets()[1]); + auto size = readValue(bp, code->srcOffsets()[2]); srcMem->copy(state, dstStart, srcStart, size, dstMem); ADD_PROGRAM_COUNTER(MemoryCopy); NEXT_INSTRUCTION(); } + DEFINE_OPCODE(MemoryCopyM64) + : + { + MemoryCopyM64* code = (MemoryCopyM64*)programCounter; + Memory* srcMem = memories[code->srcMemIndex()]; + Memory* dstMem = memories[code->dstMemIndex()]; + auto dstStart = readValue(bp, code->srcOffsets()[0]); + auto srcStart = readValue(bp, code->srcOffsets()[1]); + auto size = readValue(bp, code->srcOffsets()[2]); + srcMem->copy(state, dstStart, srcStart, size, dstMem); + ADD_PROGRAM_COUNTER(MemoryCopyM64); + NEXT_INSTRUCTION(); + } + + DEFINE_OPCODE(MemoryCopyM64M32) + : + { + MemoryCopyM64M32* code = (MemoryCopyM64M32*)programCounter; + Memory* srcMem = memories[code->srcMemIndex()]; + Memory* dstMem = memories[code->dstMemIndex()]; + auto dstStart = readValue(bp, code->srcOffsets()[0]); + auto srcStart = readValue(bp, code->srcOffsets()[1]); + auto size = readValue(bp, code->srcOffsets()[2]); + srcMem->copy(state, dstStart, srcStart, size, dstMem); + ADD_PROGRAM_COUNTER(MemoryCopyM64M32); + NEXT_INSTRUCTION(); + } + + DEFINE_OPCODE(MemoryCopyM32M64) + : + { + MemoryCopyM32M64* code = (MemoryCopyM32M64*)programCounter; + Memory* srcMem = memories[code->srcMemIndex()]; + Memory* dstMem = memories[code->dstMemIndex()]; + auto dstStart = readValue(bp, code->srcOffsets()[0]); + auto srcStart = readValue(bp, code->srcOffsets()[1]); + auto size = readValue(bp, code->srcOffsets()[2]); + srcMem->copy(state, dstStart, srcStart, size, dstMem); + ADD_PROGRAM_COUNTER(MemoryCopyM32M64); + NEXT_INSTRUCTION(); + } + DEFINE_OPCODE(MemoryFill) : { MemoryFill* code = (MemoryFill*)programCounter; Memory* m = memories[code->memIndex()]; - auto dstStart = readValue(bp, code->srcOffsets()[0]); - auto value = readValue(bp, code->srcOffsets()[1]); - auto size = readValue(bp, code->srcOffsets()[2]); + auto dstStart = readValue(bp, code->srcOffsets()[0]); + auto value = readValue(bp, code->srcOffsets()[1]); + auto size = readValue(bp, code->srcOffsets()[2]); m->fill(state, dstStart, value, size); ADD_PROGRAM_COUNTER(MemoryFill); NEXT_INSTRUCTION(); } + DEFINE_OPCODE(MemoryFillM64) + : + { + MemoryFillM64* code = (MemoryFillM64*)programCounter; + Memory* m = memories[code->memIndex()]; + auto dstStart = readValue(bp, code->srcOffsets()[0]); + auto value = readValue(bp, code->srcOffsets()[1]); + auto size = readValue(bp, code->srcOffsets()[2]); + m->fill(state, dstStart, value, size); + ADD_PROGRAM_COUNTER(MemoryFillM64); + NEXT_INSTRUCTION(); + } + DEFINE_OPCODE(DataDrop) : { diff --git a/src/jit/Backend.cpp b/src/jit/Backend.cpp index c84da17bf..f7547a404 100644 --- a/src/jit/Backend.cpp +++ b/src/jit/Backend.cpp @@ -320,9 +320,8 @@ static void emitInitR0R1(sljit_compiler* compiler, sljit_s32 movOp1, sljit_s32 m sljit_emit_op1(compiler, movOp2, SLJIT_R1, 0, SLJIT_TMP_DEST_REG, 0); } -static void emitInitR0R1R2(sljit_compiler* compiler, sljit_s32 movOp1, sljit_s32 movOp2, sljit_s32 movOp3, Operand* params) +static void emitInitR0R1R2Args(sljit_compiler* compiler, sljit_s32 movOp1, sljit_s32 movOp2, sljit_s32 movOp3, JITArg src[3]) { - JITArg src[3] = { params, params + 1, params + 2 }; int i = 0; if (src[1].arg == SLJIT_R0 || src[2].arg == SLJIT_R0) { @@ -379,6 +378,12 @@ static void emitInitR0R1R2(sljit_compiler* compiler, sljit_s32 movOp1, sljit_s32 } } +static void emitInitR0R1R2(sljit_compiler* compiler, sljit_s32 movOp1, sljit_s32 movOp2, sljit_s32 movOp3, Operand* params) +{ + JITArg src[3] = { params, params + 1, params + 2 }; + emitInitR0R1R2Args(compiler, movOp1, movOp2, movOp3, src); +} + static void emitSelect128(sljit_compiler*, Instruction*, sljit_s32); static void emitMove(sljit_compiler*, uint32_t type, Operand* from, Operand* to); static void emitStoreImmediate(sljit_compiler* compiler, Operand* to, Instruction* instr, bool isFloat); diff --git a/src/jit/ByteCodeParser.cpp b/src/jit/ByteCodeParser.cpp index 8c12484dd..c07caee32 100644 --- a/src/jit/ByteCodeParser.cpp +++ b/src/jit/ByteCodeParser.cpp @@ -194,7 +194,11 @@ static bool isFloatGlobal(uint32_t globalIndex, Module* module) OL4(OTStoreF64M64, /* SSTT */ I64, F64 | NOTMP, PTR, I32 | S0) \ OL4(OTStoreV128, /* SSTT */ I32, V128 | TMP, PTR, I32 | S0) \ OL4(OTStoreV128M64, /* SSTT */ I64, V128 | TMP, PTR, I32 | S0) \ - OL3(OTCallback3Arg, /* SSS */ I32, I32, I32) \ + OL3(OTCallbackI32I32I32, /* SSS */ I32, I32, I32) \ + OL3(OTCallbackI64I64I64, /* SSS */ I64, I64, I64) \ + OL3(OTCallbackI64I32I32, /* SSS */ I64, I32, I32) \ + OL3(OTCallbackI32I64I32, /* SSS */ I32, I64, I32) \ + OL3(OTCallbackI64I32I64, /* SSS */ I64, I32, I64) \ OL3(OTTableGrow, /* SSD */ PTR, I32, I32 | S0 | S1) \ OL3(OTTableFill, /* SSS */ I32, PTR, I32) \ OL4(OTTableSet, /* SSTT */ I32, PTR, I32 | S0, PTR) \ @@ -1812,7 +1816,7 @@ static void compileFunction(JITCompiler* compiler) Instruction* instr = compiler->append(byteCode, Instruction::Table, opcode, 3, 0); instr->addInfo(Instruction::kIsCallback); - instr->setRequiredRegsDescriptor(OTCallback3Arg); + instr->setRequiredRegsDescriptor(OTCallbackI32I32I32); compiler->increaseStackTmpSize(sizeof(TableInitArguments)); Operand* operands = instr->operands(); @@ -1832,7 +1836,7 @@ static void compileFunction(JITCompiler* compiler) Instruction* instr = compiler->append(byteCode, Instruction::Table, opcode, 3, 0); instr->addInfo(Instruction::kIsCallback); - instr->setRequiredRegsDescriptor(OTCallback3Arg); + instr->setRequiredRegsDescriptor(OTCallbackI32I32I32); compiler->increaseStackTmpSize(sizeof(TableCopyArguments)); Operand* operands = instr->operands(); @@ -1879,21 +1883,23 @@ static void compileFunction(JITCompiler* compiler) requiredInit = OTTableGet; break; } - case ByteCode::MemorySizeOpcode: { - MemorySize* memorySize = reinterpret_cast(byteCode); + case ByteCode::MemorySizeOpcode: + case ByteCode::MemorySizeM64Opcode: { + ByteCodeOffsetMemIndex* memorySize = reinterpret_cast(byteCode); Instruction* instr = compiler->append(byteCode, Instruction::Memory, opcode, 0, 1); - instr->setRequiredRegsDescriptor(OTPutI32); + instr->setRequiredRegsDescriptor(opcode == ByteCode::MemorySizeOpcode ? OTPutI32 : OTPutI64); - *instr->operands() = STACK_OFFSET(memorySize->dstOffset()); + *instr->operands() = STACK_OFFSET(memorySize->stackOffset1()); break; } - case ByteCode::MemoryInitOpcode: { - MemoryInit* memoryInit = reinterpret_cast(byteCode); + case ByteCode::MemoryInitOpcode: + case ByteCode::MemoryInitM64Opcode: { + ByteCodeOffset3MemIndexSegmentIndex* memoryInit = reinterpret_cast(byteCode); Instruction* instr = compiler->append(byteCode, Instruction::Memory, opcode, 3, 0); instr->addInfo(Instruction::kIsCallback); - instr->setRequiredRegsDescriptor(OTCallback3Arg); + instr->setRequiredRegsDescriptor(opcode == ByteCode::MemoryInitOpcode ? OTCallbackI32I32I32 : OTCallbackI64I32I32); compiler->increaseStackTmpSize(sizeof(MemoryInitArguments)); Operand* operands = instr->operands(); @@ -1902,22 +1908,64 @@ static void compileFunction(JITCompiler* compiler) operands[2] = STACK_OFFSET(memoryInit->srcOffsets()[2]); break; } + case ByteCode::MemoryFillOpcode: + case ByteCode::MemoryFillM64Opcode: { + ByteCodeOffset3MemIndex* memoryFill = reinterpret_cast(byteCode); + + Instruction* instr = compiler->append(byteCode, Instruction::Memory, opcode, 3, 0); + instr->addInfo(Instruction::kIsCallback); + instr->setRequiredRegsDescriptor(opcode == ByteCode::MemoryFillOpcode ? OTCallbackI32I32I32 : OTCallbackI64I32I64); + + Operand* operands = instr->operands(); + operands[0] = STACK_OFFSET(memoryFill->srcOffsets()[0]); + operands[1] = STACK_OFFSET(memoryFill->srcOffsets()[1]); + operands[2] = STACK_OFFSET(memoryFill->srcOffsets()[2]); + break; + } case ByteCode::MemoryCopyOpcode: - case ByteCode::MemoryFillOpcode: { - group = Instruction::Memory; - paramType = ParamTypes::ParamSrc3; - info = Instruction::kIsCallback; - requiredInit = OTCallback3Arg; - if (opcode == ByteCode::MemoryCopyOpcode) { - compiler->increaseStackTmpSize(sizeof(MemoryCopyArguments)); + case ByteCode::MemoryCopyM64Opcode: + case ByteCode::MemoryCopyM64M32Opcode: + case ByteCode::MemoryCopyM32M64Opcode: { + ByteCodeOffset3MemIndex2* memoryCopy = reinterpret_cast(byteCode); + + Instruction* instr = compiler->append(byteCode, Instruction::Memory, opcode, 3, 0); + instr->addInfo(Instruction::kIsCallback); + + switch (opcode) { + case ByteCode::MemoryCopyM64Opcode: + requiredInit = OTCallbackI64I64I64; + break; + case ByteCode::MemoryCopyM64M32Opcode: + requiredInit = OTCallbackI64I32I32; + break; + case ByteCode::MemoryCopyM32M64Opcode: + requiredInit = OTCallbackI32I64I32; + break; + default: + requiredInit = OTCallbackI32I32I32; + break; } + + instr->setRequiredRegsDescriptor(requiredInit); + compiler->increaseStackTmpSize(sizeof(MemoryCopyArguments)); + + Operand* operands = instr->operands(); + operands[0] = STACK_OFFSET(memoryCopy->srcOffsets()[0]); + operands[1] = STACK_OFFSET(memoryCopy->srcOffsets()[1]); + operands[2] = STACK_OFFSET(memoryCopy->srcOffsets()[2]); break; } - case ByteCode::MemoryGrowOpcode: { - group = Instruction::Memory; - paramType = ParamTypes::ParamSrcDst; - info = Instruction::kIsCallback; - requiredInit = OTOp1I32; + case ByteCode::MemoryGrowOpcode: + case ByteCode::MemoryGrowM64Opcode: { + ByteCodeOffset2MemIndex* memoryGrow = reinterpret_cast(byteCode); + + Instruction* instr = compiler->append(byteCode, Instruction::Memory, opcode, 1, 1); + instr->addInfo(Instruction::kIsCallback); + instr->setRequiredRegsDescriptor(opcode == ByteCode::MemoryGrowOpcode ? OTOp1I32 : OTOp1I64); + + Operand* operands = instr->operands(); + operands[0] = STACK_OFFSET(memoryGrow->stackOffset1()); + operands[1] = STACK_OFFSET(memoryGrow->stackOffset2()); break; } case ByteCode::DataDropOpcode: { diff --git a/src/jit/MemoryUtilInl.h b/src/jit/MemoryUtilInl.h index 956e8bf91..7856a7a47 100644 --- a/src/jit/MemoryUtilInl.h +++ b/src/jit/MemoryUtilInl.h @@ -33,12 +33,68 @@ static sljit_sw initMemory(uint32_t dstStart, uint32_t srcStart, uint32_t srcSiz return ExecutionContext::NoError; } +static sljit_sw initMemoryM64(sljit_uw dstStart, uint32_t srcStart, uint32_t srcSize, MemoryInitArguments* args) +{ + Memory* memory = args->memory; + DataSegment* data = args->data; + + if (!memory->checkAccessM64(dstStart, srcSize)) { + return ExecutionContext::OutOfBoundsMemAccessError; + } + + if (srcStart >= data->sizeInByte() || srcStart + srcSize > data->sizeInByte()) { + return ExecutionContext::OutOfBoundsMemAccessError; + } + + memory->initMemory(data, dstStart, srcStart, srcSize); + return ExecutionContext::NoError; +} + static sljit_sw copyMemory(uint32_t dstStart, uint32_t srcStart, uint32_t size, MemoryCopyArguments* args) { Memory* srcMemory = args->srcMemory; Memory* dstMemory = args->dstMemory; - if (!srcMemory->checkAccess(srcStart, size) || !srcMemory->checkAccess(dstStart, size)) { + if (!srcMemory->checkAccess(srcStart, size) || !dstMemory->checkAccess(dstStart, size)) { + return ExecutionContext::OutOfBoundsMemAccessError; + } + + srcMemory->copyMemory(dstMemory, dstStart, srcStart, size); + return ExecutionContext::NoError; +} + +static sljit_sw copyMemoryM64(sljit_uw dstStart, sljit_uw srcStart, sljit_uw size, MemoryCopyArguments* args) +{ + Memory* srcMemory = args->srcMemory; + Memory* dstMemory = args->dstMemory; + + if (!srcMemory->checkAccessM64(srcStart, size) || !dstMemory->checkAccessM64(dstStart, size)) { + return ExecutionContext::OutOfBoundsMemAccessError; + } + + srcMemory->copyMemory(dstMemory, dstStart, srcStart, size); + return ExecutionContext::NoError; +} + +static sljit_sw copyMemoryM64M32(sljit_uw dstStart, uint32_t srcStart, uint32_t size, MemoryCopyArguments* args) +{ + Memory* srcMemory = args->srcMemory; + Memory* dstMemory = args->dstMemory; + + if (!srcMemory->checkAccess(srcStart, size) || !dstMemory->checkAccessM64(dstStart, size)) { + return ExecutionContext::OutOfBoundsMemAccessError; + } + + srcMemory->copyMemory(dstMemory, dstStart, srcStart, size); + return ExecutionContext::NoError; +} + +static sljit_sw copyMemoryM32M64(uint32_t dstStart, sljit_uw srcStart, uint32_t size, MemoryCopyArguments* args) +{ + Memory* srcMemory = args->srcMemory; + Memory* dstMemory = args->dstMemory; + + if (!srcMemory->checkAccessM64(srcStart, size) || !dstMemory->checkAccess(dstStart, size)) { return ExecutionContext::OutOfBoundsMemAccessError; } @@ -56,6 +112,16 @@ static sljit_sw fillMemory(uint32_t start, uint32_t value, uint32_t size, Memory return ExecutionContext::NoError; } +static sljit_sw fillMemoryM64(sljit_uw start, uint32_t value, sljit_uw size, Memory* memory) +{ + if (!memory->checkAccessM64(start, size)) { + return ExecutionContext::OutOfBoundsMemAccessError; + } + + memory->fillMemory(start, value, size); + return ExecutionContext::NoError; +} + static sljit_s32 growMemory(uint32_t newSize, Instance* instance, uint16_t memIndex) { Memory* memory = instance->memory(memIndex); @@ -68,6 +134,32 @@ static sljit_s32 growMemory(uint32_t newSize, Instance* instance, uint16_t memIn return -1; } +static sljit_uw growMemoryM64(sljit_uw newSize, Instance* instance, uint16_t memIndex) +{ + Memory* memory = instance->memory(memIndex); + uint32_t oldSize = memory->sizeInPageSize(); + + if (static_cast(newSize) < Memory::s_maxMemory64Grow && memory->grow(static_cast(newSize) * Memory::s_memoryPageSize)) { + return static_cast(oldSize); + } + + return -1; +} + +#if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE) +static void memoryParamToArg(sljit_compiler* compiler, CompileContext* context, Operand* param, JITArg* arg) +{ + JITArgPair argPair(param); + + context->appendTrapJump(ExecutionContext::OutOfBoundsMemAccessError, + sljit_emit_cmp(compiler, SLJIT_NOT_EQUAL, argPair.arg2, argPair.arg2w, SLJIT_IMM, 0)); + + arg->arg = argPair.arg1; + arg->argw = argPair.arg1w; +} + +#endif /* SLJIT_32BIT_ARCHITECTURE */ + static void emitMemory(sljit_compiler* compiler, Instruction* instr) { CompileContext* context = CompileContext::get(compiler); @@ -78,26 +170,124 @@ static void emitMemory(sljit_compiler* compiler, Instruction* instr) case ByteCode::MemorySizeOpcode: { ASSERT(!(instr->info() & Instruction::kIsCallback)); - uint16_t memIndex = reinterpret_cast(instr->byteCode())->memIndex(); + uint16_t memIndex = reinterpret_cast(instr->byteCode())->memIndex(); JITArg dstArg(params); +#if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE) /* The sizeInByte is always a 32 bit number on 32 bit systems. */ sljit_emit_op2(compiler, SLJIT_LSHR, dstArg.arg, dstArg.argw, SLJIT_MEM1(kInstanceReg), context->targetBuffersStart + offsetof(Memory::TargetBuffer, sizeInByte) + memIndex * sizeof(Memory::TargetBuffer) + WORD_LOW_OFFSET, SLJIT_IMM, 16); +#else /* !SLJIT_32BIT_ARCHITECTURE */ + sljit_emit_op2(compiler, SLJIT_LSHR, SLJIT_TMP_DEST_REG, 0, SLJIT_MEM1(kInstanceReg), + context->targetBuffersStart + offsetof(Memory::TargetBuffer, sizeInByte) + memIndex * sizeof(Memory::TargetBuffer), + SLJIT_IMM, 16); + sljit_emit_op1(compiler, SLJIT_MOV_U32, dstArg.arg, dstArg.argw, SLJIT_TMP_DEST_REG, 0); +#endif /* SLJIT_32BIT_ARCHITECTURE */ + return; + } + case ByteCode::MemorySizeM64Opcode: { + ASSERT(!(instr->info() & Instruction::kIsCallback)); + + uint16_t memIndex = reinterpret_cast(instr->byteCode())->memIndex(); + +#if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE) + JITArgPair dstArgPair(params); + /* The sizeInByte is always a 32 bit number on 32 bit systems. */ + sljit_emit_op2(compiler, SLJIT_LSHR, dstArgPair.arg1, dstArgPair.arg1w, SLJIT_MEM1(kInstanceReg), + context->targetBuffersStart + offsetof(Memory::TargetBuffer, sizeInByte) + memIndex * sizeof(Memory::TargetBuffer) + WORD_LOW_OFFSET, + SLJIT_IMM, 16); + sljit_emit_op1(compiler, SLJIT_MOV, dstArgPair.arg2, dstArgPair.arg2w, SLJIT_IMM, 0); +#else /* !SLJIT_32BIT_ARCHITECTURE */ + JITArg dstArg(params); + sljit_emit_op2(compiler, SLJIT_LSHR, dstArg.arg, dstArg.argw, SLJIT_MEM1(kInstanceReg), + context->targetBuffersStart + offsetof(Memory::TargetBuffer, sizeInByte) + memIndex * sizeof(Memory::TargetBuffer), + SLJIT_IMM, 16); +#endif /* SLJIT_32BIT_ARCHITECTURE */ return; } case ByteCode::MemoryInitOpcode: + case ByteCode::MemoryInitM64Opcode: + case ByteCode::MemoryFillOpcode: + case ByteCode::MemoryFillM64Opcode: case ByteCode::MemoryCopyOpcode: - case ByteCode::MemoryFillOpcode: { + case ByteCode::MemoryCopyM64Opcode: + case ByteCode::MemoryCopyM64M32Opcode: + case ByteCode::MemoryCopyM32M64Opcode: { ASSERT(instr->info() & Instruction::kIsCallback); - emitInitR0R1R2(compiler, SLJIT_MOV32, SLJIT_MOV32, SLJIT_MOV32, params); +#if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE) + JITArg src[3]; + + switch (opcode) { + case ByteCode::MemoryInitM64Opcode: + case ByteCode::MemoryCopyM64M32Opcode: + memoryParamToArg(compiler, context, params + 0, src + 0); + src[1].set(params + 1); + src[2].set(params + 2); + break; + case ByteCode::MemoryCopyM64Opcode: + memoryParamToArg(compiler, context, params + 0, src + 0); + memoryParamToArg(compiler, context, params + 1, src + 1); + memoryParamToArg(compiler, context, params + 2, src + 2); + break; + case ByteCode::MemoryCopyM32M64Opcode: + src[0].set(params + 0); + memoryParamToArg(compiler, context, params + 1, src + 1); + src[2].set(params + 2); + break; + case ByteCode::MemoryFillM64Opcode: + memoryParamToArg(compiler, context, params + 0, src + 0); + src[1].set(params + 1); + memoryParamToArg(compiler, context, params + 2, src + 2); + break; + default: + src[0].set(params + 0); + src[1].set(params + 1); + src[2].set(params + 2); + break; + } + emitInitR0R1R2Args(compiler, SLJIT_MOV, SLJIT_MOV, SLJIT_MOV, src); +#else /* !SLJIT_32BIT_ARCHITECTURE */ + sljit_s32 movOp1, movOp2, movOp3; + + switch (opcode) { + case ByteCode::MemoryInitM64Opcode: + case ByteCode::MemoryCopyM64M32Opcode: + movOp1 = SLJIT_MOV; + movOp2 = SLJIT_MOV32; + movOp3 = SLJIT_MOV32; + break; + case ByteCode::MemoryCopyM64Opcode: + movOp1 = SLJIT_MOV; + movOp2 = SLJIT_MOV; + movOp3 = SLJIT_MOV; + break; + case ByteCode::MemoryCopyM32M64Opcode: + movOp1 = SLJIT_MOV32; + movOp2 = SLJIT_MOV; + movOp3 = SLJIT_MOV32; + break; + case ByteCode::MemoryFillM64Opcode: + movOp1 = SLJIT_MOV; + movOp2 = SLJIT_MOV32; + movOp3 = SLJIT_MOV; + break; + default: + movOp1 = SLJIT_MOV32; + movOp2 = SLJIT_MOV32; + movOp3 = SLJIT_MOV32; + break; + } + emitInitR0R1R2(compiler, movOp1, movOp2, movOp3, params); +#endif /* SLJIT_32BIT_ARCHITECTURE */ sljit_sw addr; - if (opcode == ByteCode::MemoryInitOpcode) { - MemoryInit* memoryInit = reinterpret_cast(instr->byteCode()); + switch (opcode) { + case ByteCode::MemoryInitOpcode: + case ByteCode::MemoryInitM64Opcode: { + ByteCodeOffset3MemIndexSegmentIndex* memoryInit = reinterpret_cast(instr->byteCode()); sljit_sw stackTmpStart = CompileContext::get(compiler)->stackTmpStart; sljit_get_local_base(compiler, SLJIT_R3, 0, stackTmpStart); @@ -105,8 +295,18 @@ static void emitMemory(sljit_compiler* compiler, Instruction* instr) SLJIT_MEM1(kInstanceReg), Instance::alignedSize() + memoryInit->memIndex() * sizeof(void*)); sljit_emit_op2(compiler, SLJIT_ADD, SLJIT_MEM1(SLJIT_SP), OffsetOfStackTmp(MemoryInitArguments, data), kInstanceReg, 0, SLJIT_IMM, context->dataSegmentsStart + (memoryInit->segmentIndex() * sizeof(ElementSegment))); - addr = GET_FUNC_ADDR(sljit_sw, initMemory); - } else if (opcode == ByteCode::MemoryCopyOpcode) { + addr = (opcode == ByteCode::MemoryInitOpcode) ? GET_FUNC_ADDR(sljit_sw, initMemory) : GET_FUNC_ADDR(sljit_sw, initMemoryM64); + break; + } + case ByteCode::MemoryFillOpcode: + case ByteCode::MemoryFillM64Opcode: { + ByteCodeOffset3MemIndex* memoryFill = reinterpret_cast(instr->byteCode()); + + sljit_emit_op1(compiler, SLJIT_MOV_P, SLJIT_R3, 0, SLJIT_MEM1(kInstanceReg), Instance::alignedSize() + memoryFill->memIndex() * sizeof(void*)); + addr = (opcode == ByteCode::MemoryFillOpcode) ? GET_FUNC_ADDR(sljit_sw, fillMemory) : GET_FUNC_ADDR(sljit_sw, fillMemoryM64); + break; + } + default: { MemoryCopy* memoryCopy = reinterpret_cast(instr->byteCode()); sljit_sw stackTmpStart = CompileContext::get(compiler)->stackTmpStart; @@ -115,12 +315,23 @@ static void emitMemory(sljit_compiler* compiler, Instruction* instr) SLJIT_MEM1(kInstanceReg), Instance::alignedSize() + memoryCopy->srcMemIndex() * sizeof(void*)); sljit_emit_op1(compiler, SLJIT_MOV_P, SLJIT_MEM1(SLJIT_SP), OffsetOfStackTmp(MemoryCopyArguments, dstMemory), SLJIT_MEM1(kInstanceReg), Instance::alignedSize() + memoryCopy->dstMemIndex() * sizeof(void*)); - addr = GET_FUNC_ADDR(sljit_sw, copyMemory); - } else { - MemoryFill* memoryFill = reinterpret_cast(instr->byteCode()); - sljit_emit_op1(compiler, SLJIT_MOV_P, SLJIT_R3, 0, SLJIT_MEM1(kInstanceReg), Instance::alignedSize() + memoryFill->memIndex() * sizeof(void*)); - addr = GET_FUNC_ADDR(sljit_sw, fillMemory); + switch (opcode) { + case ByteCode::MemoryCopyM64Opcode: + addr = GET_FUNC_ADDR(sljit_sw, copyMemoryM64); + break; + case ByteCode::MemoryCopyM64M32Opcode: + addr = GET_FUNC_ADDR(sljit_sw, copyMemoryM64M32); + break; + case ByteCode::MemoryCopyM32M64Opcode: + addr = GET_FUNC_ADDR(sljit_sw, copyMemoryM32M64); + break; + default: + addr = GET_FUNC_ADDR(sljit_sw, copyMemory); + break; + } + break; + } } sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS4(W, 32, 32, 32, P), SLJIT_IMM, addr); @@ -130,21 +341,43 @@ static void emitMemory(sljit_compiler* compiler, Instruction* instr) return; } default: { - ASSERT(opcode == ByteCode::MemoryGrowOpcode && (instr->info() & Instruction::kIsCallback)); + ASSERT((opcode == ByteCode::MemoryGrowOpcode || opcode == ByteCode::MemoryGrowM64Opcode) && (instr->info() & Instruction::kIsCallback)); - uint16_t memIndex = reinterpret_cast(instr->byteCode())->memIndex(); + uint16_t memIndex = reinterpret_cast(instr->byteCode())->memIndex(); +#if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE) + JITArg arg; + if (opcode == ByteCode::MemoryGrowOpcode) { + arg.set(params); + } else { + memoryParamToArg(compiler, context, params + 0, &arg); + } + MOVE_TO_REG(compiler, SLJIT_MOV, SLJIT_R0, arg.arg, arg.argw); +#else /* !SLJIT_32BIT_ARCHITECTURE */ JITArg arg(params); + sljit_s32 movOpcode = (opcode == ByteCode::MemoryGrowOpcode) ? SLJIT_MOV32 : SLJIT_MOV; + MOVE_TO_REG(compiler, movOpcode, SLJIT_R0, arg.arg, arg.argw); +#endif /* SLJIT_32BIT_ARCHITECTURE */ - MOVE_TO_REG(compiler, SLJIT_MOV32, SLJIT_R0, arg.arg, arg.argw); sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_R1, 0, kInstanceReg, 0); sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_R2, 0, SLJIT_IMM, memIndex); - sljit_sw addr = GET_FUNC_ADDR(sljit_sw, growMemory); + sljit_sw addr = (opcode == ByteCode::MemoryGrowOpcode) ? GET_FUNC_ADDR(sljit_sw, growMemory) : GET_FUNC_ADDR(sljit_sw, growMemoryM64); sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS3(32, 32, W, W), SLJIT_IMM, addr); +#if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE) + if (opcode == ByteCode::MemoryGrowOpcode) { + arg.set(params + 1); + MOVE_FROM_REG(compiler, SLJIT_MOV, arg.arg, arg.argw, SLJIT_R0); + } else { + JITArgPair argPair(params + 1); + MOVE_FROM_REG(compiler, SLJIT_MOV, argPair.arg1, argPair.arg1w, SLJIT_R0); + sljit_emit_op1(compiler, SLJIT_MOV, argPair.arg2, argPair.arg2w, SLJIT_IMM, 0); + } +#else /* !SLJIT_32BIT_ARCHITECTURE */ arg.set(params + 1); - MOVE_FROM_REG(compiler, SLJIT_MOV32, arg.arg, arg.argw, SLJIT_R0); + MOVE_FROM_REG(compiler, movOpcode, arg.arg, arg.argw, SLJIT_R0); +#endif /* SLJIT_32BIT_ARCHITECTURE */ return; } } diff --git a/src/parser/WASMParser.cpp b/src/parser/WASMParser.cpp index d302e3759..9931cd82c 100644 --- a/src/parser/WASMParser.cpp +++ b/src/parser/WASMParser.cpp @@ -2333,40 +2333,58 @@ class WASMBinaryReader : public wabt::WASMBinaryReaderDelegate { processCatchExpr(std::numeric_limits::max()); } - virtual void OnMemoryInitExpr(Index segmentIndex, Index memidx) override + virtual void OnMemoryInitExpr(Index segmentIndex, Index memIdx) override { ASSERT(peekVMStackValueType() == Walrus::Value::Type::I32); auto src2 = popVMStack(); ASSERT(peekVMStackValueType() == Walrus::Value::Type::I32); auto src1 = popVMStack(); - ASSERT(peekVMStackValueType() == Walrus::Value::Type::I32); + ASSERT((m_result.m_memoryTypes[memIdx]->is64() ? Walrus::Value::I64 : Walrus::Value::I32) == peekVMStackValueType()); auto src0 = popVMStack(); - pushByteCode(Walrus::MemoryInit(memidx, segmentIndex, src0, src1, src2), WASMOpcode::MemoryInitOpcode); + if (!m_result.m_memoryTypes[memIdx]->is64()) { + pushByteCode(Walrus::MemoryInit(memIdx, segmentIndex, src0, src1, src2), WASMOpcode::MemoryInitOpcode); + } else { + pushByteCode(Walrus::MemoryInitM64(memIdx, segmentIndex, src0, src1, src2), WASMOpcode::MemoryInitOpcode); + } } virtual void OnMemoryCopyExpr(Index srcMemIndex, Index dstMemIndex) override { - ASSERT(peekVMStackValueType() == Walrus::Value::Type::I32); + ASSERT((m_result.m_memoryTypes[srcMemIndex]->is64() && m_result.m_memoryTypes[dstMemIndex]->is64() ? Walrus::Value::I64 : Walrus::Value::I32) == peekVMStackValueType()); auto src2 = popVMStack(); - ASSERT(peekVMStackValueType() == Walrus::Value::Type::I32); + ASSERT((m_result.m_memoryTypes[srcMemIndex]->is64() ? Walrus::Value::I64 : Walrus::Value::I32) == peekVMStackValueType()); auto src1 = popVMStack(); - ASSERT(peekVMStackValueType() == Walrus::Value::Type::I32); + ASSERT((m_result.m_memoryTypes[dstMemIndex]->is64() ? Walrus::Value::I64 : Walrus::Value::I32) == peekVMStackValueType()); auto src0 = popVMStack(); - pushByteCode(Walrus::MemoryCopy(srcMemIndex, dstMemIndex, src0, src1, src2), WASMOpcode::MemoryCopyOpcode); + if (!m_result.m_memoryTypes[srcMemIndex]->is64()) { + if (!m_result.m_memoryTypes[dstMemIndex]->is64()) { + pushByteCode(Walrus::MemoryCopy(srcMemIndex, dstMemIndex, src0, src1, src2), WASMOpcode::MemoryCopyOpcode); + } else { + pushByteCode(Walrus::MemoryCopyM64M32(srcMemIndex, dstMemIndex, src0, src1, src2), WASMOpcode::MemoryCopyOpcode); + } + } else if (m_result.m_memoryTypes[dstMemIndex]->is64()) { + pushByteCode(Walrus::MemoryCopyM64(srcMemIndex, dstMemIndex, src0, src1, src2), WASMOpcode::MemoryCopyOpcode); + } else { + pushByteCode(Walrus::MemoryCopyM32M64(srcMemIndex, dstMemIndex, src0, src1, src2), WASMOpcode::MemoryCopyOpcode); + } } - virtual void OnMemoryFillExpr(Index memidx) override + virtual void OnMemoryFillExpr(Index memIdx) override { - ASSERT(peekVMStackValueType() == Walrus::Value::Type::I32); + ASSERT((m_result.m_memoryTypes[memIdx]->is64() ? Walrus::Value::I64 : Walrus::Value::I32) == peekVMStackValueType()); auto src2 = popVMStack(); ASSERT(peekVMStackValueType() == Walrus::Value::Type::I32); auto src1 = popVMStack(); - ASSERT(peekVMStackValueType() == Walrus::Value::Type::I32); + ASSERT((m_result.m_memoryTypes[memIdx]->is64() ? Walrus::Value::I64 : Walrus::Value::I32) == peekVMStackValueType()); auto src0 = popVMStack(); - pushByteCode(Walrus::MemoryFill(memidx, src0, src1, src2), WASMOpcode::MemoryFillOpcode); + if (!m_result.m_memoryTypes[memIdx]->is64()) { + pushByteCode(Walrus::MemoryFill(memIdx, src0, src1, src2), WASMOpcode::MemoryFillOpcode); + } else { + pushByteCode(Walrus::MemoryFillM64(memIdx, src0, src1, src2), WASMOpcode::MemoryFillOpcode); + } } virtual void OnDataDropExpr(Index segmentIndex) override @@ -2374,18 +2392,28 @@ class WASMBinaryReader : public wabt::WASMBinaryReaderDelegate { pushByteCode(Walrus::DataDrop(segmentIndex), WASMOpcode::DataDropOpcode); } - virtual void OnMemoryGrowExpr(Index memidx) override + virtual void OnMemoryGrowExpr(Index memIdx) override { - ASSERT(peekVMStackValueType() == Walrus::Value::Type::I32); + ASSERT((m_result.m_memoryTypes[memIdx]->is64() ? Walrus::Value::I64 : Walrus::Value::I32) == peekVMStackValueType()); auto src = popVMStack(); auto dst = computeExprResultPosition(Walrus::Value::Type::I32); - pushByteCode(Walrus::MemoryGrow(memidx, src, dst), WASMOpcode::MemoryGrowOpcode); + + if (!m_result.m_memoryTypes[memIdx]->is64()) { + pushByteCode(Walrus::MemoryGrow(memIdx, src, dst), WASMOpcode::MemoryGrowOpcode); + } else { + pushByteCode(Walrus::MemoryGrowM64(memIdx, src, dst), WASMOpcode::MemoryGrowOpcode); + } } - virtual void OnMemorySizeExpr(Index memidx) override + virtual void OnMemorySizeExpr(Index memIdx) override { - auto stackPos = computeExprResultPosition(Walrus::Value::Type::I32); - pushByteCode(Walrus::MemorySize(memidx, stackPos), WASMOpcode::MemorySizeOpcode); + if (!m_result.m_memoryTypes[memIdx]->is64()) { + auto stackPos = computeExprResultPosition(Walrus::Value::Type::I32); + pushByteCode(Walrus::MemorySize(memIdx, stackPos), WASMOpcode::MemorySizeOpcode); + } else { + auto stackPos = computeExprResultPosition(Walrus::Value::Type::I64); + pushByteCode(Walrus::MemorySizeM64(memIdx, stackPos), WASMOpcode::MemorySizeOpcode); + } } virtual void OnTableGetExpr(Index tableIndex) override diff --git a/src/runtime/Memory.cpp b/src/runtime/Memory.cpp index ab19dd5f4..d87759061 100644 --- a/src/runtime/Memory.cpp +++ b/src/runtime/Memory.cpp @@ -207,9 +207,13 @@ class ReverseArrayIterator { T* _ptr; }; -void Memory::init(ExecutionState& state, DataSegment* source, uint32_t dstStart, uint32_t srcStart, uint32_t srcSize) +void Memory::init(ExecutionState& state, DataSegment* source, uint64_t dstStart, uint32_t srcStart, uint32_t srcSize) { - checkAccess(state, dstStart, srcSize); + if (!is64()) { + checkAccess(state, dstStart, srcSize); + } else { + checkAccessM64(state, dstStart, srcSize); + } if (srcStart >= source->sizeInByte() || srcStart + srcSize > source->sizeInByte()) { throwRangeException(state, srcStart, srcStart + srcSize, srcSize); @@ -218,22 +222,41 @@ void Memory::init(ExecutionState& state, DataSegment* source, uint32_t dstStart, this->initMemory(source, dstStart, srcStart, srcSize); } -void Memory::copy(ExecutionState& state, uint32_t dstStart, uint32_t srcStart, uint32_t size, Memory* dstMem) +void Memory::copy(ExecutionState& state, uint64_t dstStart, uint64_t srcStart, uint64_t size, Memory* dstMem) { - checkAccess(state, srcStart, size); - checkAccess(state, dstStart, size, 0, dstMem); + if (!is64()) { + checkAccess(state, srcStart, size); + } else { + checkAccessM64(state, srcStart, size); + } + + if (dstMem == nullptr) { + if (!is64()) { + checkAccess(state, dstStart, size); + } else { + checkAccessM64(state, dstStart, size); + } + } else if (!dstMem->is64()) { + dstMem->checkAccess(state, dstStart, size); + } else { + dstMem->checkAccessM64(state, dstStart, size); + } this->copyMemory(dstMem, dstStart, srcStart, size); } -void Memory::fill(ExecutionState& state, uint32_t start, uint8_t value, uint32_t size) +void Memory::fill(ExecutionState& state, uint64_t start, uint8_t value, uint64_t size) { - checkAccess(state, start, size); + if (!is64()) { + checkAccess(state, start, size); + } else { + checkAccessM64(state, start, size); + } this->fillMemory(start, value, size); } -void Memory::initMemory(DataSegment* source, uint32_t dstStart, uint32_t srcStart, uint32_t srcSize) +void Memory::initMemory(DataSegment* source, size_t dstStart, uint32_t srcStart, uint32_t srcSize) { auto data = source->data(); std::copy(data + srcStart, data + srcStart + srcSize, @@ -244,7 +267,7 @@ void Memory::initMemory(DataSegment* source, uint32_t dstStart, uint32_t srcStar #endif } -void Memory::copyMemory(Memory* dstMemory, uint32_t dstStart, uint32_t srcStart, uint32_t size) +void Memory::copyMemory(Memory* dstMemory, size_t dstStart, size_t srcStart, size_t size) { #if defined(WALRUS_BIG_ENDIAN) auto srcBegin = m_buffer + m_sizeInByte + srcStart - size; @@ -262,7 +285,7 @@ void Memory::copyMemory(Memory* dstMemory, uint32_t dstStart, uint32_t srcStart, } } -void Memory::fillMemory(uint32_t start, uint8_t value, uint32_t size) +void Memory::fillMemory(size_t start, uint8_t value, size_t size) { #if defined(WALRUS_BIG_ENDIAN) std::fill(m_buffer + m_sizeInByte - start - size, m_buffer + m_sizeInByte - start, value); diff --git a/src/runtime/Memory.h b/src/runtime/Memory.h index dd9ed4a69..ec90daee6 100644 --- a/src/runtime/Memory.h +++ b/src/runtime/Memory.h @@ -33,6 +33,7 @@ class Memory : public Extern { public: static const uint32_t s_memoryPageSize = 1024 * 64; + static const uint64_t s_maxMemory64Grow = ~static_cast(0) / s_memoryPageSize; // Caching memory target for fast access. struct TargetBuffer { @@ -393,50 +394,48 @@ class Memory : public Extern { #endif - void init(ExecutionState& state, DataSegment* source, uint32_t dstStart, uint32_t srcStart, uint32_t srcSize); - void copy(ExecutionState& state, uint32_t dstStart, uint32_t srcStart, uint32_t size, Memory* dstMem = nullptr); - void fill(ExecutionState& state, uint32_t start, uint8_t value, uint32_t size); + void init(ExecutionState& state, DataSegment* source, uint64_t dstStart, uint32_t srcStart, uint32_t srcSize); + void copy(ExecutionState& state, uint64_t dstStart, uint64_t srcStart, uint64_t size, Memory* dstMem = nullptr); + void fill(ExecutionState& state, uint64_t start, uint8_t value, uint64_t size); - inline bool checkAccess(uint32_t offset, uint32_t size, uint32_t addend = 0, Memory* dstMem = nullptr) const + inline bool checkAccess(uint32_t offset, uint32_t size, uint32_t addend = 0) const { ASSERT(!is64()); - if (dstMem == nullptr) { - return !UNLIKELY(!((uint64_t)offset + (uint64_t)addend + (uint64_t)size <= m_sizeInByte)); - } else { - return !UNLIKELY(!((uint64_t)offset + (uint64_t)addend + (uint64_t)size <= dstMem->m_sizeInByte)); - } + return !UNLIKELY(!((uint64_t)offset + (uint64_t)addend + (uint64_t)size <= m_sizeInByte)); } - inline bool checkAccessM64(uint64_t offset, uint64_t size, uint64_t addend = 0, Memory* dstMem = nullptr) const + inline bool checkAccessM64(uint64_t offset, uint64_t size) const { ASSERT(is64()); - if (dstMem == nullptr) { - return !UNLIKELY(!(offset + addend + size <= m_sizeInByte)); - } else { - return !UNLIKELY(!(offset + addend + size <= dstMem->m_sizeInByte)); - } + return !UNLIKELY(offset > m_sizeInByte || size > m_sizeInByte - offset); + } + + inline bool checkAccessM64(uint64_t offset, uint64_t size, uint64_t addend) const + { + ASSERT(is64()); + return !UNLIKELY(offset > m_sizeInByte || addend > m_sizeInByte - offset || size > m_sizeInByte - offset - addend); } - void initMemory(DataSegment* source, uint32_t dstStart, uint32_t srcStart, uint32_t srcSize); - void copyMemory(uint32_t dstStart, uint32_t srcStart, uint32_t size); - void copyMemory(Memory* dstMemory, uint32_t dstStart, uint32_t srcStart, uint32_t size); - void fillMemory(uint32_t start, uint8_t value, uint32_t size); + void initMemory(DataSegment* source, size_t dstStart, uint32_t srcStart, uint32_t srcSize); + void copyMemory(size_t dstStart, size_t srcStart, size_t size); + void copyMemory(Memory* dstMemory, size_t dstStart, size_t srcStart, size_t size); + void fillMemory(size_t start, uint8_t value, size_t size); private: Memory(uint64_t initialSizeInByte, uint64_t maximumSizeInByte, bool isShared, bool is64); void throwRangeException(ExecutionState& state, uint32_t offset, uint32_t addend, uint32_t size) const; - inline void checkAccess(ExecutionState& state, uint32_t offset, uint32_t size, uint32_t addend = 0, Memory* dstMem = nullptr) const + inline void checkAccess(ExecutionState& state, uint32_t offset, uint32_t size, uint32_t addend = 0) const { - if (!this->checkAccess(offset, size, addend, dstMem)) { + if (!this->checkAccess(offset, size, addend)) { throwRangeException(state, offset, addend, size); } } - inline void checkAccessM64(ExecutionState& state, uint64_t offset, uint64_t size, uint64_t addend = 0, Memory* dstMem = nullptr) const + inline void checkAccessM64(ExecutionState& state, uint64_t offset, uint64_t size, uint64_t addend = 0) const { - if (!this->checkAccessM64(offset, size, addend, dstMem)) { + if (!this->checkAccessM64(offset, size, addend)) { throwRangeException(state, offset, addend, size); } } diff --git a/test/web-assembly3/jit/memory64_management.wast b/test/web-assembly3/jit/memory64_management.wast new file mode 100644 index 000000000..55bc2b05f --- /dev/null +++ b/test/web-assembly3/jit/memory64_management.wast @@ -0,0 +1,52 @@ +(module + (memory i64 1) + (memory 1) + (data "\01\02\03\04\05\06\07\08") + + (func (export "memory.size") (result i64) memory.size) + (func (export "memory.init") (param i64 i32 i32) (memory.init 0 (local.get 0) (local.get 1) (local.get 2))) + (func (export "memory.initS") (param i32 i64 i32) (memory.init 0 (local.get 1) (local.get 2) (local.get 0))) + (func (export "memory.fill") (param i64 i32 i64) (memory.fill (local.get 0) (local.get 1) (local.get 2))) + (func (export "memory.fillS") (param i64 i64 i32) (memory.fill (local.get 1) (local.get 2) (local.get 0))) + (func (export "memory.copy") (param i64 i64 i64) (memory.copy (local.get 0) (local.get 1) (local.get 2))) + (func (export "memory.copyS") (param i64 i64 i64) (memory.copy (local.get 1) (local.get 2) (local.get 0))) + (func (export "memory.cross_copy1") (param i64 i32 i32) (memory.copy 0 1 (local.get 0) (local.get 1) (local.get 2))) + (func (export "memory.cross_copy2") (param i32 i64 i32) (memory.copy 1 0 (local.get 0) (local.get 1) (local.get 2))) + (func (export "memory.cross_copy2S") (param i32 i32 i64) (memory.copy 1 0 (local.get 1) (local.get 2) (local.get 0))) + (func (export "memory.grow") (param i64) (result i64) (memory.grow (local.get 0))) +) + +(assert_return (invoke "memory.size") (i64.const 1)) + +(assert_return (invoke "memory.init" (i64.const 0xffff) (i32.const 0) (i32.const 1))) +(assert_return (invoke "memory.init" (i64.const 0xffff) (i32.const 0) (i32.const 0))) +(assert_trap (invoke "memory.init" (i64.const 0x100000000) (i32.const 0) (i32.const 5)) "out of bounds memory access") +(assert_trap (invoke "memory.init" (i64.const 0x100000000) (i32.const 0) (i32.const 0)) "out of bounds memory access") +(assert_trap (invoke "memory.initS" (i32.const 5) (i64.const 0x100000000) (i32.const 0)) "out of bounds memory access") + +(assert_return (invoke "memory.fill" (i64.const 0xffff) (i32.const 0) (i64.const 1))) +(assert_return (invoke "memory.fill" (i64.const 0xffff) (i32.const 0) (i64.const 0))) +(assert_trap (invoke "memory.fill" (i64.const 0xffff) (i32.const 0) (i64.const 2)) "out of bounds memory access") +(assert_trap (invoke "memory.fill" (i64.const 0x10000) (i32.const 0) (i64.const 1)) "out of bounds memory access") +(assert_trap (invoke "memory.fill" (i64.const 0x100000000) (i32.const 0) (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "memory.fill" (i64.const 0x0) (i32.const 0) (i64.const 0x100000000)) "out of bounds memory access") +(assert_trap (invoke "memory.fillS" (i64.const 0x100000000) (i64.const 0x0) (i32.const 0) ) "out of bounds memory access") +(assert_trap (invoke "memory.fillS" (i64.const 0x0) (i64.const 0x100000000) (i32.const 0) ) "out of bounds memory access") + +(assert_return (invoke "memory.copy" (i64.const 0xffff) (i64.const 0xfffe) (i64.const 1))) +(assert_return (invoke "memory.copy" (i64.const 0xffff) (i64.const 0xfffe) (i64.const 0))) +(assert_trap (invoke "memory.copy" (i64.const 0x10000) (i64.const 0xffff) (i64.const 1)) "out of bounds memory access") +(assert_trap (invoke "memory.copy" (i64.const 0x100000000) (i64.const 0x0) (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "memory.copy" (i64.const 0) (i64.const 0x100000000) (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "memory.copyS" (i64.const 1) (i64.const 0x100000000) (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "memory.copyS" (i64.const 0x100000000) (i64.const 0) (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "memory.copyS" (i64.const 1) (i64.const 0) (i64.const 0x100000000)) "out of bounds memory access") + +(assert_return (invoke "memory.cross_copy1" (i64.const 0xffff) (i32.const 0xfffe) (i32.const 1))) +(assert_trap (invoke "memory.cross_copy1" (i64.const 0x100000000) (i32.const 0xfffe) (i32.const 1)) "out of bounds memory access") + +(assert_return (invoke "memory.cross_copy2" (i32.const 0xffff) (i64.const 0xfffe) (i32.const 1))) +(assert_trap (invoke "memory.cross_copy2" (i32.const 0xffff) (i64.const 0x100000000) (i32.const 1)) "out of bounds memory access") +(assert_trap (invoke "memory.cross_copy2S" (i32.const 1) (i32.const 0xffff) (i64.const 0x100000000)) "out of bounds memory access") + +(assert_return (invoke "memory.grow" (i64.const 1)) (i64.const 1)) diff --git a/third_party/wabt/include/wabt/walrus/binary-reader-walrus.h b/third_party/wabt/include/wabt/walrus/binary-reader-walrus.h index 684b5e17a..5042bf5e3 100644 --- a/third_party/wabt/include/wabt/walrus/binary-reader-walrus.h +++ b/third_party/wabt/include/wabt/walrus/binary-reader-walrus.h @@ -147,12 +147,12 @@ class WASMBinaryReaderDelegate { virtual void OnTryExpr(Type sigType) = 0; virtual void OnCatchExpr(Index tagIndex) = 0; virtual void OnCatchAllExpr() = 0; - virtual void OnMemoryGrowExpr(Index memidx) = 0; - virtual void OnMemoryInitExpr(Index segmentIndex, Index memidx) = 0; + virtual void OnMemoryGrowExpr(Index memIdx) = 0; + virtual void OnMemoryInitExpr(Index segmentIndex, Index memIdx) = 0; virtual void OnMemoryCopyExpr(Index srcMemIndex, Index dstMemIndex) = 0; - virtual void OnMemoryFillExpr(Index memidx) = 0; + virtual void OnMemoryFillExpr(Index memIdx) = 0; virtual void OnDataDropExpr(Index segmentIndex) = 0; - virtual void OnMemorySizeExpr(Index memidx) = 0; + virtual void OnMemorySizeExpr(Index memIdx) = 0; virtual void OnTableGetExpr(Index table_index) = 0; virtual void OnTableSetExpr(Index table_index) = 0; virtual void OnTableGrowExpr(Index table_index) = 0; diff --git a/third_party/wabt/src/walrus/binary-reader-walrus.cc b/third_party/wabt/src/walrus/binary-reader-walrus.cc index f91a1d54a..df64e42d6 100644 --- a/third_party/wabt/src/walrus/binary-reader-walrus.cc +++ b/third_party/wabt/src/walrus/binary-reader-walrus.cc @@ -799,7 +799,7 @@ class BinaryReaderDelegateWalrus: public BinaryReaderDelegate { return Result::Ok; } Result OnMemoryCopyExpr(Index destmemidx, Index srcmemidx) override { - CHECK_RESULT(m_validator.OnMemoryCopy(GetLocation(), Var(srcmemidx, GetLocation()), Var(destmemidx, GetLocation()))); + CHECK_RESULT(m_validator.OnMemoryCopy(GetLocation(), Var(destmemidx, GetLocation()), Var(srcmemidx, GetLocation()))); SHOULD_GENERATE_BYTECODE; m_externalDelegate->OnMemoryCopyExpr(srcmemidx, destmemidx); return Result::Ok;