1 /*
2 * Copyright (c) 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 #include "ecmascript/compiler/gate_accessor.h"
16 #include "ecmascript/compiler/verifier.h"
17 #include "ecmascript/compiler/ts_type_lowering.h"
18 #include "ecmascript/compiler/type_lowering.h"
19 #include "ecmascript/mem/native_area_allocator.h"
20 #include "ecmascript/tests/test_helper.h"
21
22 namespace panda::test {
23 class LoweringRelateGateTests : public testing::Test {
24 };
25 using ecmascript::GlobalEnvConstants;
26 using ecmascript::ConstantIndex;
27 using ecmascript::RegionSpaceFlag;
28 using ecmascript::kungfu::Circuit;
29 using ecmascript::kungfu::GateAccessor;
30 using ecmascript::kungfu::OpCode;
31 using ecmascript::kungfu::GateType;
32 using ecmascript::kungfu::MachineType;
33 using ecmascript::kungfu::CircuitBuilder;
34 using ecmascript::kungfu::Verifier;
35 using ecmascript::kungfu::TypedBinOp;
36 using ecmascript::kungfu::Label;
37 using ecmascript::kungfu::Variable;
38 using ecmascript::kungfu::VariableType;
39 using ecmascript::kungfu::Environment;
40 using ecmascript::kungfu::TypeLowering;
41 using ecmascript::kungfu::TSTypeLowering;
42 using ecmascript::kungfu::CompilationConfig;
43
HWTEST_F_L0(LoweringRelateGateTests,TypeCheckFramework)44 HWTEST_F_L0(LoweringRelateGateTests, TypeCheckFramework)
45 {
46 // construct a circuit
47 ecmascript::NativeAreaAllocator allocator;
48 Circuit circuit(&allocator);
49 CircuitBuilder builder(&circuit);
50 GateAccessor acc(&circuit);
51 Environment env(1, &builder);
52 builder.SetEnvironment(&env);
53 auto depend = acc.GetDependRoot();
54 auto arg0 = builder.Arguments(0);
55 auto pcGate = circuit.GetConstantGate(MachineType::I64, 0, GateType::NJSValue());
56 auto frameState = circuit.NewGate(circuit.FrameState(1), {pcGate});
57 auto stateSplit = circuit.NewGate(circuit.StateSplit(), {depend, frameState});
58 builder.SetDepend(stateSplit);
59 auto check = builder.PrimitiveTypeCheck(GateType::NumberType(), arg0);
60 builder.ReturnVoid(check, depend);
61
62 CompilationConfig config("x86_64-unknown-linux-gnu", false);
63 TypeLowering typeLowering(&circuit, &config, nullptr, false, "TypeCheckFramework");
64 typeLowering.RunTypeLowering();
65 EXPECT_TRUE(Verifier::Run(&circuit));
66 }
67
HWTEST_F_L0(LoweringRelateGateTests,TypedBinaryOperatorAddFramework)68 HWTEST_F_L0(LoweringRelateGateTests, TypedBinaryOperatorAddFramework)
69 {
70 // construct a circuit
71 ecmascript::NativeAreaAllocator allocator;
72 Circuit circuit(&allocator);
73 CircuitBuilder builder(&circuit);
74 GateAccessor acc(&circuit);
75 auto entry = acc.GetStateRoot();
76 auto depend = acc.GetDependRoot();
77 auto arg0 = builder.Arguments(0);
78 auto arg1 = builder.Arguments(1);
79 auto nadd = builder.TypedBinaryOperator(MachineType::I64, TypedBinOp::TYPED_ADD,
80 GateType::NumberType(), GateType::NumberType(),
81 {entry, depend, arg0, arg1}, GateType::NumberType());
82 builder.Return(nadd, nadd, nadd);
83 EXPECT_TRUE(Verifier::Run(&circuit));
84 CompilationConfig config("x86_64-unknown-linux-gnu", false);
85 TypeLowering typeLowering(&circuit, &config, nullptr, false, "TypedBinaryOperatorAddFramework");
86 typeLowering.RunTypeLowering();
87 EXPECT_TRUE(Verifier::Run(&circuit));
88 }
89
HWTEST_F_L0(LoweringRelateGateTests,TypedBinaryOperatorLessFramework)90 HWTEST_F_L0(LoweringRelateGateTests, TypedBinaryOperatorLessFramework)
91 {
92 // construct a circuit
93 ecmascript::NativeAreaAllocator allocator;
94 Circuit circuit(&allocator);
95 CircuitBuilder builder(&circuit);
96 GateAccessor acc(&circuit);
97 auto entry = acc.GetStateRoot();
98 auto depend = acc.GetDependRoot();
99 auto arg0 = builder.Arguments(0);
100 auto arg1 = builder.Arguments(1);
101 auto nless = builder.TypedBinaryOperator(MachineType::I64, TypedBinOp::TYPED_LESS,
102 GateType::NumberType(), GateType::NumberType(),
103 {entry, depend, arg0, arg1}, GateType::BooleanType());
104 builder.Return(nless, nless, nless);
105 EXPECT_TRUE(Verifier::Run(&circuit));
106 CompilationConfig config("x86_64-unknown-linux-gnu", false);
107 TypeLowering typeLowering(&circuit, &config, nullptr, false, "TypedBinaryOperatorLessFramework");
108 typeLowering.RunTypeLowering();
109 EXPECT_TRUE(Verifier::Run(&circuit));
110 }
111
HWTEST_F_L0(LoweringRelateGateTests,TypeConvertFramework)112 HWTEST_F_L0(LoweringRelateGateTests, TypeConvertFramework)
113 {
114 // construct a circuit
115 ecmascript::NativeAreaAllocator allocator;
116 Circuit circuit(&allocator);
117 CircuitBuilder builder(&circuit);
118 GateAccessor acc(&circuit);
119 auto entry = acc.GetStateRoot();
120 auto depend = acc.GetDependRoot();
121 auto arg0 = builder.Arguments(0);
122 auto convert = builder.TypeConvert(MachineType::I64, GateType::NJSValue(), GateType::NumberType(),
123 {entry, depend, arg0});
124 builder.Return(convert, convert, convert);
125 EXPECT_TRUE(Verifier::Run(&circuit));
126 CompilationConfig config("x86_64-unknown-linux-gnu", false);
127 TypeLowering typeLowering(&circuit, &config, nullptr, false, "TypeConvertFramework");
128 typeLowering.RunTypeLowering();
129 EXPECT_TRUE(Verifier::Run(&circuit));
130 }
131
HWTEST_F_L0(LoweringRelateGateTests,TypeOpCodeFramework)132 HWTEST_F_L0(LoweringRelateGateTests, TypeOpCodeFramework)
133 {
134 // construct a circuit
135 ecmascript::NativeAreaAllocator allocator;
136 Circuit circuit(&allocator);
137 CircuitBuilder builder(&circuit);
138 GateAccessor acc(&circuit);
139 Environment env(2, &builder);
140 builder.SetEnvironment(&env);
141 VariableType arg1Type(MachineType::I64, GateType::BooleanType());
142 CompilationConfig config("x86_64-unknown-linux-gnu", false);
143 TypeLowering typeLowering(&circuit, &config, nullptr, false, "TypeOpCodeFramework");
144 auto depend = acc.GetDependRoot();
145 auto arg0 = builder.Arguments(0);
146 auto arg1 = builder.Arguments(1);
147 auto pcGate = circuit.GetConstantGate(MachineType::I64, 0, GateType::NJSValue());
148 auto frameState = circuit.NewGate(circuit.FrameState(1), {pcGate});
149 auto stateSplit = circuit.NewGate(circuit.StateSplit(), {depend, frameState});
150 builder.SetDepend(stateSplit);
151 builder.PrimitiveTypeCheck(GateType::NumberType(), arg0);
152 auto convert = builder.PrimitiveToNumber(arg1, arg1Type);
153 auto result = builder.NumberBinaryOp<TypedBinOp::TYPED_ADD>(arg0, convert);
154 builder.Return(result);
155 typeLowering.RunTypeLowering();
156 EXPECT_TRUE(Verifier::Run(&circuit));
157 }
158
HWTEST_F_L0(LoweringRelateGateTests,HeapAllocTest)159 HWTEST_F_L0(LoweringRelateGateTests, HeapAllocTest)
160 {
161 // construct a circuit
162 ecmascript::NativeAreaAllocator allocator;
163 Circuit circuit(&allocator);
164 CircuitBuilder builder(&circuit);
165 Environment env(0, &builder);
166 builder.SetEnvironment(&env);
167 auto glue = builder.Arguments(0);
168 auto arg0 = builder.Arguments(1);
169 auto arg1 = builder.Arguments(2);
170 auto array = builder.HeapAlloc(arg0, GateType::AnyType(), RegionSpaceFlag::IN_YOUNG_SPACE);
171
172 auto offset = builder.Int64(JSThread::GlueData::GetGlueGlobalConstOffset(false));
173 auto globalEnv = builder.Load(VariableType::JS_POINTER(), glue, offset);
174 auto lenthOffset = builder.IntPtr(GlobalEnvConstants::GetOffsetOfLengthString());
175 auto lengthString = builder.Load(VariableType::JS_POINTER(), globalEnv, lenthOffset);
176
177 builder.Store(VariableType::JS_POINTER(), glue, array, builder.IntPtr(0), arg1);
178 builder.StoreElement<ecmascript::kungfu::TypedStoreOp::FLOAT32ARRAY_STORE_ELEMENT>(array, builder.IntPtr(0),
179 builder.ToTaggedInt(builder.Int64(0)));
180 builder.StoreElement<ecmascript::kungfu::TypedStoreOp::FLOAT32ARRAY_STORE_ELEMENT>(array, builder.IntPtr(1),
181 builder.ToTaggedInt(builder.Int64(1)));
182 builder.StoreProperty(array, lengthString, builder.ToTaggedInt(builder.Int64(2)));
183 auto length = builder.LoadProperty(array, lengthString);
184 Label less2(&builder);
185 Label notLess2(&builder);
186 auto condtion = builder.TaggedIsTrue(builder.NumberBinaryOp<TypedBinOp::TYPED_LESS>(length,
187 builder.ToTaggedInt(builder.Int64(2))));
188 builder.Branch(condtion, &less2, ¬Less2);
189 builder.Bind(&less2);
190 auto ret =
191 builder.LoadElement<ecmascript::kungfu::TypedLoadOp::FLOAT32ARRAY_LOAD_ELEMENT>(array, builder.IntPtr(1));
192 builder.Return(ret);
193 builder.Bind(¬Less2);
194 builder.Return(builder.Int64(-1));
195 EXPECT_TRUE(Verifier::Run(&circuit));
196 }
197 } // namespace panda::test