1 /**
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #ifndef PANDA_INST_BUILDER_INL_H
17 #define PANDA_INST_BUILDER_INL_H
18
19 #include "inst_builder.h"
20
21 namespace panda::compiler {
22 // NOLINTNEXTLINE(misc-definitions-in-headers)
BuildAnyTypeCheckInst(size_t bc_addr,Inst * input,Inst * save_state,AnyBaseType type)23 Inst *InstBuilder::BuildAnyTypeCheckInst(size_t bc_addr, Inst *input, Inst *save_state, AnyBaseType type)
24 {
25 auto any_check = graph_->CreateInstAnyTypeCheck(DataType::ANY, bc_addr);
26 any_check->SetInput(0, input);
27 any_check->SetInput(1, save_state);
28 any_check->SetAnyType(type);
29 AddInstruction(any_check);
30
31 return any_check;
32 }
33
34 // NOLINTNEXTLINE(misc-definitions-in-headers)
35 template <Opcode opcode>
BuildLoadFromPool(const BytecodeInstruction * bc_inst)36 void InstBuilder::BuildLoadFromPool(const BytecodeInstruction *bc_inst)
37 {
38 auto method = GetGraph()->GetMethod();
39 uint32_t type_id;
40 // Create SaveState instruction
41 auto save_state = CreateSaveState(Opcode::SaveState, GetPc(bc_inst->GetAddress()));
42 LoadFromPool *inst;
43 // NOLINTNEXTLINE(readability-magic-numbers,readability-braces-around-statements)
44 if constexpr (opcode == Opcode::LoadType) {
45 auto type_index = bc_inst->GetId(0).AsIndex();
46 type_id = GetRuntime()->ResolveTypeIndex(method, type_index);
47 if (GetRuntime()->ResolveType(method, type_id) == nullptr) {
48 inst = GetGraph()->CreateInstUnresolvedLoadType(DataType::REFERENCE, GetPc(bc_inst->GetAddress()));
49 if (!GetGraph()->IsAotMode() && !GetGraph()->IsBytecodeOptimizer()) {
50 GetRuntime()->GetUnresolvedTypes()->AddTableSlot(method, type_id,
51 UnresolvedTypesInterface::SlotKind::MANAGED_CLASS);
52 }
53 } else {
54 inst = GetGraph()->CreateInstLoadType(DataType::REFERENCE, GetPc(bc_inst->GetAddress()));
55 }
56 // NOLINTNEXTLINE(readability-misleading-indentation)
57 } else {
58 // NOLINTNEXTLINE(readability-magic-numbers)
59 static_assert(opcode == Opcode::LoadString);
60 type_id = GetRuntime()->ResolveOffsetByIndex(GetGraph()->GetMethod(), bc_inst->GetId(0).AsIndex());
61 inst = GetGraph()->CreateInstLoadString(DataType::REFERENCE, GetPc(bc_inst->GetAddress()));
62 }
63 inst->SetTypeId(type_id);
64 inst->SetMethod(method);
65 inst->SetInput(0, save_state);
66
67 AddInstruction(save_state);
68 AddInstruction(inst);
69 UpdateDefinitionAcc(inst);
70 // NOLINTNEXTLINE(readability-magic-numbers,readability-braces-around-statements,bugprone-suspicious-semicolon)
71 if constexpr (opcode == Opcode::LoadString) {
72 if (GetGraph()->IsDynamicMethod()) {
73 BuildCastToAnyString(bc_inst);
74 }
75 }
76 }
77
78 // NOLINTNEXTLINE(misc-definitions-in-headers)
BuildCastToAnyString(const BytecodeInstruction * bc_inst)79 void InstBuilder::BuildCastToAnyString(const BytecodeInstruction *bc_inst)
80 {
81 auto input = GetDefinitionAcc();
82 ASSERT(input->GetType() == DataType::REFERENCE);
83
84 auto language = GetRuntime()->GetMethodSourceLanguage(GetMethod());
85 auto any_type = GetAnyStringType(language);
86 ASSERT(any_type != AnyBaseType::UNDEFINED_TYPE);
87
88 auto box = graph_->CreateInstCastValueToAnyType(GetPc(bc_inst->GetAddress()));
89 box->SetAnyType(any_type);
90 box->SetInput(0, input);
91 UpdateDefinitionAcc(box);
92 AddInstruction(box);
93 }
94
95 // NOLINTNEXTLINE(misc-definitions-in-headers)
BuildCastToAnyNumber(const BytecodeInstruction * bc_inst)96 void InstBuilder::BuildCastToAnyNumber(const BytecodeInstruction *bc_inst)
97 {
98 auto input = GetDefinitionAcc();
99 auto type = input->GetType();
100
101 if (input->IsConst() && !DataType::IsFloatType(type)) {
102 auto const_insn = input->CastToConstant();
103 if (const_insn->GetType() == DataType::INT64) {
104 auto value = input->CastToConstant()->GetInt64Value();
105 if (value == static_cast<uint32_t>(value)) {
106 type = DataType::INT32;
107 }
108 }
109 }
110
111 auto language = GetRuntime()->GetMethodSourceLanguage(GetMethod());
112 auto any_type = NumericDataTypeToAnyType(type, language);
113 ASSERT(any_type != AnyBaseType::UNDEFINED_TYPE);
114
115 auto box = graph_->CreateInstCastValueToAnyType(GetPc(bc_inst->GetAddress()));
116 box->SetAnyType(any_type);
117 box->SetInput(0, input);
118 UpdateDefinitionAcc(box);
119 AddInstruction(box);
120 }
121
122 } // namespace panda::compiler
123
124 #endif // PANDA_INST_BUILDER_INL_H
125