mirror of
https://github.com/Samsung/escargot.git
synced 2026-06-22 10:01:50 +00:00
implement generate CodeBlock tree in ScriptParser
you can see dump of CodeBlock tree with DUMP_CODEBLOCK_TREE=1 option(setenv) Signed-off-by: seonghyun kim <sh8281.kim@samsung.com>
This commit is contained in:
parent
70f822134c
commit
9cff64f7a6
21 changed files with 777 additions and 185 deletions
|
|
@ -0,0 +1,131 @@
|
|||
#include "Escargot.h"
|
||||
#include "ScriptParser.h"
|
||||
#include "runtime/Context.h"
|
||||
#include "parser/esprima_cpp/esprima.h"
|
||||
#include "parser/ast/AST.h"
|
||||
#include "parser/CodeBlock.h"
|
||||
|
||||
namespace Escargot {
|
||||
|
||||
ScriptParser::ScriptParser(Context* c)
|
||||
: m_context(c)
|
||||
{
|
||||
}
|
||||
|
||||
CodeBlock* ScriptParser::generateCodeBlockTreeFromASTWalker(Context* ctx, StringView source, ASTScopeContext* scopeCtx, CodeBlock* parentCodeBlock)
|
||||
{
|
||||
CodeBlock* codeBlock = new CodeBlock(ctx, StringView(source, scopeCtx->m_locStart.index, scopeCtx->m_locEnd.index), scopeCtx->m_names, parentCodeBlock,
|
||||
(CodeBlock::CodeBlockInitFlag)
|
||||
((scopeCtx->m_hasEval ? CodeBlock::CodeBlockHasEval : 0) |
|
||||
(scopeCtx->m_hasWith ? CodeBlock::CodeBlockHasWith : 0) |
|
||||
(scopeCtx->m_hasYield ? CodeBlock::CodeBlockHasYield : 0))
|
||||
);
|
||||
|
||||
#ifndef NDEBUG
|
||||
codeBlock->m_locStart = scopeCtx->m_locStart;
|
||||
codeBlock->m_locEnd = scopeCtx->m_locEnd;
|
||||
codeBlock->m_scopeContext = scopeCtx;
|
||||
#endif
|
||||
|
||||
if (parentCodeBlock) {
|
||||
if (codeBlock->hasEvalWithYield()) {
|
||||
CodeBlock* c = codeBlock;
|
||||
while (c) {
|
||||
c->notifySelfOrChildHasEvalWithYield();
|
||||
c = c->parentCodeBlock();
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < scopeCtx->m_usingNames.size(); i ++) {
|
||||
AtomicString uname = scopeCtx->m_usingNames[i];
|
||||
if (!codeBlock->hasName(uname)) {
|
||||
CodeBlock* c = codeBlock->parentCodeBlock();
|
||||
while (c) {
|
||||
if (c->tryCaptureIdentifiersFromChildCodeBlock(uname))
|
||||
break;
|
||||
c = c->parentCodeBlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0 ; i < scopeCtx->m_childScopes.size(); i ++) {
|
||||
codeBlock->appendChildBlock(generateCodeBlockTreeFromASTWalker(ctx, source, scopeCtx->m_childScopes[i], codeBlock));
|
||||
}
|
||||
return codeBlock;
|
||||
}
|
||||
|
||||
// generate code blocks from AST
|
||||
CodeBlock* ScriptParser::generateCodeBlockTreeFromAST(Context* ctx, StringView source, ProgramNode* program)
|
||||
{
|
||||
return generateCodeBlockTreeFromASTWalker(ctx, source, program->scopeContext(), nullptr);
|
||||
}
|
||||
|
||||
ScriptParser::ScriptParserResult ScriptParser::parse(StringView scriptSource)
|
||||
{
|
||||
Script* script = nullptr;
|
||||
ScriptParseError* error = nullptr;
|
||||
try {
|
||||
ProgramNode* program = esprima::parseProgram(m_context, scriptSource, [](Escargot::Node* node, NodeLOC start, NodeLOC end) {
|
||||
// printf("nd type %d\n", node->type());
|
||||
});
|
||||
|
||||
CodeBlock* topCodeBlock = generateCodeBlockTreeFromAST(m_context, scriptSource, program);
|
||||
|
||||
// dump Code Block
|
||||
#ifndef NDEBUG
|
||||
if (getenv("DUMP_CODEBLOCK_TREE") && strlen(getenv("DUMP_CODEBLOCK_TREE"))) {
|
||||
|
||||
std::function<void (CodeBlock*, size_t depth)> fn = [&](CodeBlock* cb, size_t depth) {
|
||||
|
||||
#define PRINT_TAB() for (size_t i = 0; i < depth; i ++) { printf(" "); }
|
||||
|
||||
PRINT_TAB()
|
||||
printf("CodeBlock %p (%d:%d -> %d:%d)(%s, %s) (E:%d, W:%d, Y:%d)\n", cb,
|
||||
(int)cb->m_locStart.line,
|
||||
(int)cb->m_locStart.column,
|
||||
(int)cb->m_locEnd.line,
|
||||
(int)cb->m_locEnd.column,
|
||||
cb->m_canAllocateEnvironmentOnStack ? "Stack" : "Heap",
|
||||
cb->m_canUseVectorStorage ? "Vector" : "HashMap",
|
||||
(int)cb->m_hasEval, (int)cb->m_hasWith, (int)cb->m_hasYield);
|
||||
|
||||
PRINT_TAB()
|
||||
printf("Names: ");
|
||||
for (size_t i = 0; i < cb->m_identifierInfos.size(); i ++) {
|
||||
printf("%s(%s), ", cb->m_identifierInfos[i].m_name.string()->toUTF8StringData().data(),
|
||||
cb->m_identifierInfos[i].m_needToAllocateOnStack ? "Stack" : "Heap");
|
||||
}
|
||||
puts("");
|
||||
|
||||
PRINT_TAB()
|
||||
printf("Using Names: ");
|
||||
for (size_t i = 0; i < cb->m_scopeContext->m_usingNames.size(); i ++) {
|
||||
printf("%s, ", cb->m_scopeContext->m_usingNames[i].string()->toUTF8StringData().data());
|
||||
}
|
||||
puts("");
|
||||
|
||||
for (size_t i = 0; i < cb->m_childBlocks.size(); i ++) {
|
||||
fn(cb->m_childBlocks[i], depth + 1);
|
||||
}
|
||||
|
||||
};
|
||||
fn(topCodeBlock, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
} catch(esprima::Error* orgError) {
|
||||
error = new ScriptParseError();
|
||||
error->column = orgError->column;
|
||||
error->description = orgError->description;
|
||||
error->index = orgError->index;
|
||||
error->lineNumber = orgError->lineNumber;
|
||||
error->message = orgError->message;
|
||||
error->name = orgError->name;
|
||||
}
|
||||
|
||||
ScriptParser::ScriptParserResult result(script, error);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue