Further refactoring of declarations in the AST:
Define modules as module declarations. Separate function declarations from var declarations. R=jkummerow@chromium.org BUG= TEST= Review URL: https://chromiumcodereview.appspot.com/9460064 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10854 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
ddaf909f82
commit
d809d17f5d
@ -417,8 +417,8 @@ bool Declaration::IsInlineable() const {
|
||||
return proxy()->var()->IsStackAllocated();
|
||||
}
|
||||
|
||||
bool VariableDeclaration::IsInlineable() const {
|
||||
return Declaration::IsInlineable() && fun() == NULL;
|
||||
bool FunctionDeclaration::IsInlineable() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -1003,6 +1003,7 @@ CaseClause::CaseClause(Isolate* isolate,
|
||||
}
|
||||
|
||||
INCREASE_NODE_COUNT(VariableDeclaration)
|
||||
INCREASE_NODE_COUNT(FunctionDeclaration)
|
||||
INCREASE_NODE_COUNT(ModuleDeclaration)
|
||||
INCREASE_NODE_COUNT(ModuleLiteral)
|
||||
INCREASE_NODE_COUNT(ModuleVariable)
|
||||
|
51
src/ast.h
51
src/ast.h
@ -61,6 +61,7 @@ namespace internal {
|
||||
|
||||
#define DECLARATION_NODE_LIST(V) \
|
||||
V(VariableDeclaration) \
|
||||
V(FunctionDeclaration) \
|
||||
V(ModuleDeclaration) \
|
||||
|
||||
#define MODULE_NODE_LIST(V) \
|
||||
@ -444,10 +445,10 @@ class Declaration: public AstNode {
|
||||
VariableProxy* proxy() const { return proxy_; }
|
||||
VariableMode mode() const { return mode_; }
|
||||
Scope* scope() const { return scope_; }
|
||||
virtual InitializationFlag initialization() const = 0;
|
||||
virtual bool IsInlineable() const;
|
||||
|
||||
virtual Declaration* AsDeclaration() { return this; }
|
||||
virtual VariableDeclaration* AsVariableDeclaration() { return NULL; }
|
||||
|
||||
protected:
|
||||
Declaration(VariableProxy* proxy,
|
||||
@ -475,22 +476,43 @@ class VariableDeclaration: public Declaration {
|
||||
public:
|
||||
DECLARE_NODE_TYPE(VariableDeclaration)
|
||||
|
||||
virtual VariableDeclaration* AsVariableDeclaration() { return this; }
|
||||
|
||||
FunctionLiteral* fun() const { return fun_; } // may be NULL
|
||||
virtual bool IsInlineable() const;
|
||||
virtual InitializationFlag initialization() const {
|
||||
return mode() == VAR ? kCreatedInitialized : kNeedsInitialization;
|
||||
}
|
||||
|
||||
protected:
|
||||
template<class> friend class AstNodeFactory;
|
||||
|
||||
VariableDeclaration(VariableProxy* proxy,
|
||||
VariableMode mode,
|
||||
Scope* scope)
|
||||
: Declaration(proxy, mode, scope) {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class FunctionDeclaration: public Declaration {
|
||||
public:
|
||||
DECLARE_NODE_TYPE(FunctionDeclaration)
|
||||
|
||||
FunctionLiteral* fun() const { return fun_; }
|
||||
virtual InitializationFlag initialization() const {
|
||||
return kCreatedInitialized;
|
||||
}
|
||||
virtual bool IsInlineable() const;
|
||||
|
||||
protected:
|
||||
template<class> friend class AstNodeFactory;
|
||||
|
||||
FunctionDeclaration(VariableProxy* proxy,
|
||||
VariableMode mode,
|
||||
FunctionLiteral* fun,
|
||||
Scope* scope)
|
||||
: Declaration(proxy, mode, scope),
|
||||
fun_(fun) {
|
||||
// At the moment there are no "const functions"'s in JavaScript...
|
||||
ASSERT(fun == NULL || mode == VAR || mode == LET);
|
||||
// At the moment there are no "const functions" in JavaScript...
|
||||
ASSERT(mode == VAR || mode == LET);
|
||||
ASSERT(fun != NULL);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -503,6 +525,9 @@ class ModuleDeclaration: public Declaration {
|
||||
DECLARE_NODE_TYPE(ModuleDeclaration)
|
||||
|
||||
Module* module() const { return module_; }
|
||||
virtual InitializationFlag initialization() const {
|
||||
return kCreatedInitialized;
|
||||
}
|
||||
|
||||
protected:
|
||||
template<class> friend class AstNodeFactory;
|
||||
@ -2532,13 +2557,21 @@ class AstNodeFactory BASE_EMBEDDED {
|
||||
|
||||
VariableDeclaration* NewVariableDeclaration(VariableProxy* proxy,
|
||||
VariableMode mode,
|
||||
FunctionLiteral* fun,
|
||||
Scope* scope) {
|
||||
VariableDeclaration* decl =
|
||||
new(zone_) VariableDeclaration(proxy, mode, fun, scope);
|
||||
new(zone_) VariableDeclaration(proxy, mode, scope);
|
||||
VISIT_AND_RETURN(VariableDeclaration, decl)
|
||||
}
|
||||
|
||||
FunctionDeclaration* NewFunctionDeclaration(VariableProxy* proxy,
|
||||
VariableMode mode,
|
||||
FunctionLiteral* fun,
|
||||
Scope* scope) {
|
||||
FunctionDeclaration* decl =
|
||||
new(zone_) FunctionDeclaration(proxy, mode, fun, scope);
|
||||
VISIT_AND_RETURN(FunctionDeclaration, decl)
|
||||
}
|
||||
|
||||
ModuleDeclaration* NewModuleDeclaration(VariableProxy* proxy,
|
||||
Module* module,
|
||||
Scope* scope) {
|
||||
|
@ -55,6 +55,10 @@ void BreakableStatementChecker::VisitVariableDeclaration(
|
||||
VariableDeclaration* decl) {
|
||||
}
|
||||
|
||||
void BreakableStatementChecker::VisitFunctionDeclaration(
|
||||
FunctionDeclaration* decl) {
|
||||
}
|
||||
|
||||
void BreakableStatementChecker::VisitModuleDeclaration(
|
||||
ModuleDeclaration* decl) {
|
||||
}
|
||||
@ -569,29 +573,28 @@ void FullCodeGenerator::VisitDeclarations(
|
||||
isolate()->factory()->NewFixedArray(2 * global_count_, TENURED);
|
||||
int length = declarations->length();
|
||||
for (int j = 0, i = 0; i < length; i++) {
|
||||
VariableDeclaration* decl = declarations->at(i)->AsVariableDeclaration();
|
||||
if (decl != NULL) {
|
||||
Variable* var = decl->proxy()->var();
|
||||
Declaration* decl = declarations->at(i);
|
||||
Variable* var = decl->proxy()->var();
|
||||
|
||||
if (var->IsUnallocated()) {
|
||||
array->set(j++, *(var->name()));
|
||||
if (decl->fun() == NULL) {
|
||||
if (var->binding_needs_init()) {
|
||||
// In case this binding needs initialization use the hole.
|
||||
array->set_the_hole(j++);
|
||||
} else {
|
||||
array->set_undefined(j++);
|
||||
}
|
||||
if (var->IsUnallocated()) {
|
||||
array->set(j++, *(var->name()));
|
||||
FunctionDeclaration* fun_decl = decl->AsFunctionDeclaration();
|
||||
if (fun_decl == NULL) {
|
||||
if (var->binding_needs_init()) {
|
||||
// In case this binding needs initialization use the hole.
|
||||
array->set_the_hole(j++);
|
||||
} else {
|
||||
Handle<SharedFunctionInfo> function =
|
||||
Compiler::BuildFunctionInfo(decl->fun(), script());
|
||||
// Check for stack-overflow exception.
|
||||
if (function.is_null()) {
|
||||
SetStackOverflow();
|
||||
return;
|
||||
}
|
||||
array->set(j++, *function);
|
||||
array->set_undefined(j++);
|
||||
}
|
||||
} else {
|
||||
Handle<SharedFunctionInfo> function =
|
||||
Compiler::BuildFunctionInfo(fun_decl->fun(), script());
|
||||
// Check for stack-overflow exception.
|
||||
if (function.is_null()) {
|
||||
SetStackOverflow();
|
||||
return;
|
||||
}
|
||||
array->set(j++, *function);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -605,12 +608,17 @@ void FullCodeGenerator::VisitDeclarations(
|
||||
|
||||
|
||||
void FullCodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) {
|
||||
EmitDeclaration(decl->proxy(), decl->mode(), NULL);
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) {
|
||||
EmitDeclaration(decl->proxy(), decl->mode(), decl->fun());
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* decl) {
|
||||
// TODO(rossberg)
|
||||
EmitDeclaration(decl->proxy(), decl->mode(), NULL);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2466,7 +2466,7 @@ HGraph* HGraphBuilder::CreateGraph() {
|
||||
// Handle implicit declaration of the function name in named function
|
||||
// expressions before other declarations.
|
||||
if (scope->is_function_scope() && scope->function() != NULL) {
|
||||
HandleVariableDeclaration(scope->function(), CONST, NULL, NULL);
|
||||
HandleDeclaration(scope->function(), CONST, NULL, NULL);
|
||||
}
|
||||
VisitDeclarations(scope->declarations());
|
||||
AddSimulate(AstNode::kDeclarationsId);
|
||||
@ -6826,20 +6826,16 @@ void HGraphBuilder::VisitThisFunction(ThisFunction* expr) {
|
||||
}
|
||||
|
||||
|
||||
void HGraphBuilder::VisitVariableDeclaration(VariableDeclaration* decl) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
void HGraphBuilder::VisitDeclarations(ZoneList<Declaration*>* declarations) {
|
||||
int length = declarations->length();
|
||||
int global_count = 0;
|
||||
for (int i = 0; i < declarations->length(); i++) {
|
||||
VariableDeclaration* decl = declarations->at(i)->AsVariableDeclaration();
|
||||
if (decl == NULL) continue;
|
||||
HandleVariableDeclaration(decl->proxy(),
|
||||
decl->mode(),
|
||||
decl->fun(),
|
||||
&global_count);
|
||||
Declaration* decl = declarations->at(i);
|
||||
FunctionDeclaration* fun_decl = decl->AsFunctionDeclaration();
|
||||
HandleDeclaration(decl->proxy(),
|
||||
decl->mode(),
|
||||
fun_decl != NULL ? fun_decl->fun() : NULL,
|
||||
&global_count);
|
||||
}
|
||||
|
||||
// Batch declare global functions and variables.
|
||||
@ -6847,13 +6843,13 @@ void HGraphBuilder::VisitDeclarations(ZoneList<Declaration*>* declarations) {
|
||||
Handle<FixedArray> array =
|
||||
isolate()->factory()->NewFixedArray(2 * global_count, TENURED);
|
||||
for (int j = 0, i = 0; i < length; i++) {
|
||||
VariableDeclaration* decl = declarations->at(i)->AsVariableDeclaration();
|
||||
if (decl == NULL) continue;
|
||||
Declaration* decl = declarations->at(i);
|
||||
Variable* var = decl->proxy()->var();
|
||||
|
||||
if (var->IsUnallocated()) {
|
||||
array->set(j++, *(var->name()));
|
||||
if (decl->fun() == NULL) {
|
||||
FunctionDeclaration* fun_decl = decl->AsFunctionDeclaration();
|
||||
if (fun_decl == NULL) {
|
||||
if (var->binding_needs_init()) {
|
||||
// In case this binding needs initialization use the hole.
|
||||
array->set_the_hole(j++);
|
||||
@ -6862,7 +6858,7 @@ void HGraphBuilder::VisitDeclarations(ZoneList<Declaration*>* declarations) {
|
||||
}
|
||||
} else {
|
||||
Handle<SharedFunctionInfo> function =
|
||||
Compiler::BuildFunctionInfo(decl->fun(), info()->script());
|
||||
Compiler::BuildFunctionInfo(fun_decl->fun(), info()->script());
|
||||
// Check for stack-overflow exception.
|
||||
if (function.is_null()) {
|
||||
SetStackOverflow();
|
||||
@ -6884,10 +6880,10 @@ void HGraphBuilder::VisitDeclarations(ZoneList<Declaration*>* declarations) {
|
||||
}
|
||||
|
||||
|
||||
void HGraphBuilder::HandleVariableDeclaration(VariableProxy* proxy,
|
||||
VariableMode mode,
|
||||
FunctionLiteral* function,
|
||||
int* global_count) {
|
||||
void HGraphBuilder::HandleDeclaration(VariableProxy* proxy,
|
||||
VariableMode mode,
|
||||
FunctionLiteral* function,
|
||||
int* global_count) {
|
||||
Variable* var = proxy->var();
|
||||
bool binding_needs_init =
|
||||
(mode == CONST || mode == CONST_HARMONY || mode == LET);
|
||||
@ -6923,6 +6919,16 @@ void HGraphBuilder::HandleVariableDeclaration(VariableProxy* proxy,
|
||||
}
|
||||
|
||||
|
||||
void HGraphBuilder::VisitVariableDeclaration(VariableDeclaration* decl) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
|
||||
void HGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* decl) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
|
||||
void HGraphBuilder::VisitModuleDeclaration(ModuleDeclaration* decl) {
|
||||
// TODO(rossberg)
|
||||
}
|
||||
|
@ -870,10 +870,10 @@ class HGraphBuilder: public AstVisitor {
|
||||
INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_DECLARATION)
|
||||
#undef INLINE_FUNCTION_GENERATOR_DECLARATION
|
||||
|
||||
void HandleVariableDeclaration(VariableProxy* proxy,
|
||||
VariableMode mode,
|
||||
FunctionLiteral* function,
|
||||
int* global_count);
|
||||
void HandleDeclaration(VariableProxy* proxy,
|
||||
VariableMode mode,
|
||||
FunctionLiteral* function,
|
||||
int* global_count);
|
||||
|
||||
void VisitDelete(UnaryOperation* expr);
|
||||
void VisitVoid(UnaryOperation* expr);
|
||||
|
@ -1221,13 +1221,14 @@ Block* Parser::ParseModuleDeclaration(bool* ok) {
|
||||
// Create new block with one expected declaration.
|
||||
Block* block = factory()->NewBlock(NULL, 1, true);
|
||||
Handle<String> name = ParseIdentifier(CHECK_OK);
|
||||
// top_scope_->AddDeclaration(
|
||||
// factory()->NewModuleDeclaration(proxy, module, top_scope_));
|
||||
VariableProxy* proxy = Declare(name, LET, NULL, true, CHECK_OK);
|
||||
Module* module = ParseModule(ok);
|
||||
Module* module = ParseModule(CHECK_OK);
|
||||
VariableProxy* proxy = NewUnresolved(name, LET);
|
||||
Declaration* declaration =
|
||||
factory()->NewModuleDeclaration(proxy, module, top_scope_);
|
||||
Declare(declaration, true, CHECK_OK);
|
||||
|
||||
// TODO(rossberg): Add initialization statement to block.
|
||||
USE(proxy);
|
||||
USE(module);
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
@ -1497,21 +1498,22 @@ Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) {
|
||||
}
|
||||
|
||||
|
||||
VariableProxy* Parser::Declare(Handle<String> name,
|
||||
VariableMode mode,
|
||||
FunctionLiteral* fun,
|
||||
bool resolve,
|
||||
bool* ok) {
|
||||
Variable* var = NULL;
|
||||
VariableProxy* Parser::NewUnresolved(Handle<String> name, VariableMode mode) {
|
||||
// If we are inside a function, a declaration of a var/const variable is a
|
||||
// truly local variable, and the scope of the variable is always the function
|
||||
// scope.
|
||||
// Let/const variables in harmony mode are always added to the immediately
|
||||
// enclosing scope.
|
||||
Scope* declaration_scope = (mode == LET || mode == CONST_HARMONY)
|
||||
? top_scope_ : top_scope_->DeclarationScope();
|
||||
InitializationFlag init_flag = (fun != NULL || mode == VAR)
|
||||
? kCreatedInitialized : kNeedsInitialization;
|
||||
return DeclarationScope(mode)->NewUnresolved(
|
||||
factory(), name, scanner().location().beg_pos);
|
||||
}
|
||||
|
||||
|
||||
void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) {
|
||||
Handle<String> name = declaration->proxy()->name();
|
||||
VariableMode mode = declaration->mode();
|
||||
Scope* declaration_scope = DeclarationScope(mode);
|
||||
Variable* var = NULL;
|
||||
|
||||
// If a function scope exists, then we can statically declare this
|
||||
// variable and also set its mode. In any case, a Declaration node
|
||||
@ -1531,7 +1533,8 @@ VariableProxy* Parser::Declare(Handle<String> name,
|
||||
var = declaration_scope->LocalLookup(name);
|
||||
if (var == NULL) {
|
||||
// Declare the name.
|
||||
var = declaration_scope->DeclareLocal(name, mode, init_flag);
|
||||
var = declaration_scope->DeclareLocal(
|
||||
name, mode, declaration->initialization());
|
||||
} else {
|
||||
// The name was declared in this scope before; check for conflicting
|
||||
// re-declarations. We have a conflict if either of the declarations is
|
||||
@ -1558,7 +1561,7 @@ VariableProxy* Parser::Declare(Handle<String> name,
|
||||
Vector<const char*> args(elms, 2);
|
||||
ReportMessage("redeclaration", args);
|
||||
*ok = false;
|
||||
return NULL;
|
||||
return;
|
||||
}
|
||||
const char* type = (var->mode() == VAR)
|
||||
? "var" : var->is_const_mode() ? "const" : "let";
|
||||
@ -1588,10 +1591,7 @@ VariableProxy* Parser::Declare(Handle<String> name,
|
||||
// semantic issue as long as we keep the source order, but it may be
|
||||
// a performance issue since it may lead to repeated
|
||||
// Runtime::DeclareContextSlot() calls.
|
||||
VariableProxy* proxy = declaration_scope->NewUnresolved(
|
||||
factory(), name, scanner().location().beg_pos);
|
||||
declaration_scope->AddDeclaration(
|
||||
factory()->NewVariableDeclaration(proxy, mode, fun, top_scope_));
|
||||
declaration_scope->AddDeclaration(declaration);
|
||||
|
||||
if ((mode == CONST || mode == CONST_HARMONY) &&
|
||||
declaration_scope->is_global_scope()) {
|
||||
@ -1615,7 +1615,7 @@ VariableProxy* Parser::Declare(Handle<String> name,
|
||||
mode,
|
||||
true,
|
||||
kind,
|
||||
init_flag);
|
||||
declaration->initialization());
|
||||
var->AllocateTo(Variable::LOOKUP, -1);
|
||||
resolve = true;
|
||||
}
|
||||
@ -1644,9 +1644,7 @@ VariableProxy* Parser::Declare(Handle<String> name,
|
||||
// initialization code. Thus, inside the 'with' statement, we need
|
||||
// both access to the static and the dynamic context chain; the
|
||||
// runtime needs to provide both.
|
||||
if (resolve && var != NULL) proxy->BindTo(var);
|
||||
|
||||
return proxy;
|
||||
if (resolve && var != NULL) declaration->proxy()->BindTo(var);
|
||||
}
|
||||
|
||||
|
||||
@ -1673,7 +1671,7 @@ Statement* Parser::ParseNativeDeclaration(bool* ok) {
|
||||
// isn't lazily compiled. The extension structures are only
|
||||
// accessible while parsing the first time not when reparsing
|
||||
// because of lazy compilation.
|
||||
top_scope_->DeclarationScope()->ForceEagerCompilation();
|
||||
DeclarationScope(VAR)->ForceEagerCompilation();
|
||||
|
||||
// Compute the function template for the native function.
|
||||
v8::Handle<v8::FunctionTemplate> fun_template =
|
||||
@ -1698,12 +1696,15 @@ Statement* Parser::ParseNativeDeclaration(bool* ok) {
|
||||
// TODO(1240846): It's weird that native function declarations are
|
||||
// introduced dynamically when we meet their declarations, whereas
|
||||
// other functions are set up when entering the surrounding scope.
|
||||
VariableProxy* proxy = NewUnresolved(name, VAR);
|
||||
Declaration* declaration =
|
||||
factory()->NewVariableDeclaration(proxy, VAR, top_scope_);
|
||||
Declare(declaration, true, CHECK_OK);
|
||||
SharedFunctionInfoLiteral* lit =
|
||||
factory()->NewSharedFunctionInfoLiteral(shared);
|
||||
VariableProxy* var = Declare(name, VAR, NULL, true, CHECK_OK);
|
||||
return factory()->NewExpressionStatement(
|
||||
factory()->NewAssignment(
|
||||
Token::INIT_VAR, var, lit, RelocInfo::kNoPosition));
|
||||
Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition));
|
||||
}
|
||||
|
||||
|
||||
@ -1724,7 +1725,10 @@ Statement* Parser::ParseFunctionDeclaration(bool* ok) {
|
||||
// scope, we treat is as such and introduce the function with it's
|
||||
// initial value upon entering the corresponding scope.
|
||||
VariableMode mode = is_extended_mode() ? LET : VAR;
|
||||
Declare(name, mode, fun, true, CHECK_OK);
|
||||
VariableProxy* proxy = NewUnresolved(name, mode);
|
||||
Declaration* declaration =
|
||||
factory()->NewFunctionDeclaration(proxy, mode, fun, top_scope_);
|
||||
Declare(declaration, true, CHECK_OK);
|
||||
return factory()->NewEmptyStatement();
|
||||
}
|
||||
|
||||
@ -1902,8 +1906,8 @@ Block* Parser::ParseVariableDeclarations(
|
||||
UNREACHABLE(); // by current callers
|
||||
}
|
||||
|
||||
Scope* declaration_scope = (mode == LET || mode == CONST_HARMONY)
|
||||
? top_scope_ : top_scope_->DeclarationScope();
|
||||
Scope* declaration_scope = DeclarationScope(mode);
|
||||
|
||||
// The scope of a var/const declared variable anywhere inside a function
|
||||
// is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can
|
||||
// transform a source-level var/const declaration into a (Function)
|
||||
@ -1950,7 +1954,10 @@ Block* Parser::ParseVariableDeclarations(
|
||||
// For let/const declarations in harmony mode, we can also immediately
|
||||
// pre-resolve the proxy because it resides in the same scope as the
|
||||
// declaration.
|
||||
VariableProxy* proxy = Declare(name, mode, NULL, mode != VAR, CHECK_OK);
|
||||
VariableProxy* proxy = NewUnresolved(name, mode);
|
||||
Declaration* declaration =
|
||||
factory()->NewVariableDeclaration(proxy, mode, top_scope_);
|
||||
Declare(declaration, mode != VAR, CHECK_OK);
|
||||
nvars++;
|
||||
if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) {
|
||||
ReportMessageAt(scanner().location(), "too_many_variables",
|
||||
|
10
src/parser.h
10
src/parser.h
@ -566,6 +566,10 @@ class Parser {
|
||||
ASSERT(top_scope_ != NULL);
|
||||
return top_scope_->is_extended_mode();
|
||||
}
|
||||
Scope* DeclarationScope(VariableMode mode) {
|
||||
return (mode == LET || mode == CONST_HARMONY)
|
||||
? top_scope_ : top_scope_->DeclarationScope();
|
||||
}
|
||||
|
||||
// Check if the given string is 'eval' or 'arguments'.
|
||||
bool IsEvalOrArguments(Handle<String> string);
|
||||
@ -756,10 +760,8 @@ class Parser {
|
||||
void CheckConflictingVarDeclarations(Scope* scope, bool* ok);
|
||||
|
||||
// Parser support
|
||||
VariableProxy* Declare(Handle<String> name, VariableMode mode,
|
||||
FunctionLiteral* fun,
|
||||
bool resolve,
|
||||
bool* ok);
|
||||
VariableProxy* NewUnresolved(Handle<String> name, VariableMode mode);
|
||||
void Declare(Declaration* declaration, bool resolve, bool* ok);
|
||||
|
||||
bool TargetStackContainsLabel(Handle<String> label);
|
||||
BreakableStatement* LookupBreakTarget(Handle<String> label, bool* ok);
|
||||
|
@ -61,10 +61,15 @@ void PrettyPrinter::VisitBlock(Block* node) {
|
||||
void PrettyPrinter::VisitVariableDeclaration(VariableDeclaration* node) {
|
||||
Print("var ");
|
||||
PrintLiteral(node->proxy()->name(), false);
|
||||
if (node->fun() != NULL) {
|
||||
Print(" = ");
|
||||
PrintFunctionLiteral(node->fun());
|
||||
}
|
||||
Print(";");
|
||||
}
|
||||
|
||||
|
||||
void PrettyPrinter::VisitFunctionDeclaration(FunctionDeclaration* node) {
|
||||
Print("function ");
|
||||
PrintLiteral(node->proxy()->name(), false);
|
||||
Print(" = ");
|
||||
PrintFunctionLiteral(node->fun());
|
||||
Print(";");
|
||||
}
|
||||
|
||||
@ -744,19 +749,18 @@ void AstPrinter::VisitBlock(Block* node) {
|
||||
|
||||
|
||||
void AstPrinter::VisitVariableDeclaration(VariableDeclaration* node) {
|
||||
if (node->fun() == NULL) {
|
||||
// var or const declarations
|
||||
PrintLiteralWithModeIndented(Variable::Mode2String(node->mode()),
|
||||
node->proxy()->var(),
|
||||
node->proxy()->name());
|
||||
} else {
|
||||
// function declarations
|
||||
PrintIndented("FUNCTION ");
|
||||
PrintLiteral(node->proxy()->name(), true);
|
||||
Print(" = function ");
|
||||
PrintLiteral(node->fun()->name(), false);
|
||||
Print("\n");
|
||||
}
|
||||
PrintLiteralWithModeIndented(Variable::Mode2String(node->mode()),
|
||||
node->proxy()->var(),
|
||||
node->proxy()->name());
|
||||
}
|
||||
|
||||
|
||||
void AstPrinter::VisitFunctionDeclaration(FunctionDeclaration* node) {
|
||||
PrintIndented("FUNCTION ");
|
||||
PrintLiteral(node->proxy()->name(), true);
|
||||
Print(" = function ");
|
||||
PrintLiteral(node->fun()->name(), false);
|
||||
Print("\n");
|
||||
}
|
||||
|
||||
|
||||
|
@ -210,6 +210,7 @@ void Processor::VisitWithStatement(WithStatement* node) {
|
||||
|
||||
// Do nothing:
|
||||
void Processor::VisitVariableDeclaration(VariableDeclaration* node) {}
|
||||
void Processor::VisitFunctionDeclaration(FunctionDeclaration* node) {}
|
||||
void Processor::VisitModuleDeclaration(ModuleDeclaration* node) {}
|
||||
void Processor::VisitModuleLiteral(ModuleLiteral* node) {}
|
||||
void Processor::VisitModuleVariable(ModuleVariable* node) {}
|
||||
|
Loading…
Reference in New Issue
Block a user