summaryrefslogtreecommitdiff
path: root/startop/view_compiler/dex_builder.cc
diff options
context:
space:
mode:
Diffstat (limited to 'startop/view_compiler/dex_builder.cc')
-rw-r--r--startop/view_compiler/dex_builder.cc93
1 files changed, 49 insertions, 44 deletions
diff --git a/startop/view_compiler/dex_builder.cc b/startop/view_compiler/dex_builder.cc
index 48b44d0fc99b..50cf5a50d7a8 100644
--- a/startop/view_compiler/dex_builder.cc
+++ b/startop/view_compiler/dex_builder.cc
@@ -16,8 +16,6 @@
#include "dex_builder.h"
-#include "dex/descriptors_names.h"
-
#include <fstream>
#include <memory>
@@ -30,8 +28,6 @@ using std::string;
using ::dex::kAccPublic;
using Op = Instruction::Op;
-using Opcode = ::art::Instruction::Code;
-
const TypeDescriptor TypeDescriptor::Int() { return TypeDescriptor{"I"}; };
const TypeDescriptor TypeDescriptor::Void() { return TypeDescriptor{"V"}; };
@@ -43,20 +39,29 @@ constexpr uint8_t kDexFileMagic[]{0x64, 0x65, 0x78, 0x0a, 0x30, 0x33, 0x38, 0x00
constexpr size_t kMaxEncodedStringLength{5};
// Converts invoke-* to invoke-*/range
-constexpr Opcode InvokeToInvokeRange(Opcode opcode) {
+constexpr ::dex::Opcode InvokeToInvokeRange(::dex::Opcode opcode) {
switch (opcode) {
- case ::art::Instruction::INVOKE_VIRTUAL:
- return ::art::Instruction::INVOKE_VIRTUAL_RANGE;
- case ::art::Instruction::INVOKE_DIRECT:
- return ::art::Instruction::INVOKE_DIRECT_RANGE;
- case ::art::Instruction::INVOKE_STATIC:
- return ::art::Instruction::INVOKE_STATIC_RANGE;
- case ::art::Instruction::INVOKE_INTERFACE:
- return ::art::Instruction::INVOKE_INTERFACE_RANGE;
+ case ::dex::Opcode::OP_INVOKE_VIRTUAL:
+ return ::dex::Opcode::OP_INVOKE_VIRTUAL_RANGE;
+ case ::dex::Opcode::OP_INVOKE_DIRECT:
+ return ::dex::Opcode::OP_INVOKE_DIRECT_RANGE;
+ case ::dex::Opcode::OP_INVOKE_STATIC:
+ return ::dex::Opcode::OP_INVOKE_STATIC_RANGE;
+ case ::dex::Opcode::OP_INVOKE_INTERFACE:
+ return ::dex::Opcode::OP_INVOKE_INTERFACE_RANGE;
default:
LOG(FATAL) << opcode << " is not a recognized invoke opcode.";
- UNREACHABLE();
+ __builtin_unreachable();
+ }
+}
+
+std::string DotToDescriptor(const char* class_name) {
+ std::string descriptor(class_name);
+ std::replace(descriptor.begin(), descriptor.end(), '.', '/');
+ if (descriptor.length() > 0 && descriptor[0] != '[') {
+ descriptor = "L" + descriptor + ";";
}
+ return descriptor;
}
} // namespace
@@ -178,7 +183,7 @@ void WriteTestDexFile(const string& filename) {
}
TypeDescriptor TypeDescriptor::FromClassname(const std::string& name) {
- return TypeDescriptor{art::DotToDescriptor(name.c_str())};
+ return TypeDescriptor{DotToDescriptor(name.c_str())};
}
DexBuilder::DexBuilder() : dex_file_{std::make_shared<ir::DexFile>()} {
@@ -219,11 +224,11 @@ ir::String* DexBuilder::GetOrAddString(const std::string& string) {
ClassBuilder DexBuilder::MakeClass(const std::string& name) {
auto* class_def = Alloc<ir::Class>();
- ir::Type* type_def = GetOrAddType(art::DotToDescriptor(name.c_str()));
+ ir::Type* type_def = GetOrAddType(DotToDescriptor(name.c_str()));
type_def->class_def = class_def;
class_def->type = type_def;
- class_def->super_class = GetOrAddType(art::DotToDescriptor("java.lang.Object"));
+ class_def->super_class = GetOrAddType(DotToDescriptor("java.lang.Object"));
class_def->access_flags = kAccPublic;
return ClassBuilder{this, name, class_def};
}
@@ -378,26 +383,26 @@ void MethodBuilder::EncodeInstructions() {
void MethodBuilder::EncodeInstruction(const Instruction& instruction) {
switch (instruction.opcode()) {
case Instruction::Op::kReturn:
- return EncodeReturn(instruction, ::art::Instruction::RETURN);
+ return EncodeReturn(instruction, ::dex::Opcode::OP_RETURN);
case Instruction::Op::kReturnObject:
- return EncodeReturn(instruction, ::art::Instruction::RETURN_OBJECT);
+ return EncodeReturn(instruction, ::dex::Opcode::OP_RETURN_OBJECT);
case Instruction::Op::kMove:
case Instruction::Op::kMoveObject:
return EncodeMove(instruction);
case Instruction::Op::kInvokeVirtual:
- return EncodeInvoke(instruction, art::Instruction::INVOKE_VIRTUAL);
+ return EncodeInvoke(instruction, ::dex::Opcode::OP_INVOKE_VIRTUAL);
case Instruction::Op::kInvokeDirect:
- return EncodeInvoke(instruction, art::Instruction::INVOKE_DIRECT);
+ return EncodeInvoke(instruction, ::dex::Opcode::OP_INVOKE_DIRECT);
case Instruction::Op::kInvokeStatic:
- return EncodeInvoke(instruction, art::Instruction::INVOKE_STATIC);
+ return EncodeInvoke(instruction, ::dex::Opcode::OP_INVOKE_STATIC);
case Instruction::Op::kInvokeInterface:
- return EncodeInvoke(instruction, art::Instruction::INVOKE_INTERFACE);
+ return EncodeInvoke(instruction, ::dex::Opcode::OP_INVOKE_INTERFACE);
case Instruction::Op::kBindLabel:
return BindLabel(instruction.args()[0]);
case Instruction::Op::kBranchEqz:
- return EncodeBranch(art::Instruction::IF_EQZ, instruction);
+ return EncodeBranch(::dex::Opcode::OP_IF_EQZ, instruction);
case Instruction::Op::kBranchNEqz:
- return EncodeBranch(art::Instruction::IF_NEZ, instruction);
+ return EncodeBranch(::dex::Opcode::OP_IF_NEZ, instruction);
case Instruction::Op::kNew:
return EncodeNew(instruction);
case Instruction::Op::kCheckCast:
@@ -410,10 +415,10 @@ void MethodBuilder::EncodeInstruction(const Instruction& instruction) {
}
}
-void MethodBuilder::EncodeReturn(const Instruction& instruction, ::art::Instruction::Code opcode) {
+void MethodBuilder::EncodeReturn(const Instruction& instruction, ::dex::Opcode opcode) {
CHECK(!instruction.dest().has_value());
if (instruction.args().size() == 0) {
- Encode10x(art::Instruction::RETURN_VOID);
+ Encode10x(::dex::Opcode::OP_RETURN_VOID);
} else {
CHECK_EQ(1, instruction.args().size());
size_t source = RegisterValue(instruction.args()[0]);
@@ -433,27 +438,27 @@ void MethodBuilder::EncodeMove(const Instruction& instruction) {
if (source.is_immediate()) {
// TODO: support more registers
CHECK_LT(RegisterValue(*instruction.dest()), 16);
- Encode11n(art::Instruction::CONST_4, RegisterValue(*instruction.dest()), source.value());
+ Encode11n(::dex::Opcode::OP_CONST_4, RegisterValue(*instruction.dest()), source.value());
} else if (source.is_string()) {
constexpr size_t kMaxRegisters = 256;
CHECK_LT(RegisterValue(*instruction.dest()), kMaxRegisters);
CHECK_LT(source.value(), 65536); // make sure we don't need a jumbo string
- Encode21c(::art::Instruction::CONST_STRING, RegisterValue(*instruction.dest()), source.value());
+ Encode21c(::dex::Opcode::OP_CONST_STRING, RegisterValue(*instruction.dest()), source.value());
} else if (source.is_variable()) {
// For the moment, we only use this when we need to reshuffle registers for
// an invoke instruction, meaning we are too big for the 4-bit version.
// We'll err on the side of caution and always generate the 16-bit form of
// the instruction.
- Opcode opcode = instruction.opcode() == Instruction::Op::kMove
- ? ::art::Instruction::MOVE_16
- : ::art::Instruction::MOVE_OBJECT_16;
+ auto opcode = instruction.opcode() == Instruction::Op::kMove
+ ? ::dex::Opcode::OP_MOVE_16
+ : ::dex::Opcode::OP_MOVE_OBJECT_16;
Encode32x(opcode, RegisterValue(*instruction.dest()), RegisterValue(source));
} else {
UNIMPLEMENTED(FATAL);
}
}
-void MethodBuilder::EncodeInvoke(const Instruction& instruction, ::art::Instruction::Code opcode) {
+void MethodBuilder::EncodeInvoke(const Instruction& instruction, ::dex::Opcode opcode) {
constexpr size_t kMaxArgs = 5;
// Currently, we only support up to 5 arguments.
@@ -480,8 +485,8 @@ void MethodBuilder::EncodeInvoke(const Instruction& instruction, ::art::Instruct
for (size_t i = 0; i < instruction.args().size(); ++i) {
Instruction::Op move_op;
- if (opcode == ::art::Instruction::INVOKE_VIRTUAL ||
- opcode == ::art::Instruction::INVOKE_DIRECT) {
+ if (opcode == ::dex::Opcode::OP_INVOKE_VIRTUAL ||
+ opcode == ::dex::Opcode::OP_INVOKE_DIRECT) {
// In this case, there is an implicit `this` argument, which is always an object.
if (i == 0) {
move_op = Instruction::Op::kMoveObject;
@@ -514,8 +519,8 @@ void MethodBuilder::EncodeInvoke(const Instruction& instruction, ::art::Instruct
// If there is a return value, add a move-result instruction
if (instruction.dest().has_value()) {
- Encode11x(instruction.result_is_object() ? art::Instruction::MOVE_RESULT_OBJECT
- : art::Instruction::MOVE_RESULT,
+ Encode11x(instruction.result_is_object() ? ::dex::Opcode::OP_MOVE_RESULT_OBJECT
+ : ::dex::Opcode::OP_MOVE_RESULT,
RegisterValue(*instruction.dest()));
}
@@ -523,7 +528,7 @@ void MethodBuilder::EncodeInvoke(const Instruction& instruction, ::art::Instruct
}
// Encodes a conditional branch that tests a single argument.
-void MethodBuilder::EncodeBranch(art::Instruction::Code op, const Instruction& instruction) {
+void MethodBuilder::EncodeBranch(::dex::Opcode op, const Instruction& instruction) {
const auto& args = instruction.args();
const auto& test_value = args[0];
const auto& branch_target = args[1];
@@ -546,7 +551,7 @@ void MethodBuilder::EncodeNew(const Instruction& instruction) {
const Value& type = instruction.args()[0];
CHECK_LT(RegisterValue(*instruction.dest()), 256);
CHECK(type.is_type());
- Encode21c(::art::Instruction::NEW_INSTANCE, RegisterValue(*instruction.dest()), type.value());
+ Encode21c(::dex::Opcode::OP_NEW_INSTANCE, RegisterValue(*instruction.dest()), type.value());
}
void MethodBuilder::EncodeCast(const Instruction& instruction) {
@@ -558,7 +563,7 @@ void MethodBuilder::EncodeCast(const Instruction& instruction) {
const Value& type = instruction.args()[0];
CHECK_LT(RegisterValue(*instruction.dest()), 256);
CHECK(type.is_type());
- Encode21c(::art::Instruction::CHECK_CAST, RegisterValue(*instruction.dest()), type.value());
+ Encode21c(::dex::Opcode::OP_CHECK_CAST, RegisterValue(*instruction.dest()), type.value());
}
void MethodBuilder::EncodeFieldOp(const Instruction& instruction) {
@@ -569,7 +574,7 @@ void MethodBuilder::EncodeFieldOp(const Instruction& instruction) {
CHECK(instruction.dest()->is_variable());
CHECK_EQ(0, instruction.args().size());
- Encode21c(::art::Instruction::SGET,
+ Encode21c(::dex::Opcode::OP_SGET,
RegisterValue(*instruction.dest()),
instruction.index_argument());
break;
@@ -579,7 +584,7 @@ void MethodBuilder::EncodeFieldOp(const Instruction& instruction) {
CHECK_EQ(1, args.size());
CHECK(args[0].is_variable());
- Encode21c(::art::Instruction::SPUT, RegisterValue(args[0]), instruction.index_argument());
+ Encode21c(::dex::Opcode::OP_SPUT, RegisterValue(args[0]), instruction.index_argument());
break;
}
case Instruction::Op::kGetInstanceField: {
@@ -587,7 +592,7 @@ void MethodBuilder::EncodeFieldOp(const Instruction& instruction) {
CHECK(instruction.dest()->is_variable());
CHECK_EQ(1, instruction.args().size());
- Encode22c(::art::Instruction::IGET,
+ Encode22c(::dex::Opcode::OP_IGET,
RegisterValue(*instruction.dest()),
RegisterValue(args[0]),
instruction.index_argument());
@@ -599,7 +604,7 @@ void MethodBuilder::EncodeFieldOp(const Instruction& instruction) {
CHECK(args[0].is_variable());
CHECK(args[1].is_variable());
- Encode22c(::art::Instruction::IPUT,
+ Encode22c(::dex::Opcode::OP_IPUT,
RegisterValue(args[1]),
RegisterValue(args[0]),
instruction.index_argument());