Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(152)

Side by Side Diff: src/parser.cc

Issue 8508052: Static resolution of outer variables in eval code. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments. Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/parser.h ('k') | src/runtime.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 extension_(extension), 593 extension_(extension),
594 pre_data_(pre_data), 594 pre_data_(pre_data),
595 fni_(NULL), 595 fni_(NULL),
596 stack_overflow_(false), 596 stack_overflow_(false),
597 parenthesized_function_(false), 597 parenthesized_function_(false),
598 harmony_scoping_(false) { 598 harmony_scoping_(false) {
599 AstNode::ResetIds(); 599 AstNode::ResetIds();
600 } 600 }
601 601
602 602
603 FunctionLiteral* Parser::ParseProgram(Handle<String> source, 603 FunctionLiteral* Parser::ParseProgram(CompilationInfo* info) {
604 bool in_global_context,
605 StrictModeFlag strict_mode) {
606 ZoneScope zone_scope(isolate(), DONT_DELETE_ON_EXIT); 604 ZoneScope zone_scope(isolate(), DONT_DELETE_ON_EXIT);
607 605
608 HistogramTimerScope timer(isolate()->counters()->parse()); 606 HistogramTimerScope timer(isolate()->counters()->parse());
607 Handle<String> source(String::cast(script_->source()));
609 isolate()->counters()->total_parse_size()->Increment(source->length()); 608 isolate()->counters()->total_parse_size()->Increment(source->length());
610 fni_ = new(zone()) FuncNameInferrer(isolate()); 609 fni_ = new(zone()) FuncNameInferrer(isolate());
611 610
612 // Initialize parser state. 611 // Initialize parser state.
613 source->TryFlatten(); 612 source->TryFlatten();
614 if (source->IsExternalTwoByteString()) { 613 if (source->IsExternalTwoByteString()) {
615 // Notice that the stream is destroyed at the end of the branch block. 614 // Notice that the stream is destroyed at the end of the branch block.
616 // The last line of the blocks can't be moved outside, even though they're 615 // The last line of the blocks can't be moved outside, even though they're
617 // identical calls. 616 // identical calls.
618 ExternalTwoByteStringUC16CharacterStream stream( 617 ExternalTwoByteStringUC16CharacterStream stream(
619 Handle<ExternalTwoByteString>::cast(source), 0, source->length()); 618 Handle<ExternalTwoByteString>::cast(source), 0, source->length());
620 scanner_.Initialize(&stream); 619 scanner_.Initialize(&stream);
621 return DoParseProgram(source, in_global_context, strict_mode, &zone_scope); 620 return DoParseProgram(info, source, &zone_scope);
622 } else { 621 } else {
623 GenericStringUC16CharacterStream stream(source, 0, source->length()); 622 GenericStringUC16CharacterStream stream(source, 0, source->length());
624 scanner_.Initialize(&stream); 623 scanner_.Initialize(&stream);
625 return DoParseProgram(source, in_global_context, strict_mode, &zone_scope); 624 return DoParseProgram(info, source, &zone_scope);
626 } 625 }
627 } 626 }
628 627
629 628
630 FunctionLiteral* Parser::DoParseProgram(Handle<String> source, 629 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info,
631 bool in_global_context, 630 Handle<String> source,
632 StrictModeFlag strict_mode,
633 ZoneScope* zone_scope) { 631 ZoneScope* zone_scope) {
634 ASSERT(top_scope_ == NULL); 632 ASSERT(top_scope_ == NULL);
635 ASSERT(target_stack_ == NULL); 633 ASSERT(target_stack_ == NULL);
636 if (pre_data_ != NULL) pre_data_->Initialize(); 634 if (pre_data_ != NULL) pre_data_->Initialize();
637 635
638 // Compute the parsing mode. 636 // Compute the parsing mode.
639 mode_ = FLAG_lazy ? PARSE_LAZILY : PARSE_EAGERLY; 637 mode_ = FLAG_lazy ? PARSE_LAZILY : PARSE_EAGERLY;
640 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY; 638 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY;
641 639
642 ScopeType type = in_global_context ? GLOBAL_SCOPE : EVAL_SCOPE;
643 Handle<String> no_name = isolate()->factory()->empty_symbol(); 640 Handle<String> no_name = isolate()->factory()->empty_symbol();
644 641
645 FunctionLiteral* result = NULL; 642 FunctionLiteral* result = NULL;
646 { Scope* scope = NewScope(top_scope_, type); 643 { Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE);;
644 info->SetGlobalScope(scope);
645 if (!info->is_global()) {
646 scope = Scope::DeserializeScopeChain(*info->calling_context(), scope);
647 scope = NewScope(scope, EVAL_SCOPE);
648 }
647 scope->set_start_position(0); 649 scope->set_start_position(0);
648 scope->set_end_position(source->length()); 650 scope->set_end_position(source->length());
649 FunctionState function_state(this, scope, isolate()); 651 FunctionState function_state(this, scope, isolate());
650 ASSERT(top_scope_->strict_mode_flag() == kNonStrictMode); 652 top_scope_->SetStrictModeFlag(info->strict_mode_flag());
651 top_scope_->SetStrictModeFlag(strict_mode);
652 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16); 653 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16);
653 bool ok = true; 654 bool ok = true;
654 int beg_loc = scanner().location().beg_pos; 655 int beg_loc = scanner().location().beg_pos;
655 ParseSourceElements(body, Token::EOS, &ok); 656 ParseSourceElements(body, Token::EOS, &ok);
656 if (ok && top_scope_->is_strict_mode()) { 657 if (ok && top_scope_->is_strict_mode()) {
657 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok); 658 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok);
658 } 659 }
659 660
660 if (ok && harmony_scoping_) { 661 if (ok && harmony_scoping_) {
661 CheckConflictingVarDeclarations(scope, &ok); 662 CheckConflictingVarDeclarations(scope, &ok);
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
727 fni_->PushEnclosingName(name); 728 fni_->PushEnclosingName(name);
728 729
729 mode_ = PARSE_EAGERLY; 730 mode_ = PARSE_EAGERLY;
730 731
731 // Place holder for the result. 732 // Place holder for the result.
732 FunctionLiteral* result = NULL; 733 FunctionLiteral* result = NULL;
733 734
734 { 735 {
735 // Parse the function literal. 736 // Parse the function literal.
736 Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE); 737 Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE);
738 info->SetGlobalScope(scope);
737 if (!info->closure().is_null()) { 739 if (!info->closure().is_null()) {
738 scope = Scope::DeserializeScopeChain(info, scope); 740 scope = Scope::DeserializeScopeChain(info->closure()->context(), scope);
739 } 741 }
740 FunctionState function_state(this, scope, isolate()); 742 FunctionState function_state(this, scope, isolate());
741 ASSERT(scope->strict_mode_flag() == kNonStrictMode || 743 ASSERT(scope->strict_mode_flag() == kNonStrictMode ||
742 scope->strict_mode_flag() == info->strict_mode_flag()); 744 scope->strict_mode_flag() == info->strict_mode_flag());
743 ASSERT(info->strict_mode_flag() == shared_info->strict_mode_flag()); 745 ASSERT(info->strict_mode_flag() == shared_info->strict_mode_flag());
744 scope->SetStrictModeFlag(shared_info->strict_mode_flag()); 746 scope->SetStrictModeFlag(shared_info->strict_mode_flag());
745 FunctionLiteral::Type type = shared_info->is_expression() 747 FunctionLiteral::Type type = shared_info->is_expression()
746 ? (shared_info->is_anonymous() 748 ? (shared_info->is_anonymous()
747 ? FunctionLiteral::ANONYMOUS_EXPRESSION 749 ? FunctionLiteral::ANONYMOUS_EXPRESSION
748 : FunctionLiteral::NAMED_EXPRESSION) 750 : FunctionLiteral::NAMED_EXPRESSION)
(...skipping 606 matching lines...) Expand 10 before | Expand all | Expand 10 after
1355 bool resolve, 1357 bool resolve,
1356 bool* ok) { 1358 bool* ok) {
1357 Variable* var = NULL; 1359 Variable* var = NULL;
1358 // If we are inside a function, a declaration of a var/const variable is a 1360 // If we are inside a function, a declaration of a var/const variable is a
1359 // truly local variable, and the scope of the variable is always the function 1361 // truly local variable, and the scope of the variable is always the function
1360 // scope. 1362 // scope.
1361 // Let/const variables in harmony mode are always added to the immediately 1363 // Let/const variables in harmony mode are always added to the immediately
1362 // enclosing scope. 1364 // enclosing scope.
1363 Scope* declaration_scope = (mode == LET || mode == CONST_HARMONY) 1365 Scope* declaration_scope = (mode == LET || mode == CONST_HARMONY)
1364 ? top_scope_ : top_scope_->DeclarationScope(); 1366 ? top_scope_ : top_scope_->DeclarationScope();
1367 InitializationFlag init_flag = (fun != NULL || mode == VAR)
1368 ? kCreatedInitialized : kNeedsInitialization;
1365 1369
1366 // If a function scope exists, then we can statically declare this 1370 // If a function scope exists, then we can statically declare this
1367 // variable and also set its mode. In any case, a Declaration node 1371 // variable and also set its mode. In any case, a Declaration node
1368 // will be added to the scope so that the declaration can be added 1372 // will be added to the scope so that the declaration can be added
1369 // to the corresponding activation frame at runtime if necessary. 1373 // to the corresponding activation frame at runtime if necessary.
1370 // For instance declarations inside an eval scope need to be added 1374 // For instance declarations inside an eval scope need to be added
1371 // to the calling function context. 1375 // to the calling function context.
1372 // Similarly, strict mode eval scope does not leak variable declarations to 1376 // Similarly, strict mode eval scope does not leak variable declarations to
1373 // the caller's scope so we declare all locals, too. 1377 // the caller's scope so we declare all locals, too.
1374 // Also for block scoped let/const bindings the variable can be 1378 // Also for block scoped let/const bindings the variable can be
1375 // statically declared. 1379 // statically declared.
1376 if (declaration_scope->is_function_scope() || 1380 if (declaration_scope->is_function_scope() ||
1377 declaration_scope->is_strict_mode_eval_scope() || 1381 declaration_scope->is_strict_mode_eval_scope() ||
1378 declaration_scope->is_block_scope()) { 1382 declaration_scope->is_block_scope()) {
1379 // Declare the variable in the function scope. 1383 // Declare the variable in the function scope.
1380 var = declaration_scope->LocalLookup(name); 1384 var = declaration_scope->LocalLookup(name);
1381 if (var == NULL) { 1385 if (var == NULL) {
1382 // Declare the name. 1386 // Declare the name.
1383 InitializationFlag init_flag = (fun != NULL || mode == VAR)
1384 ? kCreatedInitialized : kNeedsInitialization;
1385 var = declaration_scope->DeclareLocal(name, mode, init_flag); 1387 var = declaration_scope->DeclareLocal(name, mode, init_flag);
1386 } else { 1388 } else {
1387 // The name was declared in this scope before; check for conflicting 1389 // The name was declared in this scope before; check for conflicting
1388 // re-declarations. We have a conflict if either of the declarations is 1390 // re-declarations. We have a conflict if either of the declarations is
1389 // not a var. There is similar code in runtime.cc in the Declare 1391 // not a var. There is similar code in runtime.cc in the Declare
1390 // functions. The function CheckNonConflictingScope checks for conflicting 1392 // functions. The function CheckNonConflictingScope checks for conflicting
1391 // var and let bindings from different scopes whereas this is a check for 1393 // var and let bindings from different scopes whereas this is a check for
1392 // conflicting declarations within the same scope. This check also covers 1394 // conflicting declarations within the same scope. This check also covers
1393 // 1395 //
1394 // function () { let x; { var x; } } 1396 // function () { let x; { var x; } }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1437 // WARNING: This will lead to multiple declaration nodes for the 1439 // WARNING: This will lead to multiple declaration nodes for the
1438 // same variable if it is declared several times. This is not a 1440 // same variable if it is declared several times. This is not a
1439 // semantic issue as long as we keep the source order, but it may be 1441 // semantic issue as long as we keep the source order, but it may be
1440 // a performance issue since it may lead to repeated 1442 // a performance issue since it may lead to repeated
1441 // Runtime::DeclareContextSlot() calls. 1443 // Runtime::DeclareContextSlot() calls.
1442 VariableProxy* proxy = declaration_scope->NewUnresolved( 1444 VariableProxy* proxy = declaration_scope->NewUnresolved(
1443 name, scanner().location().beg_pos); 1445 name, scanner().location().beg_pos);
1444 declaration_scope->AddDeclaration( 1446 declaration_scope->AddDeclaration(
1445 new(zone()) Declaration(proxy, mode, fun, top_scope_)); 1447 new(zone()) Declaration(proxy, mode, fun, top_scope_));
1446 1448
1447 // For global const variables we bind the proxy to a variable.
1448 if ((mode == CONST || mode == CONST_HARMONY) && 1449 if ((mode == CONST || mode == CONST_HARMONY) &&
1449 declaration_scope->is_global_scope()) { 1450 declaration_scope->is_global_scope()) {
1451 // For global const variables we bind the proxy to a variable.
1450 ASSERT(resolve); // should be set by all callers 1452 ASSERT(resolve); // should be set by all callers
1451 Variable::Kind kind = Variable::NORMAL; 1453 Variable::Kind kind = Variable::NORMAL;
1452 var = new(zone()) Variable(declaration_scope, 1454 var = new(zone()) Variable(declaration_scope,
1453 name, 1455 name,
1454 CONST, 1456 mode,
1455 true, 1457 true,
1456 kind, 1458 kind,
1457 kNeedsInitialization); 1459 kNeedsInitialization);
1460 } else if (declaration_scope->is_eval_scope() &&
1461 !declaration_scope->is_strict_mode()) {
1462 // For variable declarations in a non-strict eval scope the proxy is bound
1463 // to a lookup variable to force a dynamic declaration using the
1464 // DeclareContextSlot runtime function.
1465 Variable::Kind kind = Variable::NORMAL;
1466 var = new(zone()) Variable(declaration_scope,
1467 name,
1468 mode,
1469 true,
1470 kind,
1471 init_flag);
1472 var->AllocateTo(Variable::LOOKUP, -1);
1473 resolve = true;
1458 } 1474 }
1459 1475
1460 // If requested and we have a local variable, bind the proxy to the variable 1476 // If requested and we have a local variable, bind the proxy to the variable
1461 // at parse-time. This is used for functions (and consts) declared inside 1477 // at parse-time. This is used for functions (and consts) declared inside
1462 // statements: the corresponding function (or const) variable must be in the 1478 // statements: the corresponding function (or const) variable must be in the
1463 // function scope and not a statement-local scope, e.g. as provided with a 1479 // function scope and not a statement-local scope, e.g. as provided with a
1464 // 'with' statement: 1480 // 'with' statement:
1465 // 1481 //
1466 // with (obj) { 1482 // with (obj) {
1467 // function f() {} 1483 // function f() {}
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after
1894 // the number of arguments (2 or 3). 1910 // the number of arguments (2 or 3).
1895 initialize = 1911 initialize =
1896 new(zone()) CallRuntime( 1912 new(zone()) CallRuntime(
1897 isolate(), 1913 isolate(),
1898 isolate()->factory()->InitializeVarGlobal_symbol(), 1914 isolate()->factory()->InitializeVarGlobal_symbol(),
1899 Runtime::FunctionForId(Runtime::kInitializeVarGlobal), 1915 Runtime::FunctionForId(Runtime::kInitializeVarGlobal),
1900 arguments); 1916 arguments);
1901 } 1917 }
1902 1918
1903 block->AddStatement(new(zone()) ExpressionStatement(initialize)); 1919 block->AddStatement(new(zone()) ExpressionStatement(initialize));
1920 } else if (needs_init) {
1921 // Constant initializations always assign to the declared constant which
1922 // is always at the function scope level. This is only relevant for
1923 // dynamically looked-up variables and constants (the start context for
1924 // constant lookups is always the function context, while it is the top
1925 // context for var declared variables). Sigh...
1926 // For 'let' and 'const' declared variables in harmony mode the
1927 // initialization also always assigns to the declared variable.
1928 ASSERT(proxy != NULL);
1929 ASSERT(proxy->var() != NULL);
1930 ASSERT(value != NULL);
1931 Assignment* assignment =
1932 new(zone()) Assignment(isolate(), init_op, proxy, value, position);
1933 block->AddStatement(new(zone()) ExpressionStatement(assignment));
1934 value = NULL;
1904 } 1935 }
1905 1936
1906 // Add an assignment node to the initialization statement block if we still 1937 // Add an assignment node to the initialization statement block if we still
1907 // have a pending initialization value. We must distinguish between 1938 // have a pending initialization value.
1908 // different kinds of declarations: 'var' initializations are simply
1909 // assignments (with all the consequences if they are inside a 'with'
1910 // statement - they may change a 'with' object property). Constant
1911 // initializations always assign to the declared constant which is
1912 // always at the function scope level. This is only relevant for
1913 // dynamically looked-up variables and constants (the start context
1914 // for constant lookups is always the function context, while it is
1915 // the top context for var declared variables). Sigh...
1916 // For 'let' and 'const' declared variables in harmony mode the
1917 // initialization is in the same scope as the declaration. Thus dynamic
1918 // lookups are unnecessary even if the block scope is inside a with.
1919 if (value != NULL) { 1939 if (value != NULL) {
1940 ASSERT(mode == VAR);
1941 // 'var' initializations are simply assignments (with all the consequences
1942 // if they are inside a 'with' statement - they may change a 'with' object
1943 // property).
1920 VariableProxy* proxy = initialization_scope->NewUnresolved(name); 1944 VariableProxy* proxy = initialization_scope->NewUnresolved(name);
1921 Assignment* assignment = 1945 Assignment* assignment =
1922 new(zone()) Assignment(isolate(), init_op, proxy, value, position); 1946 new(zone()) Assignment(isolate(), init_op, proxy, value, position);
1923 block->AddStatement(new(zone()) ExpressionStatement(assignment)); 1947 block->AddStatement(new(zone()) ExpressionStatement(assignment));
1924 } 1948 }
1925 1949
1926 if (fni_ != NULL) fni_->Leave(); 1950 if (fni_ != NULL) fni_->Leave();
1927 } while (peek() == Token::COMMA); 1951 } while (peek() == Token::COMMA);
1928 1952
1929 // If there was a single non-const declaration, return it in the output 1953 // If there was a single non-const declaration, return it in the output
(...skipping 3449 matching lines...) Expand 10 before | Expand all | Expand 10 after
5379 return !parser.failed(); 5403 return !parser.failed();
5380 } 5404 }
5381 5405
5382 5406
5383 bool ParserApi::Parse(CompilationInfo* info) { 5407 bool ParserApi::Parse(CompilationInfo* info) {
5384 ASSERT(info->function() == NULL); 5408 ASSERT(info->function() == NULL);
5385 FunctionLiteral* result = NULL; 5409 FunctionLiteral* result = NULL;
5386 Handle<Script> script = info->script(); 5410 Handle<Script> script = info->script();
5387 bool harmony_scoping = !info->is_native() && FLAG_harmony_scoping; 5411 bool harmony_scoping = !info->is_native() && FLAG_harmony_scoping;
5388 if (info->is_lazy()) { 5412 if (info->is_lazy()) {
5413 ASSERT(!info->is_eval());
5389 bool allow_natives_syntax = 5414 bool allow_natives_syntax =
5390 FLAG_allow_natives_syntax || 5415 FLAG_allow_natives_syntax ||
5391 info->is_native(); 5416 info->is_native();
5392 Parser parser(script, allow_natives_syntax, NULL, NULL); 5417 Parser parser(script, allow_natives_syntax, NULL, NULL);
5393 parser.SetHarmonyScoping(harmony_scoping); 5418 parser.SetHarmonyScoping(harmony_scoping);
5394 result = parser.ParseLazy(info); 5419 result = parser.ParseLazy(info);
5395 } else { 5420 } else {
5396 // Whether we allow %identifier(..) syntax. 5421 // Whether we allow %identifier(..) syntax.
5397 bool allow_natives_syntax = 5422 bool allow_natives_syntax =
5398 info->is_native() || FLAG_allow_natives_syntax; 5423 info->is_native() || FLAG_allow_natives_syntax;
5399 ScriptDataImpl* pre_data = info->pre_parse_data(); 5424 ScriptDataImpl* pre_data = info->pre_parse_data();
5400 Parser parser(script, 5425 Parser parser(script,
5401 allow_natives_syntax, 5426 allow_natives_syntax,
5402 info->extension(), 5427 info->extension(),
5403 pre_data); 5428 pre_data);
5404 parser.SetHarmonyScoping(harmony_scoping); 5429 parser.SetHarmonyScoping(harmony_scoping);
5405 if (pre_data != NULL && pre_data->has_error()) { 5430 if (pre_data != NULL && pre_data->has_error()) {
5406 Scanner::Location loc = pre_data->MessageLocation(); 5431 Scanner::Location loc = pre_data->MessageLocation();
5407 const char* message = pre_data->BuildMessage(); 5432 const char* message = pre_data->BuildMessage();
5408 Vector<const char*> args = pre_data->BuildArgs(); 5433 Vector<const char*> args = pre_data->BuildArgs();
5409 parser.ReportMessageAt(loc, message, args); 5434 parser.ReportMessageAt(loc, message, args);
5410 DeleteArray(message); 5435 DeleteArray(message);
5411 for (int i = 0; i < args.length(); i++) { 5436 for (int i = 0; i < args.length(); i++) {
5412 DeleteArray(args[i]); 5437 DeleteArray(args[i]);
5413 } 5438 }
5414 DeleteArray(args.start()); 5439 DeleteArray(args.start());
5415 ASSERT(info->isolate()->has_pending_exception()); 5440 ASSERT(info->isolate()->has_pending_exception());
5416 } else { 5441 } else {
5417 Handle<String> source = Handle<String>(String::cast(script->source())); 5442 result = parser.ParseProgram(info);
5418 result = parser.ParseProgram(source,
5419 info->is_global(),
5420 info->strict_mode_flag());
5421 } 5443 }
5422 } 5444 }
5423 info->SetFunction(result); 5445 info->SetFunction(result);
5424 return (result != NULL); 5446 return (result != NULL);
5425 } 5447 }
5426 5448
5427 } } // namespace v8::internal 5449 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/runtime.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698