!6 Remove builtins from ISA

Merge pull request !6 from bolshov.maxim/master
This commit is contained in:
openharmony_ci
2021-09-10 10:40:50 +00:00
committed by Gitee
35 changed files with 90 additions and 1602 deletions
-31
View File
@@ -25,7 +25,6 @@ config("arkassembler_public_config") {
}
libarkassembler_sources = [
"$target_gen_dir/builtin_parsing.cpp",
"$target_gen_dir/ins_to_string.cpp",
"annotation.cpp",
"assembly-emitter.cpp",
@@ -55,9 +54,7 @@ ohos_shared_library("libarkassembler") {
deps = [
":ark_asm_ecmascript_meta_gen_h",
":ark_asm_ins_create_builtins_api_h",
":ark_asm_meta_gen_h",
":builtin_parsing_cpp",
":isa_gen_libarkassembler_ins_create_api_h",
":isa_gen_libarkassembler_ins_emit_h",
":isa_gen_libarkassembler_ins_to_string_cpp",
@@ -82,9 +79,7 @@ ohos_static_library("libarkassembler_frontend_static") {
deps = [
":ark_asm_ecmascript_meta_gen_h",
":ark_asm_ins_create_builtins_api_h",
":ark_asm_meta_gen_h",
":builtin_parsing_cpp",
":isa_gen_libarkassembler_ins_create_api_h",
":isa_gen_libarkassembler_ins_emit_h",
":isa_gen_libarkassembler_ins_to_string_cpp",
@@ -140,11 +135,6 @@ ark_isa_gen("isa_gen_libarkassembler") {
"asm_isapi.rb",
"../libpandafile/pandafile_isapi.rb",
]
extra_dependencies = [
":ark_asm_ins_create_builtins_api_h",
":builtin_parsing_cpp",
":builtin_parsing_tests_cpp",
]
}
ark_gen_file("ark_asm_meta_gen_h") {
@@ -154,27 +144,6 @@ ark_gen_file("ark_asm_meta_gen_h") {
output_file = "$target_gen_dir/meta_gen.h"
}
ark_gen_file("ark_asm_ins_create_builtins_api_h") {
template_file = "templates/ins_create_builtins_api.h.erb"
data_file = "../isa/builtins.yaml"
requires = [ "../isa/builtinsapi.rb" ]
output_file = "$target_gen_dir/ins_create_builtins_api.h"
}
ark_gen_file("builtin_parsing_cpp") {
template_file = "templates/builtin_parsing.cpp.erb"
data_file = "../isa/builtins.yaml"
requires = [ "../isa/builtinsapi.rb" ]
output_file = "$target_gen_dir/builtin_parsing.cpp"
}
ark_gen_file("builtin_parsing_tests_cpp") {
template_file = "templates/builtin_parsing_tests.cpp.erb"
data_file = "../isa/builtins.yaml"
requires = [ "../isa/builtinsapi.rb" ]
output_file = "$target_gen_dir/builtin_parsing_tests.cpp"
}
ark_gen_file("ark_asm_ecmascript_meta_gen_h") {
template_file = "templates/meta_gen.cpp.erb"
data_file = "extensions/ecmascript/metadata.yaml"
-30
View File
@@ -16,33 +16,9 @@ project(assembler CXX)
panda_add_executable(ark_asm pandasm.cpp)
set(INS_CREATE_BUILTINS_API_H ${CMAKE_CURRENT_BINARY_DIR}/ins_create_builtins_api.h)
panda_gen_file(
DATAFILE ${PANDA_ROOT}/isa/builtins.yaml
TEMPLATE ${CMAKE_CURRENT_SOURCE_DIR}/templates/ins_create_builtins_api.h.erb
REQUIRES ${PANDA_ROOT}/isa/builtinsapi.rb
OUTPUTFILE ${INS_CREATE_BUILTINS_API_H}
)
set(BUILTIN_PARSING_CPP ${CMAKE_CURRENT_BINARY_DIR}/builtin_parsing.cpp)
panda_gen_file(
DATAFILE ${PANDA_ROOT}/isa/builtins.yaml
TEMPLATE ${CMAKE_CURRENT_SOURCE_DIR}/templates/builtin_parsing.cpp.erb
REQUIRES ${PANDA_ROOT}/isa/builtinsapi.rb
OUTPUTFILE ${BUILTIN_PARSING_CPP}
)
set(PANDASM_BIN_TESTS ${CMAKE_CURRENT_BINARY_DIR}/tests)
file(MAKE_DIRECTORY "${PANDASM_BIN_TESTS}")
set(BUILTIN_PARSING_TESTS_CPP ${PANDASM_BIN_TESTS}/builtin_parsing_tests.cpp)
panda_gen_file(
DATAFILE ${PANDA_ROOT}/isa/builtins.yaml
TEMPLATE ${CMAKE_CURRENT_SOURCE_DIR}/templates/builtin_parsing_tests.cpp.erb
REQUIRES ${PANDA_ROOT}/isa/builtinsapi.rb
OUTPUTFILE ${BUILTIN_PARSING_TESTS_CPP}
)
panda_isa_gen(
TEMPLATES
"isa.h.erb"
@@ -54,10 +30,6 @@ panda_isa_gen(
REQUIRES
"${CMAKE_CURRENT_SOURCE_DIR}/asm_isapi.rb"
"${PANDA_ROOT}/libpandafile/pandafile_isapi.rb"
EXTRA_DEPENDENCIES
${INS_CREATE_BUILTINS_API_H}
${BUILTIN_PARSING_CPP}
${BUILTIN_PARSING_TESTS_CPP}
)
add_library(arkassembler ${PANDA_DEFAULT_LIB_TYPE}
@@ -73,7 +45,6 @@ add_library(arkassembler ${PANDA_DEFAULT_LIB_TYPE}
ins_to_string.cpp
extensions/extensions.cpp
extensions/ecmascript/ecmascript_meta.cpp
builtin_parsing.cpp
)
add_dependencies(arkassembler isa_gen_assembler arkfile)
@@ -122,7 +93,6 @@ panda_add_gtest(
tests/parser_test.cpp
tests/emitter_test.cpp
tests/mangling_tests.cpp
${PANDASM_BIN_TESTS}/builtin_parsing_tests.cpp
LIBRARIES
arkbase arkassembler
SANITIZERS
-4
View File
@@ -17,10 +17,6 @@ Instruction.class_eval do
mnemonic.tr('.', '_').upcase
end
def builtin?
stripped_mnemonic == 'builtin'
end
def call?
properties.include?('call') || stripped_mnemonic == 'initobj'
end
@@ -1,63 +0,0 @@
/*
* Copyright (c) 2021 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 "assembly-parser.h"
// Autogenerated file -- DO NOT EDIT!
namespace panda::pandasm {
int64_t Parser::MnemonicToBuiltinId() {
[[maybe_unused]] const auto token = context_.GiveToken();
--context_;
[[maybe_unused]] const auto ins = context_.GiveToken();
++context_;
% PandaBuiltins::builtins.each_with_index do |builtin, i|
%
<%= i != 0 ? "else " : "" %>if (token == "<%= builtin.mnemonic%>" && ins == "<%= builtin.insn%>") {
return static_cast<int64_t>(<%= builtin.id%>);
}
%
% end
return -1;
}
bool Parser::ParseOperandBuiltinMnemonic() {
if (context_.err.err != Error::ErrorType::ERR_NONE) {
return false;
}
if (*context_ != Token::Type::ID) {
context_.err = GetError("Expected Mnemonic", Error::ErrorType::ERR_BAD_OPERAND);
return false;
}
auto builtin_id = MnemonicToBuiltinId();
if (builtin_id != -1) {
curr_ins_->imms.insert(curr_ins_->imms.begin(), builtin_id);
} else {
context_.err = GetError("The non-public extension of ISA does not contain such a builtin", Error::ErrorType::ERR_BAD_MNEMONIC_NAME);
return false;
}
++context_;
return true;
}
} // namespace panda::pandasm
@@ -1,146 +0,0 @@
/*
* Copyright (c) 2021 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 <iostream>
#include <string>
#include <gtest/gtest.h>
#include "assembly-parser.h"
#include "define.h"
#include "lexer.h"
#include "operand_types_print.h"
using namespace panda::pandasm;
% PandaBuiltins::builtins.each do |builtin|
%
TEST(builtinparsingtests, builtins_<%=builtin.insn.tr('.', '_')%>_id<%=builtin.id%>)
{
Parser p;
std::string src = std::string(R"(
.function void g() {
<%=builtin.insn%> <%=builtin.mnemonic%>)"
% PandaBuiltins::instructions.each do |insn|
%
% if (insn.mnemonic == builtin.insn)
%
% insn.sig.split(', ').each_with_index do |op, i|
% if (i != 0)
% if (op.start_with?('v'))
", v<%=i%>"
% elsif (op.start_with?('imm'))
", <%=i%>"
% elsif (op == 'type_id')
", A"
% elsif (op == 'method_id')
", g"
% elsif (op == 'string_id')
", \"string_string\""
% elsif (op == 'field_id')
", A.B"
% end
% end
% end
%
% end
% end
"\nreturn.void\n}\n");
auto res = p.Parse(src);
Error e = p.ShowError();
ASSERT_EQ(e.err, Error::ErrorType::ERR_NONE);
}
%
% end
% PandaBuiltins::instructions.each do |insn|
%
TEST(builtinparsingtests, builtins_<%=insn.mnemonic.tr('.', '_')%>_bad_mnemonic_name) {
{
Parser p;
std::string src = std::string(R"(
.function void g() {
<%=insn.mnemonic%> wrong_mnemonic)"
% insn.sig.split(', ').each_with_index do |op, i|
% if (i != 0)
% if (op.start_with?('v'))
", v<%=i%>"
% elsif (op == 'imm')
", <%=i%>"
% elsif (op == 'type_id')
", A"
% elsif (op == 'method_id')
", g"
% elsif (op == 'string_id')
", \"string_string\""
% elsif (op == 'field_id')
", A.B"
% end
% end
% end
"\nreturn.void\n}\n");
auto res = p.Parse(src);
Error e = p.ShowError();
ASSERT_EQ(e.err, Error::ErrorType::ERR_BAD_MNEMONIC_NAME);
}
}
%
% end
% PandaBuiltins::instructions.each do |insn|
%
TEST(builtinparsingtests, builtins_<%=insn.mnemonic.tr('.', '_')%>_bad_operand) {
{
Parser p;
std::string src = std::string(R"(
.record A {
u1 B
}
.function void g() {
<%=insn.mnemonic%> "")"
% insn.sig.split(', ').each_with_index do |op, i|
% if (i != 0)
% if (op.start_with?('v'))
", v<%=i%>"
% elsif (op == 'imm')
", <%=i%>"
% elsif (op == 'type_id')
", A"
% elsif (op == 'method_id')
", g"
% elsif (op == 'string_id')
", \"string_string\""
% elsif (op == 'field_id')
", A.B"
% end
% end
% end
"\nreturn.void\n}\n");
auto res = p.Parse(src);
Error e = p.ShowError();
ASSERT_EQ(e.err, Error::ErrorType::ERR_BAD_OPERAND);
}
}
%
% end
-2
View File
@@ -59,5 +59,3 @@ inline Ins Create_<%= insn.asm_token %>(<%= signature_str %>)
} // namespace panda::pandasm
#include <ins_create_builtins_api.h>
@@ -1,60 +0,0 @@
/*
* Copyright (c) 2021 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.
*/
// Autogenerated file -- DO NOT EDIT!
namespace panda::pandasm {
% PandaBuiltins::builtins.each do |builtin|
% i_mnemo = builtin.insn.tr('.', '_').upcase
% b_mnemo = builtin.mnemonic.tr('.', '_').upcase
% sig = []
% args = ['BUILTIN_ID']
%
% # NB! This logic below is very simplistic. May need proper
% # work with formats in builtinsapi.rb some day.
% format_list = builtin.format.split("_");
% format_list.each_index do |i|
% next if i == 0
% if format_list[i] == "v4" then
% sig << "uint16_t v" + i.to_s
% args << "v" + i.to_s
% elsif format_list[i] == "v8" then
% sig << "uint16_t v" + i.to_s
% args << "v" + i.to_s
% elsif format_list[i] == "id16"
% sig << "std::string& id" + i.to_s
% args << "id" + i.to_s
% elsif format_list[i] == "id32"
% sig << "std::string& id" + i.to_s
% args << "id" + i.to_s
% elsif format_list[i] == "imm8"
% sig << "uint8_t imm" + i.to_s
% args << "imm" + i.to_s
% elsif format_list[i] == "imm16"
% sig << "uint16_t imm" + i.to_s
% args << "imm" + i.to_s
% end
% end
inline Ins Create_BUILTIN_<%= b_mnemo %>(<%= sig.join(', ') %>)
{
constexpr uint8_t BUILTIN_ID = <%= builtin.id %>;
return panda::pandasm::Create_<%= i_mnemo %>(<%= args.join(', ') %>);
}
% end
} // namespace panda::pandasm
+1 -3
View File
@@ -83,9 +83,7 @@ bool Parser::ParseOperands()
ParseOperandVreg();
% elsif op.imm?
% if (insn.builtin? && j == 0)
ParseOperandBuiltinMnemonic();
% elsif properties.include?("jump")
% if properties.include?("jump")
ParseOperandLabel();
% else
% if properties.include?("float")
-10
View File
@@ -21,7 +21,6 @@ config("arkdisassembler_public_config") {
arkdisassembler_sources = [
"$target_gen_dir/bc_ins_to_pandasm_ins.cpp",
"$target_gen_dir/get_ins_info.cpp",
"$target_gen_dir/get_instructions.cpp",
"$target_gen_dir/opcode_translator.cpp",
"$target_gen_dir/type_to_pandasm_type.cpp",
"disassembler.cpp",
@@ -44,7 +43,6 @@ ohos_shared_library("arkdisassembler") {
configs = arkdisassembler_configs
deps = [
":get_instructions_cpp",
":isa_gen_ark_disam_bc_ins_to_pandasm_ins_cpp",
":isa_gen_ark_disam_get_ins_info_cpp",
":isa_gen_ark_disam_opcode_translator_cpp",
@@ -69,7 +67,6 @@ ohos_static_library("arkdisassembler_frontend_static") {
configs = arkdisassembler_configs
deps = [
":get_instructions_cpp",
":isa_gen_ark_disam_bc_ins_to_pandasm_ins_cpp",
":isa_gen_ark_disam_get_ins_info_cpp",
":isa_gen_ark_disam_opcode_translator_cpp",
@@ -123,13 +120,6 @@ ark_isa_gen("isa_gen_ark_disam") {
]
}
ark_gen_file("get_instructions_cpp") {
template_file = "$ark_root/disassembler/templates/get_instructions.cpp.erb"
data_file = "$ark_root/isa/builtins.yaml"
requires = [ "$ark_root/isa/builtinsapi.rb" ]
output_file = "$target_gen_dir/get_instructions.cpp"
}
ark_gen_file("type_to_pandasm_type_cpp") {
template_file =
"$ark_root/disassembler/templates/type_to_pandasm_type.cpp.erb"
-9
View File
@@ -28,14 +28,6 @@ panda_isa_gen(
${GET_INSTRUCTIONS_CPP}
)
set(GET_INSTRUCTIONS_CPP ${CMAKE_CURRENT_BINARY_DIR}/get_instructions.cpp)
panda_gen_file(
DATAFILE ${PANDA_ROOT}/isa/builtins.yaml
TEMPLATE ${CMAKE_CURRENT_SOURCE_DIR}/templates/get_instructions.cpp.erb
REQUIRES ${PANDA_ROOT}/isa/builtinsapi.rb
OUTPUTFILE ${GET_INSTRUCTIONS_CPP}
)
set(GENERATOR ${PANDA_ROOT}/libpandafile/types.rb)
set(TEMPLATE ${CMAKE_CURRENT_LIST_DIR}/templates/type_to_pandasm_type.cpp.erb)
set(DATAFILE ${PANDA_ROOT}/libpandafile/types.yaml)
@@ -53,7 +45,6 @@ add_library(arkdisassembler ${PANDA_DEFAULT_LIB_TYPE}
bc_ins_to_pandasm_ins.cpp
get_ins_info.cpp
type_to_pandasm_type.cpp
get_instructions.cpp
)
target_include_directories(arkdisassembler
+85
View File
@@ -1348,4 +1348,89 @@ pandasm::extensions::Language Disassembler::GetClassLanguage(panda_file::File::E
return PFLangToPandasmLang(cda.GetSourceLang());
}
IdList Disassembler::GetInstructions(pandasm::Function *method, panda_file::File::EntityId method_id,
panda_file::File::EntityId code_id) const
{
panda_file::CodeDataAccessor code_accessor(*file_, code_id);
const auto ins_sz = code_accessor.GetCodeSize();
const auto ins_arr = code_accessor.GetInstructions();
method->regs_num = code_accessor.GetNumVregs();
auto bc_ins = BytecodeInstruction(ins_arr);
const auto bc_ins_last = bc_ins.JumpTo(ins_sz);
LabelTable label_table = GetExceptions(method, method_id, code_id);
IdList unknown_external_methods {};
while (bc_ins.GetAddress() != bc_ins_last.GetAddress()) {
if (bc_ins.GetAddress() > bc_ins_last.GetAddress()) {
LOG(ERROR, DISASSEMBLER) << "> error encountered at " << std::dec << code_id.GetOffset() << " ("
<< "0x" << std::hex << code_id.GetOffset()
<< "). bytecode instructions sequence corrupted for method " << method->name
<< "! went out of bounds";
break;
}
auto pa_ins = BytecodeInstructionToPandasmInstruction(bc_ins, method_id, method->language);
// alter instructions operands depending on instruction type
if (pa_ins.IsConditionalJump() || pa_ins.IsJump()) {
const int32_t jmp_offset = std::get<int64_t>(pa_ins.imms.at(0));
const auto bc_ins_dest = bc_ins.JumpTo(jmp_offset);
if (bc_ins_last.GetAddress() > bc_ins_dest.GetAddress()) {
size_t idx = GetBytecodeInstructionNumber(BytecodeInstruction(ins_arr), bc_ins_dest);
if (idx != std::numeric_limits<size_t>::max()) {
if (label_table.find(idx) == label_table.end()) {
std::stringstream ss {};
ss << "jump_label_" << label_table.size();
label_table[idx] = ss.str();
}
pa_ins.imms.clear();
pa_ins.ids.push_back(label_table[idx]);
} else {
LOG(ERROR, DISASSEMBLER)
<< "> error encountered at " << std::dec << code_id.GetOffset() << " ("
<< "0x" << std::hex << code_id.GetOffset() << "). incorrect instruction at offset "
<< (bc_ins.GetAddress() - ins_arr) << ": invalid jump offset " << jmp_offset
<< " - jumping in the middle of another instruction!";
}
} else {
LOG(ERROR, DISASSEMBLER) << "> error encountered at " << std::dec << code_id.GetOffset() << " ("
<< "0x" << std::hex << code_id.GetOffset()
<< "). incorrect instruction at offset: " << (bc_ins.GetAddress() - ins_arr)
<< ": invalid jump offset " << jmp_offset << " - jumping out of bounds!";
}
}
// check if method id is unknown external method. if so, emplace it in table
if (bc_ins.HasFlag(BytecodeInstruction::Flags::METHOD_ID)) {
const auto arg_method_idx = bc_ins.GetId().AsIndex();
const auto arg_method_id = file_->ResolveMethodIndex(method_id, arg_method_idx);
const auto arg_method_name = GetFullMethodName(arg_method_id, method->language);
const bool is_present = prog_.function_table.find(arg_method_name) != prog_.function_table.cend();
const bool is_external = file_->IsExternal(arg_method_id);
if (is_external && !is_present) {
unknown_external_methods.push_back(arg_method_id);
}
}
method->ins.push_back(pa_ins);
bc_ins = bc_ins.GetNext();
}
for (const auto &pair : label_table) {
method->ins[pair.first].label = pair.second;
method->ins[pair.first].set_label = true;
}
return unknown_external_methods;
}
} // namespace panda::disasm
@@ -1,143 +0,0 @@
/*
* Copyright (c) 2021 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 "disassembler.h"
namespace panda::disasm {
IdList Disassembler::GetInstructions(pandasm::Function *method, panda_file::File::EntityId method_id,
panda_file::File::EntityId code_id) const {
panda_file::CodeDataAccessor code_accessor(*file_, code_id);
const auto ins_sz = code_accessor.GetCodeSize();
const auto ins_arr = code_accessor.GetInstructions();
method->regs_num = code_accessor.GetNumVregs();
auto bc_ins = BytecodeInstruction(ins_arr);
const auto bc_ins_last = bc_ins.JumpTo(ins_sz);
LabelTable label_table = GetExceptions(method, method_id, code_id);
IdList unknown_external_methods{};
while (bc_ins.GetAddress() != bc_ins_last.GetAddress()) {
if (bc_ins.GetAddress() > bc_ins_last.GetAddress()) {
LOG(ERROR, DISASSEMBLER) << "> error encountered at " << std::dec << code_id.GetOffset() << " (" << "0x" << std::hex
<< code_id.GetOffset() << "). bytecode instructions sequence corrupted for method "
<< method->name << "! went out of bounds";
break;
}
auto pa_ins = BytecodeInstructionToPandasmInstruction(bc_ins, method_id, method->language);
// alter instructions operands depending on instruction type
if (pa_ins.IsConditionalJump() || pa_ins.IsJump()) {
const int32_t jmp_offset = std::get<int64_t>(pa_ins.imms.at(0));
const auto bc_ins_dest = bc_ins.JumpTo(jmp_offset);
if (bc_ins_last.GetAddress() > bc_ins_dest.GetAddress()) {
size_t idx = GetBytecodeInstructionNumber(BytecodeInstruction(ins_arr), bc_ins_dest);
if (idx != std::numeric_limits<size_t>::max()) {
if (label_table.find(idx) == label_table.end()) {
std::stringstream ss{};
ss << "jump_label_" << label_table.size();
label_table[idx] = ss.str();
}
pa_ins.imms.clear();
pa_ins.ids.push_back(label_table[idx]);
} else {
LOG(ERROR, DISASSEMBLER) << "> error encountered at " << std::dec << code_id.GetOffset() << " ("
<< "0x" << std::hex << code_id.GetOffset() << "). incorrect instruction at offset "
<< (bc_ins.GetAddress() - ins_arr) << ": invalid jump offset "
<< jmp_offset << " - jumping in the middle of another instruction!";
}
} else {
LOG(ERROR, DISASSEMBLER) << "> error encountered at " << std::dec << code_id.GetOffset() << " ("
<< "0x" << std::hex << code_id.GetOffset()
<< "). incorrect instruction at offset: " << (bc_ins.GetAddress() - ins_arr)
<< ": invalid jump offset " << jmp_offset << " - jumping out of bounds!";
}
}
// if builtin - change imm to mnemonic
switch (pa_ins.opcode) {
% PandaBuiltins::instructions.each do |insn|
case pandasm::Opcode::<%=insn.mnemonic.tr('.', '_').upcase%>:
switch(pa_ins.imms[0].index()) {
// contains int64_t
case 0:
switch (std::get<int64_t>(pa_ins.imms[0])) {
% PandaBuiltins::builtins.each do |builtin|
% if (builtin.insn == insn.mnemonic)
case <%= builtin.id%>:
pa_ins.ids.insert(pa_ins.ids.begin(), std::string("<%=builtin.mnemonic%>"));
break;
% end
% end
default:
LOG(ERROR, DISASSEMBLER) << "> error encountered at " << std::dec << code_id.GetOffset() << " ("
<< "0x" << std::hex << code_id.GetOffset()
<< "). incorrect builtin mnemonic id!";
break;
}
break;
// float or nothing - throw error
default:
LOG(ERROR, DISASSEMBLER) << "> error encountered at " << std::dec << code_id.GetOffset() << " ("
<< "0x" << std::hex << code_id.GetOffset()
<< "). incorrect type of builtin mnemonic id! expected integer, but "
"float (or nothing) received!";
break;
}
pa_ins.imms.erase(pa_ins.imms.begin());
break;
% end
default:
break;
}
// check if method id is unknown external method. if so, emplace it in table
if (bc_ins.HasFlag(BytecodeInstruction::Flags::METHOD_ID)) {
const auto arg_method_idx = bc_ins.GetId().AsIndex();
const auto arg_method_id = file_->ResolveMethodIndex(method_id, arg_method_idx);
const auto arg_method_name = GetFullMethodName(arg_method_id, method->language);
const bool is_present = prog_.function_table.find(arg_method_name) != prog_.function_table.cend();
const bool is_external = file_->IsExternal(arg_method_id);
if (is_external && !is_present) {
unknown_external_methods.push_back(arg_method_id);
}
}
method->ins.push_back(pa_ins);
bc_ins = bc_ins.GetNext();
}
for (const auto& pair : label_table) {
method->ins[pair.first].label = pair.second;
method->ins[pair.first].set_label = true;
}
return unknown_external_methods;
}
} // namespace panda::disasm
-30
View File
@@ -1,30 +0,0 @@
# Copyright (c) 2021 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.
.function void g(f32 a0, f32 a1) {
builtin.acc i32tof32
builtin.acc i64tof32
builtin.acc f64tof32
builtin.acc monitorenter
builtin.acc monitorexit
builtin.bin2 fadd2f32, a1
builtin.bin2 fsub2f32, v13
builtin.bin2 fmul2f32, v13
builtin.bin2 fdiv2f32, v13
builtin.bin2 fmod2f32, v13
builtin.bin2 fcmpl2f32, a0
builtin.bin2 fcmpg2f32, v13
return.void
}
-398
View File
@@ -1,398 +0,0 @@
# Copyright (c) 2021 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.
---
# This is a non-public extension of Panda instruction set architecture.
# Each group from the section below defines a single 'builtin.*' instruction
# without predefined semantics. Each 'builtin.*' instruction can be
# dispatched to maximum 256 handlers, each executing in the interpreter's
# context (like all public instruction handlers do). These extension handlers
# are called builtins. Dispatching 'builtin.*' instructions to actual handlers
# is achieved via first immediate operand of each 'builtin.*' instruction.
#
# Following restrictions apply to the 'groups' section:
#
# * The entire 'groups' section must have exactly the same format as isa.yaml.
# * Each group must define exactly one 'builtin.*' instruction.
# * Each 'builtin.*' instruction must have exactly one encoding format.
# This limitation is introduced to avoid writing complex and untestable
# code generation routines -- currently "one instruction <=> one format"
# is enough. Feel free to remove this constraint on demand.
# * There must be no 'builtin.*' instructions with the same signature
# (consult with the API for signature validation rules).
#
# Following restrtictions apply to the 'builtins' section:
#
# * All builtin names must be unique
# * Signature of each builtin must match exactly one signature of some
# 'builtin.*' instruction (consult with the API for signature matching rules).
# Please note that there is no need to specify correspondence between
# builtins and 'builtin.*' instructions explicitly, this done by the API.
#
# Following runtime restrictions apply to builtins handlers:
#
# * Builtin handler is not expected to run in parallel with GC at STW phase
# * Builtin handler must not trigger runtime operations that start GC
#
# NB! Important note about ordering and dispatch table layout.
# The order of builtin definitions in this file is not important. However,
# API may reorder these definitions to guarantee following layout
# for the dispatch table:
#
# public_opcode_01
# public_opcode_02
# ...
# builtin_opcode_01
# builtin_opcode_02
# ...
# builtin_01_for_builtin_opcode_01 \
# builtin_02_for_builtin_opcode_01 | All builtins with signature of builtin_opcode_01
# builtin_03_for_builtin_opcode_01 /
# builtin_01_for_builtin_opcode_02 \
# ... | All builtins with signature of builtin_opcode_02
# builtin_NN_for_builtin_opcode_02 /
#
groups:
- title: Built-in operations without explicit operands
description: Non-public extension of the instruction set.
verification:
- none
exceptions:
- x_none
properties:
- acc_read
- acc_write
pseudo: |
builtin = resolve_builtin(imm)
acc = builtin(acc)
semantics: |
skip
instructions:
- sig: builtin.acc imm
acc: inout:top
format: [op_imm_8]
- title: Built-in two address binary operations on accumulator
description: Non-public extension of the instruction set.
verification:
- none
exceptions:
- x_none
properties:
- acc_read
- acc_write
pseudo: |
builtin = resolve_builtin(imm)
acc = builtin(acc, v)
semantics: |
skip
instructions:
- sig: builtin.bin2 imm, v:in:top
acc: inout:top
format: [op_imm_8_v_8]
- title: Built-in three address operations on accumulator
description: Non-public extension of the instruction set.
verification:
- none
exceptions:
- x_none
properties:
- acc_read
- acc_write
pseudo: |
builtin = resolve_builtin(imm)
acc = builtin(acc, v1, v2)
semantics: |
skip
instructions:
- sig: builtin.tern3 imm, v1:in:top, v2:in:top
acc: inout:top
format: [op_imm_8_v1_8_v2_8]
- title: Built-in four address operations on accumulator
description: Non-public extension of the instruction set.
verification:
- none
exceptions:
- x_none
properties:
- acc_read
- acc_write
pseudo: |
builtin = resolve_builtin(imm)
acc = builtin(acc, v1, v2, v3)
semantics: |
skip
instructions:
- sig: builtin.quatern4 imm, v1:in:top, v2:in:top, v3:in:top
acc: inout:top
format: [op_imm_8_v1_8_v2_8_v3_8]
- title: Built-in five address operations on accumulator
description: Non-public extension of the instruction set.
verification:
- none
exceptions:
- x_none
properties:
- acc_read
- acc_write
pseudo: |
builtin = resolve_builtin(imm)
acc = builtin(acc, v1, v2, v3, v4)
semantics: |
skip
instructions:
- sig: builtin.quin5 imm, v1:in:top, v2:in:top, v3:in:top, v4:in:top
acc: inout:top
format: [op_imm_8_v1_8_v2_8_v3_8_v4_8]
- title: Built-in opcode for imm8_v
description: Non-public extension of the instruction set.
verification:
- none
exceptions:
- x_none
properties:
- acc_read
- acc_write
pseudo: |
builtin = resolve_builtin(imm1)
acc = builtin(imm2, acc, v)
semantics: |
skip
instructions:
- sig: builtin.r2i imm1, imm2, v:in:top
acc: inout:top
format: [op_imm1_8_imm2_16_v_8]
- title: Built-in opcode for imm8_v1_v2
description: Non-public extension of the instruction set.
verification:
- none
exceptions:
- x_none
properties:
- acc_read
- acc_write
pseudo: |
builtin = resolve_builtin(imm1)
acc = builtin(imm2, acc, v1, v2)
semantics: |
skip
instructions:
- sig: builtin.r3i imm1, imm2, v1:in:top, v2:in:top
acc: inout:top
format: [op_imm1_8_imm2_16_v1_8_v2_8]
- title: Built-in opcode for imm8_v1_v2_v3
description: Non-public extension of the instruction set.
verification:
- none
exceptions:
- x_none
properties:
- acc_read
- acc_write
pseudo: |
builtin = resolve_builtin(imm1)
acc = builtin(imm2, acc, v1, v2, v3)
semantics: |
skip
instructions:
- sig: builtin.r4i imm1, imm2, v1:in:top, v2:in:top, v3:in:top
acc: inout:top
format: [op_imm1_8_imm2_16_v1_8_v2_8_v3_8]
- title: Built-in opcode for id_32
description: Non-public extension of the instruction set.
verification:
- none
exceptions:
- x_none
properties:
- string_id
- acc_read
- acc_write
pseudo: |
builtin = resolve_builtin(imm)
acc = builtin(acc, id)
semantics: |
skip
instructions:
- sig: builtin.id imm, string_id
acc: inout:top
format: [op_imm_8_id_32]
- title: Built-in opcode for method_id_v_8
description: Non-public extension of the instruction set.
verification:
- method_id_static
exceptions:
- x_none
properties:
- method_id
- acc_read
- acc_write
pseudo: |
builtin = resolve_builtin(imm)
acc = builtin(acc, method_id, v)
semantics: |
skip
instructions:
- sig: builtin.midr imm, method_id, v:in:top
acc: inout:top
format: [op_imm_8_id_16_v_8]
- title: Built-in opcode for id_32_imm_16
description: Non-public extension of the instruction set.
verification:
- none
exceptions:
- x_none
properties:
- string_id
- acc_read
- acc_write
pseudo: |
builtin = resolve_builtin(imm1)
acc = builtin(acc, id, imm2)
semantics: |
skip
instructions:
- sig: builtin.idi imm1, string_id, imm2
acc: inout:top
format: [op_imm1_8_id_32_imm2_16]
- title: Built-in opcode for id_32_imm_16_v_8
description: Non-public extension of the instruction set.
verification:
- none
exceptions:
- x_none
properties:
- string_id
- acc_read
- acc_write
pseudo: |
builtin = resolve_builtin(imm1)
acc = builtin(acc, id, imm2, v)
semantics: |
skip
instructions:
- sig: builtin.idr3i imm1, string_id, imm2, v:in:top
acc: inout:top
format: [op_imm1_8_id_32_imm2_16_v_8]
- title: Built-in opcode for id_32_imm_16_v1_8_v2_8
description: Non-public extension of the instruction set.
verification:
- none
exceptions:
- x_none
properties:
- string_id
- acc_read
- acc_write
pseudo: |
builtin = resolve_builtin(imm1)
acc = builtin(acc, id, imm2, v1, v2)
semantics: |
skip
instructions:
- sig: builtin.idr4i imm1, string_id, imm2, v1:in:top, v2:in:top
acc: inout:top
format: [op_imm1_8_id_32_imm2_16_v1_8_v2_8]
- title: Built-in opcode for imm_16_imm_16_v_8
description: Non-public extension of the instruction set.
verification:
- none
exceptions:
- x_none
properties:
- acc_read
- acc_write
pseudo: |
builtin = resolve_builtin(imm1)
acc = builtin(acc, imm2, imm3, v)
semantics: |
skip
instructions:
- sig: builtin.i2r3 imm1, imm2, imm3, v:in:top
acc: inout:top
format: [op_imm1_8_imm2_16_imm3_16_v_8]
- title: Built-in opcode for imm_16_imm_16
description: Non-public extension of the instruction set.
verification:
- none
exceptions:
- x_none
properties:
- acc_read
- acc_write
pseudo: |
builtin = resolve_builtin(imm1)
acc = builtin(acc, imm2, imm3)
semantics: |
skip
instructions:
- sig: builtin.i2r2 imm1, imm2, imm3
acc: inout:top
format: [op_imm1_8_imm2_16_imm3_16]
- title: Built-in opcode for imm_16
description: Non-public extension of the instruction set.
verification:
- none
exceptions:
- x_none
properties:
- acc_read
- acc_write
pseudo: |
builtin = resolve_builtin(imm1)
acc = builtin(acc, imm2)
semantics: |
skip
instructions:
- sig: builtin.imm imm1, imm2
acc: inout:top
format: [op_imm1_8_imm2_16]
- title: Built-in opcode with method id imm16 and two regs
description: Non-public extension of the instruction set.
verification:
- none
exceptions:
- x_none
properties:
- acc_write
- method_id
pseudo: |
pseudo: |
builtin = resolve_builtin(imm1)
acc = builtin(id, imm2, v1, v2)
semantics: |
skip
instructions:
- sig: builtin.imr2 imm1, method_id, imm2, v1:in:top, v2:in:top
acc: out:top
format: [op_imm1_8_id_16_imm2_16_v1_8_v2_8]
builtins: [ ]
#
-224
View File
@@ -1,224 +0,0 @@
# Copyright (c) 2021 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.
require 'delegate'
require 'ostruct'
class BuiltinInstruction < SimpleDelegator
def mnemonic
sig.split(' ')[0]
end
def opcode
mnemonic.sub('.', '_') + self[:format]
end
def format
self[:format].length() == 0 ? 'NONE' : self[:format].sub('_', '')
end
end
class Builtin < SimpleDelegator
def mnemonic
sig.split(' ')[0]
end
def opcode
mnemonic.sub('.', '_') + self[:format]
end
def format
self[:format].length() == 0 ? 'NONE' : self[:format].sub('_', '')
end
def stripped_mnemonic
mnemonic.split('.')[0]
end
def throwing?
throwable = ['monitorenter', 'monitorexit']
throwable.include?(stripped_mnemonic) || self[:exception] == true
end
def ins
self[:insn].sub('.', '_')
end
def id
self[:id]
end
def language_context
self[:space]
end
end
module PandaBuiltins
module_function
def instructions
insns = []
@data["groups"].each do |group|
group.instructions[0][:format].each do |f|
props = group.instructions[0].to_h
props[:format] = f.sub('op', '').gsub(/imm[0-9]+?/, 'imm').gsub(/v[0-9]+?/, 'v').gsub(/_([0-9]+)/, '\1')
insns << BuiltinInstruction.new(OpenStruct.new(props))
end
end
insns
end
def builtins
all_builtins = []
@data["builtins"].each do |b|
b[:format].each do |f|
props = b.to_h
props[:format] = f.sub('op', '').gsub(/imm[0-9]+?/, 'imm').gsub(/v[0-9]+?/, 'v').gsub(/_([0-9]+)/, '\1')
all_builtins << Builtin.new(OpenStruct.new(props))
end
end
# Assign an ID to each builtin.
# NB! IDs are unique only for builtins corresponding
# to a *single* 'builtin.*' instruction!
id = 0
for i in 1 .. all_builtins.length() - 1
all_builtins[i - 1][:id] = id
id += 1
id = 0 unless all_builtins[i - 1][:insn] == all_builtins[i][:insn]
end
all_builtins[all_builtins.length() - 1][:id] = id if all_builtins.any?
all_builtins
end
# Delegating part of module
#
def wrap_data(data)
@data = data
end
end
def prepare_data(data)
insn_ids = []
mnemos = {} # insn id => mnemonics
formats = {} # insn id => supported encoding formats
counts = {} # insn id => number of corresponding builtins (counting different formats)
ordered = {} # insn id => list of corresponding builtins in order of definition
raise 'Number of builtin.* instructions is too high' if data["groups"].length() > 20
insn_names = {}
data["groups"].each do |group|
raise 'Expecting exactly one instruction per builtin.* group' unless group["instructions"].length() == 1
group["instructions"].each do |insn|
sig = insn["sig"]
args = sig.split(/,?\s+/)
args_len = args.length()
raise 'Expecting at least one argument for a builtin' if args_len < 2
raise "Expecting 'builtin.' prefix for the mnemonic" unless /^builtin\./.match(args[0])
raise "Expecting an imm as the builtin's first argument" unless args[1].start_with?('imm')
raise "Duplicate builtin instruction name '#{args[0]}'" if insn_names.key?(args[0])
insn_names[args[0]] = 1
insn_id = args[2 .. args_len - 1].map{ |arg| arg =~ /^([^:]+):?/; $1 }.join('_')
raise "Non-unique signature is detected while parsing instruction '#{sig}'" if formats.key?(insn_id)
# Currently a single format per instruction is enough, so the assert below just guards status quo
raise 'Expecting exactly one encoding format per instruction' unless insn["format"].length() == 1
insn_ids << insn_id
mnemos[insn_id] = args[0]
formats[insn_id] = insn["format"]
counts[insn_id] = 0
ordered[insn_id] = []
end
end
builtin_names = {}
data["builtins"].each do |builtin|
raise "'sig' property is missing" unless builtin['sig']
raise "'acc' property is missing" unless builtin['acc']
raise "Unexpected 'insn' property" if builtin['insn']
raise "Unexpected 'format' property" if builtin['format']
sig = builtin["sig"]
args = sig.split(/,?\s+/)
args_len = args.length()
raise "Malformed signature of a builtin" if args_len < 1
raise "Duplicate builtin name '#{args[0]}'" if builtin_names.key?(args[0])
builtin_names[args[0]] = 1
insn_id = args[1 .. args_len - 1].map{ |arg| arg =~ /^([^:]+):?/; $1 }.join('_')
raise "Signature for builtin '#{sig}' does not match any builtin.* instruction" unless formats.key?(insn_id)
builtin["insn"] = mnemos[insn_id]
builtin["format"] = formats[insn_id].clone
counts[insn_id] += builtin["format"].length()
ordered[insn_id] << builtin
raise "Number of builtins for '#{insn_id}' exceeds builtin_id" if counts[insn_id] > 256
end
# Enforce order of builtins and add "delta" property, defined as follows:
# builtin1.delta = 0
# builtin2.delta = num_builtins_with_sig_of(builtin1)
# builtin3.delta = num_builtins_with_sig_of(builtin1) + num_builtins_with_sig_of(builtin2)
# ...
# builtinN.delta = num_builtins_with_sig_of(builtin1) + num_builtins_with_sig_of(builtin2) + ... + num_builtins_with_sig_of(builtinN_1)
builtins = []
for i in 0 .. data["groups"].length() - 1
curr_insn = data["groups"][i]["instructions"][0]
curr_insn_id = insn_ids[i]
if i > 0
prev_insn = data["groups"][i - 1]["instructions"][0]
prev_insn_id = insn_ids[i - 1]
curr_insn["delta"] = prev_insn["delta"] + counts[prev_insn_id]
else
curr_insn["delta"] = 0
end
ordered[curr_insn_id].each do |builtin|
builtins << builtin
end
end
{"groups" => data["groups"], "builtins" => builtins}
end
module ExtBuiltins
def self.load_ecma_builtins(data); end
end
def Gen.on_require(data)
ExtBuiltins.load_ecma_builtins(data)
prepared_data = prepare_data(data)
PandaBuiltins.wrap_data(prepared_data)
end
-7
View File
@@ -533,12 +533,5 @@ module Panda
end
def Gen.on_require(data)
builtins_fname = File.expand_path(File.join(File.dirname(__FILE__), 'builtins.yaml'))
builtins = YAML.load_file(builtins_fname)
builtins = JSON.parse(builtins.to_json, object_class: OpenStruct)
builtins.groups.each do |group|
data.groups << group
end
Panda.wrap_data(data)
end
-10
View File
@@ -66,7 +66,6 @@ ohos_shared_library("libarkfile") {
":isa_gen_libarkfile_bytecode_instruction_enum_gen_h",
":isa_gen_libarkfile_file_format_version_h",
":isa_gen_libarkfile_tests_bytecode_emitter_tests_gen_h",
":libarkfile_bytecode_builtin_enum_gen_h",
":libarkfile_type_gen_h",
"$ark_root/libpandabase:libarkbase",
"$ark_root/libziparchive:libarkziparchive",
@@ -92,7 +91,6 @@ ohos_static_library("libarkfile_frontend_static") {
":isa_gen_libarkfile_bytecode_instruction_enum_gen_h",
":isa_gen_libarkfile_file_format_version_h",
":isa_gen_libarkfile_tests_bytecode_emitter_tests_gen_h",
":libarkfile_bytecode_builtin_enum_gen_h",
":libarkfile_type_gen_h",
"$ark_root/libpandabase:libarkbase_frontend_static",
"$ark_root/libziparchive:libarkziparchive_frontend_static",
@@ -107,13 +105,6 @@ ark_gen_file("libarkfile_type_gen_h") {
output_file = "$target_gen_dir/type.h"
}
ark_gen_file("libarkfile_bytecode_builtin_enum_gen_h") {
template_file = "templates/bytecode_builtin_enum_gen.h.erb"
data_file = "$ark_root/isa/builtins.yaml"
requires = [ "$ark_root/isa/builtinsapi.rb" ]
output_file = "$target_gen_dir/bytecode_builtin_enum_gen.h"
}
ark_isa_gen("isa_gen_libarkfile") {
template_files = [
"bytecode_instruction_enum_gen.h.erb",
@@ -126,5 +117,4 @@ ark_isa_gen("isa_gen_libarkfile") {
sources = "templates" ## ark_root/templates
destination = "$target_gen_dir/include" ## target_gen_dir/include
requires = [ "pandafile_isapi.rb" ]
extra_dependencies = [ ":libarkfile_bytecode_builtin_enum_gen_h" ]
}
-8
View File
@@ -28,14 +28,6 @@ set(TEMPLATES
tests/bytecode_emitter_tests_gen.h.erb
)
set(output "${CMAKE_CURRENT_BINARY_DIR}/include/bytecode_builtin_enum_gen.h")
panda_gen_file(
DATAFILE "${PANDA_ROOT}/isa/builtins.yaml"
REQUIRES "${PANDA_ROOT}/isa/builtinsapi.rb"
TEMPLATE "${CMAKE_CURRENT_SOURCE_DIR}/templates/bytecode_builtin_enum_gen.h.erb"
OUTPUTFILE ${output}
)
panda_isa_gen(TEMPLATES ${TEMPLATES}
SOURCE ${CMAKE_CURRENT_LIST_DIR}/templates
DESTINATION ${GEN_INCLUDE_DIR}
-4
View File
@@ -209,8 +209,6 @@ class BytecodeInst : public BytecodeInstBase<Mode> {
public:
#include <bytecode_instruction_enum_gen.h>
#include <bytecode_builtin_enum_gen.h>
BytecodeInst() = default;
~BytecodeInst() = default;
@@ -349,8 +347,6 @@ public:
bool CanThrow() const;
bool IsBuiltin() const;
bool IsTerminator() const
{
return HasFlag(Flags::RETURN) || HasFlag(Flags::JUMP) || (GetOpcode() == Opcode::THROW_V8);
@@ -1,22 +0,0 @@
/*
* Copyright (c) 2021 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.
*/
% PandaBuiltins::instructions.each do |instr|
enum <%= instr.mnemonic.tr('.','_').upcase %> {
% PandaBuiltins::builtins.select{ |b| b.insn == instr.mnemonic }.each do |builtin|
<%= builtin.opcode.tr('.','_').upcase %>,
% end
};
% end
@@ -359,21 +359,6 @@ std::ostream& operator<<(std::ostream& os, const typename BytecodeInst<Mode>::Op
return os;
}
template <const BytecodeInstMode Mode>
inline bool BytecodeInst<Mode>::IsBuiltin() const
{
switch (GetOpcode()) {
% Panda::instructions.each do |inst|
% if inst["sig"].include? "builtin"
case BytecodeInst<Mode>::Opcode::<%= inst.opcode.upcase %>:
% end
% end
return true;
default:
return false;
}
}
template <const BytecodeInstMode Mode>
inline bool BytecodeInst<Mode>::IsPrimaryOpcodeValid() const
{
-20
View File
@@ -212,7 +212,6 @@ ohos_static_library("libarkruntime_static") {
"$ark_root/verification/gen:isa_gen_verification_gen_abs_int_inl_gen_h",
"$ark_root/verification/gen:isa_gen_verification_gen_cflow_iterate_inl_gen_h",
"$ark_root/verification/gen:isa_gen_verification_gen_job_fill_gen_h",
"$ark_root/verification/gen:verification_abs_int_builtin_handlers_h",
"$ark_root/verification/gen:verification_abs_int_inl_compat_checks_h",
"$ark_root/verification/gen:verification_verifier_messages_h",
sdk_libc_secshared_dep,
@@ -358,24 +357,6 @@ gen_intrinsics_yaml("arkruntime_gen_intrinsics_yaml") {
output_file = "$target_gen_dir/intrinsics.yaml"
}
builtin_templates = [
"builtin_count",
"builtin_dispatch",
"builtin_handlers",
"builtin_insn_handlers",
]
builtin_labels = []
foreach(t, builtin_templates) {
output = "$target_gen_dir/include/${t}.h"
builtin_labels += [ ":${t}" ]
ark_gen_file(t) {
data_file = "$ark_root/isa/builtins.yaml"
requires = [ "$ark_root/isa/builtinsapi.rb" ]
template_file = "interpreter/templates/${t}.h.erb"
output_file = output
}
}
gen_include_dir = "$target_gen_dir/include"
ark_isa_gen("isa_gen_libarkruntime") {
@@ -386,7 +367,6 @@ ark_isa_gen("isa_gen_libarkruntime") {
]
sources = "interpreter/templates"
destination = gen_include_dir
extra_dependencies = builtin_labels
}
isa = "$root_gen_dir/isa/isa.yaml"
-20
View File
@@ -179,25 +179,6 @@ set(INTERPRETER_IMPL_SOURCES
add_library(arkruntime_interpreter_impl OBJECT ${INTERPRETER_IMPL_SOURCES})
panda_set_lib_32bit_property(arkruntime_interpreter_impl)
set(builtin_templates
builtin_count
builtin_dispatch
builtin_handlers
builtin_insn_handlers
)
set(builtin_headers)
foreach(template ${builtin_templates})
set(output "${CMAKE_CURRENT_BINARY_DIR}/include/${template}.h")
panda_gen_file(
DATAFILE "${PANDA_ROOT}/isa/builtins.yaml"
REQUIRES "${PANDA_ROOT}/isa/builtinsapi.rb"
TEMPLATE "${CMAKE_CURRENT_SOURCE_DIR}/interpreter/templates/${template}.h.erb"
OUTPUTFILE ${output}
)
list(APPEND builtin_headers ${output})
endforeach()
set(ISA_TEMPLATES
interpreter-inl_gen.h.erb
isa_constants_gen.h.erb
@@ -209,7 +190,6 @@ panda_isa_gen(
TEMPLATES ${ISA_TEMPLATES}
SOURCE ${CMAKE_CURRENT_LIST_DIR}/interpreter/templates
DESTINATION ${GEN_INCLUDE_DIR}
EXTRA_DEPENDENCIES ${builtin_headers}
)
set(ISA "${CMAKE_BINARY_DIR}/isa/isa.yaml")
@@ -1,21 +0,0 @@
/*
* Copyright (c) 2021 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.
*/
#ifndef PANDA_RUNTIME_INCLUDE_BUILTIN_COUNT_H_
#define PANDA_RUNTIME_INCLUDE_BUILTIN_COUNT_H_
constexpr size_t NUM_BUILTINS = <%= PandaBuiltins::builtins.length() %>;
#endif // PANDA_RUNTIME_INCLUDE_BUILTIN_COUNT_H_
@@ -1,23 +0,0 @@
/*
* Copyright (c) 2021 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.
*/
#ifndef PANDA_RUNTIME_INCLUDE_BUILTIN_DISPATCH_H_
#define PANDA_RUNTIME_INCLUDE_BUILTIN_DISPATCH_H_
% PandaBuiltins::builtins.each do |builtin|
&&HANDLE_BUILTIN_<%= builtin.opcode.tr('.','_').upcase %>,
% end
#endif // PANDA_RUNTIME_INCLUDE_BUILTIN_DISPATCH_H_
@@ -1,57 +0,0 @@
/*
* Copyright (c) 2021 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.
*/
#ifndef PANDA_RUNTIME_INCLUDE_BUILTIN_HANDLERS_H_
#define PANDA_RUNTIME_INCLUDE_BUILTIN_HANDLERS_H_
% PandaBuiltins::builtins.each do |builtin|
HANDLE_BUILTIN_<%= builtin.opcode.tr('.','_').upcase %>: {
% if builtin.language_context == 'ecmascript'
ecmascript::InstructionHandler<RuntimeIfaceT, enable_instrumentation> handler(&state);
% elsif builtin.language_context == 'java'
java::InstructionHandler<RuntimeIfaceT, enable_instrumentation> handler(&state);
% else
InstructionHandler<RuntimeIfaceT, enable_instrumentation> handler(&state);
% end
% mnemonic = builtin.mnemonic.split('.').map { |p| p == '64' ? 'Wide' : p.capitalize }.join
handler.DumpVRegs();
handler.InstrumentInstruction();
ASSERT(PandaVM::GetCurrent()->GetLanguageContext().GetLanguage() == panda_file::SourceLang::ECMASCRIPT ||
!PandaVM::GetCurrent()->GetGC()->IsGCRunning() || Locks::mutator_lock->HasLock());
handler.template HandleBuiltin<%= mnemonic %><BytecodeInstruction::Format::<%= builtin.format.upcase %>>();
ASSERT(PandaVM::GetCurrent()->GetLanguageContext().GetLanguage() == panda_file::SourceLang::ECMASCRIPT ||
!PandaVM::GetCurrent()->GetGC()->IsGCRunning() || Locks::mutator_lock->HasLock());
if (enable_instrumentation) {
frame->GetAcc() = handler.GetAcc();
}
% if builtin['sig'].include?('Return') || builtin['sig'].include?('suspendGenerator')
return;
% else
% if builtin.throwing?
ASSERT(handler.GetExceptionOpcode() < dispatch_table.size());
DISPATCH(GetDispatchTable(dispatch_table), handler.GetExceptionOpcode(), label);
% else
ASSERT(handler.GetPrimaryOpcode() < dispatch_table.size());
DISPATCH(GetDispatchTable(dispatch_table), handler.GetPrimaryOpcode(), label);
% end
% end
}
% end
#endif // PANDA_RUNTIME_INCLUDE_BUILTIN_HANDLERS_H_
@@ -1,30 +0,0 @@
/*
* Copyright (c) 2021 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.
*/
#ifndef PANDA_RUNTIME_INCLUDE_BUILTIN_INSN_HANDLERS_H_
#define PANDA_RUNTIME_INCLUDE_BUILTIN_INSN_HANDLERS_H_
% PandaBuiltins::instructions.each do |insn|
HANDLE_<%= insn.opcode.upcase %>: {
const auto builtin_id = state.GetInst().template GetImm<BytecodeInstruction::Format::<%= insn.format.upcase %>>();
LOG(DEBUG, INTERPRETER) << "Subdispatch: " << "<%= insn.mnemonic %>, " << builtin_id
<< " (NUM_PREFIXED=" << NUM_PREFIXED
<< ", delta=" << <%= insn.delta %> << ")";
DISPATCH(GetDispatchTable(dispatch_table), 256 + NUM_PREFIXED + 1 + <%= insn.delta %> + builtin_id, label);
}
% end
#endif // PANDA_RUNTIME_INCLUDE_BUILTIN_INSN_HANDLERS_H_
@@ -34,7 +34,6 @@ void ExecuteImpl(ManagedThread* thread, const uint8_t *pc, Frame* frame) {
#define INSTRUMENT_FRAME() do { if (enable_instrumentation && (handler.GetFrame()->IsForcePop() || handler.GetFrame()->IsRetryInstruction())) { goto INSTRUMENT_FRAME_HANDLER; } } while (0)
ASSERT(!thread->IsCurrentFrameCompiled());
#include <builtin_count.h>
EVENT_METHOD_ENTER(frame->GetMethod()->GetFullName(), events::MethodEnterKind::INTERP, thread->RecordMethodEnter());
@@ -45,12 +44,11 @@ void ExecuteImpl(ManagedThread* thread, const uint8_t *pc, Frame* frame) {
PandaUniquePtr<void, decltype(method_exit_event)> method_exit(&method_exit_event, method_exit_event);
#endif
static std::array<const void*, 256 + NUM_PREFIXED + 1 + NUM_BUILTINS> dispatch_table{
static std::array<const void*, 256 + NUM_PREFIXED + 1> dispatch_table{
% Panda::dispatch_table.handler_names.each do |name|
&&HANDLE_<%= name %>,
% end
&&EXCEPTION_HANDLER,
#include <builtin_dispatch.h>
};
SetDispatchTable(dispatch_table);
@@ -64,7 +62,7 @@ void ExecuteImpl(ManagedThread* thread, const uint8_t *pc, Frame* frame) {
const void *label;
DISPATCH(GetDispatchTable(dispatch_table), state.GetPrimaryOpcode(), label);
% Panda::instructions.reject(&:builtin?).each do |i|
% Panda::instructions.each do |i|
% mnemonic = i.mnemonic.split('.').map { |p| p == '64' ? 'Wide' : p.capitalize }.join
HANDLE_<%= i.handler_name %>: {
% namespace = i.namespace == 'core' ? '' : "#{i.namespace}::"
@@ -117,10 +115,6 @@ HANDLE_<%= p.handler_name %>: {
}
% end
#include <builtin_insn_handlers.h>
#include <builtin_handlers.h>
INSTRUMENT_FRAME_HANDLER: {
InstructionHandler<RuntimeIfaceT, enable_instrumentation> handler(&state);
-59
View File
@@ -3800,65 +3800,6 @@ public:
return inst_;
}
template <BytecodeInstructionSafe::Format format>
bool HandleBuiltinCall_polymorphic_short()
{
LOG_INST();
DBGBRK();
Sync();
return true;
}
template <BytecodeInstructionSafe::Format format>
bool HandleBuiltinMonitorenter()
{
LOG_VERIFIER_DEBUG_BUILTIN("monitorenter");
DBGBRK();
Sync();
auto &&acc_type = GetAccType();
if (acc_type.ForAllTypes([&](Type acc_type1) { return acc_type1 == Types().NullRefType(); })) {
// treat it as always throw NPE
SHOW_MSG(AlwaysNpeAccumulator)
LOG_VERIFIER_ALWAYS_NPE_ACCUMULATOR();
END_SHOW_MSG();
SET_STATUS_FOR_MSG(AlwaysNpeAccumulator);
return false;
}
if (!CheckTypes(acc_type, {Types().RefType()})) {
SET_STATUS_FOR_MSG(BadRegisterType);
SET_STATUS_FOR_MSG(UndefinedRegister);
return false;
}
MoveToNextInst<format>();
return true;
}
template <BytecodeInstructionSafe::Format format>
bool HandleBuiltinMonitorexit()
{
LOG_VERIFIER_DEBUG_BUILTIN("monitorexit");
DBGBRK();
Sync();
auto &&acc_type = GetAccType();
if (acc_type.ForAllTypes([&](Type acc_type1) { return acc_type1 == Types().NullRefType(); })) {
// treat it as always throw NPE
SHOW_MSG(AlwaysNpeAccumulator)
LOG_VERIFIER_ALWAYS_NPE_ACCUMULATOR();
END_SHOW_MSG();
SET_STATUS_FOR_MSG(AlwaysNpeAccumulator);
return false;
}
if (!CheckTypes(acc_type, {Types().RefType()})) {
SET_STATUS_FOR_MSG(BadRegisterType);
SET_STATUS_FOR_MSG(UndefinedRegister);
return false;
}
MoveToNextInst<format>();
return true;
}
#include "abs_int_builtin_handlers.h"
static PandaString RegisterName(int reg_idx, bool capitalize = false)
{
if (reg_idx == ACC) {
-17
View File
@@ -22,21 +22,6 @@ config("verification_public_config") {
]
}
ark_gen_file("verification_abs_int_builtin_handlers_h") {
template_file = "templates/abs_int_builtin_handlers.h.erb"
data_file = "$ark_root/isa/builtins.yaml"
requires = [ "$ark_root/isa/builtinsapi.rb" ]
output_file = "$target_gen_dir/include/abs_int_builtin_handlers.h"
}
ark_gen_file("verification_cflow_iterate_inl_gen_builtin_handlers_h") {
template_file = "templates/cflow_iterate_inl_gen_builtin_handlers.h.erb"
data_file = "$ark_root/isa/builtins.yaml"
requires = [ "$ark_root/isa/builtinsapi.rb" ]
output_file =
"$target_gen_dir/include/cflow_iterate_inl_gen_builtin_handlers.h"
}
ark_gen_file("verification_abs_int_inl_compat_checks_h") {
template_file = "templates/abs_int_inl_compat_checks.h.erb"
data_file = "$ark_root/verification/verification.yaml"
@@ -53,9 +38,7 @@ ark_isa_gen("isa_gen_verification_gen") {
sources = "templates" ## ark_root/templates
destination = "$target_gen_dir/include" ## target_gen_dir/include
extra_dependencies = [
":verification_abs_int_builtin_handlers_h",
":verification_abs_int_inl_compat_checks_h",
":verification_cflow_iterate_inl_gen_builtin_handlers_h",
]
}
+1 -17
View File
@@ -15,22 +15,6 @@ cmake_minimum_required(VERSION 3.10)
project(pandaverification_gen)
set(abs_int_builtin_templates
abs_int_builtin_handlers
cflow_iterate_inl_gen_builtin_handlers
)
set(abs_int_builtin_headers)
foreach(template ${abs_int_builtin_templates})
set(output "${CMAKE_CURRENT_BINARY_DIR}/include/${template}.h")
panda_gen_file(
DATAFILE "${PANDA_ROOT}/isa/builtins.yaml"
REQUIRES "${PANDA_ROOT}/isa/builtinsapi.rb"
TEMPLATE "${CMAKE_CURRENT_SOURCE_DIR}/templates/${template}.h.erb"
OUTPUTFILE ${output}
)
list(APPEND abs_int_builtin_headers ${output})
endforeach()
set(ABS_INT_EXTRA_HEADERS)
set(ABS_INT_TEMPLATES
abs_int_inl_compat_checks
@@ -57,7 +41,7 @@ panda_isa_gen(
TEMPLATES ${ISA_TEMPLATES}
SOURCE ${CMAKE_CURRENT_LIST_DIR}/templates
DESTINATION ${GEN_INCLUDE_DIR}
EXTRA_DEPENDENCIES ${abs_int_builtin_headers};${ABS_INT_EXTRA_HEADERS}
EXTRA_DEPENDENCIES ${ABS_INT_EXTRA_HEADERS}
)
panda_gen_messages(
@@ -1,48 +0,0 @@
/*
* Copyright (c) 2021 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.
*/
% builtin_kinds = PandaBuiltins::builtins.map(&:insn).uniq
% builtin_mnemonics = PandaBuiltins::instructions.map { |instruction| instruction.sig.split(' ').at(0) }
% undefined_builtins = builtin_mnemonics.select { |mnemonic| not builtin_kinds.include?(mnemonic) }.uniq
% builtin_kinds.each do |kind|
% mnemonic = kind.split('.').map { |p| p == '64' ? 'Wide' : p.capitalize }.join
% builtins = PandaBuiltins::builtins.select { |builtin| builtin.insn == kind }.sort_by(&:id)
template <BytecodeInstructionSafe::Format format>
bool Handle<%= mnemonic %>() {
LOG_INST();
const auto builtin_id = GetInst().template GetImm<format>();
switch (builtin_id) {
% builtins.each do |builtin|
case <%= builtin.id %>: return HandleBuiltin<%= builtin.mnemonic.capitalize.tr('.', '_') %><format>();
% end
default:
LOG(DEBUG, VERIFIER) << "Incorrect builtin id 0x" << std::hex << builtin_id << " for '<%= kind %>'";
}
status_ = VerificationStatus::ERROR;
return false;
}
% end
% undefined_builtins.each do |builtin|
% mnemonic = builtin.split('.').map { |p| p == '64' ? 'Wide' : p.capitalize }.join
template <BytecodeInstructionSafe::Format format>
bool Handle<%= mnemonic %>() {
LOG_INST();
LOG(DEBUG, VERIFIER) << "ABSINT: "
<< "<%= builtin %>";
return true;
}
%end
@@ -35,8 +35,6 @@ public:
return inst_.IsPrimaryOpcodeValid();
}
#include "cflow_iterate_inl_gen_builtin_handlers.h"
% Panda::instructions.uniq{|i| i.mnemonic}.each do |i|
% mnemonic = i.mnemonic.split('.').map { |p| p == '64' ? 'Wide' : p.capitalize }.join
template <BytecodeInstructionSafe::Format format>
@@ -47,10 +45,7 @@ public:
}
const uint8_t* pc = inst_.GetAddress();
const size_t sz = inst_.Size(format);
% if i.mnemonic.split('.').at(0) == 'builtin'
bool const EXC_SRC = IsExceptionSource<%= mnemonic %><format>();
% elsif i.properties.include?('call') or i.stripped_mnemonic == 'throw' or !i.exceptions.include?('x_none')
// TOOD: add support of builtins: monitorenter monitorexit
% if !i.exceptions.include?('x_none')
bool const EXC_SRC = true;
% else
bool const EXC_SRC = false;
@@ -1,51 +0,0 @@
/*
* Copyright (c) 2021 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.
*/
% throwing_builtins = [ "monitorenter", "monitorexit" ]
% builtin_kinds = PandaBuiltins::builtins.map(&:insn).uniq
% builtin_mnemonics = PandaBuiltins::instructions.map { |instruction| instruction.sig.split(' ').at(0) }
% undefined_builtins = builtin_mnemonics.select { |mnemonic| not builtin_kinds.include?(mnemonic) }.uniq
% builtin_kinds.each do |kind|
% mnemonic = kind.split('.').map { |p| p == '64' ? 'Wide' : p.capitalize }.join
% builtins = PandaBuiltins::builtins.select { |builtin| builtin.insn == kind }.sort_by(&:id)
% builtins.each do |builtin|
bool IsExceptionSourceBuiltin<%= builtin.mnemonic.capitalize %>() {
% if throwing_builtins.include?(builtin.mnemonic)
return true;
% else
return false;
% end
}
% end
template <BytecodeInstructionSafe::Format format>
bool IsExceptionSource<%= mnemonic %>() {
const auto builtin_id = inst_.template GetImm<format>();
switch (builtin_id) {
% builtins.each do |builtin|
case <%= builtin.id %>: return IsExceptionSourceBuiltin<%= builtin.mnemonic.capitalize %>();
% end
default:
LOG(DEBUG, VERIFIER) << "Incorrect builtin id 0x" << std::hex << builtin_id << " for '<%= kind %>'";
}
return false;
}
% end
% undefined_builtins.each do |builtin|
template <BytecodeInstructionSafe::Format format>
bool IsExceptionSource<%= builtin.split('.').map { |p| p == '64' ? 'Wide' : p.capitalize }.join %>() {
return false;
}
% end
-6
View File
@@ -51,12 +51,6 @@ messages:
args: method
message: ( method is '${method}' )
DebugBuiltin:
number: 306
level: debug
args: name
message: "builtin: ${name}"
DebugResult:
number: 307
level: debug