diff --git a/ets2panda/compiler/core/ETSCompiler.cpp b/ets2panda/compiler/core/ETSCompiler.cpp index 770c3326900a8615bf5d71c8de4828e64c955ca8..d90757510ef7416f910d0cca1615854c38f3cded 100644 --- a/ets2panda/compiler/core/ETSCompiler.cpp +++ b/ets2panda/compiler/core/ETSCompiler.cpp @@ -1085,23 +1085,70 @@ static bool CompileComputed(compiler::ETSGen *etsg, const ir::MemberExpression * void ETSCompiler::Compile(const ir::MemberExpression *expr) const { ETSGen *etsg = GetETSGen(); - auto lambda = etsg->VarBinder()->LambdaObjects().find(expr); - if (lambda != etsg->VarBinder()->LambdaObjects().end()) { - etsg->CreateLambdaObjectFromMemberReference(expr, expr->object_, lambda->second.first); - etsg->SetAccumulatorType(expr->TsType()); + + if (HandleLambdaObject(expr, etsg)) { return; } compiler::RegScope rs(etsg); - auto *const objectType = etsg->Checker()->GetApparentType(expr->Object()->TsType()); - if (CompileComputed(etsg, expr)) { return; } + if (HandleArrayTypeLengthProperty(expr, etsg)) { + return; + } + + if (HandleEnumTypes(expr, etsg)) { + return; + } + + if (HandleStaticProperties(expr, etsg)) { + return; + } + + auto *const objectType = etsg->Checker()->GetApparentType(expr->Object()->TsType()); auto &propName = expr->Property()->AsIdentifier()->Name(); + auto ottctx = compiler::TargetTypeContext(etsg, expr->Object()->TsType()); + etsg->CompileAndCheck(expr->Object()); + + etsg->ApplyConversion(expr->Object()); + compiler::VReg objReg = etsg->AllocReg(); + etsg->StoreAccumulator(expr, objReg); + + auto ttctx = compiler::TargetTypeContext(etsg, expr->TsType()); + + if (expr->PropVar()->TsType()->HasTypeFlag(checker::TypeFlag::GETTER_SETTER)) { + checker::Signature *sig = expr->PropVar()->TsType()->AsETSFunctionType()->FindGetter(); + etsg->CallThisVirtual0(expr, objReg, sig->InternalName()); + } else if (objectType->IsETSDynamicType()) { + etsg->LoadPropertyDynamic(expr, expr->TsType(), objReg, propName); + } else if (objectType->IsETSUnionType()) { + etsg->LoadUnionProperty(expr, expr->TsType(), objReg, propName); + } else { + const auto fullName = etsg->FormClassPropReference(objectType->AsETSObjectType(), propName); + etsg->LoadProperty(expr, expr->TsType(), objReg, fullName); + } + etsg->GuardUncheckedType(expr, expr->UncheckedType(), expr->TsType()); +} + +bool ETSCompiler::HandleLambdaObject(const ir::MemberExpression *expr, ETSGen *etsg) const +{ + auto lambda = etsg->VarBinder()->LambdaObjects().find(expr); + if (lambda != etsg->VarBinder()->LambdaObjects().end()) { + etsg->CreateLambdaObjectFromMemberReference(expr, expr->object_, lambda->second.first); + etsg->SetAccumulatorType(expr->TsType()); + return true; + } + return false; +} + +bool ETSCompiler::HandleArrayTypeLengthProperty(const ir::MemberExpression *expr, ETSGen *etsg) const +{ + auto *const objectType = etsg->Checker()->GetApparentType(expr->Object()->TsType()); + auto &propName = expr->Property()->AsIdentifier()->Name(); if (objectType->IsETSArrayType() && propName.Is("length")) { auto ottctx = compiler::TargetTypeContext(etsg, objectType); etsg->CompileAndCheck(expr->Object()); @@ -1112,9 +1159,14 @@ void ETSCompiler::Compile(const ir::MemberExpression *expr) const auto ttctx = compiler::TargetTypeContext(etsg, expr->TsType()); etsg->LoadArrayLength(expr, objReg); etsg->ApplyConversion(expr, expr->TsType()); - return; + return true; } + return false; +} +bool ETSCompiler::HandleEnumTypes(const ir::MemberExpression *expr, ETSGen *etsg) const +{ + auto *const objectType = etsg->Checker()->GetApparentType(expr->Object()->TsType()); if (objectType->IsETSEnumType() || objectType->IsETSStringEnumType()) { auto const *const enumInterface = [objectType, expr]() -> checker::ETSEnumInterface const * { if (objectType->IsETSEnumType()) { @@ -1125,9 +1177,14 @@ void ETSCompiler::Compile(const ir::MemberExpression *expr) const auto ttctx = compiler::TargetTypeContext(etsg, expr->TsType()); etsg->LoadAccumulatorInt(expr, enumInterface->GetOrdinal()); - return; + return true; } + return false; +} +bool ETSCompiler::HandleStaticProperties(const ir::MemberExpression *expr, ETSGen *etsg) const +{ + auto &propName = expr->Property()->AsIdentifier()->Name(); if (etsg->Checker()->IsVariableStatic(expr->PropVar())) { auto ttctx = compiler::TargetTypeContext(etsg, expr->TsType()); @@ -1135,35 +1192,14 @@ void ETSCompiler::Compile(const ir::MemberExpression *expr) const checker::Signature *sig = expr->PropVar()->TsType()->AsETSFunctionType()->FindGetter(); etsg->CallStatic0(expr, sig->InternalName()); etsg->SetAccumulatorType(expr->TsType()); - return; + return true; } util::StringView fullName = etsg->FormClassPropReference(expr->Object()->TsType()->AsETSObjectType(), propName); etsg->LoadStaticProperty(expr, expr->TsType(), fullName); - return; + return true; } - - auto ottctx = compiler::TargetTypeContext(etsg, expr->Object()->TsType()); - etsg->CompileAndCheck(expr->Object()); - - etsg->ApplyConversion(expr->Object()); - compiler::VReg objReg = etsg->AllocReg(); - etsg->StoreAccumulator(expr, objReg); - - auto ttctx = compiler::TargetTypeContext(etsg, expr->TsType()); - - if (expr->PropVar()->TsType()->HasTypeFlag(checker::TypeFlag::GETTER_SETTER)) { - checker::Signature *sig = expr->PropVar()->TsType()->AsETSFunctionType()->FindGetter(); - etsg->CallThisVirtual0(expr, objReg, sig->InternalName()); - } else if (objectType->IsETSDynamicType()) { - etsg->LoadPropertyDynamic(expr, expr->TsType(), objReg, propName); - } else if (objectType->IsETSUnionType()) { - etsg->LoadUnionProperty(expr, expr->TsType(), objReg, propName); - } else { - const auto fullName = etsg->FormClassPropReference(objectType->AsETSObjectType(), propName); - etsg->LoadProperty(expr, expr->TsType(), objReg, fullName); - } - etsg->GuardUncheckedType(expr, expr->UncheckedType(), expr->TsType()); + return false; } void ETSCompiler::Compile([[maybe_unused]] const ir::NewExpression *expr) const diff --git a/ets2panda/compiler/core/ETSCompiler.h b/ets2panda/compiler/core/ETSCompiler.h index d7efc115934bb3b0bc484fc330cebb3959a41f36..65749152ead1838ea9c54d560060881af6c6844c 100644 --- a/ets2panda/compiler/core/ETSCompiler.h +++ b/ets2panda/compiler/core/ETSCompiler.h @@ -41,6 +41,10 @@ private: void CompileCast(const ir::TSAsExpression *expr) const; void EmitCall(const ir::CallExpression *expr, compiler::VReg &calleeReg, bool isStatic, checker::Signature *signature, bool isReference) const; + bool HandleLambdaObject(const ir::MemberExpression *expr, ETSGen *etsg) const; + bool HandleArrayTypeLengthProperty(const ir::MemberExpression *expr, ETSGen *etsg) const; + bool HandleEnumTypes(const ir::MemberExpression *expr, ETSGen *etsg) const; + bool HandleStaticProperties(const ir::MemberExpression *expr, ETSGen *etsg) const; ETSGen *GetETSGen() const; };