From 03161c350f50eb9715d17fcdf5037424429dba49 Mon Sep 17 00:00:00 2001 From: hufeng Date: Thu, 11 Aug 2022 20:34:38 +0800 Subject: [PATCH] Generate record Signed-off-by: hufeng Change-Id: Iaf60bf742e474321822b1797ce89ee3b863b502b --- es2panda/aot/main.cpp | 3 ++- es2panda/aot/options.cpp | 7 +++++++ es2panda/aot/options.h | 6 ++++++ es2panda/binder/binder.cpp | 4 +++- es2panda/compiler/core/emitter/commonjs.cpp | 12 ++++-------- es2panda/compiler/core/emitter/emitter.cpp | 21 +++++++++++---------- es2panda/compiler/core/emitter/emitter.h | 5 ++++- es2panda/es2panda.cpp | 3 ++- es2panda/es2panda.h | 5 +++-- es2panda/parser/commonjs.cpp | 2 +- es2panda/parser/parserImpl.cpp | 14 ++++++++------ es2panda/parser/parserImpl.h | 9 +++++---- es2panda/parser/program/program.h | 11 +++++++++++ 13 files changed, 67 insertions(+), 35 deletions(-) diff --git a/es2panda/aot/main.cpp b/es2panda/aot/main.cpp index f96cb711a1..773bb51eaf 100644 --- a/es2panda/aot/main.cpp +++ b/es2panda/aot/main.cpp @@ -148,7 +148,8 @@ int Run(int argc, const char **argv) } es2panda::Compiler compiler(options->Extension(), options->ThreadCount()); - es2panda::SourceFile input(options->SourceFile(), options->ParserInput(), options->ScriptKind()); + es2panda::SourceFile input(options->SourceFile(), options->ParserInput(), + options->RecordName(), options->ScriptKind()); auto *program = compiler.Compile(input, options->CompilerOptions()); diff --git a/es2panda/aot/options.cpp b/es2panda/aot/options.cpp index 0f430e302e..400e90d174 100644 --- a/es2panda/aot/options.cpp +++ b/es2panda/aot/options.cpp @@ -65,6 +65,7 @@ bool Options::Parse(int argc, const char **argv) panda::PandArg opSizeStat("dump-size-stat", false, "Dump size statistics"); panda::PandArg opDumpLiteralBuffer("dump-literal-buffer", false, "Dump literal buffer"); panda::PandArg outputFile("output", "", "Compiler binary output (.abc)"); + panda::PandArg recordName("record-name", "", "Specify the record name"); panda::PandArg debuggerEvaluateExpression("debugger-evaluate-expression", false, "evaluate expression in debugger mode"); panda::PandArg base64Input("base64Input", "", "base64 input of js content"); @@ -92,6 +93,7 @@ bool Options::Parse(int argc, const char **argv) argparser_->Add(&inputExtension); argparser_->Add(&outputFile); + argparser_->Add(&recordName); argparser_->PushBackTail(&inputFile); argparser_->EnableTail(); @@ -143,6 +145,11 @@ bool Options::Parse(int argc, const char **argv) parserInput_ = ss.str(); sourceFile_ = BaseName(sourceFile_); + + recordName_ = RemoveExtension(sourceFile_); + if (!recordName.GetValue().empty()) { + recordName_ = recordName.GetValue(); + } } else { // input content is base64 string parserInput_ = ExtractContentFromBase64Input(base64Input.GetValue()); diff --git a/es2panda/aot/options.h b/es2panda/aot/options.h index 49286015ae..d8e69ffcb4 100644 --- a/es2panda/aot/options.h +++ b/es2panda/aot/options.h @@ -91,6 +91,11 @@ public: return sourceFile_; } + const std::string &RecordName() const + { + return recordName_; + } + const std::string &ErrorMsg() const { return errorMsg_; @@ -128,6 +133,7 @@ private: std::string compilerOutput_; std::string result_; std::string sourceFile_; + std::string recordName_; std::string errorMsg_; int optLevel_ {0}; int threadCount_ {0}; diff --git a/es2panda/binder/binder.cpp b/es2panda/binder/binder.cpp index 3398132ee7..011506415f 100644 --- a/es2panda/binder/binder.cpp +++ b/es2panda/binder/binder.cpp @@ -195,11 +195,13 @@ void Binder::BuildFunction(FunctionScope *funcScope, util::StringView name) bool funcNameWithoutDot = (name.Find(".") == std::string::npos); bool funcNameWithoutBackslash = (name.Find("\\") == std::string::npos); if (name != ANONYMOUS_FUNC_NAME && funcNameWithoutDot && funcNameWithoutBackslash && !functionNames_.count(name)) { + auto internalName = program_->RecordName().Mutf8() + "." + name.Mutf8(); functionNames_.insert(name); - funcScope->BindName(name, name); + funcScope->BindName(name, util::UString(internalName, Allocator()).View()); return; } std::stringstream ss; + ss << program_->RecordName().Mutf8() << "."; uint32_t idx = functionNameIndex_++; ss << "#" << std::to_string(idx) << "#"; if (funcNameWithoutDot && funcNameWithoutBackslash) { diff --git a/es2panda/compiler/core/emitter/commonjs.cpp b/es2panda/compiler/core/emitter/commonjs.cpp index a623269fa6..ddf5ec3e16 100644 --- a/es2panda/compiler/core/emitter/commonjs.cpp +++ b/es2panda/compiler/core/emitter/commonjs.cpp @@ -20,17 +20,13 @@ namespace panda::es2panda::compiler { constexpr const auto LANG_EXT = panda::pandasm::extensions::Language::ECMASCRIPT; -void Emitter::GenCommonjsRecord() +void Emitter::SetCommonjsField(bool isCommonjs) { - auto commonjsRecord = panda::pandasm::Record("_CommonJsRecord", LANG_EXT); - commonjsRecord.metadata->SetAccessFlags(panda::ACC_PUBLIC); auto isCommonJsField = panda::pandasm::Field(LANG_EXT); - isCommonJsField.name = "isCommonJs"; + isCommonJsField.name = "isCommonjs"; isCommonJsField.type = panda::pandasm::Type("u8", 0); isCommonJsField.metadata->SetValue( - panda::pandasm::ScalarValue::Create(static_cast(true))); - commonjsRecord.field_list.emplace_back(std::move(isCommonJsField)); - - prog_->record_table.emplace(commonjsRecord.name, std::move(commonjsRecord)); + panda::pandasm::ScalarValue::Create(static_cast(isCommonjs))); + rec_->field_list.emplace_back(std::move(isCommonJsField)); } } // namespace panda::es2panda::compiler \ No newline at end of file diff --git a/es2panda/compiler/core/emitter/emitter.cpp b/es2panda/compiler/core/emitter/emitter.cpp index 4852e6a3f1..f0b455f918 100644 --- a/es2panda/compiler/core/emitter/emitter.cpp +++ b/es2panda/compiler/core/emitter/emitter.cpp @@ -352,13 +352,14 @@ void FunctionEmitter::GenVariablesDebugInfo() Emitter::Emitter(const CompilerContext *context) { prog_ = new panda::pandasm::Program(); - prog_->lang = panda::pandasm::extensions::Language::ECMASCRIPT; + prog_->lang = LANG_EXT; + + rec_ = new panda::pandasm::Record(context->Binder()->Program()->RecordName().Mutf8(), LANG_EXT); prog_->function_table.reserve(context->Binder()->Functions().size()); + + SetCommonjsField(context->Binder()->Program()->Kind() == parser::ScriptKind::COMMONJS); GenESAnnoatationRecord(); - if (context->Binder()->Program()->Kind() == parser::ScriptKind::COMMONJS) { - GenCommonjsRecord(); - } } Emitter::~Emitter() @@ -395,16 +396,12 @@ void Emitter::AddSourceTextModuleRecord(ModuleRecordEmitter *module, const Compi { std::lock_guard lock(m_); - auto ecmaModuleRecord = panda::pandasm::Record("_ESModuleRecord", LANG_EXT); - ecmaModuleRecord.metadata->SetAccessFlags(panda::ACC_PUBLIC); - auto moduleIdxField = panda::pandasm::Field(LANG_EXT); - moduleIdxField.name = std::string {context->Binder()->Program()->SourceFile()}; + moduleIdxField.name = "moduleRecordIdx"; moduleIdxField.type = panda::pandasm::Type("u32", 0); moduleIdxField.metadata->SetValue(panda::pandasm::ScalarValue::Create( static_cast(module->Index()))); - ecmaModuleRecord.field_list.emplace_back(std::move(moduleIdxField)); - prog_->record_table.emplace(ecmaModuleRecord.name, std::move(ecmaModuleRecord)); + rec_->field_list.emplace_back(std::move(moduleIdxField)); auto &moduleLiteralsBuffer = module->Buffer(); auto literalArrayInstance = panda::pandasm::LiteralArray(std::move(moduleLiteralsBuffer)); @@ -453,6 +450,10 @@ panda::pandasm::Program *Emitter::Finalize(bool dumpDebugInfo) dumper.Dump(); } + prog_->record_table.emplace(rec_->name, std::move(*rec_)); + delete rec_; + rec_ = nullptr; + auto *prog = prog_; prog_ = nullptr; return prog; diff --git a/es2panda/compiler/core/emitter/emitter.h b/es2panda/compiler/core/emitter/emitter.h index add3a5ec0b..3d9cbea0cb 100644 --- a/es2panda/compiler/core/emitter/emitter.h +++ b/es2panda/compiler/core/emitter/emitter.h @@ -34,6 +34,7 @@ namespace panda::pandasm { struct Program; struct Function; struct Ins; +struct Record; } // namespace panda::pandasm namespace panda::es2panda::ir { @@ -105,11 +106,13 @@ public: panda::pandasm::Program *Finalize(bool dumpDebugInfo); private: + void GenRecord(const CompilerContext *context); void GenESAnnoatationRecord(); - void GenCommonjsRecord(); + void SetCommonjsField(bool isCommonjs); std::mutex m_; panda::pandasm::Program *prog_; + panda::pandasm::Record *rec_; }; } // namespace panda::es2panda::compiler diff --git a/es2panda/es2panda.cpp b/es2panda/es2panda.cpp index 59fc0b90d0..f8db67e7ca 100644 --- a/es2panda/es2panda.cpp +++ b/es2panda/es2panda.cpp @@ -47,10 +47,11 @@ panda::pandasm::Program *Compiler::Compile(const SourceFile &input, const Compil /* TODO(dbatyai): pass string view */ std::string fname(input.fileName); std::string src(input.source); + std::string rname(input.recordName); parser::ScriptKind kind(input.scriptKind); try { - auto ast = parser_->Parse(fname, src, kind); + auto ast = parser_->Parse(fname, src, rname, kind); if (options.dumpAst) { std::cout << ast.Dump() << std::endl; diff --git a/es2panda/es2panda.h b/es2panda/es2panda.h index 602f77642c..cfdf1a1641 100644 --- a/es2panda/es2panda.h +++ b/es2panda/es2panda.h @@ -41,13 +41,14 @@ enum class ScriptExtension { }; struct SourceFile { - SourceFile(std::string_view fn, std::string_view s, parser::ScriptKind sk) - : fileName(fn), source(s), scriptKind(sk) + SourceFile(std::string_view fn, std::string_view s, std::string_view rn, parser::ScriptKind sk) + : fileName(fn), source(s), recordName(rn), scriptKind(sk) { } std::string_view fileName {}; std::string_view source {}; + std::string_view recordName {}; parser::ScriptKind scriptKind {}; }; diff --git a/es2panda/parser/commonjs.cpp b/es2panda/parser/commonjs.cpp index 0f41609e7a..912640e06e 100644 --- a/es2panda/parser/commonjs.cpp +++ b/es2panda/parser/commonjs.cpp @@ -53,7 +53,7 @@ void ParserImpl::AddCommonjsArgs(ArenaVector &args) } } -void ParserImpl::ParseCommonjs(const std::string &fileName, const std::string &source) +void ParserImpl::ParseCommonjs() { // create FunctionExpression as callee ir::FunctionExpression *funcExpr = nullptr; diff --git a/es2panda/parser/parserImpl.cpp b/es2panda/parser/parserImpl.cpp index 4c06cda889..debe3c38f2 100644 --- a/es2panda/parser/parserImpl.cpp +++ b/es2panda/parser/parserImpl.cpp @@ -108,9 +108,11 @@ std::unique_ptr ParserImpl::InitLexer(const std::string &fileName, return lexer; } -Program ParserImpl::Parse(const std::string &fileName, const std::string &source, ScriptKind kind) +Program ParserImpl::Parse(const std::string &fileName, const std::string &source, + const std::string &recordName, ScriptKind kind) { program_.SetKind(kind); + program_.SetRecordName(recordName); /* * In order to make the lexer's memory alive, the return value 'lexer' can not be omitted. @@ -118,15 +120,15 @@ Program ParserImpl::Parse(const std::string &fileName, const std::string &source auto lexer = InitLexer(fileName, source); switch (kind) { case ScriptKind::SCRIPT: { - ParseScript(fileName, source); + ParseScript(); break; } case ScriptKind::MODULE: { - ParseModule(fileName, source); + ParseModule(); break; } case ScriptKind::COMMONJS: { - ParseCommonjs(fileName, source); + ParseCommonjs(); break; } default: { @@ -137,12 +139,12 @@ Program ParserImpl::Parse(const std::string &fileName, const std::string &source return std::move(program_); } -void ParserImpl::ParseScript(const std::string &fileName, const std::string &source) +void ParserImpl::ParseScript() { ParseProgram(ScriptKind::SCRIPT); } -void ParserImpl::ParseModule(const std::string &fileName, const std::string &source) +void ParserImpl::ParseModule() { context_.Status() |= (ParserStatus::MODULE); ParseProgram(ScriptKind::MODULE); diff --git a/es2panda/parser/parserImpl.h b/es2panda/parser/parserImpl.h index 258d5c9169..5775dda864 100644 --- a/es2panda/parser/parserImpl.h +++ b/es2panda/parser/parserImpl.h @@ -176,7 +176,8 @@ public: NO_MOVE_SEMANTIC(ParserImpl); ~ParserImpl() = default; - Program Parse(const std::string &fileName, const std::string &source, ScriptKind kind); + Program Parse(const std::string &fileName, const std::string &source, + const std::string &recordName, ScriptKind kind); ScriptExtension Extension() const; @@ -205,15 +206,15 @@ private: } [[nodiscard]] std::unique_ptr InitLexer(const std::string &fileName, const std::string &source); - void ParseScript(const std::string &fileName, const std::string &source); - void ParseModule(const std::string &fileName, const std::string &source); + void ParseScript(); + void ParseModule(); /* * Transform the commonjs's AST by wrapping the sourceCode * e.g. (function (exports, require, module, __filename, __dirname) { * [Origin_SourceCode] * })(exports, require, module, __filename, __dirname); */ - void ParseCommonjs(const std::string &fileName, const std::string &source); + void ParseCommonjs(); void AddCommonjsParams(ArenaVector ¶ms); void AddCommonjsArgs(ArenaVector &args); void ParseProgram(ScriptKind kind); diff --git a/es2panda/parser/program/program.h b/es2panda/parser/program/program.h index 667d38cffe..54a68dcdb8 100644 --- a/es2panda/parser/program/program.h +++ b/es2panda/parser/program/program.h @@ -84,6 +84,11 @@ public: return sourceFile_.View(); } + util::StringView RecordName() const + { + return recordName_.View(); + } + const lexer::LineIndex &GetLineIndex() const { return lineIndex_; @@ -111,6 +116,11 @@ public: lineIndex_ = lexer::LineIndex(SourceCode()); } + void SetRecordName(const std::string &recordName) + { + recordName_ = util::UString(recordName, Allocator()); + } + std::string Dump() const; void SetKind(ScriptKind kind); @@ -120,6 +130,7 @@ private: ir::BlockStatement *ast_ {}; util::UString sourceCode_ {}; util::UString sourceFile_ {}; + util::UString recordName_ {}; ScriptKind kind_ {}; ScriptExtension extension_ {}; lexer::LineIndex lineIndex_ {}; -- Gitee