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 COMPILER_OPTIMIZER_IR_BUILDER_INST_BUILDER_INL_H
17 #define COMPILER_OPTIMIZER_IR_BUILDER_INST_BUILDER_INL_H
18
19 #include "inst_builder.h"
20
21 namespace panda::compiler {
22 // NOLINTNEXTLINE(misc-definitions-in-headers)
23 // NOLINTNEXTLINE(misc-definitions-in-headers)
24 template <Opcode opcode>
BuildLoadFromPool(const BytecodeInstruction * bc_inst)25 void InstBuilder::BuildLoadFromPool(const BytecodeInstruction *bc_inst)
26 {
27 auto method = GetGraph()->GetMethod();
28 uint32_t type_id;
29 // Create SaveState instruction
30 auto save_state = CreateSaveState(Opcode::SaveState, GetPc(bc_inst->GetAddress()));
31 LoadFromPool *inst;
32 // NOLINTNEXTLINE(readability-magic-numbers)
33 static_assert(opcode == Opcode::LoadString);
34 type_id = GetRuntime()->ResolveOffsetByIndex(GetGraph()->GetMethod(), bc_inst->GetId(0).AsIndex());
35 inst = GetGraph()->CreateInstLoadString(DataType::REFERENCE, GetPc(bc_inst->GetAddress()));
36 inst->SetTypeId(type_id);
37 inst->SetMethod(method);
38 inst->SetInput(0, save_state);
39
40 AddInstruction(save_state);
41 AddInstruction(inst);
42 UpdateDefinitionAcc(inst);
43 BuildCastToAnyString(bc_inst);
44 }
45
46 // NOLINTNEXTLINE(misc-definitions-in-headers)
BuildCastToAnyString(const BytecodeInstruction * bc_inst)47 void InstBuilder::BuildCastToAnyString(const BytecodeInstruction *bc_inst)
48 {
49 auto input = GetDefinitionAcc();
50 ASSERT(input->GetType() == DataType::REFERENCE);
51
52 auto language = GetRuntime()->GetMethodSourceLanguage(GetMethod());
53 auto any_type = GetAnyStringType(language);
54 ASSERT(any_type != AnyBaseType::UNDEFINED_TYPE);
55
56 auto box = graph_->CreateInstCastValueToAnyType(GetPc(bc_inst->GetAddress()));
57 box->SetAnyType(any_type);
58 box->SetInput(0, input);
59 UpdateDefinitionAcc(box);
60 AddInstruction(box);
61 }
62
63 // NOLINTNEXTLINE(misc-definitions-in-headers)
BuildCastToAnyNumber(const BytecodeInstruction * bc_inst)64 void InstBuilder::BuildCastToAnyNumber(const BytecodeInstruction *bc_inst)
65 {
66 auto input = GetDefinitionAcc();
67 auto type = input->GetType();
68
69 if (input->IsConst() && !DataType::IsFloatType(type)) {
70 auto const_insn = input->CastToConstant();
71 if (const_insn->GetType() == DataType::INT64) {
72 auto value = input->CastToConstant()->GetInt64Value();
73 if (value == static_cast<uint32_t>(value)) {
74 type = DataType::INT32;
75 }
76 }
77 }
78
79 auto language = GetRuntime()->GetMethodSourceLanguage(GetMethod());
80 auto any_type = NumericDataTypeToAnyType(type, language);
81 ASSERT(any_type != AnyBaseType::UNDEFINED_TYPE);
82
83 auto box = graph_->CreateInstCastValueToAnyType(GetPc(bc_inst->GetAddress()));
84 box->SetAnyType(any_type);
85 box->SetInput(0, input);
86 UpdateDefinitionAcc(box);
87 AddInstruction(box);
88 }
89
90 } // namespace panda::compiler
91
92 #endif // COMPILER_OPTIMIZER_IR_BUILDER_INST_BUILDER_INL_H
93