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
16 #include "assembler/assembly-emitter.h"
17 #include "assembler/assembly-parser.h"
18 #include "libpandafile/class_data_accessor-inl.h"
19
20 #include "ecmascript/global_env.h"
21 #include "ecmascript/jspandafile/js_pandafile.h"
22 #include "ecmascript/jspandafile/js_pandafile_executor.h"
23 #include "ecmascript/jspandafile/js_pandafile_manager.h"
24 #include "ecmascript/jspandafile/program_object.h"
25 #include "ecmascript/tests/test_helper.h"
26
27 using namespace panda::ecmascript;
28 using namespace panda::panda_file;
29 using namespace panda::pandasm;
30
31 namespace panda::test {
32 class JSPandaFileExecutorTest : public testing::Test {
33 public:
SetUpTestCase()34 static void SetUpTestCase()
35 {
36 GTEST_LOG_(INFO) << "SetUpTestCase";
37 }
38
TearDownTestCase()39 static void TearDownTestCase()
40 {
41 GTEST_LOG_(INFO) << "TearDownCase";
42 }
43
SetUp()44 void SetUp() override
45 {
46 TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
47 }
48
TearDown()49 void TearDown() override
50 {
51 TestHelper::DestroyEcmaVMWithScope(instance, scope);
52 }
53
54 EcmaVM *instance {nullptr};
55 EcmaHandleScope *scope {nullptr};
56 JSThread *thread {nullptr};
57 };
58
HWTEST_F_L0(JSPandaFileExecutorTest,Execute)59 HWTEST_F_L0(JSPandaFileExecutorTest, Execute)
60 {
61 const char *fileName = "__JSPandaFileExecutorTest1.abc";
62 const char *data = R"(
63 .language ECMAScript
64 .function any func_main_0(any a0, any a1, any a2) {
65 ldai 1
66 return
67 }
68 )";
69 JSPandaFileManager *pfManager = JSPandaFileManager::GetInstance();
70 Parser parser;
71 auto res = parser.Parse(data);
72 std::unique_ptr<const File> pfPtr = pandasm::AsmEmitter::Emit(res.Value());
73 JSPandaFile *pf = pfManager->NewJSPandaFile(pfPtr.release(), CString(fileName));
74 const uint8_t *typeDesc = utf::CStringAsMutf8("L_GLOBAL;");
75 const File *file = pf->GetPandaFile();
76 File::EntityId class_id = file->GetClassId(typeDesc);
77 ClassDataAccessor cda(*file, class_id);
78 std::vector<File::EntityId> methodId {};
79 cda.EnumerateMethods([&](panda_file::MethodDataAccessor &mda) {
80 methodId.push_back(mda.GetMethodId());
81 });
82 pf->UpdateMainMethodIndex(methodId[0].GetOffset());
83 MethodLiteral method(pf, methodId[0]);
84 pf->SetMethodLiteralToMap(&method);
85 pfManager->InsertJSPandaFile(pf);
86 Expected<JSTaggedValue, bool> result = JSPandaFileExecutor::Execute(thread, pf, JSPandaFile::ENTRY_MAIN_FUNCTION);
87 EXPECT_TRUE(result);
88 EXPECT_EQ(result.Value(), JSTaggedValue::Hole());
89
90 pfManager->RemoveJSPandaFile((void *)pf);
91 }
92
HWTEST_F_L0(JSPandaFileExecutorTest,ExecuteFromFile)93 HWTEST_F_L0(JSPandaFileExecutorTest, ExecuteFromFile)
94 {
95 const char *fileName = "__JSPandaFileExecutorTest2.abc";
96 const char *data = R"(
97 .language ECMAScript
98 .function any func_main_0(any a0, any a1, any a2) {
99 ldai 1
100 return
101 }
102 )";
103 JSPandaFileManager *pfManager = JSPandaFileManager::GetInstance();
104 Parser parser;
105 auto res = parser.Parse(data);
106 std::unique_ptr<const File> pfPtr = pandasm::AsmEmitter::Emit(res.Value());
107 JSPandaFile *pf = pfManager->NewJSPandaFile(pfPtr.release(), CString(fileName));
108 const uint8_t *typeDesc = utf::CStringAsMutf8("L_GLOBAL;");
109 const File *file = pf->GetPandaFile();
110 File::EntityId class_id = file->GetClassId(typeDesc);
111 ClassDataAccessor cda(*file, class_id);
112 std::vector<File::EntityId> methodId {};
113 cda.EnumerateMethods([&](panda_file::MethodDataAccessor &mda) {
114 methodId.push_back(mda.GetMethodId());
115 });
116 pf->UpdateMainMethodIndex(methodId[0].GetOffset());
117 MethodLiteral method(pf, methodId[0]);
118 pf->SetMethodLiteralToMap(&method);
119 pfManager->InsertJSPandaFile(pf);
120 Expected<JSTaggedValue, bool> result =
121 JSPandaFileExecutor::ExecuteFromFile(thread, CString(fileName), JSPandaFile::ENTRY_MAIN_FUNCTION);
122 EXPECT_TRUE(result);
123 EXPECT_EQ(result.Value(), JSTaggedValue::Hole());
124
125 pfManager->RemoveJSPandaFile((void *)pf);
126 const JSPandaFile *foundPf = pfManager->FindJSPandaFile(fileName);
127 pfManager->RemoveJSPandaFile((void *)foundPf);
128 }
129
HWTEST_F_L0(JSPandaFileExecutorTest,ExecuteFromBuffer)130 HWTEST_F_L0(JSPandaFileExecutorTest, ExecuteFromBuffer)
131 {
132 const char *fileName = "__JSPandaFileExecutorTest2.abc";
133 const char *data = R"(
134 .language ECMAScript
135 .function any func_main_0(any a0, any a1, any a2) {
136 ldai 1
137 return
138 }
139 )";
140 JSPandaFileManager *pfManager = JSPandaFileManager::GetInstance();
141 Parser parser;
142 auto res = parser.Parse(data);
143 std::unique_ptr<const File> pfPtr = pandasm::AsmEmitter::Emit(res.Value());
144 JSPandaFile *pf = pfManager->NewJSPandaFile(pfPtr.release(), CString(fileName));
145 const uint8_t *typeDesc = utf::CStringAsMutf8("L_GLOBAL;");
146 const File *file = pf->GetPandaFile();
147 File::EntityId class_id = file->GetClassId(typeDesc);
148 ClassDataAccessor cda(*file, class_id);
149 std::vector<File::EntityId> methodId {};
150 cda.EnumerateMethods([&](panda_file::MethodDataAccessor &mda) {
151 methodId.push_back(mda.GetMethodId());
152 });
153 pf->UpdateMainMethodIndex(methodId[0].GetOffset());
154 MethodLiteral method(pf, methodId[0]);
155 pf->SetMethodLiteralToMap(&method);
156 pfManager->InsertJSPandaFile(pf);
157 Expected<JSTaggedValue, bool> result = JSPandaFileExecutor::ExecuteFromBuffer(
158 thread, (void *)data, sizeof(data), JSPandaFile::ENTRY_MAIN_FUNCTION, CString(fileName));
159 EXPECT_TRUE(result);
160 EXPECT_EQ(result.Value(), JSTaggedValue::Hole());
161
162 pfManager->RemoveJSPandaFile((void *)pf);
163 const JSPandaFile *foundPf = pfManager->FindJSPandaFile(fileName);
164 pfManager->RemoveJSPandaFile((void *)foundPf);
165 }
166 } // namespace panda::test
167