From c125ea630cff06b741bb54bf870d67dc2a1c1198 Mon Sep 17 00:00:00 2001 From: chenyiyuan Date: Thu, 1 Feb 2024 08:56:48 +0000 Subject: [PATCH] Fix imm data read exception in optimizer and disassembler issue: https://gitee.com/openharmony/arkcompiler_runtime_core/issues/I900SM Signed-off-by: chenyiyuan Change-Id: Id458ff0260eaaa28468674419635fc314705a720 --- BUILD.gn | 5 + .../templates/inst_builder_gen.cpp.erb | 6 +- disassembler/disassembler.h | 4 +- .../templates/bc_ins_to_pandasm_ins.cpp.erb | 38 ++- disassembler/tests/BUILD.gn | 9 + disassembler/tests/disassembler_imm_tests.cpp | 107 ++++++ isa/isa.yaml | 306 +++++++++--------- isa/isapi.rb | 12 + libpandafile/bytecode_instruction.h | 2 +- .../bytecode_instruction-inl_gen.h.erb | 30 +- libpandafile/tests/BUILD.gn | 1 + .../tests/bytecode_imm_fetch_tests.cpp | 184 +++++++++++ 12 files changed, 522 insertions(+), 182 deletions(-) create mode 100644 disassembler/tests/disassembler_imm_tests.cpp create mode 100644 libpandafile/tests/bytecode_imm_fetch_tests.cpp diff --git a/BUILD.gn b/BUILD.gn index ad98f64400..0ce720284c 100755 --- a/BUILD.gn +++ b/BUILD.gn @@ -360,6 +360,11 @@ if (!ark_standalone_build) { ] } + group("verifier_host_unittest") { + testonly = true + deps = [ "$ark_root/verifier/tests:host_unittest" ] + } + group("compiler_host_unittest") { testonly = true deps = [ "$ark_root/compiler/tests:host_unittest" ] diff --git a/compiler/optimizer/templates/inst_builder_gen.cpp.erb b/compiler/optimizer/templates/inst_builder_gen.cpp.erb index 7c25cbb590..489e4efb30 100644 --- a/compiler/optimizer/templates/inst_builder_gen.cpp.erb +++ b/compiler/optimizer/templates/inst_builder_gen.cpp.erb @@ -190,7 +190,7 @@ int64_t InstBuilder::GetInstructionJumpOffset(const BytecodeInstruction* inst) { // NOLINTNEXTLINE(bugprone-branch-clone) case BytecodeInstruction::Opcode::<%= inst.opcode.upcase %>: % if inst.jump? - return inst->GetImm, 0>(); + return inst->GetImm, 0, true>(); % else return INVALID_OFFSET; % end @@ -291,7 +291,7 @@ void InstBuilder::BuildEcmaAsIntrinsics(const BytecodeInstruction* bc_inst) // N % end % has_ic_slot = inst.properties.include?('ic_slot') || inst.properties.include?('jit_ic_slot') % if is_range_call - size_t args_count = <%= num_inputs %>U + static_cast(bc_inst->GetImm<<%= format %>, <%= has_ic_slot ? 1 : 0 %>>()); + size_t args_count = <%= num_inputs %>U + static_cast(bc_inst->GetImm<<%= format %>, <%= has_ic_slot ? 1 : 0 %>, false>()); % else size_t args_count {<%= num_inputs %>U}; % end @@ -314,7 +314,7 @@ void InstBuilder::BuildEcmaAsIntrinsics(const BytecodeInstruction* bc_inst) // N AddInstruction(inst_save_state); % params_arr.each do |param| % if param.imm? - auto imm<%= imm_index %> = static_cast(bc_inst->GetImm<<%= format %>, <%= imm_index %>>()); + auto imm<%= imm_index %> = static_cast(bc_inst->GetImm<<%= format %>, <%= imm_index %>, false>()); inst->AddImm(GetGraph()->GetAllocator(), imm<%= imm_index %>); % imm_index = imm_index + 1 % elsif param.reg? diff --git a/disassembler/disassembler.h b/disassembler/disassembler.h index 70fd56c3ad..91ffca24c4 100755 --- a/disassembler/disassembler.h +++ b/disassembler/disassembler.h @@ -73,6 +73,8 @@ public: template void FillLiteralArrayData(pandasm::LiteralArray *lit_array, const panda_file::LiteralTag &tag, const panda_file::LiteralDataAccessor::LiteralValue &value) const; + pandasm::Ins BytecodeInstructionToPandasmInstruction(BytecodeInstruction bc_ins, + panda_file::File::EntityId method_id) const; const ProgInfo &GetProgInfo() const { @@ -172,8 +174,6 @@ private: pandasm::Opcode BytecodeOpcodeToPandasmOpcode(BytecodeInstruction::Opcode o) const; pandasm::Opcode BytecodeOpcodeToPandasmOpcode(uint8_t o) const; - pandasm::Ins BytecodeInstructionToPandasmInstruction(BytecodeInstruction bc_ins, - panda_file::File::EntityId method_id) const; std::string IDToString(BytecodeInstruction bc_ins, panda_file::File::EntityId method_id, size_t idx) const; panda::panda_file::SourceLang GetRecordLanguage(panda_file::File::EntityId class_id) const; diff --git a/disassembler/templates/bc_ins_to_pandasm_ins.cpp.erb b/disassembler/templates/bc_ins_to_pandasm_ins.cpp.erb index 2f037b36e2..801be141b3 100644 --- a/disassembler/templates/bc_ins_to_pandasm_ins.cpp.erb +++ b/disassembler/templates/bc_ins_to_pandasm_ins.cpp.erb @@ -25,35 +25,39 @@ pandasm::Ins Disassembler::BytecodeInstructionToPandasmInstruction(BytecodeInstr const BytecodeInstruction::Format format = bc_ins.GetFormat(); - switch (format) { -% insns_uniq_sort_fmts.each do |i| # Panda::formats.each do |fmt| + switch (bc_ins.GetOpcode()) { +% Panda::instructions.each do |inst| % imm_count = 0 % reg_count = 0 % id_count = 0 - case BytecodeInstruction::Format::<%=i.format.pretty.upcase%>: + case BytecodeInstruction::Opcode::<%= inst.opcode.upcase %>: % -% i.operands.each do |operand| -% if (operand.name == :imm) -% if (operand.type != "i64") - ins.imms.push_back(static_cast(bc_ins.GetImm, <%=imm_count%>>())); -% else - ins.imms.push_back(bc_ins.GetImm, <%=imm_count%>>()); +% inst.operands.each do |op| +% if op.imm? +% if op.is_float_imm? + ins.imms.push_back(bit_cast(bc_ins.GetImm, <%=imm_count%>, true>())); +% elsif op.is_signed_imm? + ins.imms.push_back(static_cast(bc_ins.GetImm, <%=imm_count%>, true>())); +% elsif op.is_unsigned_imm? + ins.imms.push_back(static_cast(bc_ins.GetImm, <%=imm_count%>, false>())); +% else +% raise "Incorrect imm type #{op.type}" % end % imm_count += 1 % -% elsif (operand.name == :v) - ins.regs.push_back(bc_ins.GetVReg(<%=reg_count%>)); +% elsif op.reg? + ins.regs.push_back(bc_ins.GetVReg(<%=reg_count%>)); % reg_count += 1 -% elsif (i.operands.count(&:id?) != 0) - ins.ids.push_back(IDToString(bc_ins, method_id, <%=id_count%>)); +% elsif op.id? + ins.ids.push_back(IDToString(bc_ins, method_id, <%=id_count%>)); % id_count += 1 % end % end - break; + break; % end - default: - break; - } + default: + break; + } if (ins.IsCall()) { // clearing excessive arguments if there are any diff --git a/disassembler/tests/BUILD.gn b/disassembler/tests/BUILD.gn index 222dd04f8a..b6b486fb96 100644 --- a/disassembler/tests/BUILD.gn +++ b/disassembler/tests/BUILD.gn @@ -167,10 +167,19 @@ host_unittest_action("DisasmScriptTest") { } } +host_unittest_action("DisasmImmTest") { + module_out_path = module_output_path + sources = [ "disassembler_imm_tests.cpp" ] + include_dirs = disasm_include_dirs + configs = disasm_test_configs + deps = disasm_test_deps +} + group("host_unittest") { testonly = true deps = [ ":DisasmDebugTestAction", + ":DisasmImmTestAction", ":DisasmModuleTestAction", ":DisasmScriptTestAction", ] diff --git a/disassembler/tests/disassembler_imm_tests.cpp b/disassembler/tests/disassembler_imm_tests.cpp new file mode 100644 index 0000000000..cede73a877 --- /dev/null +++ b/disassembler/tests/disassembler_imm_tests.cpp @@ -0,0 +1,107 @@ +/** + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include "disassembler.h" + +namespace panda::disasm { + +panda_file::File::EntityId method_id {0x00}; +panda::disasm::Disassembler disasm {}; + +TEST(BytecodeInstruction, Signed) +{ + { + // jeqz 23 + const uint8_t bytecode[] = {0x4f, 0x17}; + BytecodeInstruction inst(bytecode); + const panda::pandasm::Ins &ins = disasm.BytecodeInstructionToPandasmInstruction(inst, method_id); + EXPECT_EQ(static_cast(inst.GetOpcode()), 0x4f); + EXPECT_EQ(std::get(ins.imms[0]), static_cast(0x17)); + } + + { + // jmp -22 + const uint8_t bytecode[] = {0x4d, 0xea}; + BytecodeInstruction inst(bytecode); + const panda::pandasm::Ins &ins = disasm.BytecodeInstructionToPandasmInstruction(inst, method_id); + EXPECT_EQ(static_cast(inst.GetOpcode()), 0x4d); + EXPECT_EQ(std::get(ins.imms[0]), static_cast(-22)); + } + + { + // ldai 30 + const uint8_t bytecode[] = {0x62, 0x1e, 0x00, 0x00, 0x00}; + BytecodeInstruction inst(bytecode); + const panda::pandasm::Ins &ins = disasm.BytecodeInstructionToPandasmInstruction(inst, method_id); + EXPECT_EQ(static_cast(inst.GetOpcode()), 0x62); + EXPECT_EQ(std::get(ins.imms[0]), static_cast(0x1e)); + } + + { + // fldai 3.14 + const uint8_t bytecode[] = {0x63, 0x1f, 0x85, 0xeb, 0x51, 0xb8, 0x1e, 0x09, 0x40}; + BytecodeInstruction inst(bytecode); + const panda::pandasm::Ins &ins = disasm.BytecodeInstructionToPandasmInstruction(inst, method_id); + EXPECT_EQ(static_cast(inst.GetOpcode()), 0x63); + EXPECT_EQ(std::get(ins.imms[0]), 3.14); + } +} + +TEST(BytecodeInstruction, Unsigned) +{ + { + // callthis2 142, v0, v2, v3 + const uint8_t bytecode[] = {0x2f, 0x8e, 0x00, 0x02, 0x03}; + BytecodeInstruction inst(bytecode); + const panda::pandasm::Ins &ins = disasm.BytecodeInstructionToPandasmInstruction(inst, method_id); + EXPECT_EQ(static_cast(inst.GetOpcode()), 0x2f); + EXPECT_EQ(std::get(ins.imms[0]), static_cast(0x8e)); + } + + { + // neg 13 + const uint8_t bytecode[] = {0x1f, 0x0d}; + BytecodeInstruction inst(bytecode); + const panda::pandasm::Ins &ins = disasm.BytecodeInstructionToPandasmInstruction(inst, method_id); + EXPECT_EQ(static_cast(inst.GetOpcode()), 0x1f); + EXPECT_EQ(std::get(ins.imms[0]), static_cast(0x0d)); + } + + { + // stlexvar 0, 2 + const uint8_t bytecode[] = {0x3d, 0x20}; + BytecodeInstruction inst(bytecode); + const panda::pandasm::Ins &ins = disasm.BytecodeInstructionToPandasmInstruction(inst, method_id); + EXPECT_EQ(static_cast(inst.GetOpcode()), 0x3d); + EXPECT_EQ(std::get(ins.imms[0]), 0); + EXPECT_EQ(std::get(ins.imms[1]), 2); + } + + { + // newobjrange 17, 1, v11 + const uint8_t bytecode[] = {0x08, 0x11, 0x01, 0x0b}; + BytecodeInstruction inst(bytecode); + const panda::pandasm::Ins &ins = disasm.BytecodeInstructionToPandasmInstruction(inst, method_id); + EXPECT_EQ(static_cast(inst.GetOpcode()), 0x08); + EXPECT_EQ(std::get(ins.imms[0]), static_cast(0x11)); + EXPECT_EQ(std::get(ins.imms[1]), static_cast(0x01)); + } +} + +} // namespace panda::disasm diff --git a/isa/isa.yaml b/isa/isa.yaml index b7be8b6c25..ae0c35caea 100644 --- a/isa/isa.yaml +++ b/isa/isa.yaml @@ -391,12 +391,12 @@ groups: acc: inout:top opcode_idx: [0x66] format: [op_none] - - sig: getiterator imm + - sig: getiterator imm:u16 acc: inout:top opcode_idx: [0x67, 0xab] format: [op_imm_8, op_imm_16] properties: [ic_slot, two_slot, eight_sixteen_bit_ic] - - sig: closeiterator imm, v:in:top + - sig: closeiterator imm:u16, v:in:top acc: out:top opcode_idx: [0x68, 0xac] format: [op_imm_8_v_8, op_imm_16_v_8] @@ -406,27 +406,27 @@ groups: opcode_idx: [0x02] format: [pref_op_v1_8_v2_8] prefix: deprecated - - sig: getasynciterator imm + - sig: getasynciterator imm:u8 acc: inout:top opcode_idx: [0xd7] format: [op_imm_8] properties: [ic_slot, eight_bit_ic] - - sig: ldprivateproperty imm1, imm2, imm3 + - sig: ldprivateproperty imm1:u8, imm2:u16, imm3:u16 acc: inout:top opcode_idx: [0xd8] format: [op_imm1_8_imm2_16_imm3_16] properties: [ic_slot, two_slot, eight_bit_ic] - - sig: stprivateproperty imm1, imm2, imm3, v:in:top + - sig: stprivateproperty imm1:u8, imm2:u16, imm3:u16, v:in:top acc: in:top opcode_idx: [0xd9] format: [op_imm1_8_imm2_16_imm3_16_v_8] properties: [ic_slot, two_slot, eight_bit_ic] - - sig: testin imm1, imm2, imm3 + - sig: testin imm1:u8, imm2:u16, imm3:u16 acc: inout:top opcode_idx: [0xda] format: [op_imm1_8_imm2_16_imm3_16] properties: [ic_slot, two_slot, eight_bit_ic] - - sig: definefieldbyname imm, string_id, v:in:top + - sig: definefieldbyname imm:u8, string_id, v:in:top acc: in:top opcode_idx: [0xdb] format: [op_imm_8_id_16_v_8] @@ -451,7 +451,7 @@ groups: acc: out:top opcode_idx: [0x04] format: [op_none] - - sig: createemptyarray imm + - sig: createemptyarray imm:u16 acc: out:top opcode_idx: [0x05, 0x80] format: [op_imm_8, op_imm_16] @@ -464,70 +464,70 @@ groups: acc: out:top opcode_idx: [0xb2] format: [op_v1_8_v2_8] - - sig: createobjectwithexcludedkeys imm, v1:in:top, v2:in:top + - sig: createobjectwithexcludedkeys imm:u8, v1:in:top, v2:in:top acc: out:top opcode_idx: [0xb3] format: [op_imm_8_v1_8_v2_8] - - sig: wide.createobjectwithexcludedkeys imm, v1:in:top, v2:in:top + - sig: wide.createobjectwithexcludedkeys imm:u16, v1:in:top, v2:in:top acc: out:top opcode_idx: [0x00] format: [pref_op_imm_16_v1_8_v2_8] prefix: wide - - sig: createarraywithbuffer imm, literalarray_id + - sig: createarraywithbuffer imm:u16, literalarray_id acc: out:top opcode_idx: [0x06, 0x81] format: [op_imm_8_id_16, op_imm_16_id_16] properties: [ic_slot, one_slot, eight_sixteen_bit_ic, literalarray_id] - - sig: deprecated.createarraywithbuffer imm + - sig: deprecated.createarraywithbuffer imm:u16 acc: out:top opcode_idx: [0x03] format: [pref_op_imm_16] prefix: deprecated - - sig: createobjectwithbuffer imm, literalarray_id + - sig: createobjectwithbuffer imm:u16, literalarray_id opcode_idx: [0x07, 0x82] acc: out:top format: [op_imm_8_id_16, op_imm_16_id_16] properties: [ic_slot, one_slot, eight_sixteen_bit_ic, literalarray_id] - - sig: deprecated.createobjectwithbuffer imm + - sig: deprecated.createobjectwithbuffer imm:u16 acc: out:top opcode_idx: [0x04] format: [pref_op_imm_16] prefix: deprecated - - sig: createregexpwithliteral imm1, string_id, imm2 + - sig: createregexpwithliteral imm1:u16, string_id, imm2:u8 acc: out:top opcode_idx: [0x71, 0x72] format: [op_imm1_8_id_16_imm2_8, op_imm1_16_id_16_imm2_8] properties: [string_id, ic_slot, two_slot, eight_sixteen_bit_ic] - - sig: newobjapply imm, v:in:top + - sig: newobjapply imm:u16, v:in:top acc: inout:top opcode_idx: [0xb4, 0xb5] format: [op_imm_8_v_8, op_imm_16_v_8] properties: [ic_slot, two_slot, eight_sixteen_bit_ic] - - sig: newobjrange imm1, imm2, v:in:top + - sig: newobjrange imm1:u16, imm2:u8, v:in:top acc: out:top opcode_idx: [0x08, 0x83] format: [op_imm1_8_imm2_8_v_8, op_imm1_16_imm2_8_v_8] properties: [ic_slot, two_slot, eight_sixteen_bit_ic] - - sig: wide.newobjrange imm, v:in:top + - sig: wide.newobjrange imm:u16, v:in:top acc: out:top opcode_idx: [0x01] format: [pref_op_imm_16_v_8] prefix: wide - - sig: newlexenv imm + - sig: newlexenv imm:u8 acc: out:top opcode_idx: [0x09] format: [op_imm_8] - - sig: wide.newlexenv imm + - sig: wide.newlexenv imm:u16 acc: out:top opcode_idx: [0x02] format: [pref_op_imm_16] prefix: wide - - sig: newlexenvwithname imm, literalarray_id + - sig: newlexenvwithname imm:u8, literalarray_id acc: out:top opcode_idx: [0xb6] format: [op_imm_8_id_16] properties: [literalarray_id] - - sig: wide.newlexenvwithname imm, literalarray_id + - sig: wide.newlexenvwithname imm:u16, literalarray_id acc: out:top opcode_idx: [0x03] format: [pref_op_imm_16_id_16] @@ -557,92 +557,92 @@ groups: semantics: | skip instructions: - - sig: add2 imm, v:in:top + - sig: add2 imm:u8, v:in:top acc: inout:top opcode_idx: [0x0a] format: [op_imm_8_v_8] properties: [jit_ic_slot, one_slot, eight_bit_ic] - - sig: sub2 imm, v:in:top + - sig: sub2 imm:u8, v:in:top acc: inout:top opcode_idx: [0x0b] format: [op_imm_8_v_8] properties: [jit_ic_slot, one_slot, eight_bit_ic] - - sig: mul2 imm, v:in:top + - sig: mul2 imm:u8, v:in:top acc: inout:top opcode_idx: [0x0c] format: [op_imm_8_v_8] properties: [jit_ic_slot, one_slot, eight_bit_ic] - - sig: div2 imm, v:in:top + - sig: div2 imm:u8, v:in:top acc: inout:top opcode_idx: [0x0d] format: [op_imm_8_v_8] properties: [jit_ic_slot, one_slot, eight_bit_ic] - - sig: mod2 imm, v:in:top + - sig: mod2 imm:u8, v:in:top acc: inout:top opcode_idx: [0x0e] format: [op_imm_8_v_8] properties: [jit_ic_slot, one_slot, eight_bit_ic] - - sig: eq imm, v:in:top + - sig: eq imm:u8, v:in:top acc: inout:top opcode_idx: [0x0f] format: [op_imm_8_v_8] properties: [jit_ic_slot, one_slot, eight_bit_ic] - - sig: noteq imm, v:in:top + - sig: noteq imm:u8, v:in:top acc: inout:top opcode_idx: [0x10] format: [op_imm_8_v_8] properties: [jit_ic_slot, one_slot, eight_bit_ic] - - sig: less imm, v:in:top + - sig: less imm:u8, v:in:top acc: inout:top opcode_idx: [0x11] format: [op_imm_8_v_8] properties: [jit_ic_slot, one_slot, eight_bit_ic] - - sig: lesseq imm, v:in:top + - sig: lesseq imm:u8, v:in:top acc: inout:top opcode_idx: [0x12] format: [op_imm_8_v_8] properties: [jit_ic_slot, one_slot, eight_bit_ic] - - sig: greater imm, v:in:top + - sig: greater imm:u8, v:in:top acc: inout:top opcode_idx: [0x13] format: [op_imm_8_v_8] properties: [jit_ic_slot, one_slot, eight_bit_ic] - - sig: greatereq imm, v:in:top + - sig: greatereq imm:u8, v:in:top acc: inout:top opcode_idx: [0x14] format: [op_imm_8_v_8] properties: [jit_ic_slot, one_slot, eight_bit_ic] - - sig: shl2 imm, v:in:top + - sig: shl2 imm:u8, v:in:top acc: inout:top opcode_idx: [0x15] format: [op_imm_8_v_8] properties: [jit_ic_slot, one_slot, eight_bit_ic] - - sig: shr2 imm, v:in:top + - sig: shr2 imm:u8, v:in:top acc: inout:top opcode_idx: [0x16] format: [op_imm_8_v_8] properties: [jit_ic_slot, one_slot, eight_bit_ic] - - sig: ashr2 imm, v:in:top + - sig: ashr2 imm:u8, v:in:top acc: inout:top opcode_idx: [0x17] format: [op_imm_8_v_8] properties: [jit_ic_slot, one_slot, eight_bit_ic] - - sig: and2 imm, v:in:top + - sig: and2 imm:u8, v:in:top acc: inout:top opcode_idx: [0x18] format: [op_imm_8_v_8] properties: [jit_ic_slot, one_slot, eight_bit_ic] - - sig: or2 imm, v:in:top + - sig: or2 imm:u8, v:in:top acc: inout:top opcode_idx: [0x19] format: [op_imm_8_v_8] properties: [jit_ic_slot, one_slot, eight_bit_ic] - - sig: xor2 imm, v:in:top + - sig: xor2 imm:u8, v:in:top acc: inout:top opcode_idx: [0x1a] format: [op_imm_8_v_8] properties: [jit_ic_slot, one_slot, eight_bit_ic] - - sig: exp imm, v:in:top + - sig: exp imm:u8, v:in:top acc: inout:top opcode_idx: [0x1b] format: [op_imm_8_v_8] @@ -663,12 +663,12 @@ groups: semantics: | skip instructions: - - sig: typeof imm + - sig: typeof imm:u16 acc: inout:top opcode_idx: [0x1c, 0x84] format: [op_imm_8, op_imm_16] properties: [ic_slot, two_slot, sixteen_bit_ic] - - sig: tonumber imm + - sig: tonumber imm:u8 acc: inout:top opcode_idx: [0x1d] format: [op_imm_8] @@ -678,7 +678,7 @@ groups: opcode_idx: [0x05] format: [pref_op_v_8] prefix: deprecated - - sig: tonumeric imm + - sig: tonumeric imm:u8 acc: inout:top opcode_idx: [0x1e] format: [op_imm_8] @@ -688,7 +688,7 @@ groups: acc: inout:top prefix: deprecated format: [pref_op_v_8] - - sig: neg imm + - sig: neg imm:u8 acc: inout:top opcode_idx: [0x1f] format: [op_imm_8] @@ -698,7 +698,7 @@ groups: opcode_idx: [0x07] format: [pref_op_v_8] prefix: deprecated - - sig: not imm + - sig: not imm:u8 acc: inout:top opcode_idx: [0x20] format: [op_imm_8] @@ -708,7 +708,7 @@ groups: opcode_idx: [0x08] prefix: deprecated format: [pref_op_v_8] - - sig: inc imm + - sig: inc imm:u8 acc: inout:top opcode_idx: [0x21] format: [op_imm_8] @@ -718,7 +718,7 @@ groups: opcode_idx: [0x09] prefix: deprecated format: [pref_op_v_8] - - sig: dec imm + - sig: dec imm:u8 acc: inout:top opcode_idx: [0x22] format: [op_imm_8] @@ -752,22 +752,22 @@ groups: semantics: | skip instructions: - - sig: isin imm, v:in:top + - sig: isin imm:u8, v:in:top acc: inout:top opcode_idx: [0x25] format: [op_imm_8_v_8] properties: [jit_ic_slot, one_slot, eight_bit_ic] - - sig: instanceof imm, v:in:top + - sig: instanceof imm:u8, v:in:top acc: inout:top opcode_idx: [0x26] format: [op_imm_8_v_8] properties: [jit_ic_slot, two_slot, eight_bit_ic] - - sig: strictnoteq imm, v:in:top + - sig: strictnoteq imm:u8, v:in:top acc: inout:top opcode_idx: [0x27] format: [op_imm_8_v_8] properties: [jit_ic_slot, one_slot, eight_bit_ic] - - sig: stricteq imm, v:in:top + - sig: stricteq imm:u8, v:in:top acc: inout:top opcode_idx: [0x28] format: [op_imm_8_v_8] @@ -793,13 +793,13 @@ groups: opcode_idx: [0x00] format: [pref_op_none] prefix: callruntime - - sig: callruntime.definefieldbyvalue imm, v1:in:top, v2:in:top + - sig: callruntime.definefieldbyvalue imm:u8, v1:in:top, v2:in:top acc: in:top opcode_idx: [0x01] prefix: callruntime format: [pref_op_imm_8_v1_8_v2_8] properties: [ic_slot, two_slot, eight_bit_ic] - - sig: callruntime.definefieldbyindex imm1, imm2, v:in:top + - sig: callruntime.definefieldbyindex imm1:u8, imm2:u32, v:in:top acc: in:top opcode_idx: [0x02] prefix: callruntime @@ -810,41 +810,41 @@ groups: opcode_idx: [0x03] format: [pref_op_none] prefix: callruntime - - sig: callruntime.createprivateproperty imm, literalarray_id + - sig: callruntime.createprivateproperty imm:u16, literalarray_id acc: none opcode_idx: [0x04] format: [pref_op_imm_16_id_16] prefix: callruntime properties: [literalarray_id] - - sig: callruntime.defineprivateproperty imm1, imm2, imm3, v:in:top + - sig: callruntime.defineprivateproperty imm1:u8, imm2:u16, imm3:u16, v:in:top acc: in:top opcode_idx: [0x05] format: [pref_op_imm1_8_imm2_16_imm3_16_v_8] prefix: callruntime properties: [ic_slot, two_slot, eight_bit_ic] - - sig: callruntime.callinit imm, v:in:top + - sig: callruntime.callinit imm:u8, v:in:top acc: in:top opcode_idx: [0x06] format: [pref_op_imm_8_v_8] prefix: callruntime properties: [jit_ic_slot, two_slot, eight_bit_ic] - - sig: callruntime.definesendableclass imm1, method_id, literalarray_id, imm2, v:in:top + - sig: callruntime.definesendableclass imm1:u16, method_id, literalarray_id, imm2:u16, v:in:top acc: out:top opcode_idx: [0x07] format: [pref_op_imm1_16_id1_16_id2_16_imm2_16_v_8] prefix: callruntime properties: [method_id, ic_slot, one_slot, sixteen_bit_ic, literalarray_id] - - sig: callruntime.ldsendableclass imm + - sig: callruntime.ldsendableclass imm:u16 acc: out:top opcode_idx: [0x08] format: [pref_op_imm_16] prefix: callruntime - - sig: callruntime.ldsendableexternalmodulevar imm + - sig: callruntime.ldsendableexternalmodulevar imm:u8 acc: out:top opcode_idx: [0x09] format: [pref_op_imm_8] prefix: callruntime - - sig: callruntime.wideldsendableexternalmodulevar imm + - sig: callruntime.wideldsendableexternalmodulevar imm:u16 acc: out:top opcode_idx: [0x0a] format: [pref_op_imm_16] @@ -902,7 +902,7 @@ groups: opcode_idx: [0x06] format: [pref_op_v1_8_v2_8] prefix: throw - - sig: throw.ifsupernotcorrectcall imm + - sig: throw.ifsupernotcorrectcall imm:u16 acc: in:top opcode_idx: [0x07, 0x08] format: [pref_op_imm_8, pref_op_imm_16] @@ -929,7 +929,7 @@ groups: semantics: | skip instructions: - - sig: callarg0 imm + - sig: callarg0 imm:u8 acc: inout:top opcode_idx: [0x29] format: [op_imm_8] @@ -939,7 +939,7 @@ groups: opcode_idx: [0x0b] format: [pref_op_v_8] prefix: deprecated - - sig: callarg1 imm, v:in:top + - sig: callarg1 imm:u8, v:in:top acc: inout:top opcode_idx: [0x2a] format: [op_imm_8_v_8] @@ -949,7 +949,7 @@ groups: opcode_idx: [0x0c] format: [pref_op_v1_8_v2_8] prefix: deprecated - - sig: callargs2 imm, v1:in:top, v2:in:top + - sig: callargs2 imm:u8, v1:in:top, v2:in:top acc: inout:top opcode_idx: [0x2b] format: [op_imm_8_v1_8_v2_8] @@ -959,7 +959,7 @@ groups: opcode_idx: [0x0d] format: [pref_op_v1_8_v2_8_v3_8] prefix: deprecated - - sig: callargs3 imm, v1:in:top, v2:in:top, v3:in:top + - sig: callargs3 imm:u8, v1:in:top, v2:in:top, v3:in:top acc: inout:top opcode_idx: [0x2c] format: [op_imm_8_v1_8_v2_8_v3_8] @@ -969,27 +969,27 @@ groups: opcode_idx: [0x0e] format: [pref_op_v1_8_v2_8_v3_8_v4_8] prefix: deprecated - - sig: callrange imm1, imm2, v:in:top + - sig: callrange imm1:u8, imm2:u8, v:in:top acc: inout:top opcode_idx: [0x73] format: [op_imm1_8_imm2_8_v_8] properties: [jit_ic_slot, two_slot, eight_bit_ic] - - sig: wide.callrange imm, v:in:top + - sig: wide.callrange imm:u16, v:in:top acc: inout:top opcode_idx: [0x04] format: [pref_op_imm_16_v_8] prefix: wide - - sig: deprecated.callrange imm, v:in:top + - sig: deprecated.callrange imm:u16, v:in:top acc: out:top opcode_idx: [0x0f] format: [pref_op_imm_16_v_8] prefix: deprecated - - sig: supercallspread imm, v:in:top + - sig: supercallspread imm:u8, v:in:top acc: inout:top opcode_idx: [0xb9] format: [op_imm_8_v_8] properties: [jit_ic_slot, two_slot, eight_bit_ic] - - sig: apply imm, v1:in:top, v2:in:top + - sig: apply imm:u8, v1:in:top, v2:in:top acc: inout:top opcode_idx: [0xba] format: [op_imm_8_v1_8_v2_8] @@ -999,57 +999,57 @@ groups: opcode_idx: [0x10] format: [pref_op_v1_8_v2_8_v3_8] prefix: deprecated - - sig: callthis0 imm, v:in:top + - sig: callthis0 imm:u8, v:in:top acc: inout:top opcode_idx: [0x2d] format: [op_imm_8_v_8] properties: [jit_ic_slot, two_slot, eight_bit_ic] - - sig: callthis1 imm, v1:in:top, v2:in:top + - sig: callthis1 imm:u8, v1:in:top, v2:in:top acc: inout:top opcode_idx: [0x2e] format: [op_imm_8_v1_8_v2_8] properties: [jit_ic_slot, two_slot, eight_bit_ic] - - sig: callthis2 imm, v1:in:top, v2:in:top, v3:in:top + - sig: callthis2 imm:u8, v1:in:top, v2:in:top, v3:in:top acc: inout:top opcode_idx: [0x2f] format: [op_imm_8_v1_8_v2_8_v3_8] properties: [jit_ic_slot, two_slot, eight_bit_ic] - - sig: callthis3 imm, v1:in:top, v2:in:top, v3:in:top, v4:in:top + - sig: callthis3 imm:u8, v1:in:top, v2:in:top, v3:in:top, v4:in:top acc: inout:top opcode_idx: [0x30] format: [op_imm_8_v1_8_v2_8_v3_8_v4_8] properties: [jit_ic_slot, two_slot, eight_bit_ic] - - sig: callthisrange imm1, imm2, v:in:top + - sig: callthisrange imm1:u8, imm2:u8, v:in:top acc: inout:top opcode_idx: [0x31] format: [op_imm1_8_imm2_8_v_8] properties: [jit_ic_slot, two_slot, eight_bit_ic] - - sig: wide.callthisrange imm, v:in:top + - sig: wide.callthisrange imm:u16, v:in:top acc: inout:top opcode_idx: [0x05] format: [pref_op_imm_16_v_8] prefix: wide - - sig: deprecated.callthisrange imm, v:in:top + - sig: deprecated.callthisrange imm:u16, v:in:top acc: out:top opcode_idx: [0x11] format: [pref_op_imm_16_v_8] prefix: deprecated - - sig: supercallthisrange imm1, imm2, v:in:top + - sig: supercallthisrange imm1:u8, imm2:u8, v:in:top acc: out:top opcode_idx: [0x32] format: [op_imm1_8_imm2_8_v_8] properties: [jit_ic_slot, two_slot, eight_bit_ic] - - sig: wide.supercallthisrange imm, v:in:top + - sig: wide.supercallthisrange imm:u16, v:in:top acc: out:top opcode_idx: [0x06] format: [pref_op_imm_16_v_8] prefix: wide - - sig: supercallarrowrange imm1, imm2, v:in:top + - sig: supercallarrowrange imm1:u8, imm2:u8, v:in:top acc: inout:top opcode_idx: [0xbb] format: [op_imm1_8_imm2_8_v_8] properties: [jit_ic_slot, two_slot, eight_bit_ic] - - sig: wide.supercallarrowrange imm, v:in:top + - sig: wide.supercallarrowrange imm:u16, v:in:top acc: inout:top opcode_idx: [0x07] format: [pref_op_imm_16_v_8] @@ -1074,22 +1074,22 @@ groups: acc: inout:top opcode_idx: [0xbc] format: [op_v1_8_v2_8_v3_8_v4_8] - - sig: definefunc imm1, method_id, imm2 + - sig: definefunc imm1:u16, method_id, imm2:u8 acc: out:top opcode_idx: [0x33, 0x74] format: [op_imm1_8_id_16_imm2_8, op_imm1_16_id_16_imm2_8] properties: [method_id, ic_slot, one_slot, eight_sixteen_bit_ic] - - sig: definemethod imm1, method_id, imm2 + - sig: definemethod imm1:u16, method_id, imm2:u8 acc: inout:top opcode_idx: [0x34, 0xbe] format: [op_imm1_8_id_16_imm2_8, op_imm1_16_id_16_imm2_8] properties: [method_id, ic_slot, one_slot, eight_sixteen_bit_ic] - - sig: defineclasswithbuffer imm1, method_id, literalarray_id, imm2, v:in:top + - sig: defineclasswithbuffer imm1:u16, method_id, literalarray_id, imm2:u16, v:in:top acc: out:top opcode_idx: [0x35, 0x75] format: [op_imm1_8_id1_16_id2_16_imm2_16_v_8, op_imm1_16_id1_16_id2_16_imm2_16_v_8] properties: [method_id, ic_slot, one_slot, eight_sixteen_bit_ic, literalarray_id] - - sig: deprecated.defineclasswithbuffer method_id, imm1, imm2, v1:in:top, v2:in:top + - sig: deprecated.defineclasswithbuffer method_id, imm1:u16, imm2:u16, v1:in:top, v2:in:top acc: out:top opcode_idx: [0x12] format: [pref_op_id_16_imm1_16_imm2_16_v1_8_v2_8] @@ -1129,7 +1129,7 @@ groups: opcode_idx: [0x14] format: [pref_op_v_8] prefix: deprecated - - sig: gettemplateobject imm + - sig: gettemplateobject imm:u16 acc: inout:top opcode_idx: [0x76, 0xc1] format: [op_imm_8, op_imm_16] @@ -1183,7 +1183,7 @@ groups: acc: inout:top opcode_idx: [0xc6] format: [op_v1_8_v2_8] - - sig: setobjectwithproto imm, v:in:top + - sig: setobjectwithproto imm:u16, v:in:top acc: in:top opcode_idx: [0x77, 0xc7] format: [op_imm_8_v_8, op_imm_16_v_8] @@ -1193,7 +1193,7 @@ groups: opcode_idx: [0x1a] format: [pref_op_v1_8_v2_8] prefix: deprecated - - sig: ldobjbyvalue imm, v:in:top + - sig: ldobjbyvalue imm:u16, v:in:top acc: inout:top opcode_idx: [0x37, 0x85] format: [op_imm_8_v_8, op_imm_16_v_8] @@ -1203,17 +1203,17 @@ groups: opcode_idx: [0x1b] format: [pref_op_v1_8_v2_8] prefix: deprecated - - sig: stobjbyvalue imm, v1:in:top, v2:in:top + - sig: stobjbyvalue imm:u16, v1:in:top, v2:in:top acc: in:top opcode_idx: [0x38, 0x86] format: [op_imm_8_v1_8_v2_8, op_imm_16_v1_8_v2_8] properties: [ic_slot, two_slot, eight_sixteen_bit_ic] - - sig: stownbyvalue imm, v1:in:top, v2:in:top + - sig: stownbyvalue imm:u16, v1:in:top, v2:in:top acc: in:top opcode_idx: [0x78, 0xc8] format: [op_imm_8_v1_8_v2_8, op_imm_16_v1_8_v2_8] properties: [ic_slot, two_slot, eight_sixteen_bit_ic] - - sig: ldsuperbyvalue imm, v:in:top + - sig: ldsuperbyvalue imm:u16, v:in:top acc: inout:top opcode_idx: [0x39, 0x87] format: [op_imm_8_v_8, op_imm_16_v_8] @@ -1223,42 +1223,42 @@ groups: opcode_idx: [0x1c] format: [pref_op_v1_8_v2_8] prefix: deprecated - - sig: stsuperbyvalue imm, v1:in:top, v2:in:top + - sig: stsuperbyvalue imm:u16, v1:in:top, v2:in:top acc: in:top opcode_idx: [0xc9, 0xca] format: [op_imm_8_v1_8_v2_8, op_imm_16_v1_8_v2_8] properties: [ic_slot, two_slot, eight_sixteen_bit_ic] - - sig: ldobjbyindex imm1, imm2 + - sig: ldobjbyindex imm1:u16, imm2:u16 acc: inout:top opcode_idx: [0x3a, 0x88] format: [op_imm1_8_imm2_16, op_imm1_16_imm2_16] properties: [ic_slot, two_slot, eight_sixteen_bit_ic] - - sig: wide.ldobjbyindex imm + - sig: wide.ldobjbyindex imm:u32 acc: inout:top opcode_idx: [0x08] format: [pref_op_imm_32] prefix: wide - - sig: deprecated.ldobjbyindex v:in:top, imm + - sig: deprecated.ldobjbyindex v:in:top, imm:u32 acc: out:top opcode_idx: [0x1d] format: [pref_op_v_8_imm_32] prefix: deprecated - - sig: stobjbyindex imm1, v:in:top, imm2 + - sig: stobjbyindex imm1:u16, v:in:top, imm2:u16 acc: in:top opcode_idx: [0x3b, 0x89] format: [op_imm1_8_v_8_imm2_16, op_imm1_16_v_8_imm2_16] properties: [ic_slot, two_slot, eight_sixteen_bit_ic] - - sig: wide.stobjbyindex v:in:top, imm + - sig: wide.stobjbyindex v:in:top, imm:u32 acc: in:top opcode_idx: [0x09] format: [pref_op_v_8_imm_32] prefix: wide - - sig: stownbyindex imm1, v:in:top, imm2 + - sig: stownbyindex imm1:u16, v:in:top, imm2:u16 acc: in:top opcode_idx: [0x79, 0xcb] format: [op_imm1_8_v_8_imm2_16, op_imm1_16_v_8_imm2_16] properties: [ic_slot, two_slot, eight_sixteen_bit_ic] - - sig: wide.stownbyindex v:in:top, imm + - sig: wide.stownbyindex v:in:top, imm:u32 acc: in:top opcode_idx: [0x0a] format: [pref_op_v_8_imm_32] @@ -1281,43 +1281,43 @@ groups: opcode_idx: [0x1f] format: [pref_op_v1_8_v2_8_v3_8] prefix: deprecated - - sig: copyrestargs imm + - sig: copyrestargs imm:u8 acc: out:top opcode_idx: [0xcf] format: [op_imm_8] - - sig: wide.copyrestargs imm + - sig: wide.copyrestargs imm:u16 acc: out:top opcode_idx: [0x0b] format: [pref_op_imm_16] prefix: wide - - sig: ldlexvar imm1, imm2 + - sig: ldlexvar imm1:u8, imm2:u8 acc: out:top opcode_idx: [0x3c, 0x8a] format: [op_imm1_4_imm2_4, op_imm1_8_imm2_8] - - sig: wide.ldlexvar imm1, imm2 + - sig: wide.ldlexvar imm1:u16, imm2:u16 acc: out:top opcode_idx: [0x0c] format: [pref_op_imm1_16_imm2_16] prefix: wide - - sig: stlexvar imm1, imm2 + - sig: stlexvar imm1:u8, imm2:u8 acc: in:top opcode_idx: [0x3d, 0x8b] format: [op_imm1_4_imm2_4, op_imm1_8_imm2_8] - - sig: wide.stlexvar imm1, imm2 + - sig: wide.stlexvar imm1:u16, imm2:u16 acc: in:top opcode_idx: [0x0d] format: [pref_op_imm1_16_imm2_16] prefix: wide - - sig: deprecated.stlexvar imm1, imm2, v:in:top + - sig: deprecated.stlexvar imm1:u16, imm2:u16, v:in:top acc: none opcode_idx: [0x20, 0x21, 0x22] format: [pref_op_imm1_4_imm2_4_v_8, pref_op_imm1_8_imm2_8_v_8, pref_op_imm1_16_imm2_16_v_8] prefix: deprecated - - sig: getmodulenamespace imm + - sig: getmodulenamespace imm:u8 acc: out:top opcode_idx: [0x7b] format: [op_imm_8] - - sig: wide.getmodulenamespace imm + - sig: wide.getmodulenamespace imm:u16 acc: out:top opcode_idx: [0x0e] format: [pref_op_imm_16] @@ -1328,11 +1328,11 @@ groups: format: [pref_op_id_32] properties: [string_id] prefix: deprecated - - sig: stmodulevar imm + - sig: stmodulevar imm:u8 acc: in:top opcode_idx: [0x7c] format: [op_imm_8] - - sig: wide.stmodulevar imm + - sig: wide.stmodulevar imm:u16 acc: in:top opcode_idx: [0x0f] format: [pref_op_imm_16] @@ -1343,27 +1343,27 @@ groups: format: [pref_op_id_32] properties: [string_id] prefix: deprecated - - sig: tryldglobalbyname imm, string_id + - sig: tryldglobalbyname imm:u16, string_id acc: out:top opcode_idx: [0x3f, 0x8c] format: [op_imm_8_id_16, op_imm_16_id_16] properties: [string_id, ic_slot, one_slot, eight_sixteen_bit_ic] - - sig: trystglobalbyname imm, string_id + - sig: trystglobalbyname imm:u16, string_id acc: in:top opcode_idx: [0x40, 0x8d] format: [op_imm_8_id_16, op_imm_16_id_16] properties: [string_id, ic_slot, one_slot, eight_sixteen_bit_ic] - - sig: ldglobalvar imm, string_id + - sig: ldglobalvar imm:u16, string_id acc: out:top opcode_idx: [0x41] format: [op_imm_16_id_16] properties: [string_id, ic_slot, one_slot, sixteen_bit_ic] - - sig: stglobalvar imm, string_id + - sig: stglobalvar imm:u16, string_id acc: in:top opcode_idx: [0x7f] format: [op_imm_16_id_16] properties: [string_id, ic_slot, one_slot, sixteen_bit_ic] - - sig: ldobjbyname imm, string_id + - sig: ldobjbyname imm:u16, string_id acc: inout:top opcode_idx: [0x42, 0x90] format: [op_imm_8_id_16, op_imm_16_id_16] @@ -1374,17 +1374,17 @@ groups: format: [pref_op_id_32_v_8] properties: [string_id] prefix: deprecated - - sig: stobjbyname imm, string_id, v:in:top + - sig: stobjbyname imm:u16, string_id, v:in:top acc: in:top opcode_idx: [0x43, 0x91] format: [op_imm_8_id_16_v_8, op_imm_16_id_16_v_8] properties: [string_id, ic_slot, two_slot, eight_sixteen_bit_ic] - - sig: stownbyname imm, string_id, v:in:top + - sig: stownbyname imm:u16, string_id, v:in:top acc: in:top opcode_idx: [0x7a, 0xcc] format: [op_imm_8_id_16_v_8, op_imm_16_id_16_v_8] properties: [string_id, ic_slot, two_slot, eight_sixteen_bit_ic] - - sig: ldsuperbyname imm, string_id + - sig: ldsuperbyname imm:u16, string_id acc: inout:top opcode_idx: [0x46, 0x92] format: [op_imm_8_id_16, op_imm_16_id_16] @@ -1395,36 +1395,36 @@ groups: format: [pref_op_id_32_v_8] properties: [string_id] prefix: deprecated - - sig: stsuperbyname imm, string_id, v:in:top + - sig: stsuperbyname imm:u16, string_id, v:in:top acc: in:top opcode_idx: [0xd0, 0xd1] format: [op_imm_8_id_16_v_8, op_imm_16_id_16_v_8] properties: [string_id, ic_slot, two_slot, eight_sixteen_bit_ic] - - sig: ldlocalmodulevar imm + - sig: ldlocalmodulevar imm:u8 opcode_idx: [0x7d] acc: out:top format: [op_imm_8] - - sig: wide.ldlocalmodulevar imm + - sig: wide.ldlocalmodulevar imm:u16 acc: out:top opcode_idx: [0x10] format: [pref_op_imm_16] prefix: wide - - sig: ldexternalmodulevar imm + - sig: ldexternalmodulevar imm:u8 acc: out:top opcode_idx: [0x7e] format: [op_imm_8] - - sig: wide.ldexternalmodulevar imm + - sig: wide.ldexternalmodulevar imm:u16 acc: out:top opcode_idx: [0x11] format: [pref_op_imm_16] prefix: wide - - sig: deprecated.ldmodulevar string_id, imm + - sig: deprecated.ldmodulevar string_id, imm:u8 acc: out:top opcode_idx: [0x27] format: [pref_op_id_32_imm_8] prefix: deprecated properties: [string_id] - - sig: stconsttoglobalrecord imm, string_id + - sig: stconsttoglobalrecord imm:u16, string_id acc: in:top opcode_idx: [0x47] format: [op_imm_16_id_16] @@ -1435,7 +1435,7 @@ groups: format: [pref_op_id_32] properties: [string_id] prefix: deprecated - - sig: sttoglobalrecord imm, string_id + - sig: sttoglobalrecord imm:u16, string_id acc: in:top opcode_idx: [0x48] format: [op_imm_16_id_16] @@ -1457,17 +1457,17 @@ groups: opcode_idx: [0x2b] format: [pref_op_none] prefix: deprecated - - sig: deprecated.createobjecthavingmethod imm + - sig: deprecated.createobjecthavingmethod imm:u16 acc: inout:top opcode_idx: [0x2c] format: [pref_op_imm_16] prefix: deprecated - - sig: stownbyvaluewithnameset imm, v1:in:top, v2:in:top + - sig: stownbyvaluewithnameset imm:u16, v1:in:top, v2:in:top acc: in:top opcode_idx: [0x99, 0xd2] format: [op_imm_8_v1_8_v2_8, op_imm_16_v1_8_v2_8] properties: [ic_slot, two_slot, eight_sixteen_bit_ic] - - sig: stownbynamewithnameset imm, string_id, v:in:top + - sig: stownbynamewithnameset imm:u16, string_id, v:in:top acc: in:top opcode_idx: [0x8e, 0xd4] format: [op_imm_8_id_16_v_8, op_imm_16_id_16_v_8] @@ -1477,32 +1477,32 @@ groups: opcode_idx: [0xd3] format: [op_id_16] properties: [string_id] - - sig: ldthisbyname imm, string_id + - sig: ldthisbyname imm:u16, string_id acc: out:top opcode_idx: [0x49, 0x93] format: [op_imm_8_id_16, op_imm_16_id_16] properties: [string_id, ic_slot, two_slot, eight_sixteen_bit_ic] - - sig: stthisbyname imm, string_id + - sig: stthisbyname imm:u16, string_id acc: in:top opcode_idx: [0x4a, 0x94] format: [op_imm_8_id_16, op_imm_16_id_16] properties: [string_id, ic_slot, two_slot, eight_sixteen_bit_ic] - - sig: ldthisbyvalue imm + - sig: ldthisbyvalue imm:u16 acc: inout:top opcode_idx: [0x4b, 0x95] format: [op_imm_8, op_imm_16] properties: [ic_slot, two_slot, eight_sixteen_bit_ic] - - sig: stthisbyvalue imm, v:in:top + - sig: stthisbyvalue imm:u16, v:in:top acc: in:top opcode_idx: [0x4c, 0x96] format: [op_imm_8_v_8, op_imm_16_v_8] properties: [ic_slot, two_slot, eight_sixteen_bit_ic] - - sig: wide.ldpatchvar imm + - sig: wide.ldpatchvar imm:u16 acc: out:top opcode_idx: [0x12] format: [pref_op_imm_16] prefix: wide - - sig: wide.stpatchvar imm + - sig: wide.stpatchvar imm:u16 acc: in:top opcode_idx: [0x13] format: [pref_op_imm_16] @@ -1525,7 +1525,7 @@ groups: opcode_idx: [0x2e] format: [pref_op_v1_8_v2_8] prefix: deprecated - - sig: setgeneratorstate imm + - sig: setgeneratorstate imm:u8 acc: in:top opcode_idx: [0xd6] format: [op_imm_8] @@ -1563,86 +1563,86 @@ groups: pseudo: | pc += imm instructions: - - sig: jmp imm + - sig: jmp imm:i32 acc: none opcode_idx: [0x4d, 0x4e, 0x98] format: [op_imm_8, op_imm_16, op_imm_32] - - sig: jeqz imm + - sig: jeqz imm:i32 acc: in:top opcode_idx: [0x4f, 0x50, 0x9a] format: [op_imm_8, op_imm_16, op_imm_32] properties: [conditional] - - sig: jnez imm + - sig: jnez imm:i32 acc: in:top opcode_idx: [0x51, 0x9b, 0x9c] format: [op_imm_8, op_imm_16, op_imm_32] properties: [conditional] - - sig: jstricteqz imm + - sig: jstricteqz imm:i16 acc: in:top opcode_idx: [0x52, 0x9d] format: [op_imm_8, op_imm_16] properties: [conditional] - - sig: jnstricteqz imm + - sig: jnstricteqz imm:i16 acc: in:top opcode_idx: [0x53, 0x9e] format: [op_imm_8, op_imm_16] properties: [conditional] - - sig: jeqnull imm + - sig: jeqnull imm:i16 acc: in:top opcode_idx: [0x54, 0x9f] format: [op_imm_8, op_imm_16] properties: [conditional] - - sig: jnenull imm + - sig: jnenull imm:i16 acc: in:top opcode_idx: [0x55, 0xa0] format: [op_imm_8, op_imm_16] properties: [conditional] - - sig: jstricteqnull imm + - sig: jstricteqnull imm:i16 acc: in:top opcode_idx: [0x56, 0xa1] format: [op_imm_8, op_imm_16] properties: [conditional] - - sig: jnstricteqnull imm + - sig: jnstricteqnull imm:i16 acc: in:top opcode_idx: [0x57, 0xa2] format: [op_imm_8, op_imm_16] properties: [conditional] - - sig: jequndefined imm + - sig: jequndefined imm:i16 acc: in:top opcode_idx: [0x58, 0xa3] format: [op_imm_8, op_imm_16] properties: [conditional] - - sig: jneundefined imm + - sig: jneundefined imm:i16 acc: in:top opcode_idx: [0x59, 0xa4] format: [op_imm_8, op_imm_16] properties: [conditional] - - sig: jstrictequndefined imm + - sig: jstrictequndefined imm:i16 acc: in:top opcode_idx: [0x5a, 0xa5] format: [op_imm_8, op_imm_16] properties: [conditional] - - sig: jnstrictequndefined imm + - sig: jnstrictequndefined imm:i16 acc: in:top opcode_idx: [0x5b, 0xa6] format: [op_imm_8, op_imm_16] properties: [conditional] - - sig: jeq v:in:top, imm + - sig: jeq v:in:top, imm:i16 acc: in:top opcode_idx: [0x5c, 0xa7] format: [op_v_8_imm_8, op_v_8_imm_16] properties: [conditional] - - sig: jne v:in:top, imm + - sig: jne v:in:top, imm:i16 acc: in:top opcode_idx: [0x5d, 0xa8] format: [op_v_8_imm_8, op_v_8_imm_16] properties: [conditional] - - sig: jstricteq v:in:top, imm + - sig: jstricteq v:in:top, imm:i16 acc: in:top opcode_idx: [0x5e, 0xa9] format: [op_v_8_imm_8, op_v_8_imm_16] properties: [conditional] - - sig: jnstricteq v:in:top, imm + - sig: jnstricteq v:in:top, imm:i16 acc: in:top opcode_idx: [0x5f, 0xaa] format: [op_v_8_imm_8, op_v_8_imm_16] diff --git a/isa/isapi.rb b/isa/isapi.rb index 0984eecccf..f0cc8d442b 100644 --- a/isa/isapi.rb +++ b/isa/isapi.rb @@ -360,6 +360,18 @@ class Operand @name == :imm end + def is_float_imm? + %i[f32 f64].include?(@type.to_sym) + end + + def is_signed_imm? + %i[i8 i16 i32 i64].include?(@type.to_sym) + end + + def is_unsigned_imm? + %i[u1 u2 u8 u16 u32 u64].include?(@type.to_sym) + end + def id? %i[method_id type_id field_id string_id literalarray_id].include?(@name) end diff --git a/libpandafile/bytecode_instruction.h b/libpandafile/bytecode_instruction.h index fe16f231f9..512daa7fed 100644 --- a/libpandafile/bytecode_instruction.h +++ b/libpandafile/bytecode_instruction.h @@ -245,7 +245,7 @@ public: template uint16_t GetVReg() const; - template + template auto GetImm() const; BytecodeId GetId(size_t idx = 0) const; diff --git a/libpandafile/templates/bytecode_instruction-inl_gen.h.erb b/libpandafile/templates/bytecode_instruction-inl_gen.h.erb index c9cd862ec7..86f4f99b6f 100644 --- a/libpandafile/templates/bytecode_instruction-inl_gen.h.erb +++ b/libpandafile/templates/bytecode_instruction-inl_gen.h.erb @@ -244,7 +244,7 @@ ALWAYS_INLINE inline uint16_t BytecodeInst::GetVReg(size_t idx /* = 0 */) } template -template ::Format format, size_t idx /* = 0 */> +template ::Format format, size_t idx /* = 0 */, bool is_signed /* = true */> inline auto BytecodeInst::GetImm() const { // NOLINTNEXTLINE(readability-function-size) static_assert(HasImm(format, idx), "Instruction doesn't have imm operand with such index"); @@ -262,7 +262,7 @@ inline auto BytecodeInst::GetImm() const { // NOLINTNEXTLINE(readability- if constexpr (format == Format::<%= fmt.pretty.upcase %>) { constexpr std::array> OFFSETS{<%= offsets.join(", ") %>}; constexpr std::array> WIDTHS{<%= widths.join(", ") %>}; - return Read(); + return Read(); } % end @@ -428,13 +428,31 @@ template inline bool BytecodeInst::CanThrow() template std::ostream& operator<<(std::ostream& os, const BytecodeInst& inst) { switch(inst.GetOpcode()) { % Panda::instructions.each do |inst| +% imm_count = 0 +% reg_count = 0 +% id_count = 0 case BytecodeInst::Opcode::<%= inst.opcode.upcase %>: os << "<%= inst.mnemonic %>"; % sep = " " -% inst.each_operand do |op, idx| -% op_str = "\"#{sep}v\" << inst.template GetVReg::Format::#{inst.format.pretty.upcase}, #{idx}>()" if op.reg? -% op_str = "\"#{sep}\" << inst.template GetImm::Format::#{inst.format.pretty.upcase}, #{idx}>()" if op.imm? -% op_str = "\"#{sep}id\" << inst.template GetId::Format::#{inst.format.pretty.upcase}, #{idx}>()" if op.id? +% inst.operands.each do |op| +% if op.imm? +% if op.is_float_imm? +% op_str = "\"#{sep}\" << bit_cast(inst.template GetImm::Format::#{inst.format.pretty.upcase}, #{imm_count}, true>())"; +% elsif op.is_unsigned_imm? +% op_str = "\"#{sep}\" << inst.template GetImm::Format::#{inst.format.pretty.upcase}, #{imm_count}, false>()"; +% elsif op.is_signed_imm? +% op_str = "\"#{sep}\" << inst.template GetImm::Format::#{inst.format.pretty.upcase}, #{imm_count}, true>()"; +% else +% raise "Incorrect imm type #{op.type}" +% end +% imm_count += 1 +% elsif op.reg? +% op_str = "\"#{sep}v\" << inst.template GetVReg::Format::#{inst.format.pretty.upcase}, #{reg_count}>()"; +% reg_count += 1 +% elsif op.id? +% op_str = "\"#{sep}id\" << inst.template GetId::Format::#{inst.format.pretty.upcase}, #{id_count}>()"; +% id_count += 1 +% end os << <%= op_str %>; % sep = ', ' % end diff --git a/libpandafile/tests/BUILD.gn b/libpandafile/tests/BUILD.gn index d21899d1b0..f3d4e6ce0d 100644 --- a/libpandafile/tests/BUILD.gn +++ b/libpandafile/tests/BUILD.gn @@ -19,6 +19,7 @@ host_unittest_action("LibPandaFileTest") { sources = [ "bytecode_emitter_tests.cpp", + "bytecode_imm_fetch_tests.cpp", "debug_info_extractor_test.cpp", "file_format_version_test.cpp", "file_item_container_test.cpp", diff --git a/libpandafile/tests/bytecode_imm_fetch_tests.cpp b/libpandafile/tests/bytecode_imm_fetch_tests.cpp new file mode 100644 index 0000000000..63bc55d987 --- /dev/null +++ b/libpandafile/tests/bytecode_imm_fetch_tests.cpp @@ -0,0 +1,184 @@ +/** + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +#include "bytecode_instruction-inl.h" + +namespace panda::test { + +TEST(BytecodeInstruction, Signed) +{ + { + // jeqz 23 + const uint8_t bytecode[] = {0x4f, 0x17}; + BytecodeInstruction inst(bytecode); + EXPECT_EQ(static_cast(inst.GetOpcode()), 0x4f); + EXPECT_EQ((inst.GetImm()), static_cast(0x17)); + EXPECT_EQ((inst.GetImm()), + static_cast(0x17)); + } + + { + // jmp -22 + const uint8_t bytecode[] = {0x4d, 0xea}; + BytecodeInstruction inst(bytecode); + EXPECT_EQ(static_cast(inst.GetOpcode()), 0x4d); + EXPECT_EQ((inst.GetImm()), static_cast(-22)); + EXPECT_EQ((inst.GetImm()), static_cast(-22)); + } + + { + // ldai 30 + const uint8_t bytecode[] = {0x62, 0x1e, 0x00, 0x00, 0x00}; + BytecodeInstruction inst(bytecode); + EXPECT_EQ(static_cast(inst.GetOpcode()), 0x62); + EXPECT_EQ(inst.GetFormat(), BytecodeInstruction::Format::IMM32); + EXPECT_EQ((inst.GetImm()), static_cast(0x1e)); + EXPECT_EQ((inst.GetImm()), static_cast(0x1e)); + } + + { + // fldai 3.14 + const uint8_t bytecode[] = {0x63, 0x1f, 0x85, 0xeb, 0x51, 0xb8, 0x1e, 0x09, 0x40}; + BytecodeInstruction inst(bytecode); + EXPECT_EQ(static_cast(inst.GetOpcode()), 0x63); + EXPECT_EQ((bit_cast(inst.GetImm())), 3.14); + } +} + +TEST(BytecodeInstruction, UnsignedOneImm) +{ + { + // callthis2 142, v0, v2, v3 + const uint8_t bytecode[] = {0x2f, 0x8e, 0x00, 0x02, 0x03}; + BytecodeInstruction inst(bytecode); + EXPECT_EQ(static_cast(inst.GetOpcode()), 0x2f); + EXPECT_EQ((inst.GetImm()), static_cast(0x8e)); + EXPECT_NE((inst.GetImm()), static_cast(0x8e)); + EXPECT_EQ((inst.GetImm()), + static_cast(0x8e)); + } + + { + // neg 13 + const uint8_t bytecode[] = {0x1f, 0x0d}; + BytecodeInstruction inst(bytecode); + EXPECT_EQ(static_cast(inst.GetOpcode()), 0x1f); + EXPECT_EQ((inst.GetImm()), static_cast(0x0d)); + EXPECT_EQ((inst.GetImm()), + static_cast(0x0d)); + } + + { + // tryldglobalbyname 128, id6 + const uint8_t bytecode[] = {0x8c, 0x80, 0x00, 0x06, 0x00}; + BytecodeInstruction inst(bytecode); + EXPECT_EQ(static_cast(inst.GetOpcode()), 0x8c); + EXPECT_EQ((inst.GetImm()), static_cast(0x80)); + EXPECT_EQ((inst.GetImm()), + static_cast(0x80)); + } +} + +TEST(BytecodeInstruction, UnsignedTwoImm) +{ + { + // stlexvar 0, 2 + const uint8_t bytecode[] = {0x3d, 0x20}; + BytecodeInstruction inst(bytecode); + EXPECT_EQ(static_cast(inst.GetOpcode()), 0x3d); + EXPECT_EQ(inst.GetFormat(), BytecodeInstruction::Format::IMM4_IMM4); + EXPECT_EQ((inst.GetImm()), 0); + EXPECT_EQ((inst.GetImm()), 2); + EXPECT_EQ((inst.GetImm()), 0); + EXPECT_EQ((inst.GetImm()), 2); + } + + { + // definefunc 2, id8, 1 + const uint8_t bytecode[] = {0x33, 0x02, 0x08, 0x00, 0x01}; + BytecodeInstruction inst(bytecode); + EXPECT_EQ(static_cast(inst.GetOpcode()), 0x33); + EXPECT_EQ(inst.GetFormat(), BytecodeInstruction::Format::IMM8_ID16_IMM8); + EXPECT_EQ((inst.GetImm()), static_cast(2)); + EXPECT_EQ((inst.GetImm()), static_cast(1)); + EXPECT_EQ((inst.GetImm()), static_cast(2)); + EXPECT_EQ((inst.GetImm()), static_cast(1)); + } + + { + // defineclasswithbuffer 2, id9, id12, 2, v3 + const uint8_t bytecode[] = {0x35, 0x02, 0x09, 0x00, 0x0c, 0x00, 0x02, 0x00, 0x03}; + BytecodeInstruction inst(bytecode); + EXPECT_EQ(static_cast(inst.GetOpcode()), 0x35); + EXPECT_EQ(inst.GetFormat(), BytecodeInstruction::Format::IMM8_ID16_ID16_IMM16_V8); + EXPECT_EQ((inst.GetImm()), static_cast(2)); + EXPECT_EQ((inst.GetImm()), static_cast(2)); + EXPECT_EQ((inst.GetImm()), + static_cast(2)); + EXPECT_EQ((inst.GetImm()), + static_cast(2)); + } +} + +TEST(BytecodeInstruction, OutputOperator) +{ + { + const uint8_t bytecode[] = {0x4f, 0x17}; + BytecodeInstruction inst(bytecode); + std::ostringstream oss; + oss << inst; + EXPECT_EQ(oss.str(), "jeqz 23"); + } + + { + const uint8_t bytecode[] = {0x4d, 0xea}; + BytecodeInstruction inst(bytecode); + std::ostringstream oss; + oss << inst; + EXPECT_EQ(oss.str(), "jmp -22"); + } + + { + const uint8_t bytecode[] = {0x62, 0x1e, 0x00, 0x00, 0x00}; + BytecodeInstruction inst(bytecode); + std::ostringstream oss; + oss << inst; + EXPECT_EQ(oss.str(), "ldai 30"); + } + + { + const uint8_t bytecode[] = {0x63, 0x1f, 0x85, 0xeb, 0x51, 0xb8, 0x1e, 0x09, 0x40}; + BytecodeInstruction inst(bytecode); + std::ostringstream oss; + oss << inst; + EXPECT_EQ(oss.str(), "fldai 3.14"); + } + + { + const uint8_t bytecode[] = {0x2d, 0x80, 0x00}; + BytecodeInstruction inst(bytecode); + std::ostringstream oss; + oss << inst; + EXPECT_EQ(oss.str(), "callthis0 128, v0"); + } +} + +} // namespace panda::test -- Gitee