Decouple generating TSHClasses from parsing TSTypes

In the process of parsing one TSType (at that point the TSType has not yet been generated),
if we try to get it to do something, then the program crashes. We need to fix it.

Issue:
https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I6FP5J

Tests:
typeinfer test, aot test

Change-Id: I319cdfcc2a072450a4925eb15e51bf1fba4d7ce8
Signed-off-by: huoqingyi <huoqingyi@huawei.com>
This commit is contained in:
huoqingyi 2023-02-17 00:07:46 +08:00
parent fd5b688455
commit ca9bc147eb
9 changed files with 93 additions and 21 deletions

View File

@ -30,6 +30,7 @@ TypeRecorder::TypeRecorder(const JSPandaFile *jsPandaFile, const MethodLiteral *
return;
}
LoadTypes(jsPandaFile, methodLiteral, tsManager, recordName);
tsManager->GenerateTSHClasses();
}
void TypeRecorder::LoadTypes(const JSPandaFile *jsPandaFile, const MethodLiteral *methodLiteral,

View File

@ -653,13 +653,33 @@ void TSManager::GenerateTSHClass(JSHandle<TSClassType> classType)
gtIhcMap_.insert({gt, IHClassData(JSTaggedValue(ihc).GetRawData())});
}
void TSManager::GenerateTSHClasses()
{
for (const auto &gt : collectedTypeOffsets_) {
JSHandle<JSTaggedValue> tsType = GetTSType(gt);
if (tsType->IsUndefined()) {
continue;
}
ASSERT(tsType->IsTSClassType());
JSHandle<TSClassType> classType(tsType);
if (!classType->GetHasLinked()) {
RecursivelyMergeClassField(classType);
}
if (IsUserDefinedClassTypeKind(gt)) {
GenerateTSHClass(classType);
}
}
collectedTypeOffsets_.clear();
}
JSHandle<JSTaggedValue> TSManager::GetTSType(const GlobalTSTypeRef &gt) const
{
uint32_t moduleId = gt.GetModuleId();
uint32_t localId = gt.GetLocalId();
if (moduleId == TSModuleTable::BUILTINS_TABLE_ID && !IsBuiltinsDTSEnabled()) {
return JSHandle<JSTaggedValue>(thread_, JSTaggedValue::Undefined());
if ((moduleId == TSModuleTable::BUILTINS_TABLE_ID && !IsBuiltinsDTSEnabled()) ||
(moduleId == TSModuleTable::PRIMITIVE_TABLE_ID)) {
return thread_->GlobalConstants()->GetHandledUndefined();
}
JSHandle<TSModuleTable> mTable = GetTSModuleTable();

View File

@ -365,6 +365,8 @@ public:
void GenerateTSHClass(JSHandle<TSClassType> classType);
void GenerateTSHClasses();
JSHandle<JSTaggedValue> GetTSType(const GlobalTSTypeRef &gt) const;
std::string PUBLIC_API GetTypeStr(kungfu::GateType gateType) const;
@ -648,6 +650,13 @@ public:
return name;
}
inline void CollectTypeOffsets(GlobalTSTypeRef classGT)
{
if (IsClassTypeKind(classGT)) {
collectedTypeOffsets_.insert(classGT);
}
}
private:
NO_COPY_SEMANTIC(TSManager);
NO_MOVE_SEMANTIC(TSManager);
@ -735,6 +744,7 @@ private:
CString builtinsRecordName_ {""};
std::map<LocalModuleInfo, GlobalTSTypeRef> localModuleVarGtMap_{};
kungfu::CompilationDriver *cmpDriver_ {nullptr};
std::set<GlobalTSTypeRef> collectedTypeOffsets_ {}; // use for storing types that need to generate hclasses
friend class EcmaVM;

View File

@ -355,7 +355,9 @@ GlobalTSTypeRef TSInterfaceType::GetPropTypeGT(JSThread *thread, JSHandle<TSInte
uint32_t gtRawData = static_cast<uint32_t>(extendsValue.GetInt());
GlobalTSTypeRef extendsGT = GlobalTSTypeRef(gtRawData);
JSHandle<JSTaggedValue> extendsType = tsManager->GetTSType(extendsGT);
if (extendsType->IsUndefined()) {
return GlobalTSTypeRef::Default();
}
ASSERT(extendsType->IsTSType());
if (extendsType->IsTSClassType()) {

View File

@ -72,8 +72,7 @@ GlobalTSTypeRef TSTypeParser::ParseType(const JSPandaFile *jsPandaFile, const CS
GlobalTSTypeRef gt = GetGT(jsPandaFile, table, moduleId, typeId, recordName);
JSHandle<JSTaggedValue> type = ParseNonImportType(jsPandaFile, recordName, literal, kind, typeId);
SetTSType(table, type, gt);
GenerateTSHClass(type);
tsManager_->CollectTypeOffsets(gt); // collect types that need to generate hclasses
return gt;
}
@ -396,20 +395,6 @@ void TSTypeParser::FillInterfaceMethodTypes(const JSPandaFile *jsPandaFile, cons
}
}
void TSTypeParser::GenerateTSHClass(JSHandle<JSTaggedValue> type)
{
if (type->IsTSClassType()) {
JSHandle<TSClassType> classType(type);
if (!classType->GetHasLinked()) {
tsManager_->RecursivelyMergeClassField(classType);
}
auto gt = classType->GetGT();
if (tsManager_->IsUserDefinedClassTypeKind(gt)) {
tsManager_->GenerateTSHClass(classType);
}
}
}
JSHandle<TaggedArray> TSTypeParser::GetExportDataFromRecord(const JSPandaFile *jsPandaFile,
const CString &recordName)
{

View File

@ -102,8 +102,6 @@ private:
uint32_t startIndex, uint32_t lastIndex,
uint32_t &index);
void GenerateTSHClass(JSHandle<JSTaggedValue> type);
JSHandle<TaggedArray> GetExportDataFromRecord(const JSPandaFile *jsPandaFile, const CString &recordName);
JSHandle<TaggedArray> GenerateExportTableFromRecord(const JSPandaFile *jsPandaFile, const CString &recordName);

View File

@ -92,6 +92,7 @@ group("ark_typeinfer_test") {
"stlettoglobalrecord:stlettoglobalrecordAotTypeInferAction",
"sub2dyn:sub2dynAotTypeInferAction",
"supercall:supercallAotTypeInferAction",
"superclass:superclassAotTypeInferAction",
"throwdyn_1:throwdyn_1AotTypeInferAction",
"throwdyn_2:throwdyn_2AotTypeInferAction",
"tryldglobalbyname:tryldglobalbynameAotTypeInferAction",

View File

@ -0,0 +1,19 @@
# Copyright (c) 2023 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//arkcompiler/ets_runtime/test/test_helper.gni")
host_typeinfer_test_action("superclass") {
deps = []
is_disable_type_lowering = true
}

View File

@ -0,0 +1,36 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
declare function AssertType(value: any, type: string): void;
class A {
foo():B {
let v = new B();
AssertType(v, "B");
return v;
}
}
class B extends A {}
let a = new A();
let b = a.foo();
let c = new B();
let d = c.foo();
AssertType(a, "A");
AssertType(b, "B");
AssertType(c, "B");
AssertType(d, "B");