• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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