60 previous_ = stack->top();
66 Element* previous() {
return previous_; }
67 int value() {
return value_; }
76 int result = top_->value();
77 top_ = top_->previous();
82 Element* top() {
return top_; }
83 void set_top(Element* value) { top_ = value; }
91 pending_empty_(
false),
96 , last_added_(ADD_NONE)
101 void RegExpBuilder::FlushCharacters() {
102 pending_empty_ =
false;
103 if (characters_ !=
NULL) {
106 text_.Add(atom, zone());
112 void RegExpBuilder::FlushText() {
114 int num_text = text_.length();
117 }
else if (num_text == 1) {
118 terms_.Add(text_.last(), zone());
120 RegExpText* text =
new(zone()) RegExpText(zone());
121 for (
int i = 0; i < num_text; i++)
122 text_.Get(i)->AppendToText(text, zone());
123 terms_.Add(text, zone());
130 pending_empty_ =
false;
131 if (characters_ ==
NULL) {
134 characters_->
Add(c, zone());
140 pending_empty_ =
true;
145 if (term->IsEmpty()) {
151 text_.Add(term, zone());
154 terms_.Add(term, zone());
162 terms_.Add(assert, zone());
172 void RegExpBuilder::FlushTerms() {
174 int num_terms = terms_.length();
176 if (num_terms == 0) {
178 }
else if (num_terms == 1) {
179 alternative = terms_.last();
181 alternative =
new(zone()) RegExpAlternative(terms_.GetList(zone()));
183 alternatives_.Add(alternative, zone());
191 int num_alternatives = alternatives_.length();
192 if (num_alternatives == 0) {
195 if (num_alternatives == 1) {
196 return alternatives_.last();
205 if (pending_empty_) {
206 pending_empty_ =
false;
210 if (characters_ !=
NULL) {
211 ASSERT(last_added_ == ADD_CHAR);
214 int num_chars = char_vector.
length();
217 text_.Add(
new(zone())
RegExpAtom(prefix), zone());
218 char_vector = char_vector.
SubVector(num_chars - 1, num_chars);
223 }
else if (text_.length() > 0) {
224 ASSERT(last_added_ == ADD_ATOM);
225 atom = text_.RemoveLast();
227 }
else if (terms_.length() > 0) {
228 ASSERT(last_added_ == ADD_ATOM);
229 atom = terms_.RemoveLast();
236 terms_.Add(atom, zone());
254 if (static_cast<unsigned>(symbol_id)
255 >= static_cast<unsigned>(symbol_cache_.length())) {
258 scanner().literal_ascii_string());
261 scanner().literal_utf16_string());
264 return LookupCachedSymbol(symbol_id);
268 Handle<String> Parser::LookupCachedSymbol(
int symbol_id) {
270 if (symbol_cache_.length() <= symbol_id) {
273 symbol_id + 1 - symbol_cache_.length(), zone());
275 Handle<String> result = symbol_cache_.
at(symbol_id);
276 if (result.is_null()) {
279 scanner().literal_ascii_string());
282 scanner().literal_utf16_string());
284 symbol_cache_.
at(symbol_id) = result;
287 isolate()->
counters()->total_preparse_symbols_skipped()->Increment();
295 if ((function_index_ + FunctionEntry::kSize <= store_.
length())
296 && (static_cast<int>(store_[function_index_]) == start)) {
297 int index = function_index_;
298 function_index_ += FunctionEntry::kSize;
299 return FunctionEntry(store_.
SubVector(index,
300 index + FunctionEntry::kSize));
302 return FunctionEntry();
307 return ReadNumber(&symbol_data_);
329 for (
unsigned int i = 0; i <= arg_count; i++) {
333 int length =
static_cast<int>(
Read(pos));
334 if (length < 0)
return false;
345 if (functions_size < 0)
return false;
346 if (functions_size % FunctionEntry::kSize != 0)
return false;
350 if (symbol_count < 0)
return false;
354 if (store_.
length() < minimum_size)
return false;
360 const char* ScriptDataImpl::ReadString(
unsigned* start,
int* chars) {
361 int length = start[0];
362 char* result = NewArray<char>(length + 1);
363 for (
int i = 0; i < length; i++) {
364 result[i] = start[i + 1];
366 result[length] =
'\0';
367 if (chars !=
NULL) *chars = length;
380 return ReadString(start,
NULL);
386 const char** array = NewArray<const char*>(arg_count);
391 for (
int i = 0; i < arg_count; i++) {
393 array[i] = ReadString(ReadAddress(pos), &count);
405 unsigned* ScriptDataImpl::ReadAddress(
int position) {
411 Scope* result =
new(zone()) Scope(parent, type, zone());
412 result->Initialize();
426 : variable_(variable), node_(node), previous_(*variable) {
431 *variable_ = previous_;
447 : variable_(variable), previous_(*variable) {
452 *variable_ = previous_;
472 outer_scope_(parser->top_scope_) {
473 parser->top_scope_ = scope;
484 Parser::FunctionState::FunctionState(Parser* parser,
487 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize),
488 next_handler_index_(0),
489 expected_property_count_(0),
490 only_simple_this_property_assignments_(
false),
491 this_property_assignments_(isolate->factory()->empty_fixed_array()),
493 outer_function_state_(parser->current_function_state_),
494 outer_scope_(parser->top_scope_),
495 saved_ast_node_id_(isolate->ast_node_id()),
497 parser->top_scope_ = scope;
498 parser->current_function_state_ =
this;
503 Parser::FunctionState::~FunctionState() {
504 parser_->top_scope_ = outer_scope_;
505 parser_->current_function_state_ = outer_function_state_;
506 if (outer_function_state_ !=
NULL) {
507 parser_->isolate()->set_ast_node_id(saved_ast_node_id_);
520 #define CHECK_OK ok); \
521 if (!*ok) return NULL; \
523 #define DUMMY ) // to make indentation work
526 #define CHECK_FAILED ); \
527 if (failed_) return NULL; \
529 #define DUMMY ) // to make indentation work
540 : isolate_(script->GetIsolate()),
541 symbol_cache_(pre_data ? pre_data->symbol_count() : 0, zone),
543 scanner_(isolate_->unicode_cache()),
544 reusable_preparser_(
NULL),
546 current_function_state_(
NULL),
548 extension_(extension),
552 allow_lazy_((parser_flags &
kAllowLazy) != 0),
554 stack_overflow_(
false),
555 parenthesized_function_(
false),
557 isolate_->set_ast_node_id(0);
570 HistogramTimerScope timer(isolate()->counters()->parse());
572 isolate()->counters()->total_parse_size()->Increment(source->length());
576 source->TryFlatten();
577 if (source->IsExternalTwoByteString()) {
584 return DoParseProgram(info, source, &zone_scope);
588 return DoParseProgram(info, source, &zone_scope);
595 ZoneScope* zone_scope) {
601 mode_ = (FLAG_lazy && allow_lazy_) ? PARSE_LAZILY : PARSE_EAGERLY;
602 if (allow_natives_syntax_ || extension_ !=
NULL) mode_ = PARSE_EAGERLY;
608 info->SetGlobalScope(scope);
609 if (info->is_eval()) {
611 if (!info->is_global() && (shared.
is_null() || shared->is_function())) {
623 ZoneList<Statement*>* body =
new(zone()) ZoneList<Statement*>(16, zone());
626 ParseSourceElements(body, Token::EOS, info->is_eval(), &ok);
628 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok);
631 if (ok && is_extended_mode()) {
632 CheckConflictingVarDeclarations(top_scope_, &ok);
636 result = factory()->NewFunctionLiteral(
640 function_state.materialized_literal_count(),
641 function_state.expected_property_count(),
642 function_state.handler_count(),
643 function_state.only_simple_this_property_assignments(),
644 function_state.this_property_assignments(),
650 }
else if (stack_overflow_) {
651 isolate()->StackOverflow();
660 if (result ==
NULL) zone_scope->DeleteOnExit();
667 HistogramTimerScope timer(isolate()->counters()->parse_lazy());
669 isolate()->counters()->total_parse_size()->Increment(source->length());
673 source->TryFlatten();
674 if (source->IsExternalTwoByteString()) {
677 shared_info->start_position(),
678 shared_info->end_position());
683 shared_info->start_position(),
684 shared_info->end_position());
693 ZoneScope* zone_scope) {
703 mode_ = PARSE_EAGERLY;
711 info->SetGlobalScope(scope);
712 if (!info->closure().is_null()) {
719 info->is_extended_mode());
720 ASSERT(info->language_mode() == shared_info->language_mode());
723 ? (shared_info->is_anonymous()
724 ? FunctionLiteral::ANONYMOUS_EXPRESSION
728 result = ParseFunctionLiteral(
name,
730 RelocInfo::kNoPosition,
742 if (result ==
NULL) {
743 zone_scope->DeleteOnExit();
744 if (stack_overflow_) isolate()->StackOverflow();
746 Handle<String> inferred_name(shared_info->inferred_name());
753 Handle<String> Parser::GetSymbol(
bool* ok) {
755 if (pre_data() !=
NULL) {
758 return LookupSymbol(symbol_id);
762 void Parser::ReportMessage(
const char* type, Vector<const char*> args) {
763 Scanner::Location source_location = scanner().
location();
768 void Parser::ReportMessage(
const char* type, Vector<Handle<String> > args) {
769 Scanner::Location source_location = scanner().
location();
780 Factory* factory = isolate()->factory();
782 for (
int i = 0; i < args.
length(); i++) {
784 elements->set(i, *arg_string);
788 isolate()->Throw(*result, &location);
798 Factory* factory = isolate()->factory();
800 for (
int i = 0; i < args.length(); i++) {
801 elements->set(i, *args[i]);
805 isolate()->Throw(*result, &location);
818 return exp_stat->
expression()->AsAssignment();
832 : enabled_(top_scope->DeclarationScope()->is_global_scope() &&
833 !IsLoopTarget(target)),
834 first_in_block_(
NULL),
835 last_in_block_(
NULL),
839 if (!enabled_)
return;
840 if (InBlock()) EndBlock();
844 if (!enabled_)
return;
847 if (BlockContinues(assignment)) {
848 UpdateBlock(assignment);
853 if (!InBlock() && (assignment !=
NULL) &&
854 (assignment->
op() == Token::ASSIGN)) {
855 StartBlock(assignment);
863 static const int kMinInitializationBlock = 3;
865 static bool IsLoopTarget(Target* target) {
866 while (target !=
NULL) {
867 if (target->node()->AsIterationStatement() !=
NULL)
return true;
868 target = target->previous();
876 static bool SameObject(Expression* e1, Expression* e2) {
877 VariableProxy* v1 = e1->AsVariableProxy();
878 VariableProxy* v2 = e2->AsVariableProxy();
880 return v1->name()->Equals(*v2->name());
882 Property*
p1 = e1->AsProperty();
883 Property*
p2 = e2->AsProperty();
884 if ((p1 ==
NULL) || (p2 ==
NULL))
return false;
885 Literal* key1 = p1->key()->AsLiteral();
886 Literal* key2 = p2->key()->AsLiteral();
887 if ((key1 ==
NULL) || (key2 ==
NULL))
return false;
888 if (!key1->handle()->IsString() || !key2->handle()->IsString()) {
893 if (!name1->Equals(name2))
return false;
894 return SameObject(p1->obj(), p2->obj());
899 static bool PropertyOfSameObject(Expression* e1, Expression* e2) {
900 Property* p1 = e1->AsProperty();
901 Property* p2 = e2->AsProperty();
902 if ((p1 ==
NULL) || (p2 ==
NULL))
return false;
903 return SameObject(p1->obj(), p2->obj());
906 bool BlockContinues(Assignment* assignment) {
907 if ((assignment ==
NULL) || (first_in_block_ ==
NULL))
return false;
908 if (assignment->op() != Token::ASSIGN)
return false;
909 return PropertyOfSameObject(first_in_block_->
target(),
910 assignment->target());
913 void StartBlock(Assignment* assignment) {
914 first_in_block_ = assignment;
915 last_in_block_ = assignment;
919 void UpdateBlock(Assignment* assignment) {
920 last_in_block_ = assignment;
925 if (block_size_ >= kMinInitializationBlock) {
929 last_in_block_ = first_in_block_ =
NULL;
933 bool InBlock() {
return first_in_block_ !=
NULL; }
936 Assignment* first_in_block_;
937 Assignment* last_in_block_;
951 only_simple_this_property_assignments_(
true),
953 assigned_arguments_(0, zone),
954 assigned_constants_(0, zone),
961 if (!only_simple_this_property_assignments_) {
967 if (IsThisPropertyAssignment(assignment)) {
968 HandleThisPropertyAssignment(scope, assignment);
970 only_simple_this_property_assignments_ =
false;
977 return only_simple_this_property_assignments_;
983 if (names_.is_empty()) {
984 return isolate_->
factory()->empty_fixed_array();
986 ASSERT_EQ(names_.length(), assigned_arguments_.length());
987 ASSERT_EQ(names_.length(), assigned_constants_.length());
990 for (
int i = 0; i < names_.length(); ++i) {
991 assignments->set(i * 3, *names_[i]);
992 assignments->set(i * 3 + 1,
Smi::FromInt(assigned_arguments_[i]));
993 assignments->set(i * 3 + 2, *assigned_constants_[i]);
999 bool IsThisPropertyAssignment(
Assignment* assignment) {
1000 if (assignment !=
NULL) {
1002 return assignment->
op() == Token::ASSIGN
1004 &&
property->obj()->AsVariableProxy() !=
NULL
1005 &&
property->obj()->AsVariableProxy()->is_this();
1010 void HandleThisPropertyAssignment(Scope* scope, Assignment* assignment) {
1013 Property*
property = assignment->
target()->AsProperty();
1015 Literal* literal =
property->key()->AsLiteral();
1017 if (literal !=
NULL &&
1018 literal->handle()->IsString() &&
1020 isolate_->
heap()->Proto_symbol()) &&
1026 if (assignment->value()->AsLiteral() !=
NULL) {
1028 Literal* literal = assignment->value()->AsLiteral();
1029 AssignmentFromConstant(key, literal->handle());
1031 }
else if (assignment->value()->AsVariableProxy() !=
NULL) {
1033 Handle<String>
name =
1034 assignment->value()->AsVariableProxy()->name();
1036 for (
int i = 0; i < scope->num_parameters(); i++) {
1037 if (*scope->parameter(i)->name() == *
name) {
1039 AssignmentFromParameter(key, i);
1047 AssignmentFromSomethingElse();
1055 void AssignmentFromParameter(Handle<String> name,
int index) {
1056 EnsureInitialized();
1057 for (
int i = 0; i < names_.length(); ++i) {
1058 if (name->Equals(*names_[i])) {
1059 assigned_arguments_[i] = index;
1060 assigned_constants_[i] = isolate_->
factory()->undefined_value();
1064 names_.
Add(name, zone());
1065 assigned_arguments_.
Add(index, zone());
1066 assigned_constants_.
Add(isolate_->
factory()->undefined_value(), zone());
1069 void AssignmentFromConstant(Handle<String> name, Handle<Object> value) {
1070 EnsureInitialized();
1071 for (
int i = 0; i < names_.length(); ++i) {
1072 if (name->Equals(*names_[i])) {
1073 assigned_arguments_[i] = -1;
1074 assigned_constants_[i] = value;
1078 names_.
Add(name, zone());
1079 assigned_arguments_.
Add(-1, zone());
1080 assigned_constants_.
Add(value, zone());
1083 void AssignmentFromSomethingElse() {
1085 only_simple_this_property_assignments_ =
false;
1088 void EnsureInitialized() {
1089 if (names_.capacity() == 0) {
1090 ASSERT(assigned_arguments_.capacity() == 0);
1091 ASSERT(assigned_constants_.capacity() == 0);
1092 names_.Initialize(4, zone());
1093 assigned_arguments_.Initialize(4, zone());
1094 assigned_constants_.Initialize(4, zone());
1098 Zone* zone()
const {
return zone_; }
1101 bool only_simple_this_property_assignments_;
1103 ZoneList<int> assigned_arguments_;
1109 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
1120 TargetScope scope(&this->target_stack_);
1123 InitializationBlockFinder block_finder(top_scope_, target_stack_);
1124 ThisNamedPropertyAssignmentFinder this_property_assignment_finder(isolate(),
1126 bool directive_prologue =
true;
1128 while (peek() != end_token) {
1129 if (directive_prologue && peek() != Token::STRING) {
1130 directive_prologue =
false;
1135 if (stat ==
NULL || stat->IsEmpty()) {
1136 directive_prologue =
false;
1140 if (directive_prologue) {
1142 ExpressionStatement* e_stat;
1145 if ((e_stat = stat->AsExpressionStatement()) !=
NULL &&
1146 (literal = e_stat->expression()->AsLiteral()) !=
NULL &&
1147 literal->handle()->IsString()) {
1152 directive->Equals(isolate()->heap()->use_strict()) &&
1153 token_loc.end_pos - token_loc.beg_pos ==
1154 isolate()->heap()->use_strict()->length() + 2) {
1161 Scope* scope = NewScope(top_scope_,
EVAL_SCOPE);
1170 directive_prologue =
false;
1174 directive_prologue =
false;
1178 block_finder.Update(stat);
1181 this_property_assignment_finder.Update(top_scope_, stat);
1183 processor->Add(stat, zone());
1188 bool only_simple_this_property_assignments =
1189 this_property_assignment_finder.only_simple_this_property_assignments()
1191 if (only_simple_this_property_assignments) {
1192 current_function_state_->SetThisPropertyAssignmentInfo(
1193 only_simple_this_property_assignments,
1194 this_property_assignment_finder.GetThisPropertyAssignments());
1218 case Token::FUNCTION:
1219 return ParseFunctionDeclaration(
NULL, ok);
1222 return ParseVariableStatement(kModuleElement,
NULL, ok);
1224 return ParseImportDeclaration(ok);
1226 return ParseExportDeclaration(ok);
1228 Statement* stmt = ParseStatement(labels,
CHECK_OK);
1230 if (FLAG_harmony_modules &&
1231 peek() == Token::IDENTIFIER &&
1232 !scanner().HasAnyLineTerminatorBeforeNext() &&
1234 ExpressionStatement* estmt = stmt->AsExpressionStatement();
1235 if (estmt !=
NULL &&
1236 estmt->expression()->AsVariableProxy() !=
NULL &&
1237 estmt->expression()->AsVariableProxy()->name()->Equals(
1238 isolate()->heap()->module_symbol()) &&
1240 return ParseModuleDeclaration(
NULL, ok);
1254 Block* block = factory()->NewBlock(
NULL, 1,
true, zone());
1255 Handle<String> name = ParseIdentifier(
CHECK_OK);
1258 if (FLAG_print_interface_details)
1259 PrintF(
"# Module %s...\n", name->ToAsciiArray());
1262 Module* module = ParseModule(
CHECK_OK);
1263 VariableProxy* proxy = NewUnresolved(name,
LET, module->interface());
1264 Declaration* declaration =
1265 factory()->NewModuleDeclaration(proxy, module, top_scope_);
1266 Declare(declaration,
true,
CHECK_OK);
1269 if (FLAG_print_interface_details)
1270 PrintF(
"# Module %s.\n", name->ToAsciiArray());
1272 if (FLAG_print_interfaces) {
1273 PrintF(
"module %s : ", name->ToAsciiArray());
1274 module->interface()->Print();
1280 if (names) names->Add(name, zone());
1285 Module* Parser::ParseModule(
bool* ok) {
1293 return ParseModuleLiteral(ok);
1295 case Token::ASSIGN: {
1297 Module* result = ParseModulePath(
CHECK_OK);
1303 ExpectContextualKeyword(
"at",
CHECK_OK);
1304 Module* result = ParseModuleUrl(
CHECK_OK);
1312 Module* Parser::ParseModuleLiteral(
bool* ok) {
1317 Block* body = factory()->NewBlock(
NULL, 16,
false, zone());
1319 if (FLAG_print_interface_details)
PrintF(
"# Literal ");
1324 scope->set_start_position(scanner().location().beg_pos);
1329 TargetCollector collector(zone());
1330 Target target(&this->target_stack_, &collector);
1331 Target target_body(&this->target_stack_, body);
1332 InitializationBlockFinder block_finder(top_scope_, target_stack_);
1334 while (peek() != Token::RBRACE) {
1336 if (stat && !stat->IsEmpty()) {
1337 body->AddStatement(stat, zone());
1338 block_finder.Update(stat);
1344 scope->set_end_position(scanner().location().end_pos);
1345 body->set_scope(scope);
1350 Interface*
interface = scope->interface();
1351 interface->MakeModule(ok);
1353 interface->MakeSingleton(Isolate::Current()->factory()->NewJSModule(), ok);
1355 interface->Freeze(ok);
1357 return factory()->NewModuleLiteral(body, interface);
1361 Module* Parser::ParseModulePath(
bool* ok) {
1366 Module* result = ParseModuleVariable(
CHECK_OK);
1367 while (Check(Token::PERIOD)) {
1368 Handle<String> name = ParseIdentifierName(
CHECK_OK);
1370 if (FLAG_print_interface_details)
1371 PrintF(
"# Path .%s ", name->ToAsciiArray());
1373 Module* member = factory()->NewModulePath(result, name);
1374 result->interface()->Add(name, member->interface(), zone(), ok);
1377 if (FLAG_print_interfaces) {
1378 PrintF(
"PATH TYPE ERROR at '%s'\n", name->ToAsciiArray());
1380 result->interface()->Print();
1382 member->interface()->Print();
1385 ReportMessage(
"invalid_module_path", Vector<Handle<String> >(&name, 1));
1395 Module* Parser::ParseModuleVariable(
bool* ok) {
1399 Handle<String> name = ParseIdentifier(
CHECK_OK);
1401 if (FLAG_print_interface_details)
1402 PrintF(
"# Module variable %s ", name->ToAsciiArray());
1405 factory(), name, scanner().location().beg_pos,
1408 return factory()->NewModuleVariable(proxy);
1412 Module* Parser::ParseModuleUrl(
bool* ok) {
1417 Handle<String> symbol = GetSymbol(
CHECK_OK);
1422 if (FLAG_print_interface_details)
PrintF(
"# Url ");
1425 Module* result = factory()->NewModuleUrl(symbol);
1426 Interface*
interface = result->interface();
1427 interface->MakeSingleton(Isolate::Current()->factory()->NewJSModule(), ok);
1429 interface->Freeze(ok);
1435 Module* Parser::ParseModuleSpecifier(
bool* ok) {
1440 if (peek() == Token::STRING) {
1441 return ParseModuleUrl(ok);
1443 return ParseModulePath(ok);
1448 Block* Parser::ParseImportDeclaration(
bool* ok) {
1457 Handle<String> name = ParseIdentifierName(
CHECK_OK);
1458 names.Add(name, zone());
1459 while (peek() == Token::COMMA) {
1460 Consume(Token::COMMA);
1461 name = ParseIdentifierName(
CHECK_OK);
1462 names.Add(name, zone());
1465 ExpectContextualKeyword(
"from",
CHECK_OK);
1466 Module* module = ParseModuleSpecifier(
CHECK_OK);
1471 Block* block = factory()->NewBlock(
NULL, 1,
true, zone());
1472 for (
int i = 0; i < names.length(); ++i) {
1474 if (FLAG_print_interface_details)
1475 PrintF(
"# Import %s ", names[i]->ToAsciiArray());
1478 module->interface()->
Add(names[i], interface, zone(), ok);
1481 if (FLAG_print_interfaces) {
1482 PrintF(
"IMPORT TYPE ERROR at '%s'\n", names[i]->ToAsciiArray());
1484 module->interface()->Print();
1487 ReportMessage(
"invalid_module_path", Vector<Handle<String> >(&name, 1));
1490 VariableProxy* proxy = NewUnresolved(names[i],
LET, interface);
1491 Declaration* declaration =
1492 factory()->NewImportDeclaration(proxy, module, top_scope_);
1493 Declare(declaration,
true,
CHECK_OK);
1501 Statement* Parser::ParseExportDeclaration(
bool* ok) {
1512 Statement* result =
NULL;
1515 case Token::IDENTIFIER: {
1516 Handle<String> name = ParseIdentifier(
CHECK_OK);
1518 if (!name->IsEqualTo(
CStrVector(
"module"))) {
1519 names.Add(name, zone());
1520 while (peek() == Token::COMMA) {
1521 Consume(Token::COMMA);
1523 names.Add(name, zone());
1526 result = factory()->NewEmptyStatement();
1528 result = ParseModuleDeclaration(&names,
CHECK_OK);
1533 case Token::FUNCTION:
1534 result = ParseFunctionDeclaration(&names,
CHECK_OK);
1540 result = ParseVariableStatement(kModuleElement, &names,
CHECK_OK);
1545 ReportUnexpectedToken(scanner().current_token());
1550 Interface*
interface = top_scope_->interface();
1551 for (
int i = 0; i < names.length(); ++i) {
1553 if (FLAG_print_interface_details)
1554 PrintF(
"# Export %s ", names[i]->ToAsciiArray());
1557 interface->Add(names[i], inner, zone(),
CHECK_OK);
1560 VariableProxy* proxy = NewUnresolved(names[i],
LET, inner);
1587 case Token::FUNCTION:
1588 return ParseFunctionDeclaration(
NULL, ok);
1591 return ParseVariableStatement(kModuleElement,
NULL, ok);
1593 return ParseStatement(labels, ok);
1598 Statement* Parser::ParseStatement(
ZoneStringList* labels,
bool* ok) {
1625 Statement* stmt =
NULL;
1628 return ParseBlock(labels, ok);
1633 stmt = ParseVariableStatement(kStatement,
NULL, ok);
1636 case Token::SEMICOLON:
1638 return factory()->NewEmptyStatement();
1641 stmt = ParseIfStatement(labels, ok);
1645 stmt = ParseDoWhileStatement(labels, ok);
1649 stmt = ParseWhileStatement(labels, ok);
1653 stmt = ParseForStatement(labels, ok);
1656 case Token::CONTINUE:
1657 stmt = ParseContinueStatement(ok);
1661 stmt = ParseBreakStatement(labels, ok);
1665 stmt = ParseReturnStatement(ok);
1669 stmt = ParseWithStatement(labels, ok);
1673 stmt = ParseSwitchStatement(labels, ok);
1677 stmt = ParseThrowStatement(ok);
1686 Block* result = factory()->NewBlock(labels, 1,
false, zone());
1687 Target target(&this->target_stack_, result);
1688 TryStatement* statement = ParseTryStatement(
CHECK_OK);
1690 statement->set_statement_pos(statement_pos);
1692 if (result) result->AddStatement(statement, zone());
1696 case Token::FUNCTION: {
1710 return ParseFunctionDeclaration(
NULL, ok);
1713 case Token::DEBUGGER:
1714 stmt = ParseDebuggerStatement(ok);
1718 stmt = ParseExpressionOrLabelledStatement(labels, ok);
1722 if (stmt !=
NULL) stmt->set_statement_pos(statement_pos);
1727 VariableProxy* Parser::NewUnresolved(
1728 Handle<String> name,
VariableMode mode, Interface* interface) {
1735 factory(), name, scanner().location().beg_pos, interface);
1739 void Parser::Declare(Declaration* declaration,
bool resolve,
bool* ok) {
1740 VariableProxy* proxy = declaration->proxy();
1741 Handle<String> name = proxy->
name();
1743 Scope* declaration_scope = DeclarationScope(mode);
1744 Variable* var =
NULL;
1756 if (declaration_scope->is_function_scope() ||
1757 declaration_scope->is_strict_or_extended_eval_scope() ||
1758 declaration_scope->is_block_scope() ||
1759 declaration_scope->is_module_scope() ||
1760 declaration->AsModuleDeclaration() !=
NULL) {
1762 var = declaration_scope->LocalLookup(name);
1765 var = declaration_scope->DeclareLocal(
1766 name, mode, declaration->initialization(), proxy->interface());
1779 if ((mode !=
VAR) || (var->mode() !=
VAR)) {
1782 var->mode() ==
CONST ||
1784 var->mode() ==
LET);
1785 if (is_extended_mode()) {
1788 SmartArrayPointer<char> c_string = name->ToCString(
DISALLOW_NULLS);
1789 const char* elms[2] = {
"Variable", *c_string };
1790 Vector<const char*> args(elms, 2);
1791 ReportMessage(
"redeclaration", args);
1795 const char* type = (var->mode() ==
VAR)
1796 ?
"var" : var->is_const_mode() ?
"const" :
"let";
1797 Handle<String> type_string =
1799 Expression* expression =
1800 NewThrowTypeError(isolate()->factory()->redeclaration_symbol(),
1802 declaration_scope->SetIllegalRedeclaration(expression);
1823 declaration_scope->AddDeclaration(declaration);
1826 declaration_scope->is_global_scope()) {
1830 var =
new(zone()) Variable(declaration_scope,
1836 }
else if (declaration_scope->is_eval_scope() &&
1837 declaration_scope->is_classic_mode()) {
1842 var =
new(zone()) Variable(declaration_scope,
1847 declaration->initialization());
1876 if (resolve && var !=
NULL) {
1879 if (FLAG_harmony_modules) {
1882 if (FLAG_print_interface_details)
1883 PrintF(
"# Declare %s\n", var->name()->ToAsciiArray());
1885 proxy->interface()->Unify(var->interface(), zone(), &ok);
1888 if (FLAG_print_interfaces) {
1889 PrintF(
"DECLARE TYPE ERROR\n");
1891 proxy->interface()->Print();
1893 var->interface()->Print();
1896 ReportMessage(
"module_type_error", Vector<Handle<String> >(&name, 1));
1907 Statement* Parser::ParseNativeDeclaration(
bool* ok) {
1909 Handle<String> name = ParseIdentifier(
CHECK_OK);
1911 bool done = (peek() == Token::RPAREN);
1914 done = (peek() == Token::RPAREN);
1920 Expect(Token::SEMICOLON,
CHECK_OK);
1935 const int literals = fun->NumberOfLiterals();
1936 Handle<Code> code = Handle<Code>(fun->shared()->code());
1937 Handle<Code> construct_stub = Handle<Code>(fun->shared()->construct_stub());
1938 Handle<SharedFunctionInfo> shared =
1939 isolate()->factory()->NewSharedFunctionInfo(name, literals, code,
1940 Handle<ScopeInfo>(fun->shared()->scope_info()));
1941 shared->set_construct_stub(*construct_stub);
1944 shared->set_function_data(fun->shared()->function_data());
1945 int parameters = fun->shared()->formal_parameter_count();
1946 shared->set_formal_parameter_count(parameters);
1951 VariableProxy* proxy = NewUnresolved(name,
VAR);
1952 Declaration* declaration =
1953 factory()->NewVariableDeclaration(proxy,
VAR, top_scope_);
1954 Declare(declaration,
true,
CHECK_OK);
1955 SharedFunctionInfoLiteral* lit =
1956 factory()->NewSharedFunctionInfoLiteral(shared);
1957 return factory()->NewExpressionStatement(
1958 factory()->NewAssignment(
1959 Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition));
1963 Statement* Parser::ParseFunctionDeclaration(
ZoneStringList* names,
bool* ok) {
1968 bool is_strict_reserved =
false;
1969 Handle<String> name = ParseIdentifierOrStrictReservedWord(
1971 FunctionLiteral* fun = ParseFunctionLiteral(name,
1973 function_token_position,
1980 VariableProxy* proxy = NewUnresolved(name, mode);
1981 Declaration* declaration =
1982 factory()->NewFunctionDeclaration(proxy, mode, fun, top_scope_);
1983 Declare(declaration,
true,
CHECK_OK);
1984 if (names) names->Add(name, zone());
1985 return factory()->NewEmptyStatement();
1999 Block* result = factory()->NewBlock(labels, 16,
false, zone());
2000 Target target(&this->target_stack_, result);
2002 InitializationBlockFinder block_finder(top_scope_, target_stack_);
2003 while (peek() != Token::RBRACE) {
2005 if (stat && !stat->IsEmpty()) {
2006 result->AddStatement(stat, zone());
2007 block_finder.Update(stat);
2022 Block* body = factory()->NewBlock(labels, 16,
false, zone());
2023 Scope* block_scope = NewScope(top_scope_,
BLOCK_SCOPE);
2027 block_scope->set_start_position(scanner().location().beg_pos);
2029 TargetCollector collector(zone());
2030 Target target(&this->target_stack_, &collector);
2031 Target target_body(&this->target_stack_, body);
2032 InitializationBlockFinder block_finder(top_scope_, target_stack_);
2034 while (peek() != Token::RBRACE) {
2036 if (stat && !stat->IsEmpty()) {
2037 body->AddStatement(stat, zone());
2038 block_finder.Update(stat);
2043 block_scope->set_end_position(scanner().location().end_pos);
2044 block_scope = block_scope->FinalizeBlockScope();
2045 body->set_scope(block_scope);
2050 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context,
2056 Handle<String> ignore;
2058 ParseVariableDeclarations(var_context,
NULL, names, &ignore,
CHECK_OK);
2064 bool Parser::IsEvalOrArguments(Handle<String>
string) {
2065 return string.is_identical_to(isolate()->factory()->eval_symbol()) ||
2066 string.is_identical_to(isolate()->factory()->arguments_symbol());
2075 Block* Parser::ParseVariableDeclarations(
2076 VariableDeclarationContext var_context,
2077 VariableDeclarationProperties* decl_props,
2079 Handle<String>* out,
2099 bool needs_init =
false;
2100 bool is_const =
false;
2119 init_op = Token::INIT_CONST;
2126 if (var_context == kStatement) {
2134 init_op = Token::INIT_CONST_HARMONY;
2145 if (!is_extended_mode()) {
2151 if (var_context == kStatement) {
2159 init_op = Token::INIT_LET;
2164 Scope* declaration_scope = DeclarationScope(mode);
2179 Block* block = factory()->NewBlock(
NULL, 1,
true, zone());
2181 Handle<String>
name;
2186 if (nvars > 0) Consume(Token::COMMA);
2191 if (!declaration_scope->is_classic_mode() && IsEvalOrArguments(name)) {
2212 VariableProxy* proxy = NewUnresolved(name, mode);
2213 Declaration* declaration =
2214 factory()->NewVariableDeclaration(proxy, mode, top_scope_);
2217 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) {
2223 if (names) names->Add(name, zone());
2252 Scope* initialization_scope = is_const ? declaration_scope : top_scope_;
2253 Expression* value =
NULL;
2259 value = ParseAssignmentExpression(var_context != kForStatement,
CHECK_OK);
2262 value->AsCall() ==
NULL &&
2263 value->AsCallNew() ==
NULL) {
2268 if (decl_props !=
NULL) *decl_props = kHasInitializers;
2272 if (proxy->var() !=
NULL) {
2273 proxy->var()->set_initializer_position(scanner().location().end_pos);
2277 if (value ==
NULL && needs_init) {
2278 value = GetLiteralUndefined();
2300 if (initialization_scope->is_global_scope()) {
2302 ZoneList<Expression*>* arguments =
2303 new(zone()) ZoneList<Expression*>(3, zone());
2305 arguments->Add(factory()->NewLiteral(name), zone());
2306 CallRuntime* initialize;
2309 arguments->Add(value, zone());
2316 initialize = factory()->NewCallRuntime(
2317 isolate()->factory()->InitializeConstGlobal_symbol(),
2323 LanguageMode language_mode = initialization_scope->language_mode();
2324 arguments->Add(factory()->NewNumberLiteral(language_mode), zone());
2330 if (value !=
NULL && !inside_with()) {
2331 arguments->Add(value, zone());
2339 initialize = factory()->NewCallRuntime(
2340 isolate()->factory()->InitializeVarGlobal_symbol(),
2345 block->AddStatement(factory()->NewExpressionStatement(initialize),
2347 }
else if (needs_init) {
2358 Assignment* assignment =
2359 factory()->NewAssignment(init_op, proxy, value, position);
2360 block->AddStatement(factory()->NewExpressionStatement(assignment),
2367 if (value !=
NULL) {
2372 VariableProxy* proxy =
2373 initialization_scope->NewUnresolved(factory(), name);
2374 Assignment* assignment =
2375 factory()->NewAssignment(init_op, proxy, value, position);
2376 block->AddStatement(factory()->NewExpressionStatement(assignment),
2381 }
while (peek() == Token::COMMA);
2385 if (nvars == 1 && !is_const) {
2393 static bool ContainsLabel(
ZoneStringList* labels, Handle<String> label) {
2394 ASSERT(!label.is_null());
2396 for (
int i = labels->length(); i-- > 0; )
2397 if (labels->at(i).is_identical_to(label))
2404 Statement* Parser::ParseExpressionOrLabelledStatement(
ZoneStringList* labels,
2409 bool starts_with_idenfifier = peek_any_identifier();
2410 Expression* expr = ParseExpression(
true,
CHECK_OK);
2411 if (peek() == Token::COLON && starts_with_idenfifier && expr !=
NULL &&
2412 expr->AsVariableProxy() !=
NULL &&
2413 !expr->AsVariableProxy()->is_this()) {
2416 VariableProxy* var = expr->AsVariableProxy();
2417 Handle<String> label = var->name();
2423 if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) {
2424 SmartArrayPointer<char> c_string = label->ToCString(
DISALLOW_NULLS);
2425 const char* elms[2] = {
"Label", *c_string };
2426 Vector<const char*> args(elms, 2);
2427 ReportMessage(
"redeclaration", args);
2431 if (labels ==
NULL) {
2434 labels->
Add(label, zone());
2440 return ParseStatement(labels, ok);
2446 if (extension_ !=
NULL &&
2447 peek() == Token::FUNCTION &&
2448 !scanner().HasAnyLineTerminatorBeforeNext() &&
2450 expr->AsVariableProxy() !=
NULL &&
2451 expr->AsVariableProxy()->name()->Equals(
2452 isolate()->heap()->native_symbol()) &&
2454 return ParseNativeDeclaration(ok);
2459 if (!FLAG_harmony_modules ||
2460 peek() != Token::IDENTIFIER ||
2461 scanner().HasAnyLineTerminatorBeforeNext() ||
2462 expr->AsVariableProxy() ==
NULL ||
2463 !expr->AsVariableProxy()->name()->Equals(
2464 isolate()->heap()->module_symbol()) ||
2468 return factory()->NewExpressionStatement(expr);
2472 IfStatement* Parser::ParseIfStatement(
ZoneStringList* labels,
bool* ok) {
2478 Expression* condition = ParseExpression(
true,
CHECK_OK);
2480 Statement* then_statement = ParseStatement(labels,
CHECK_OK);
2481 Statement* else_statement =
NULL;
2482 if (peek() == Token::ELSE) {
2484 else_statement = ParseStatement(labels,
CHECK_OK);
2486 else_statement = factory()->NewEmptyStatement();
2488 return factory()->NewIfStatement(condition, then_statement, else_statement);
2492 Statement* Parser::ParseContinueStatement(
bool* ok) {
2499 if (!scanner().HasAnyLineTerminatorBeforeNext() &&
2500 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
2503 IterationStatement* target =
NULL;
2504 target = LookupContinueTarget(label,
CHECK_OK);
2505 if (target ==
NULL) {
2507 const char* message =
"illegal_continue";
2508 Vector<Handle<String> > args;
2509 if (!label.is_null()) {
2510 message =
"unknown_label";
2511 args = Vector<Handle<String> >(&label, 1);
2518 return factory()->NewContinueStatement(target);
2522 Statement* Parser::ParseBreakStatement(
ZoneStringList* labels,
bool* ok) {
2527 Handle<String> label;
2529 if (!scanner().HasAnyLineTerminatorBeforeNext() &&
2530 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
2535 if (!label.is_null() && ContainsLabel(labels, label)) {
2537 return factory()->NewEmptyStatement();
2539 BreakableStatement* target =
NULL;
2540 target = LookupBreakTarget(label,
CHECK_OK);
2541 if (target ==
NULL) {
2543 const char* message =
"illegal_break";
2544 Vector<Handle<String> > args;
2545 if (!label.is_null()) {
2546 message =
"unknown_label";
2547 args = Vector<Handle<String> >(&label, 1);
2554 return factory()->NewBreakStatement(target);
2558 Statement* Parser::ParseReturnStatement(
bool* ok) {
2569 if (scanner().HasAnyLineTerminatorBeforeNext() ||
2570 tok == Token::SEMICOLON ||
2571 tok == Token::RBRACE ||
2572 tok == Token::EOS) {
2574 result = factory()->NewReturnStatement(GetLiteralUndefined());
2576 Expression* expr = ParseExpression(
true,
CHECK_OK);
2578 result = factory()->NewReturnStatement(expr);
2587 if (declaration_scope->is_global_scope() ||
2588 declaration_scope->is_eval_scope()) {
2589 Handle<String> type = isolate()->factory()->illegal_return_symbol();
2591 return factory()->NewExpressionStatement(throw_error);
2597 Statement* Parser::ParseWithStatement(
ZoneStringList* labels,
bool* ok) {
2610 Expression* expr = ParseExpression(
true,
CHECK_OK);
2614 Scope* with_scope = NewScope(top_scope_,
WITH_SCOPE);
2617 with_scope->set_start_position(scanner().peek_location().beg_pos);
2618 stmt = ParseStatement(labels,
CHECK_OK);
2619 with_scope->set_end_position(scanner().location().end_pos);
2621 return factory()->NewWithStatement(expr, stmt);
2625 CaseClause* Parser::ParseCaseClause(
bool* default_seen_ptr,
bool* ok) {
2630 Expression* label =
NULL;
2631 if (peek() == Token::CASE) {
2633 label = ParseExpression(
true,
CHECK_OK);
2636 if (*default_seen_ptr) {
2637 ReportMessage(
"multiple_defaults_in_switch",
2642 *default_seen_ptr =
true;
2646 ZoneList<Statement*>* statements =
2647 new(zone()) ZoneList<Statement*>(5, zone());
2648 while (peek() != Token::CASE &&
2650 peek() != Token::RBRACE) {
2652 statements->Add(stat, zone());
2655 return new(zone()) CaseClause(isolate(), label, statements, pos);
2659 SwitchStatement* Parser::ParseSwitchStatement(
ZoneStringList* labels,
2664 SwitchStatement* statement = factory()->NewSwitchStatement(labels);
2665 Target target(&this->target_stack_, statement);
2669 Expression* tag = ParseExpression(
true,
CHECK_OK);
2672 bool default_seen =
false;
2673 ZoneList<CaseClause*>* cases =
new(zone()) ZoneList<CaseClause*>(4, zone());
2675 while (peek() != Token::RBRACE) {
2676 CaseClause* clause = ParseCaseClause(&default_seen,
CHECK_OK);
2677 cases->Add(clause, zone());
2681 if (statement) statement->Initialize(tag, cases);
2686 Statement* Parser::ParseThrowStatement(
bool* ok) {
2692 if (scanner().HasAnyLineTerminatorBeforeNext()) {
2697 Expression* exception = ParseExpression(
true,
CHECK_OK);
2700 return factory()->NewExpressionStatement(factory()->NewThrow(exception, pos));
2704 TryStatement* Parser::ParseTryStatement(
bool* ok) {
2718 TargetCollector try_collector(zone());
2721 { Target target(&this->target_stack_, &try_collector);
2726 if (tok != Token::CATCH && tok != Token::FINALLY) {
2736 TargetCollector catch_collector(zone());
2737 Scope* catch_scope =
NULL;
2738 Variable* catch_variable =
NULL;
2740 Handle<String>
name;
2741 if (tok == Token::CATCH) {
2742 Consume(Token::CATCH);
2746 catch_scope->set_start_position(scanner().location().beg_pos);
2757 if (peek() == Token::LBRACE) {
2758 Target target(&this->target_stack_, &catch_collector);
2768 catch_scope->set_end_position(scanner().location().end_pos);
2773 if (tok == Token::FINALLY || catch_block ==
NULL) {
2774 Consume(Token::FINALLY);
2783 if (catch_block !=
NULL && finally_block !=
NULL) {
2786 int index = current_function_state_->NextHandlerIndex();
2787 TryCatchStatement* statement = factory()->NewTryCatchStatement(
2788 index, try_block, catch_scope, catch_variable, catch_block);
2789 statement->set_escaping_targets(try_collector.targets());
2790 try_block = factory()->NewBlock(
NULL, 1,
false, zone());
2791 try_block->AddStatement(statement, zone());
2795 TryStatement* result =
NULL;
2796 if (catch_block !=
NULL) {
2799 int index = current_function_state_->NextHandlerIndex();
2800 result = factory()->NewTryCatchStatement(
2801 index, try_block, catch_scope, catch_variable, catch_block);
2804 int index = current_function_state_->NextHandlerIndex();
2805 result = factory()->NewTryFinallyStatement(index, try_block, finally_block);
2807 try_collector.targets()->AddAll(*catch_collector.targets(), zone());
2810 result->set_escaping_targets(try_collector.targets());
2815 DoWhileStatement* Parser::ParseDoWhileStatement(
ZoneStringList* labels,
2820 DoWhileStatement* loop = factory()->NewDoWhileStatement(labels);
2821 Target target(&this->target_stack_, loop);
2830 loop->set_condition_position(position);
2833 Expression* cond = ParseExpression(
true,
CHECK_OK);
2840 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON);
2842 if (loop !=
NULL) loop->Initialize(cond, body);
2847 WhileStatement* Parser::ParseWhileStatement(
ZoneStringList* labels,
bool* ok) {
2851 WhileStatement* loop = factory()->NewWhileStatement(labels);
2852 Target target(&this->target_stack_, loop);
2856 Expression* cond = ParseExpression(
true,
CHECK_OK);
2860 if (loop !=
NULL) loop->Initialize(cond, body);
2865 Statement* Parser::ParseForStatement(
ZoneStringList* labels,
bool* ok) {
2869 Statement* init =
NULL;
2872 Scope* saved_scope = top_scope_;
2873 Scope* for_scope = NewScope(top_scope_,
BLOCK_SCOPE);
2874 top_scope_ = for_scope;
2878 for_scope->set_start_position(scanner().location().beg_pos);
2879 if (peek() != Token::SEMICOLON) {
2881 Handle<String>
name;
2882 Block* variable_statement =
2885 if (peek() ==
Token::IN && !name.is_null()) {
2886 VariableProxy* each = top_scope_->
NewUnresolved(factory(), name);
2887 ForInStatement* loop = factory()->NewForInStatement(labels);
2888 Target target(&this->target_stack_, loop);
2891 Expression* enumerable = ParseExpression(
true,
CHECK_OK);
2895 loop->Initialize(each, enumerable, body);
2896 Block* result = factory()->NewBlock(
NULL, 2,
false, zone());
2897 result->AddStatement(variable_statement, zone());
2898 result->AddStatement(loop, zone());
2899 top_scope_ = saved_scope;
2901 for_scope = for_scope->FinalizeBlockScope();
2906 init = variable_statement;
2909 Handle<String>
name;
2910 VariableDeclarationProperties decl_props = kHasNoInitializers;
2911 Block* variable_statement =
2912 ParseVariableDeclarations(kForStatement, &decl_props,
NULL, &name,
2914 bool accept_IN = !name.is_null() && decl_props != kHasInitializers;
2932 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
2933 VariableProxy* each = top_scope_->
NewUnresolved(factory(), name);
2934 ForInStatement* loop = factory()->NewForInStatement(labels);
2935 Target target(&this->target_stack_, loop);
2938 Expression* enumerable = ParseExpression(
true,
CHECK_OK);
2942 Block* body_block = factory()->NewBlock(
NULL, 3,
false, zone());
2943 Assignment* assignment = factory()->NewAssignment(
2944 Token::ASSIGN, each, temp_proxy, RelocInfo::kNoPosition);
2945 Statement* assignment_statement =
2946 factory()->NewExpressionStatement(assignment);
2947 body_block->AddStatement(variable_statement, zone());
2948 body_block->AddStatement(assignment_statement, zone());
2949 body_block->AddStatement(body, zone());
2950 loop->Initialize(temp_proxy, enumerable, body_block);
2951 top_scope_ = saved_scope;
2953 for_scope = for_scope->FinalizeBlockScope();
2954 body_block->set_scope(for_scope);
2959 init = variable_statement;
2962 Expression* expression = ParseExpression(
false,
CHECK_OK);
2968 if (expression ==
NULL || !expression->IsValidLeftHandSide()) {
2969 Handle<String> type =
2970 isolate()->factory()->invalid_lhs_in_for_in_symbol();
2971 expression = NewThrowReferenceError(type);
2973 ForInStatement* loop = factory()->NewForInStatement(labels);
2974 Target target(&this->target_stack_, loop);
2977 Expression* enumerable = ParseExpression(
true,
CHECK_OK);
2981 if (loop) loop->Initialize(expression, enumerable, body);
2982 top_scope_ = saved_scope;
2984 for_scope = for_scope->FinalizeBlockScope();
2990 init = factory()->NewExpressionStatement(expression);
2996 ForStatement* loop = factory()->NewForStatement(labels);
2997 Target target(&this->target_stack_, loop);
3000 Expect(Token::SEMICOLON,
CHECK_OK);
3002 Expression* cond =
NULL;
3003 if (peek() != Token::SEMICOLON) {
3004 cond = ParseExpression(
true,
CHECK_OK);
3006 Expect(Token::SEMICOLON,
CHECK_OK);
3008 Statement* next =
NULL;
3009 if (peek() != Token::RPAREN) {
3010 Expression* exp = ParseExpression(
true,
CHECK_OK);
3011 next = factory()->NewExpressionStatement(exp);
3016 top_scope_ = saved_scope;
3018 for_scope = for_scope->FinalizeBlockScope();
3019 if (for_scope !=
NULL) {
3031 Block* result = factory()->NewBlock(
NULL, 2,
false, zone());
3032 result->AddStatement(init, zone());
3033 result->AddStatement(loop, zone());
3034 result->set_scope(for_scope);
3035 if (loop) loop->Initialize(
NULL, cond, next, body);
3038 if (loop) loop->Initialize(init, cond, next, body);
3045 Expression* Parser::ParseExpression(
bool accept_IN,
bool* ok) {
3050 Expression* result = ParseAssignmentExpression(accept_IN,
CHECK_OK);
3051 while (peek() == Token::COMMA) {
3054 Expression* right = ParseAssignmentExpression(accept_IN,
CHECK_OK);
3056 factory()->NewBinaryOperation(Token::COMMA, result, right, position);
3063 Expression* Parser::ParseAssignmentExpression(
bool accept_IN,
bool* ok) {
3069 Expression* expression = ParseConditionalExpression(accept_IN,
CHECK_OK);
3081 if (expression ==
NULL || !expression->IsValidLeftHandSide()) {
3082 Handle<String> type =
3083 isolate()->factory()->invalid_lhs_in_assignment_symbol();
3084 expression = NewThrowReferenceError(type);
3089 CheckStrictModeLValue(expression,
"strict_lhs_assignment",
CHECK_OK);
3091 MarkAsLValue(expression);
3095 Expression* right = ParseAssignmentExpression(accept_IN,
CHECK_OK);
3102 Property*
property = expression ? expression->AsProperty() :
NULL;
3103 if (op == Token::ASSIGN &&
3105 property->obj()->AsVariableProxy() !=
NULL &&
3106 property->obj()->AsVariableProxy()->is_this()) {
3107 current_function_state_->AddProperty();
3112 if (property !=
NULL && right->AsFunctionLiteral() !=
NULL) {
3113 right->AsFunctionLiteral()->set_pretenure();
3120 if ((op == Token::INIT_VAR
3121 || op == Token::INIT_CONST
3122 || op == Token::ASSIGN)
3123 && (right->AsCall() ==
NULL && right->AsCallNew() ==
NULL)) {
3131 return factory()->NewAssignment(op, expression, right, pos);
3136 Expression* Parser::ParseConditionalExpression(
bool accept_IN,
bool* ok) {
3142 Expression* expression = ParseBinaryExpression(4, accept_IN,
CHECK_OK);
3143 if (peek() != Token::CONDITIONAL)
return expression;
3144 Consume(Token::CONDITIONAL);
3149 Expression* left = ParseAssignmentExpression(
true,
CHECK_OK);
3152 Expression* right = ParseAssignmentExpression(accept_IN,
CHECK_OK);
3153 return factory()->NewConditional(
3154 expression, left, right, left_position, right_position);
3158 static int Precedence(
Token::Value tok,
bool accept_IN) {
3167 Expression* Parser::ParseBinaryExpression(
int prec,
bool accept_IN,
bool* ok) {
3169 Expression* x = ParseUnaryExpression(
CHECK_OK);
3170 for (
int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
3172 while (Precedence(peek(), accept_IN) == prec1) {
3175 Expression* y = ParseBinaryExpression(prec1 + 1, accept_IN,
CHECK_OK);
3178 if (x && x->AsLiteral() && x->AsLiteral()->handle()->IsNumber() &&
3179 y && y->AsLiteral() && y->AsLiteral()->handle()->IsNumber()) {
3180 double x_val = x->AsLiteral()->handle()->Number();
3181 double y_val = y->AsLiteral()->handle()->Number();
3185 x = factory()->NewNumberLiteral(x_val + y_val);
3188 x = factory()->NewNumberLiteral(x_val - y_val);
3191 x = factory()->NewNumberLiteral(x_val * y_val);
3194 x = factory()->NewNumberLiteral(x_val / y_val);
3196 case Token::BIT_OR: {
3198 x = factory()->NewNumberLiteral(value);
3201 case Token::BIT_AND: {
3203 x = factory()->NewNumberLiteral(value);
3206 case Token::BIT_XOR: {
3208 x = factory()->NewNumberLiteral(value);
3213 x = factory()->NewNumberLiteral(value);
3219 x = factory()->NewNumberLiteral(value);
3225 x = factory()->NewNumberLiteral(value);
3241 case Token::NE_STRICT: cmp = Token::EQ_STRICT;
break;
3244 x = factory()->NewCompareOperation(cmp, x, y, position);
3247 x = factory()->NewUnaryOperation(Token::NOT, x, position);
3252 x = factory()->NewBinaryOperation(op, x, y, position);
3260 Expression* Parser::ParseUnaryExpression(
bool* ok) {
3277 Expression* expression = ParseUnaryExpression(
CHECK_OK);
3279 if (expression !=
NULL && (expression->AsLiteral() !=
NULL)) {
3280 Handle<Object> literal = expression->AsLiteral()->handle();
3281 if (op == Token::NOT) {
3283 bool condition = literal->ToBoolean()->IsTrue();
3284 Handle<Object> result(isolate()->heap()->ToBoolean(!condition));
3285 return factory()->NewLiteral(result);
3286 }
else if (literal->IsNumber()) {
3288 double value = literal->Number();
3293 return factory()->NewNumberLiteral(-value);
3294 case Token::BIT_NOT:
3304 VariableProxy* operand = expression->AsVariableProxy();
3305 if (operand !=
NULL && !operand->is_this()) {
3312 return factory()->NewUnaryOperation(op, expression, position);
3316 Expression* expression = ParseUnaryExpression(
CHECK_OK);
3321 if (expression ==
NULL || !expression->IsValidLeftHandSide()) {
3322 Handle<String> type =
3323 isolate()->factory()->invalid_lhs_in_prefix_op_symbol();
3324 expression = NewThrowReferenceError(type);
3329 CheckStrictModeLValue(expression,
"strict_lhs_prefix",
CHECK_OK);
3331 MarkAsLValue(expression);
3334 return factory()->NewCountOperation(op,
3340 return ParsePostfixExpression(ok);
3345 Expression* Parser::ParsePostfixExpression(
bool* ok) {
3349 Expression* expression = ParseLeftHandSideExpression(
CHECK_OK);
3350 if (!scanner().HasAnyLineTerminatorBeforeNext() &&
3356 if (expression ==
NULL || !expression->IsValidLeftHandSide()) {
3357 Handle<String> type =
3358 isolate()->factory()->invalid_lhs_in_postfix_op_symbol();
3359 expression = NewThrowReferenceError(type);
3364 CheckStrictModeLValue(expression,
"strict_lhs_prefix",
CHECK_OK);
3366 MarkAsLValue(expression);
3371 factory()->NewCountOperation(next,
3380 Expression* Parser::ParseLeftHandSideExpression(
bool* ok) {
3385 if (peek() == Token::NEW) {
3386 result = ParseNewExpression(
CHECK_OK);
3388 result = ParseMemberExpression(
CHECK_OK);
3393 case Token::LBRACK: {
3394 Consume(Token::LBRACK);
3396 Expression* index = ParseExpression(
true,
CHECK_OK);
3397 result = factory()->NewProperty(result, index, pos);
3402 case Token::LPAREN: {
3404 if (scanner().current_token() == Token::IDENTIFIER) {
3416 ZoneList<Expression*>* args = ParseArguments(
CHECK_OK);
3425 VariableProxy* callee = result->AsVariableProxy();
3426 if (callee !=
NULL &&
3427 callee->IsVariable(isolate()->factory()->eval_symbol())) {
3430 result = factory()->NewCall(result, args, pos);
3434 case Token::PERIOD: {
3435 Consume(Token::PERIOD);
3437 Handle<String> name = ParseIdentifierName(
CHECK_OK);
3439 factory()->NewProperty(result, factory()->NewLiteral(name), pos);
3451 Expression* Parser::ParseNewPrefix(PositionStack* stack,
bool* ok) {
3464 PositionStack::Element pos(stack, scanner().location().beg_pos);
3467 if (peek() == Token::NEW) {
3468 result = ParseNewPrefix(stack,
CHECK_OK);
3470 result = ParseMemberWithNewPrefixesExpression(stack,
CHECK_OK);
3473 if (!stack->is_empty()) {
3474 int last = stack->pop();
3475 result = factory()->NewCallNew(
3476 result,
new(zone()) ZoneList<Expression*>(0, zone()), last);
3482 Expression* Parser::ParseNewExpression(
bool* ok) {
3483 PositionStack stack(ok);
3484 return ParseNewPrefix(&stack, ok);
3488 Expression* Parser::ParseMemberExpression(
bool* ok) {
3489 return ParseMemberWithNewPrefixesExpression(
NULL, ok);
3493 Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack,
3500 Expression* result =
NULL;
3501 if (peek() == Token::FUNCTION) {
3504 Handle<String>
name;
3505 bool is_strict_reserved_name =
false;
3506 if (peek_any_identifier()) {
3507 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
3511 ? FunctionLiteral::ANONYMOUS_EXPRESSION
3513 result = ParseFunctionLiteral(name,
3514 is_strict_reserved_name,
3515 function_token_position,
3519 result = ParsePrimaryExpression(
CHECK_OK);
3524 case Token::LBRACK: {
3525 Consume(Token::LBRACK);
3527 Expression* index = ParseExpression(
true,
CHECK_OK);
3528 result = factory()->NewProperty(result, index, pos);
3530 if (index->IsPropertyName()) {
3534 isolate()->factory()->anonymous_function_symbol());
3540 case Token::PERIOD: {
3541 Consume(Token::PERIOD);
3543 Handle<String> name = ParseIdentifierName(
CHECK_OK);
3545 factory()->NewProperty(result, factory()->NewLiteral(name), pos);
3549 case Token::LPAREN: {
3550 if ((stack ==
NULL) || stack->is_empty())
return result;
3552 ZoneList<Expression*>* args = ParseArguments(
CHECK_OK);
3553 int last = stack->pop();
3554 result = factory()->NewCallNew(result, args, last);
3564 DebuggerStatement* Parser::ParseDebuggerStatement(
bool* ok) {
3573 return factory()->NewDebuggerStatement();
3577 void Parser::ReportUnexpectedToken(
Token::Value token) {
3581 if (token == Token::ILLEGAL && stack_overflow_)
return;
3587 return ReportMessage(
"unexpected_token_number",
3590 return ReportMessage(
"unexpected_token_string",
3592 case Token::IDENTIFIER:
3593 return ReportMessage(
"unexpected_token_identifier",
3595 case Token::FUTURE_RESERVED_WORD:
3596 return ReportMessage(
"unexpected_reserved",
3598 case Token::FUTURE_STRICT_RESERVED_WORD:
3600 "unexpected_token_identifier" :
3601 "unexpected_strict_reserved",
3606 ReportMessage(
"unexpected_token", Vector<const char*>(&name, 1));
3611 void Parser::ReportInvalidPreparseData(Handle<String> name,
bool* ok) {
3612 SmartArrayPointer<char> name_string = name->ToCString(
DISALLOW_NULLS);
3613 const char* element[1] = { *name_string };
3614 ReportMessage(
"invalid_preparser_data",
3615 Vector<const char*>(element, 1));
3620 Expression* Parser::ParsePrimaryExpression(
bool* ok) {
3634 Expression* result =
NULL;
3637 Consume(Token::THIS);
3638 result = factory()->NewVariableProxy(top_scope_->
receiver());
3642 case Token::NULL_LITERAL:
3643 Consume(Token::NULL_LITERAL);
3644 result = factory()->NewLiteral(isolate()->factory()->null_value());
3647 case Token::TRUE_LITERAL:
3648 Consume(Token::TRUE_LITERAL);
3649 result = factory()->NewLiteral(isolate()->factory()->true_value());
3652 case Token::FALSE_LITERAL:
3653 Consume(Token::FALSE_LITERAL);
3654 result = factory()->NewLiteral(isolate()->factory()->false_value());
3657 case Token::IDENTIFIER:
3658 case Token::FUTURE_STRICT_RESERVED_WORD: {
3659 Handle<String> name = ParseIdentifier(
CHECK_OK);
3663 if (FLAG_print_interface_details)
3664 PrintF(
"# Variable %s ", name->ToAsciiArray());
3668 factory(), name, scanner().location().beg_pos, interface);
3672 case Token::NUMBER: {
3673 Consume(Token::NUMBER);
3674 ASSERT(scanner().is_literal_ascii());
3676 scanner().literal_ascii_string(),
3678 result = factory()->NewNumberLiteral(value);
3682 case Token::STRING: {
3683 Consume(Token::STRING);
3684 Handle<String> symbol = GetSymbol(
CHECK_OK);
3685 result = factory()->NewLiteral(symbol);
3690 case Token::ASSIGN_DIV:
3691 result = ParseRegExpLiteral(
true,
CHECK_OK);
3695 result = ParseRegExpLiteral(
false,
CHECK_OK);
3699 result = ParseArrayLiteral(
CHECK_OK);
3703 result = ParseObjectLiteral(
CHECK_OK);
3707 Consume(Token::LPAREN);
3710 parenthesized_function_ = (peek() == Token::FUNCTION);
3711 result = ParseExpression(
true,
CHECK_OK);
3716 if (allow_natives_syntax_ || extension_ !=
NULL) {
3717 result = ParseV8Intrinsic(
CHECK_OK);
3725 ReportUnexpectedToken(tok);
3735 void Parser::BuildArrayLiteralBoilerplateLiterals(ZoneList<Expression*>* values,
3736 Handle<FixedArray> literals,
3741 bool is_simple_acc =
true;
3743 for (
int i = 0; i < values->length(); i++) {
3744 MaterializedLiteral* m_literal = values->at(i)->AsMaterializedLiteral();
3745 if (m_literal !=
NULL && m_literal->depth() >= depth_acc) {
3746 depth_acc = m_literal->depth() + 1;
3748 Handle<Object> boilerplate_value = GetBoilerplateValue(values->at(i));
3749 if (boilerplate_value->IsUndefined()) {
3750 literals->set_the_hole(i);
3751 is_simple_acc =
false;
3753 literals->set(i, *boilerplate_value);
3757 *is_simple = is_simple_acc;
3762 Expression* Parser::ParseArrayLiteral(
bool* ok) {
3766 ZoneList<Expression*>* values =
new(zone()) ZoneList<Expression*>(4, zone());
3768 while (peek() != Token::RBRACK) {
3770 if (peek() == Token::COMMA) {
3771 elem = GetLiteralTheHole();
3773 elem = ParseAssignmentExpression(
true,
CHECK_OK);
3775 values->Add(elem, zone());
3776 if (peek() != Token::RBRACK) {
3783 int literal_index = current_function_state_->NextMaterializedLiteralIndex();
3786 Handle<FixedArray> object_literals =
3787 isolate()->factory()->NewFixedArray(values->length(),
TENURED);
3788 Handle<FixedDoubleArray> double_literals;
3790 bool has_only_undefined_values =
true;
3791 bool has_hole_values =
false;
3794 Heap* heap = isolate()->heap();
3795 bool is_simple =
true;
3797 for (
int i = 0, n = values->length(); i < n; i++) {
3798 MaterializedLiteral* m_literal = values->at(i)->AsMaterializedLiteral();
3799 if (m_literal !=
NULL && m_literal->depth() + 1 > depth) {
3800 depth = m_literal->depth() + 1;
3802 Handle<Object> boilerplate_value = GetBoilerplateValue(values->at(i));
3803 if (boilerplate_value->IsTheHole()) {
3804 has_hole_values =
true;
3805 object_literals->set_the_hole(i);
3807 double_literals->set_the_hole(i);
3809 }
else if (boilerplate_value->IsUndefined()) {
3813 double_literals->set(i, 0);
3822 has_only_undefined_values =
false;
3823 object_literals->set(i, *boilerplate_value);
3827 if (!boilerplate_value->IsSmi()) {
3828 if (boilerplate_value->IsNumber() && FLAG_smi_only_arrays) {
3831 double_literals = isolate()->factory()->NewFixedDoubleArray(
3835 for (
int j = 0; j < i; ++j) {
3836 Object* smi_value = object_literals->get(j);
3837 if (smi_value->IsTheHole()) {
3838 double_literals->set_the_hole(j);
3840 double_literals->set(j,
Smi::cast(smi_value)->value());
3843 double_literals->set(i, boilerplate_value->Number());
3852 if (boilerplate_value->IsNumber()) {
3853 double_literals->set(i, boilerplate_value->Number());
3864 if (has_only_undefined_values && values->length() <= 2) {
3870 if (is_simple && depth == 1 && values->length() > 0 &&
3872 object_literals->set_map(heap->fixed_cow_array_map());
3876 ? Handle<FixedArrayBase>(double_literals)
3877 : Handle<FixedArrayBase>(object_literals);
3881 Handle<FixedArray> literals =
3882 isolate()->factory()->NewFixedArray(2,
TENURED);
3884 if (has_hole_values || !FLAG_packed_arrays) {
3889 literals->set(1, *element_values);
3891 return factory()->NewArrayLiteral(
3892 literals, values, literal_index, is_simple, depth);
3896 bool Parser::IsBoilerplateProperty(ObjectLiteral::Property* property) {
3897 return property !=
NULL &&
3903 if (expression->AsLiteral() !=
NULL)
return true;
3913 if (value->AsLiteral() !=
NULL)
return false;
3924 ObjectLiteral* object_literal = expression->AsObjectLiteral();
3925 if (object_literal !=
NULL) {
3934 ArrayLiteral* array_literal = expression->AsArrayLiteral();
3945 return static_cast<Type>(type_value->
value());
3955 if (expression->AsLiteral() !=
NULL) {
3956 return expression->AsLiteral()->handle();
3961 return isolate()->factory()->undefined_value();
3970 language_mode_(language_mode) {
3980 kGetAccessor = 0x01,
3981 kSetAccessor = 0x02,
3982 kAccessor = kGetAccessor | kSetAccessor,
3986 static intptr_t GetPropertyKind(ObjectLiteral::Property* property) {
3987 switch (property->kind()) {
3989 return kGetAccessor;
3991 return kSetAccessor;
4008 Literal* literal =
property->key();
4009 HashMap::Entry* entry = props_.
Lookup(literal, literal->
Hash(),
true);
4010 intptr_t prev =
reinterpret_cast<intptr_t
> (entry->value);
4011 intptr_t curr = GetPropertyKind(property);
4014 if (language_mode_ !=
CLASSIC_MODE && (curr & prev & kData) != 0) {
4021 if (((curr & kData) && (prev & kAccessor)) ||
4022 ((prev & kData) && (curr & kAccessor))) {
4029 if ((curr & prev & kAccessor) != 0) {
4037 entry->value =
reinterpret_cast<void*
> (prev | curr);
4042 void Parser::BuildObjectLiteralConstantProperties(
4046 bool* fast_elements,
4050 bool is_simple_acc =
true;
4052 uint32_t max_element_index = 0;
4053 uint32_t elements = 0;
4054 for (
int i = 0; i < properties->length(); i++) {
4056 if (!IsBoilerplateProperty(property)) {
4057 is_simple_acc =
false;
4060 MaterializedLiteral* m_literal =
property->value()->AsMaterializedLiteral();
4061 if (m_literal !=
NULL && m_literal->depth() >= depth_acc) {
4062 depth_acc = m_literal->depth() + 1;
4068 Handle<Object> key =
property->key()->handle();
4069 Handle<Object> value = GetBoilerplateValue(property->value());
4070 is_simple_acc = is_simple_acc && !value->IsUndefined();
4076 uint32_t element_index = 0;
4079 && element_index > max_element_index) {
4080 max_element_index = element_index;
4082 }
else if (key->IsSmi()) {
4085 && static_cast<uint32_t>(key_value) > max_element_index) {
4086 max_element_index = key_value;
4092 constant_properties->set(position++, *key);
4093 constant_properties->set(position++, *value);
4096 (max_element_index <= 32) || ((2 * elements) >= max_element_index);
4097 *is_simple = is_simple_acc;
4102 ObjectLiteral::Property* Parser::ParseObjectLiteralGetSet(
bool is_getter,
4109 if (next == Token::IDENTIFIER || next == Token::NUMBER ||
4110 next == Token::FUTURE_RESERVED_WORD ||
4111 next == Token::FUTURE_STRICT_RESERVED_WORD ||
4112 next == Token::STRING || is_keyword) {
4113 Handle<String>
name;
4119 FunctionLiteral* value =
4120 ParseFunctionLiteral(name,
4122 RelocInfo::kNoPosition,
4123 FunctionLiteral::ANONYMOUS_EXPRESSION,
4127 return factory()->NewObjectLiteralProperty(is_getter, value);
4129 ReportUnexpectedToken(next);
4136 Expression* Parser::ParseObjectLiteral(
bool* ok) {
4143 ZoneList<ObjectLiteral::Property*>* properties =
4144 new(zone()) ZoneList<ObjectLiteral::Property*>(4, zone());
4145 int number_of_boilerplate_properties = 0;
4146 bool has_function =
false;
4148 ObjectLiteralPropertyChecker checker(
this, top_scope_->
language_mode());
4152 while (peek() != Token::RBRACE) {
4155 Literal* key =
NULL;
4162 case Token::FUTURE_RESERVED_WORD:
4163 case Token::FUTURE_STRICT_RESERVED_WORD:
4164 case Token::IDENTIFIER: {
4165 bool is_getter =
false;
4166 bool is_setter =
false;
4168 ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter,
CHECK_OK);
4171 if ((is_getter || is_setter) && peek() != Token::COLON) {
4174 ObjectLiteral::Property*
property =
4175 ParseObjectLiteralGetSet(is_getter,
CHECK_OK);
4176 if (IsBoilerplateProperty(property)) {
4177 number_of_boilerplate_properties++;
4180 checker.CheckProperty(property, loc,
CHECK_OK);
4181 properties->Add(property, zone());
4182 if (peek() != Token::RBRACE) Expect(Token::COMMA,
CHECK_OK);
4192 key = factory()->NewLiteral(
id);
4195 case Token::STRING: {
4196 Consume(Token::STRING);
4197 Handle<String>
string = GetSymbol(
CHECK_OK);
4200 if (!
string.is_null() && string->AsArrayIndex(&index)) {
4201 key = factory()->NewNumberLiteral(index);
4204 key = factory()->NewLiteral(
string);
4207 case Token::NUMBER: {
4208 Consume(Token::NUMBER);
4209 ASSERT(scanner().is_literal_ascii());
4211 scanner().literal_ascii_string(),
4213 key = factory()->NewNumberLiteral(value);
4219 Handle<String>
string = GetSymbol(
CHECK_OK);
4220 key = factory()->NewLiteral(
string);
4224 ReportUnexpectedToken(next);
4231 Expression* value = ParseAssignmentExpression(
true,
CHECK_OK);
4233 ObjectLiteral::Property*
property =
4234 new(zone()) ObjectLiteral::Property(key, value, isolate());
4240 value->AsFunctionLiteral() !=
NULL) {
4241 has_function =
true;
4242 value->AsFunctionLiteral()->set_pretenure();
4246 if (IsBoilerplateProperty(property)) number_of_boilerplate_properties++;
4248 checker.CheckProperty(property, loc,
CHECK_OK);
4249 properties->Add(property, zone());
4252 if (peek() != Token::RBRACE) Expect(Token::COMMA,
CHECK_OK);
4262 int literal_index = current_function_state_->NextMaterializedLiteralIndex();
4264 Handle<FixedArray> constant_properties = isolate()->factory()->NewFixedArray(
4265 number_of_boilerplate_properties * 2,
TENURED);
4267 bool is_simple =
true;
4268 bool fast_elements =
true;
4270 BuildObjectLiteralConstantProperties(properties,
4271 constant_properties,
4275 return factory()->NewObjectLiteral(constant_properties,
4285 Expression* Parser::ParseRegExpLiteral(
bool seen_equal,
bool* ok) {
4286 if (!scanner().ScanRegExpPattern(seen_equal)) {
4293 int literal_index = current_function_state_->NextMaterializedLiteralIndex();
4295 Handle<String> js_pattern = NextLiteralString(
TENURED);
4297 Handle<String> js_flags = NextLiteralString(
TENURED);
4300 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index);
4304 ZoneList<Expression*>* Parser::ParseArguments(
bool* ok) {
4308 ZoneList<Expression*>* result =
new(zone()) ZoneList<Expression*>(4, zone());
4310 bool done = (peek() == Token::RPAREN);
4312 Expression* argument = ParseAssignmentExpression(
true,
CHECK_OK);
4313 result->Add(argument, zone());
4314 if (result->length() > kMaxNumFunctionParameters) {
4320 done = (peek() == Token::RPAREN);
4321 if (!done) Expect(Token::COMMA,
CHECK_OK);
4357 const char* message,
4403 return argument_opt_;
4415 const char* message_;
4416 const char* argument_opt_;
4420 FunctionLiteral* Parser::ParseFunctionLiteral(
Handle<String> function_name,
4421 bool name_is_strict_reserved,
4422 int function_token_position,
4431 bool should_infer_name = function_name.is_null();
4434 if (should_infer_name) {
4435 function_name = isolate()->factory()->empty_symbol();
4438 int num_parameters = 0;
4445 ZoneList<Statement*>* body =
NULL;
4446 int materialized_literal_count = -1;
4447 int expected_property_count = -1;
4448 int handler_count = 0;
4449 bool only_simple_this_property_assignments;
4453 AstProperties ast_properties;
4461 scope->set_start_position(scanner().location().beg_pos);
4466 bool done = (peek() == Token::RPAREN);
4468 bool is_strict_reserved =
false;
4469 Handle<String> param_name =
4470 ParseIdentifierOrStrictReservedWord(&is_strict_reserved,
4474 if (!name_loc.IsValid() && IsEvalOrArguments(param_name)) {
4477 if (!dupe_loc.IsValid() && top_scope_->
IsDeclared(param_name)) {
4481 if (!reserved_loc.IsValid() && is_strict_reserved) {
4482 reserved_loc = scanner().
location();
4487 if (num_parameters > kMaxNumFunctionParameters) {
4493 done = (peek() == Token::RPAREN);
4494 if (!done) Expect(Token::COMMA,
CHECK_OK);
4506 Variable* fvar =
NULL;
4509 if (is_extended_mode()) fvar_init_op = Token::INIT_CONST_HARMONY;
4511 fvar =
new(zone()) Variable(top_scope_,
4512 function_name, fvar_mode,
true ,
4514 VariableProxy* proxy = factory()->NewVariableProxy(fvar);
4515 VariableDeclaration* fvar_declaration =
4516 factory()->NewVariableDeclaration(proxy, fvar_mode, top_scope_);
4531 bool is_lazily_compiled = (mode() == PARSE_LAZILY &&
4534 !parenthesized_function_);
4535 parenthesized_function_ =
false;
4537 if (is_lazily_compiled) {
4539 FunctionEntry entry;
4540 if (pre_data_ !=
NULL) {
4545 if (entry.is_valid()) {
4546 if (entry.end_pos() <= function_block_pos) {
4549 ReportInvalidPreparseData(function_name,
CHECK_OK);
4553 scope->set_end_position(entry.end_pos());
4555 isolate()->counters()->total_preparse_skipped()->Increment(
4556 scope->end_position() - function_block_pos);
4557 materialized_literal_count = entry.literal_count();
4558 expected_property_count = entry.property_count();
4560 only_simple_this_property_assignments =
false;
4561 this_property_assignments = isolate()->factory()->empty_fixed_array();
4563 is_lazily_compiled =
false;
4569 SingletonLogger logger;
4571 LazyParseFunctionLiteral(&logger);
4574 stack_overflow_ =
true;
4578 if (logger.has_error()) {
4579 const char* arg = logger.argument_opt();
4580 Vector<const char*> args;
4582 args = Vector<const char*>(&arg, 1);
4585 logger.message(), args);
4589 scope->set_end_position(logger.end());
4591 isolate()->counters()->total_preparse_skipped()->Increment(
4592 scope->end_position() - function_block_pos);
4593 materialized_literal_count = logger.literals();
4594 expected_property_count = logger.properties();
4596 only_simple_this_property_assignments =
false;
4597 this_property_assignments = isolate()->factory()->empty_fixed_array();
4601 if (!is_lazily_compiled) {
4602 body =
new(zone()) ZoneList<Statement*>(8, zone());
4604 VariableProxy* fproxy =
4607 body->Add(factory()->NewExpressionStatement(
4608 factory()->NewAssignment(fvar_init_op,
4610 factory()->NewThisFunction(),
4611 RelocInfo::kNoPosition)),
4614 ParseSourceElements(body, Token::RBRACE,
false,
CHECK_OK);
4616 materialized_literal_count = function_state.materialized_literal_count();
4617 expected_property_count = function_state.expected_property_count();
4618 handler_count = function_state.handler_count();
4619 only_simple_this_property_assignments =
4620 function_state.only_simple_this_property_assignments();
4621 this_property_assignments = function_state.this_property_assignments();
4624 scope->set_end_position(scanner().location().end_pos);
4629 if (IsEvalOrArguments(function_name)) {
4630 int start_pos = scope->start_position();
4631 int position = function_token_position != RelocInfo::kNoPosition
4632 ? function_token_position
4633 : (start_pos > 0 ? start_pos - 1 : start_pos);
4634 Scanner::Location location = Scanner::Location(position, start_pos);
4640 if (name_loc.IsValid()) {
4646 if (dupe_loc.IsValid()) {
4652 if (name_is_strict_reserved) {
4653 int start_pos = scope->start_position();
4654 int position = function_token_position != RelocInfo::kNoPosition
4655 ? function_token_position
4656 : (start_pos > 0 ? start_pos - 1 : start_pos);
4657 Scanner::Location location = Scanner::Location(position, start_pos);
4663 if (reserved_loc.IsValid()) {
4669 CheckOctalLiteral(scope->start_position(),
4670 scope->end_position(),
4673 ast_properties = *factory()->visitor()->ast_properties();
4676 if (is_extended_mode()) {
4677 CheckConflictingVarDeclarations(scope,
CHECK_OK);
4680 FunctionLiteral* function_literal =
4681 factory()->NewFunctionLiteral(function_name,
4684 materialized_literal_count,
4685 expected_property_count,
4687 only_simple_this_property_assignments,
4688 this_property_assignments,
4690 duplicate_parameters,
4693 function_literal->set_function_token_position(function_token_position);
4694 function_literal->set_ast_properties(&ast_properties);
4696 if (fni_ !=
NULL && should_infer_name) fni_->
AddFunction(function_literal);
4697 return function_literal;
4702 SingletonLogger* logger) {
4703 HistogramTimerScope preparse_scope(isolate()->counters()->pre_parse());
4704 ASSERT_EQ(Token::LBRACE, scanner().current_token());
4706 if (reusable_preparser_ ==
NULL) {
4707 intptr_t stack_limit = isolate()->stack_guard()->real_climit();
4708 bool do_allow_lazy =
true;
4709 reusable_preparser_ =
new preparser::PreParser(&scanner_,
4713 allow_natives_syntax_,
4723 Expression* Parser::ParseV8Intrinsic(
bool* ok) {
4728 Handle<String> name = ParseIdentifier(
CHECK_OK);
4729 ZoneList<Expression*>* args = ParseArguments(
CHECK_OK);
4731 if (extension_ !=
NULL) {
4740 if (
function !=
NULL &&
4742 function->function_id == Runtime::kIS_VAR) {
4746 if (args->length() == 1 && args->at(0)->AsVariableProxy() !=
NULL) {
4756 if (
function !=
NULL &&
4757 function->nargs != -1 &&
4758 function->nargs != args->length()) {
4765 return factory()->NewCallRuntime(name,
function, args);
4769 bool Parser::peek_any_identifier() {
4771 return next == Token::IDENTIFIER ||
4772 next == Token::FUTURE_RESERVED_WORD ||
4773 next == Token::FUTURE_STRICT_RESERVED_WORD;
4787 if (next == token)
return;
4788 ReportUnexpectedToken(next);
4795 if (next == token) {
4803 void Parser::ExpectSemicolon(
bool* ok) {
4807 if (tok == Token::SEMICOLON) {
4811 if (scanner().HasAnyLineTerminatorBeforeNext() ||
4812 tok == Token::RBRACE ||
4813 tok == Token::EOS) {
4816 Expect(Token::SEMICOLON, ok);
4820 void Parser::ExpectContextualKeyword(
const char* keyword,
bool* ok) {
4821 Expect(Token::IDENTIFIER, ok);
4823 Handle<String> symbol = GetSymbol(ok);
4825 if (!symbol->IsEqualTo(
CStrVector(keyword))) {
4827 ReportUnexpectedToken(scanner().current_token());
4832 Literal* Parser::GetLiteralUndefined() {
4833 return factory()->NewLiteral(isolate()->factory()->undefined_value());
4837 Literal* Parser::GetLiteralTheHole() {
4838 return factory()->NewLiteral(isolate()->factory()->the_hole_value());
4844 Handle<String> Parser::ParseIdentifier(
bool* ok) {
4846 Expect(Token::IDENTIFIER, ok);
4847 }
else if (!Check(Token::IDENTIFIER)) {
4848 Expect(Token::FUTURE_STRICT_RESERVED_WORD, ok);
4850 if (!*ok)
return Handle<String>();
4851 return GetSymbol(ok);
4857 Handle<String> Parser::ParseIdentifierOrStrictReservedWord(
4858 bool* is_strict_reserved,
bool* ok) {
4859 *is_strict_reserved =
false;
4860 if (!Check(Token::IDENTIFIER)) {
4861 Expect(Token::FUTURE_STRICT_RESERVED_WORD, ok);
4862 *is_strict_reserved =
true;
4864 if (!*ok)
return Handle<String>();
4865 return GetSymbol(ok);
4869 Handle<String> Parser::ParseIdentifierName(
bool* ok) {
4871 if (next != Token::IDENTIFIER &&
4872 next != Token::FUTURE_RESERVED_WORD &&
4873 next != Token::FUTURE_STRICT_RESERVED_WORD &&
4875 ReportUnexpectedToken(next);
4877 return Handle<String>();
4879 return GetSymbol(ok);
4883 void Parser::MarkAsLValue(Expression* expression) {
4884 VariableProxy* proxy = expression !=
NULL
4885 ? expression->AsVariableProxy()
4888 if (proxy !=
NULL) proxy->MarkAsLValue();
4894 void Parser::CheckStrictModeLValue(Expression* expression,
4898 VariableProxy* lhs = expression !=
NULL
4899 ? expression->AsVariableProxy()
4902 if (lhs !=
NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) {
4911 void Parser::CheckOctalLiteral(
int beg_pos,
int end_pos,
bool* ok) {
4913 if (octal.IsValid() &&
4914 beg_pos <= octal.beg_pos &&
4915 octal.end_pos <= end_pos) {
4924 void Parser::CheckConflictingVarDeclarations(Scope* scope,
bool* ok) {
4925 Declaration* decl = scope->CheckConflictingVarDeclarations();
4929 Handle<String> name = decl->proxy()->name();
4930 SmartArrayPointer<char> c_string = name->ToCString(
DISALLOW_NULLS);
4931 const char* elms[2] = {
"Variable", *c_string };
4932 Vector<const char*> args(elms, 2);
4933 int position = decl->proxy()->position();
4934 Scanner::Location location = position == RelocInfo::kNoPosition
4936 : Scanner::Location(position, position + 1);
4945 Handle<String> Parser::ParseIdentifierNameOrGetOrSet(
bool* is_get,
4948 Handle<String> result = ParseIdentifierName(ok);
4949 if (!*ok)
return Handle<String>();
4952 *is_get = strncmp(token,
"get", 3) == 0;
4953 *is_set = !*is_get && strncmp(token,
"set", 3) == 0;
4963 bool Parser::TargetStackContainsLabel(Handle<String> label) {
4964 for (Target* t = target_stack_; t !=
NULL; t = t->previous()) {
4965 BreakableStatement* stat = t->node()->AsBreakableStatement();
4966 if (stat !=
NULL && ContainsLabel(stat->labels(), label))
4973 BreakableStatement* Parser::LookupBreakTarget(Handle<String> label,
bool* ok) {
4974 bool anonymous = label.is_null();
4975 for (Target* t = target_stack_; t !=
NULL; t = t->previous()) {
4976 BreakableStatement* stat = t->node()->AsBreakableStatement();
4977 if (stat ==
NULL)
continue;
4978 if ((anonymous && stat->is_target_for_anonymous()) ||
4979 (!anonymous && ContainsLabel(stat->labels(), label))) {
4980 RegisterTargetUse(stat->break_target(), t->previous());
4988 IterationStatement* Parser::LookupContinueTarget(Handle<String> label,
4990 bool anonymous = label.is_null();
4991 for (Target* t = target_stack_; t !=
NULL; t = t->previous()) {
4992 IterationStatement* stat = t->node()->AsIterationStatement();
4993 if (stat ==
NULL)
continue;
4995 ASSERT(stat->is_target_for_anonymous());
4996 if (anonymous || ContainsLabel(stat->labels(), label)) {
4997 RegisterTargetUse(stat->continue_target(), t->previous());
5005 void Parser::RegisterTargetUse(Label* target, Target* stop) {
5009 for (Target* t = target_stack_; t != stop; t = t->previous()) {
5010 TargetCollector* collector = t->node()->AsTargetCollector();
5011 if (collector !=
NULL) collector->AddTarget(target, zone());
5016 Expression* Parser::NewThrowReferenceError(Handle<String> type) {
5017 return NewThrowError(isolate()->factory()->MakeReferenceError_symbol(),
5018 type, HandleVector<Object>(
NULL, 0));
5022 Expression* Parser::NewThrowSyntaxError(Handle<String> type,
5023 Handle<Object> first) {
5024 int argc = first.is_null() ? 0 : 1;
5025 Vector< Handle<Object> > arguments = HandleVector<Object>(&first, argc);
5026 return NewThrowError(
5027 isolate()->factory()->MakeSyntaxError_symbol(), type, arguments);
5031 Expression* Parser::NewThrowTypeError(Handle<String> type,
5032 Handle<Object> first,
5033 Handle<Object> second) {
5034 ASSERT(!first.is_null() && !second.is_null());
5035 Handle<Object> elements[] = { first, second };
5036 Vector< Handle<Object> > arguments =
5037 HandleVector<Object>(elements,
ARRAY_SIZE(elements));
5038 return NewThrowError(
5039 isolate()->factory()->MakeTypeError_symbol(), type, arguments);
5043 Expression* Parser::NewThrowError(Handle<String> constructor,
5044 Handle<String> type,
5045 Vector< Handle<Object> > arguments) {
5046 int argc = arguments.length();
5047 Handle<FixedArray> elements = isolate()->factory()->NewFixedArray(argc,
5049 for (
int i = 0; i < argc; i++) {
5050 Handle<Object> element = arguments[i];
5051 if (!element.is_null()) {
5052 elements->set(i, *element);
5055 Handle<JSArray> array = isolate()->factory()->NewJSArrayWithElements(
5058 ZoneList<Expression*>* args =
new(zone()) ZoneList<Expression*>(2, zone());
5059 args->Add(factory()->NewLiteral(type), zone());
5060 args->Add(factory()->NewLiteral(array), zone());
5061 CallRuntime* call_constructor =
5062 factory()->NewCallRuntime(constructor,
NULL, args);
5063 return factory()->NewThrow(call_constructor, scanner().location().beg_pos);
5073 : isolate_(
Isolate::Current()),
5081 multiline_(multiline),
5083 contains_anchor_(
false),
5084 is_scanned_for_captures_(
false),
5090 uc32 RegExpParser::Next() {
5092 return in()->
Get(next_pos_);
5100 if (next_pos_ < in()->length()) {
5101 StackLimitCheck
check(isolate());
5102 if (check.HasOverflowed()) {
5104 }
else if (isolate()->zone()->excess_allocation()) {
5107 current_ = in()->
Get(next_pos_);
5124 next_pos_ += dist - 1;
5135 *error_ = isolate()->factory()->NewStringFromAscii(message,
NOT_TENURED);
5138 next_pos_ = in()->
length();
5150 if (result->IsAtom() && result->AsAtom()->length() == in()->
length()) {
5169 RegExpParserState initial_state(
NULL, INITIAL, 0, zone());
5170 RegExpParserState* stored_state = &initial_state;
5174 switch (current()) {
5176 if (stored_state->IsSubexpression()) {
5180 ASSERT_EQ(INITIAL, stored_state->group_type());
5184 if (!stored_state->IsSubexpression()) {
5187 ASSERT_NE(INITIAL, stored_state->group_type());
5196 int capture_index = stored_state->capture_index();
5197 SubexpressionType type = stored_state->group_type();
5200 stored_state = stored_state->previous_state();
5201 builder = stored_state->builder();
5204 if (type == CAPTURE) {
5206 captures_->at(capture_index - 1) = capture;
5208 }
else if (type != GROUPING) {
5209 ASSERT(type == POSITIVE_LOOKAHEAD || type == NEGATIVE_LOOKAHEAD);
5210 bool is_positive = (type == POSITIVE_LOOKAHEAD);
5213 end_capture_index - capture_index,
5261 SubexpressionType type = CAPTURE;
5263 if (current() ==
'?') {
5269 type = POSITIVE_LOOKAHEAD;
5272 type = NEGATIVE_LOOKAHEAD;
5280 if (captures_ ==
NULL) {
5286 captures_->Add(
NULL, zone());
5289 stored_state =
new(zone()) RegExpParserState(stored_state, type,
5291 builder = stored_state->builder();
5320 case 'd':
case 'D':
case 's':
case 'S':
case 'w':
case 'W': {
5330 case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
5331 case '7':
case '8':
case '9': {
5335 if (captures_ !=
NULL && index <= captures_->length()) {
5336 capture = captures_->at(index - 1);
5338 if (capture ==
NULL) {
5346 uc32 first_digit = Next();
5347 if (first_digit ==
'8' || first_digit ==
'9') {
5385 uc32 controlLetter = Next();
5388 uc32 letter = controlLetter & ~(
'a' ^
'A');
5389 if (letter <
'A' ||
'Z' < letter) {
5443 switch (current()) {
5478 if (current() ==
'?') {
5481 }
else if (FLAG_regexp_possessive_quantifier && current() ==
'+') {
5493 static bool IsSpecialClassEscape(
uc32 c) {
5512 void RegExpParser::ScanForCaptures() {
5530 if (c ==
']')
break;
5536 if (current() !=
'?') capture_count++;
5540 capture_count_ = capture_count;
5541 is_scanned_for_captures_ =
true;
5547 ASSERT(
'1' <= Next() && Next() <=
'9');
5551 int value = Next() -
'0';
5556 value = 10 * value + (c -
'0');
5567 if (!is_scanned_for_captures_) {
5570 Reset(saved_position);
5572 if (value > capture_count_) {
5599 int next = current() -
'0';
5608 min = 10 * min + next;
5612 if (current() ==
'}') {
5615 }
else if (current() ==
',') {
5617 if (current() ==
'}') {
5622 int next = current() -
'0';
5630 max = 10 * max + next;
5633 if (current() !=
'}') {
5650 ASSERT(
'0' <= current() && current() <=
'7');
5653 uc32 value = current() -
'0';
5655 if (
'0' <= current() && current() <=
'7') {
5656 value = value * 8 + current() -
'0';
5658 if (value < 32 &&
'0' <= current() && current() <=
'7') {
5659 value = value * 8 + current() -
'0';
5671 for (
int i = 0; !done; i++) {
5680 if (i == length - 1) {
5690 ASSERT(current() ==
'\\');
5691 ASSERT(has_next() && !IsSpecialClassEscape(Next()));
5693 switch (current()) {
5715 uc32 controlLetter = Next();
5716 uc32 letter = controlLetter & ~(
'A' ^
'a');
5719 if ((controlLetter >=
'0' && controlLetter <=
'9') ||
5720 controlLetter ==
'_' ||
5721 (letter >=
'A' && letter <=
'Z')) {
5725 return controlLetter & 0x1f;
5731 case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
5761 uc32 result = current();
5772 uc32 first = current();
5773 if (first ==
'\\') {
5775 case 'w':
case 'W':
case 'd':
case 'D':
case 's':
case 'S': {
5776 *char_class = Next();
5793 static const uc16 kNoCharClass = 0;
5802 if (char_class != kNoCharClass) {
5805 ranges->
Add(range, zone);
5811 static const char* kUnterminated =
"Unterminated character class";
5812 static const char* kRangeOutOfOrder =
"Range out of order in character class";
5816 bool is_negated =
false;
5817 if (current() ==
'^') {
5823 while (has_more() && current() !=
']') {
5824 uc16 char_class = kNoCharClass;
5826 if (current() ==
'-') {
5832 }
else if (current() ==
']') {
5833 AddRangeOrEscape(ranges, char_class, first, zone());
5837 uc16 char_class_2 = kNoCharClass;
5839 if (char_class != kNoCharClass || char_class_2 != kNoCharClass) {
5841 AddRangeOrEscape(ranges, char_class, first, zone());
5843 AddRangeOrEscape(ranges, char_class_2, next, zone());
5846 if (first.
from() > next.
to()) {
5851 AddRangeOrEscape(ranges, char_class, first, zone());
5858 if (ranges->length() == 0) {
5860 is_negated = !is_negated;
5877 if (owns_store_) store_.
Dispose();
5882 return store_.
length() *
sizeof(unsigned);
5887 return reinterpret_cast<const char*
>(store_.
start());
5902 if (store_.length() > symbol_data_offset) {
5903 symbol_data_ =
reinterpret_cast<byte*
>(&store_[symbol_data_offset]);
5906 symbol_data_ =
reinterpret_cast<byte*
>(&store_[0] + store_.length());
5908 symbol_data_end_ =
reinterpret_cast<byte*
>(&store_[0] + store_.length());
5913 int ScriptDataImpl::ReadNumber(
byte** source) {
5920 byte* data = *source;
5921 if (data >= symbol_data_end_)
return -1;
5927 int result = input & 0x7f;
5929 while ((input & 0x80u) != 0) {
5930 if (data >= symbol_data_end_)
return -1;
5932 result = (result << 7) | (input & 0x7f);
5941 static ScriptDataImpl* DoPreParse(Utf16CharacterStream* source,
5943 ParserRecorder* recorder) {
5944 Isolate* isolate = Isolate::Current();
5945 HistogramTimerScope timer(isolate->counters()->pre_parse());
5946 Scanner scanner(isolate->unicode_cache());
5947 scanner.SetHarmonyScoping(FLAG_harmony_scoping);
5948 scanner.Initialize(source);
5949 intptr_t stack_limit = isolate->stack_guard()->real_climit();
5956 isolate->StackOverflow();
5962 Vector<unsigned> store = recorder->ExtractData();
5963 return new ScriptDataImpl(store);
5972 bool allow_lazy = FLAG_lazy && (extension ==
NULL);
5980 int source_length = source->length();
5981 if (source->IsExternalTwoByteString()) {
5984 return DoPreParse(&stream, flags, &recorder);
5987 return DoPreParse(&stream, flags, &recorder);
5996 if (FLAG_lazy && (extension ==
NULL)) {
6000 return DoPreParse(source, flags, &recorder);
6016 result->
tree = tree;
6018 result->
simple = tree->IsAtom() && parser.
simple() && capture_count == 0;
6031 if (!info->is_native() && FLAG_harmony_scoping) {
6035 if (!info->is_native() && FLAG_harmony_modules) {
6038 if (FLAG_allow_natives_syntax || info->is_native()) {
6042 if (info->is_lazy()) {
6043 ASSERT(!info->is_eval());
6045 if (info->shared_info()->is_function()) {
6048 result = parser.ParseProgram(info);
6052 Parser parser(script, parsing_flags, info->extension(), pre_data,
6053 info->isolate()->zone());
6058 parser.ReportMessageAt(loc, message, args);
6060 for (
int i = 0; i < args.
length(); i++) {
6064 ASSERT(info->isolate()->has_pending_exception());
6066 result = parser.ParseProgram(info);
6069 info->SetFunction(result);
6070 return (result !=
NULL);
bool is_global_scope() const
static bool ParseRegExp(FlatStringReader *input, bool multiline, RegExpCompileData *result)
virtual v8::Handle< v8::FunctionTemplate > GetNativeFunction(v8::Handle< v8::String > name)
static ScriptDataImpl * PartialPreParse(Handle< String > source, v8::Extension *extension, int flags)
Scope * DeclarationScope()
static ScriptDataImpl * PreParse(Utf16CharacterStream *source, v8::Extension *extension, int flags)
virtual bool IsTextElement()
ThisNamedPropertyAssignmentFinder(Isolate *isolate, Zone *zone)
Vector< const char * > BuildArgs()
void PushVariableName(Handle< String > name)
static const Function * FunctionForSymbol(Handle< String > name)
BlockState(Parser *parser, Scope *scope)
void PrintF(const char *format,...)
static Interface * NewModule(Zone *zone)
static String * cast(Object *obj)
int GetSymbolIdentifier()
static const unsigned kMagicNumber
static const int kDeclarationsId
static Smi * FromInt(int value)
~InitializationBlockFinder()
virtual void LogUtf16Symbol(int start, Vector< const uc16 > literal)
static const uc32 kEndMarker
Vector< const T > ToConstVector()
static int Precedence(Value tok)
RegExpTree * ReportError(Vector< const char > message)
InitializationBlockFinder(Scope *top_scope, Target *target)
bool ParseHexEscape(int length, uc32 *value)
value format" "after each garbage collection") DEFINE_bool(print_cumulative_gc_stat, false, "print cumulative GC statistics in name=value format on exit") DEFINE_bool(trace_gc_verbose, false, "print more details following each garbage collection") DEFINE_bool(trace_fragmentation, false, "report fragmentation for old pointer and data pages") DEFINE_bool(collect_maps, true, "garbage collect maps from which no objects can be reached") DEFINE_bool(flush_code, true, "flush code that we expect not to use again before full gc") DEFINE_bool(incremental_marking, true, "use incremental marking") DEFINE_bool(incremental_marking_steps, true, "do incremental marking steps") DEFINE_bool(trace_incremental_marking, false, "trace progress of the incremental marking") DEFINE_bool(use_idle_notification, true, "Use idle notification to reduce memory footprint.") DEFINE_bool(send_idle_notification, false, "Send idle notifcation between stress runs.") DEFINE_bool(use_ic, true, "use inline caching") DEFINE_bool(native_code_counters, false, "generate extra code for manipulating stats counters") DEFINE_bool(always_compact, false, "Perform compaction on every full GC") DEFINE_bool(lazy_sweeping, true, "Use lazy sweeping for old pointer and data spaces") DEFINE_bool(never_compact, false, "Never perform compaction on full GC-testing only") DEFINE_bool(compact_code_space, true, "Compact code space on full non-incremental collections") DEFINE_bool(cleanup_code_caches_at_gc, true, "Flush inline caches prior to mark compact collection and" "flush code caches in maps during mark compact cycle.") DEFINE_int(random_seed, 0, "Default seed for initializing random generator" "(0, the default, means to use system random).") DEFINE_bool(use_verbose_printer, true, "allows verbose printing") DEFINE_bool(allow_natives_syntax, false, "allow natives syntax") DEFINE_bool(trace_sim, false, "Trace simulator execution") DEFINE_bool(check_icache, false, "Check icache flushes in ARM and MIPS simulator") DEFINE_int(stop_sim_at, 0, "Simulator stop after x number of instructions") DEFINE_int(sim_stack_alignment, 8, "Stack alingment in bytes in simulator(4 or 8, 8 is default)") DEFINE_bool(trace_exception, false, "print stack trace when throwing exceptions") DEFINE_bool(preallocate_message_memory, false, "preallocate some memory to build stack traces.") DEFINE_bool(randomize_hashes, true, "randomize hashes to avoid predictable hash collisions" "(with snapshots this option cannot override the baked-in seed)") DEFINE_int(hash_seed, 0, "Fixed seed to use to hash property keys(0 means random)" "(with snapshots this option cannot override the baked-in seed)") DEFINE_bool(preemption, false, "activate a 100ms timer that switches between V8 threads") DEFINE_bool(regexp_optimization, true, "generate optimized regexp code") DEFINE_bool(testing_bool_flag, true, "testing_bool_flag") DEFINE_int(testing_int_flag, 13, "testing_int_flag") DEFINE_float(testing_float_flag, 2.5, "float-flag") DEFINE_string(testing_string_flag, "Hello, world!", "string-flag") DEFINE_int(testing_prng_seed, 42, "Seed used for threading test randomness") DEFINE_string(testing_serialization_file, "/tmp/serdes", "file in which to serialize heap") DEFINE_bool(help, false, "Print usage message, including flags, on console") DEFINE_bool(dump_counters, false, "Dump counters on exit") DEFINE_string(map_counters, "", "Map counters to a file") DEFINE_args(js_arguments, JSARGUMENTS_INIT, "Pass all remaining arguments to the script.Alias for\"--\".") DEFINE_bool(debug_compile_events, true,"Enable debugger compile events") DEFINE_bool(debug_script_collected_events, true,"Enable debugger script collected events") DEFINE_bool(gdbjit, false,"enable GDBJIT interface (disables compacting GC)") DEFINE_bool(gdbjit_full, false,"enable GDBJIT interface for all code objects") DEFINE_bool(gdbjit_dump, false,"dump elf objects with debug info to disk") DEFINE_string(gdbjit_dump_filter,"","dump only objects containing this substring") DEFINE_bool(force_marking_deque_overflows, false,"force overflows of marking deque by reducing it's size ""to 64 words") DEFINE_bool(stress_compaction, false,"stress the GC compactor to flush out bugs (implies ""--force_marking_deque_overflows)")#define FLAG DEFINE_bool(enable_slow_asserts, false,"enable asserts that are slow to execute") DEFINE_bool(trace_codegen, false,"print name of functions for which code is generated") DEFINE_bool(print_source, false,"pretty print source code") DEFINE_bool(print_builtin_source, false,"pretty print source code for builtins") DEFINE_bool(print_ast, false,"print source AST") DEFINE_bool(print_builtin_ast, false,"print source AST for builtins") DEFINE_string(stop_at,"","function name where to insert a breakpoint") DEFINE_bool(print_builtin_scopes, false,"print scopes for builtins") DEFINE_bool(print_scopes, false,"print scopes") DEFINE_bool(trace_contexts, false,"trace contexts operations") DEFINE_bool(gc_greedy, false,"perform GC prior to some allocations") DEFINE_bool(gc_verbose, false,"print stuff during garbage collection") DEFINE_bool(heap_stats, false,"report heap statistics before and after GC") DEFINE_bool(code_stats, false,"report code statistics after GC") DEFINE_bool(verify_heap, false,"verify heap pointers before and after GC") DEFINE_bool(print_handles, false,"report handles after GC") DEFINE_bool(print_global_handles, false,"report global handles after GC") DEFINE_bool(trace_ic, false,"trace inline cache state transitions") DEFINE_bool(print_interfaces, false,"print interfaces") DEFINE_bool(print_interface_details, false,"print interface inference details") DEFINE_int(print_interface_depth, 5,"depth for printing interfaces") DEFINE_bool(trace_normalization, false,"prints when objects are turned into dictionaries.") DEFINE_bool(trace_lazy, false,"trace lazy compilation") DEFINE_bool(collect_heap_spill_statistics, false,"report heap spill statistics along with heap_stats ""(requires heap_stats)") DEFINE_bool(trace_isolates, false,"trace isolate state changes") DEFINE_bool(log_state_changes, false,"Log state changes.") DEFINE_bool(regexp_possessive_quantifier, false,"enable possessive quantifier syntax for testing") DEFINE_bool(trace_regexp_bytecodes, false,"trace regexp bytecode execution") DEFINE_bool(trace_regexp_assembler, false,"trace regexp macro assembler calls.")#define FLAG DEFINE_bool(log, false,"Minimal logging (no API, code, GC, suspect, or handles samples).") DEFINE_bool(log_all, false,"Log all events to the log file.") DEFINE_bool(log_runtime, false,"Activate runtime system %Log call.") DEFINE_bool(log_api, false,"Log API events to the log file.") DEFINE_bool(log_code, false,"Log code events to the log file without profiling.") DEFINE_bool(log_gc, false,"Log heap samples on garbage collection for the hp2ps tool.") DEFINE_bool(log_handles, false,"Log global handle events.") DEFINE_bool(log_snapshot_positions, false,"log positions of (de)serialized objects in the snapshot.") DEFINE_bool(log_suspect, false,"Log suspect operations.") DEFINE_bool(prof, false,"Log statistical profiling information (implies --log-code).") DEFINE_bool(prof_auto, true,"Used with --prof, starts profiling automatically") DEFINE_bool(prof_lazy, false,"Used with --prof, only does sampling and logging"" when profiler is active (implies --noprof_auto).") DEFINE_bool(prof_browser_mode, true,"Used with --prof, turns on browser-compatible mode for profiling.") DEFINE_bool(log_regexp, false,"Log regular expression execution.") DEFINE_bool(sliding_state_window, false,"Update sliding state window counters.") DEFINE_string(logfile,"v8.log","Specify the name of the log file.") DEFINE_bool(ll_prof, false,"Enable low-level linux profiler.")#define FLAG DEFINE_bool(trace_elements_transitions, false,"trace elements transitions") DEFINE_bool(print_code_stubs, false,"print code stubs") DEFINE_bool(test_secondary_stub_cache, false,"test secondary stub cache by disabling the primary one") DEFINE_bool(test_primary_stub_cache, false,"test primary stub cache by disabling the secondary one") DEFINE_bool(print_code, false,"print generated code") DEFINE_bool(print_opt_code, false,"print optimized code") DEFINE_bool(print_unopt_code, false,"print unoptimized code before ""printing optimized code based on it") DEFINE_bool(print_code_verbose, false,"print more information for code") DEFINE_bool(print_builtin_code, false,"print generated code for builtins")#43"/Users/thlorenz/dev/dx/v8-perf/build/v8/src/flags.cc"2#define FLAG_MODE_DEFINE_DEFAULTS#1"/Users/thlorenz/dev/dx/v8-perf/build/v8/src/flag-definitions.h"1#define FLAG_FULL(ftype, ctype, nam, def, cmt)#define FLAG_READONLY(ftype, ctype, nam, def, cmt)#define DEFINE_implication(whenflag, thenflag)#define DEFINE_bool(nam, def, cmt)#define DEFINE_int(nam, def, cmt)#define DEFINE_float(nam, def, cmt)#define DEFINE_string(nam, def, cmt)#define DEFINE_args(nam, def, cmt)#define FLAG DEFINE_bool(use_strict, false,"enforce strict mode") DEFINE_bool(es5_readonly, false,"activate correct semantics for inheriting readonliness") DEFINE_bool(es52_globals, false,"activate new semantics for global var declarations") DEFINE_bool(harmony_typeof, false,"enable harmony semantics for typeof") DEFINE_bool(harmony_scoping, false,"enable harmony block scoping") DEFINE_bool(harmony_modules, false,"enable harmony modules (implies block scoping)") DEFINE_bool(harmony_proxies, false,"enable harmony proxies") DEFINE_bool(harmony_collections, false,"enable harmony collections (sets, maps, and weak maps)") DEFINE_bool(harmony, false,"enable all harmony features (except typeof)") DEFINE_implication(harmony, harmony_scoping) DEFINE_implication(harmony, harmony_modules) DEFINE_implication(harmony, harmony_proxies) DEFINE_implication(harmony, harmony_collections) DEFINE_implication(harmony_modules, harmony_scoping) DEFINE_bool(packed_arrays, false,"optimizes arrays that have no holes") DEFINE_bool(smi_only_arrays, true,"tracks arrays with only smi values") DEFINE_bool(clever_optimizations, true,"Optimize object size, Array shift, DOM strings and string +") DEFINE_bool(unbox_double_arrays, true,"automatically unbox arrays of doubles") DEFINE_bool(string_slices, true,"use string slices") DEFINE_bool(crankshaft, true,"use crankshaft") DEFINE_string(hydrogen_filter,"","optimization filter") DEFINE_bool(use_range, true,"use hydrogen range analysis") DEFINE_bool(eliminate_dead_phis, true,"eliminate dead phis") DEFINE_bool(use_gvn, true,"use hydrogen global value numbering") DEFINE_bool(use_canonicalizing, true,"use hydrogen instruction canonicalizing") DEFINE_bool(use_inlining, true,"use function inlining") DEFINE_int(max_inlined_source_size, 600,"maximum source size in bytes considered for a single inlining") DEFINE_int(max_inlined_nodes, 196,"maximum number of AST nodes considered for a single inlining") DEFINE_int(max_inlined_nodes_cumulative, 196,"maximum cumulative number of AST nodes considered for inlining") DEFINE_bool(loop_invariant_code_motion, true,"loop invariant code motion") DEFINE_bool(collect_megamorphic_maps_from_stub_cache, true,"crankshaft harvests type feedback from stub cache") DEFINE_bool(hydrogen_stats, false,"print statistics for hydrogen") DEFINE_bool(trace_hydrogen, false,"trace generated hydrogen to file") DEFINE_string(trace_phase,"Z","trace generated IR for specified phases") DEFINE_bool(trace_inlining, false,"trace inlining decisions") DEFINE_bool(trace_alloc, false,"trace register allocator") DEFINE_bool(trace_all_uses, false,"trace all use positions") DEFINE_bool(trace_range, false,"trace range analysis") DEFINE_bool(trace_gvn, false,"trace global value numbering") DEFINE_bool(trace_representation, false,"trace representation types") DEFINE_bool(stress_pointer_maps, false,"pointer map for every instruction") DEFINE_bool(stress_environments, false,"environment for every instruction") DEFINE_int(deopt_every_n_times, 0,"deoptimize every n times a deopt point is passed") DEFINE_bool(trap_on_deopt, false,"put a break point before deoptimizing") DEFINE_bool(deoptimize_uncommon_cases, true,"deoptimize uncommon cases") DEFINE_bool(polymorphic_inlining, true,"polymorphic inlining") DEFINE_bool(use_osr, true,"use on-stack replacement") DEFINE_bool(array_bounds_checks_elimination, false,"perform array bounds checks elimination") DEFINE_bool(array_index_dehoisting, false,"perform array index dehoisting") DEFINE_bool(trace_osr, false,"trace on-stack replacement") DEFINE_int(stress_runs, 0,"number of stress runs") DEFINE_bool(optimize_closures, true,"optimize closures") DEFINE_bool(inline_construct, true,"inline constructor calls") DEFINE_bool(inline_arguments, true,"inline functions with arguments object") DEFINE_int(loop_weight, 1,"loop weight for representation inference") DEFINE_bool(optimize_for_in, true,"optimize functions containing for-in loops") DEFINE_bool(experimental_profiler, true,"enable all profiler experiments") DEFINE_bool(watch_ic_patching, false,"profiler considers IC stability") DEFINE_int(frame_count, 1,"number of stack frames inspected by the profiler") DEFINE_bool(self_optimization, false,"primitive functions trigger their own optimization") DEFINE_bool(direct_self_opt, false,"call recompile stub directly when self-optimizing") DEFINE_bool(retry_self_opt, false,"re-try self-optimization if it failed") DEFINE_bool(count_based_interrupts, false,"trigger profiler ticks based on counting instead of timing") DEFINE_bool(interrupt_at_exit, false,"insert an interrupt check at function exit") DEFINE_bool(weighted_back_edges, false,"weight back edges by jump distance for interrupt triggering") DEFINE_int(interrupt_budget, 5900,"execution budget before interrupt is triggered") DEFINE_int(type_info_threshold, 15,"percentage of ICs that must have type info to allow optimization") DEFINE_int(self_opt_count, 130,"call count before self-optimization") DEFINE_implication(experimental_profiler, watch_ic_patching) DEFINE_implication(experimental_profiler, self_optimization) DEFINE_implication(experimental_profiler, retry_self_opt) DEFINE_implication(experimental_profiler, count_based_interrupts) DEFINE_implication(experimental_profiler, interrupt_at_exit) DEFINE_implication(experimental_profiler, weighted_back_edges) DEFINE_bool(trace_opt_verbose, false,"extra verbose compilation tracing") DEFINE_implication(trace_opt_verbose, trace_opt) DEFINE_bool(debug_code, false,"generate extra code (assertions) for debugging") DEFINE_bool(code_comments, false,"emit comments in code disassembly") DEFINE_bool(enable_sse2, true,"enable use of SSE2 instructions if available") DEFINE_bool(enable_sse3, true,"enable use of SSE3 instructions if available") DEFINE_bool(enable_sse4_1, true,"enable use of SSE4.1 instructions if available") DEFINE_bool(enable_cmov, true,"enable use of CMOV instruction if available") DEFINE_bool(enable_rdtsc, true,"enable use of RDTSC instruction if available") DEFINE_bool(enable_sahf, true,"enable use of SAHF instruction if available (X64 only)") DEFINE_bool(enable_vfp3, true,"enable use of VFP3 instructions if available - this implies ""enabling ARMv7 instructions (ARM only)") DEFINE_bool(enable_armv7, true,"enable use of ARMv7 instructions if available (ARM only)") DEFINE_bool(enable_fpu, true,"enable use of MIPS FPU instructions if available (MIPS only)") DEFINE_string(expose_natives_as, NULL,"expose natives in global object") DEFINE_string(expose_debug_as, NULL,"expose debug in global object") DEFINE_bool(expose_gc, false,"expose gc extension") DEFINE_bool(expose_externalize_string, false,"expose externalize string extension") DEFINE_int(stack_trace_limit, 10,"number of stack frames to capture") DEFINE_bool(builtins_in_stack_traces, false,"show built-in functions in stack traces") DEFINE_bool(disable_native_files, false,"disable builtin natives files") DEFINE_bool(inline_new, true,"use fast inline allocation") DEFINE_bool(stack_trace_on_abort, true,"print a stack trace if an assertion failure occurs") DEFINE_bool(trace, false,"trace function calls") DEFINE_bool(mask_constants_with_cookie, true,"use random jit cookie to mask large constants") DEFINE_bool(lazy, true,"use lazy compilation") DEFINE_bool(trace_opt, false,"trace lazy optimization") DEFINE_bool(trace_opt_stats, false,"trace lazy optimization statistics") DEFINE_bool(opt, true,"use adaptive optimizations") DEFINE_bool(always_opt, false,"always try to optimize functions") DEFINE_bool(prepare_always_opt, false,"prepare for turning on always opt") DEFINE_bool(trace_deopt, false,"trace deoptimization") DEFINE_int(min_preparse_length, 1024,"minimum length for automatic enable preparsing") DEFINE_bool(always_full_compiler, false,"try to use the dedicated run-once backend for all code") DEFINE_bool(trace_bailout, false,"print reasons for falling back to using the classic V8 backend") DEFINE_bool(compilation_cache, true,"enable compilation cache") DEFINE_bool(cache_prototype_transitions, true,"cache prototype transitions") DEFINE_bool(trace_debug_json, false,"trace debugging JSON request/response") DEFINE_bool(debugger_auto_break, true,"automatically set the debug break flag when debugger commands are ""in the queue") DEFINE_bool(enable_liveedit, true,"enable liveedit experimental feature") DEFINE_bool(break_on_abort, true,"always cause a debug break before aborting") DEFINE_int(stack_size, kPointerSize *123,"default size of stack region v8 is allowed to use (in kBytes)") DEFINE_int(max_stack_trace_source_length, 300,"maximum length of function source code printed in a stack trace.") DEFINE_bool(always_inline_smi_code, false,"always inline smi code in non-opt code") DEFINE_int(max_new_space_size, 0,"max size of the new generation (in kBytes)") DEFINE_int(max_old_space_size, 0,"max size of the old generation (in Mbytes)") DEFINE_int(max_executable_size, 0,"max size of executable memory (in Mbytes)") DEFINE_bool(gc_global, false,"always perform global GCs") DEFINE_int(gc_interval,-1,"garbage collect after <n> allocations") DEFINE_bool(trace_gc, false,"print one trace line following each garbage collection") DEFINE_bool(trace_gc_nvp, false,"print one detailed trace line in name=value format ""after each garbage collection") DEFINE_bool(print_cumulative_gc_stat, false,"print cumulative GC statistics in name=value format on exit") DEFINE_bool(trace_gc_verbose, false,"print more details following each garbage collection") DEFINE_bool(trace_fragmentation, false,"report fragmentation for old pointer and data pages") DEFINE_bool(collect_maps, true,"garbage collect maps from which no objects can be reached") DEFINE_bool(flush_code, true,"flush code that we expect not to use again before full gc") DEFINE_bool(incremental_marking, true,"use incremental marking") DEFINE_bool(incremental_marking_steps, true,"do incremental marking steps") DEFINE_bool(trace_incremental_marking, false,"trace progress of the incremental marking") DEFINE_bool(use_idle_notification, true,"Use idle notification to reduce memory footprint.") DEFINE_bool(send_idle_notification, false,"Send idle notifcation between stress runs.") DEFINE_bool(use_ic, true,"use inline caching") DEFINE_bool(native_code_counters, false,"generate extra code for manipulating stats counters") DEFINE_bool(always_compact, false,"Perform compaction on every full GC") DEFINE_bool(lazy_sweeping, true,"Use lazy sweeping for old pointer and data spaces") DEFINE_bool(never_compact, false,"Never perform compaction on full GC - testing only") DEFINE_bool(compact_code_space, true,"Compact code space on full non-incremental collections") DEFINE_bool(cleanup_code_caches_at_gc, true,"Flush inline caches prior to mark compact collection and ""flush code caches in maps during mark compact cycle.") DEFINE_int(random_seed, 0,"Default seed for initializing random generator ""(0, the default, means to use system random).") DEFINE_bool(use_verbose_printer, true,"allows verbose printing") DEFINE_bool(allow_natives_syntax, false,"allow natives syntax") DEFINE_bool(trace_sim, false,"Trace simulator execution") DEFINE_bool(check_icache, false,"Check icache flushes in ARM and MIPS simulator") DEFINE_int(stop_sim_at, 0,"Simulator stop after x number of instructions") DEFINE_int(sim_stack_alignment, 8,"Stack alingment in bytes in simulator (4 or 8, 8 is default)") DEFINE_bool(trace_exception, false,"print stack trace when throwing exceptions") DEFINE_bool(preallocate_message_memory, false,"preallocate some memory to build stack traces.") DEFINE_bool(randomize_hashes, true,"randomize hashes to avoid predictable hash collisions ""(with snapshots this option cannot override the baked-in seed)") DEFINE_int(hash_seed, 0,"Fixed seed to use to hash property keys (0 means random)""(with snapshots this option cannot override the baked-in seed)") DEFINE_bool(preemption, false,"activate a 100ms timer that switches between V8 threads") DEFINE_bool(regexp_optimization, true,"generate optimized regexp code") DEFINE_bool(testing_bool_flag, true,"testing_bool_flag") DEFINE_int(testing_int_flag, 13,"testing_int_flag") DEFINE_float(testing_float_flag, 2.5,"float-flag") DEFINE_string(testing_string_flag,"Hello, world!","string-flag") DEFINE_int(testing_prng_seed, 42,"Seed used for threading test randomness") DEFINE_string(testing_serialization_file,"/tmp/serdes","file in which to serialize heap") DEFINE_bool(help, false,"Print usage message, including flags, on console") DEFINE_bool(dump_counters, false,"Dump counters on exit") DEFINE_string(map_counters,"","Map counters to a file") DEFINE_args(js_arguments, JSARGUMENTS_INIT,"Pass all remaining arguments to the script. Alias for \"--\".") DEFINE_bool(debug_compile_events, true,"Enable debugger compile events") DEFINE_bool(debug_script_collected_events, true,"Enable debugger script collected events") DEFINE_bool(gdbjit, false,"enable GDBJIT interface (disables compacting GC)") DEFINE_bool(gdbjit_full, false,"enable GDBJIT interface for all code objects") DEFINE_bool(gdbjit_dump, false,"dump elf objects with debug info to disk") DEFINE_string(gdbjit_dump_filter,"","dump only objects containing this substring") DEFINE_bool(force_marking_deque_overflows, false,"force overflows of marking deque by reducing it's size ""to 64 words") DEFINE_bool(stress_compaction, false,"stress the GC compactor to flush out bugs (implies ""--force_marking_deque_overflows)")#define FLAG DEFINE_bool(enable_slow_asserts, false,"enable asserts that are slow to execute") DEFINE_bool(trace_codegen, false,"print name of functions for which code is generated") DEFINE_bool(print_source, false,"pretty print source code") DEFINE_bool(print_builtin_source, false,"pretty print source code for builtins") DEFINE_bool(print_ast, false,"print source AST") DEFINE_bool(print_builtin_ast, false,"print source AST for builtins") DEFINE_string(stop_at,"","function name where to insert a breakpoint") DEFINE_bool(print_builtin_scopes, false,"print scopes for builtins") DEFINE_bool(print_scopes, false,"print scopes") DEFINE_bool(trace_contexts, false,"trace contexts operations") DEFINE_bool(gc_greedy, false,"perform GC prior to some allocations") DEFINE_bool(gc_verbose, false,"print stuff during garbage collection") DEFINE_bool(heap_stats, false,"report heap statistics before and after GC") DEFINE_bool(code_stats, false,"report code statistics after GC") DEFINE_bool(verify_heap, false,"verify heap pointers before and after GC") DEFINE_bool(print_handles, false,"report handles after GC") DEFINE_bool(print_global_handles, false,"report global handles after GC") DEFINE_bool(trace_ic, false,"trace inline cache state transitions") DEFINE_bool(print_interfaces, false,"print interfaces") DEFINE_bool(print_interface_details, false,"print interface inference details") DEFINE_int(print_interface_depth, 5,"depth for printing interfaces") DEFINE_bool(trace_normalization, false,"prints when objects are turned into dictionaries.") DEFINE_bool(trace_lazy, false,"trace lazy compilation") DEFINE_bool(collect_heap_spill_statistics, false,"report heap spill statistics along with heap_stats ""(requires heap_stats)") DEFINE_bool(trace_isolates, false,"trace isolate state changes") DEFINE_bool(log_state_changes, false,"Log state changes.") DEFINE_bool(regexp_possessive_quantifier, false,"enable possessive quantifier syntax for testing") DEFINE_bool(trace_regexp_bytecodes, false,"trace regexp bytecode execution") DEFINE_bool(trace_regexp_assembler, false,"trace regexp macro assembler calls.")#define FLAG DEFINE_bool(log, false,"Minimal logging (no API, code, GC, suspect, or handles samples).") DEFINE_bool(log_all, false,"Log all events to the log file.") DEFINE_bool(log_runtime, false,"Activate runtime system %Log call.") DEFINE_bool(log_api, false,"Log API events to the log file.") DEFINE_bool(log_code, false,"Log code events to the log file without profiling.") DEFINE_bool(log_gc, false,"Log heap samples on garbage collection for the hp2ps tool.") DEFINE_bool(log_handles, false,"Log global handle events.") DEFINE_bool(log_snapshot_positions, false,"log positions of (de)serialized objects in the snapshot.") DEFINE_bool(log_suspect, false,"Log suspect operations.") DEFINE_bool(prof, false,"Log statistical profiling information (implies --log-code).") DEFINE_bool(prof_auto, true,"Used with --prof, starts profiling automatically") DEFINE_bool(prof_lazy, false,"Used with --prof, only does sampling and logging"" when profiler is active (implies --noprof_auto).") DEFINE_bool(prof_browser_mode, true,"Used with --prof, turns on browser-compatible mode for profiling.") DEFINE_bool(log_regexp, false,"Log regular expression execution.") DEFINE_bool(sliding_state_window, false,"Update sliding state window counters.") DEFINE_string(logfile,"v8.log","Specify the name of the log file.") DEFINE_bool(ll_prof, false,"Enable low-level linux profiler.")#define FLAG DEFINE_bool(trace_elements_transitions, false,"trace elements transitions") DEFINE_bool(print_code_stubs, false,"print code stubs") DEFINE_bool(test_secondary_stub_cache, false,"test secondary stub cache by disabling the primary one") DEFINE_bool(test_primary_stub_cache, false,"test primary stub cache by disabling the secondary one") DEFINE_bool(print_code, false,"print generated code") DEFINE_bool(print_opt_code, false,"print optimized code") DEFINE_bool(print_unopt_code, false,"print unoptimized code before ""printing optimized code based on it") DEFINE_bool(print_code_verbose, false,"print more information for code") DEFINE_bool(print_builtin_code, false,"print generated code for builtins")#47"/Users/thlorenz/dev/dx/v8-perf/build/v8/src/flags.cc"2 namespace{struct Flag{enum FlagType{TYPE_BOOL, TYPE_INT, TYPE_FLOAT, TYPE_STRING, TYPE_ARGS} name
static bool IsCompareOp(Value op)
static Handle< T > cast(Handle< S > that)
Expression * target() const
void Update(Scope *scope, Statement *stat)
void SetHarmonyScoping(bool scoping)
static bool IsUnaryOp(Value op)
Scope * outer_scope() const
static Handle< FixedArray > GetElements(Handle< FixedArray > value)
Vector< T > SubVector(int from, int to)
int literal_length() const
FunctionLiteral * ParseProgram(CompilationInfo *info)
bool is_classic_mode() const
RegExpTree * ParseCharacterClass()
void DeclareParameter(Handle< String > name, VariableMode mode)
static CharacterRange Everything()
void AddAtom(RegExpTree *tree)
static const Function * FunctionForId(FunctionId id)
static Assignment * AsAssignment(Statement *stat)
#define ASSERT(condition)
Variable * NewTemporary(Handle< String > name)
void ForceEagerCompilation()
static bool IsCompileTimeValue(Expression *expression)
Isolate * isolate() const
virtual MaterializedLiteral * AsMaterializedLiteral()
static Type GetType(Handle< FixedArray > value)
void SetHarmonyModules(bool modules)
void set_end_position(int statement_pos)
Vector< const char * > args()
virtual ~ScriptDataImpl()
Handle< String > name() const
Element(PositionStack *stack, int value)
Handle< String > LookupAsciiSymbol(Vector< const char > str)
Handle< Object > NewSyntaxError(const char *type, Handle< JSArray > args)
bool AsArrayIndex(uint32_t *index)
bool ParseBackReferenceIndex(int *index_out)
static Smi * cast(Object *object)
RegExpTree * ParsePattern()
static bool Parse(CompilationInfo *info, int flags)
bool Equals(String *other)
bool HasTrivialOuterContext() const
static const int kSymbolCountOffset
FunctionEntry GetFunctionEntry(int start)
v8::Handle< v8::Value > Read(const v8::Arguments &args)
Handle< FixedArray > constant_elements() const
void DeclareFunctionVar(VariableDeclaration *declaration)
double StringToDouble(UnicodeCache *unicode_cache, const char *str, int flags, double empty_string_val)
static RegExpEmpty * GetInstance()
ObjectLiteralPropertyChecker(Parser *parser, LanguageMode language_mode)
virtual Vector< unsigned > ExtractData()
void AddQuantifierToAtom(int min, int max, RegExpQuantifier::Type type)
Handle< FixedArray > constant_properties() const
RegExpTree * ParseDisjunction()
Handle< String > NewStringFromUtf8(Vector< const char > str, PretenureFlag pretenure=NOT_TENURED)
kPropertyAccessorsOffset kNamedPropertyHandlerOffset kInstanceTemplateOffset kAccessCheckInfoOffset kEvalFrominstructionsOffsetOffset this_property_assignments
void AddAssertion(RegExpTree *tree)
RegExpParser(FlatStringReader *in, Handle< String > *error, bool multiline_mode)
int start_position() const
static Interface * NewUnknown(Zone *zone)
friend class FunctionState
bool literal_contains_escapes() const
bool is_eval_scope() const
static CharacterRange Range(uc16 from, uc16 to)
void set_contains_anchor()
static const int kInfinity
void RemoveLastFunction()
static const char * String(Value tok)
static const int kMessageEndPos
void set_start_position(int statement_pos)
void SetScopeName(Handle< String > scope_name)
virtual void LogAsciiSymbol(int start, Vector< const char > literal)
static bool IsAssignmentOp(Value tok)
CharacterRange ParseClassAtom(uc16 *char_class)
bool only_simple_this_property_assignments()
static const int kMessageStartPos
static const int kMessageTextPos
static const int kMessageArgCountPos
void SeekForward(int pos)
virtual void PauseRecording()
Handle< FixedArray > GetThisPropertyAssignments()
static const int kFunctionsSizeOffset
Entry * Lookup(void *key, uint32_t hash, bool insert, AllocationPolicy allocator=AllocationPolicy())
virtual int symbol_position()
Handle< FixedArray > NewFixedArray(int size, PretenureFlag pretenure=NOT_TENURED)
TargetScope(Target **variable)
Expression * expression() const
void CheckProperty(ObjectLiteral::Property *property, Scanner::Location loc, bool *ok)
FunctionLiteral * ParseLazy(CompilationInfo *info)
static bool IsKeyword(Value tok)
void Initialize(Utf16CharacterStream *source)
Vector< const char > CStrVector(const char *data)
static Local< Context > ToLocal(v8::internal::Handle< v8::internal::Context > obj)
PreParseResult PreParseLazyFunction(i::LanguageMode mode, i::ParserRecorder *log)
virtual void LogFunction(int start, int end, int literals, int properties, LanguageMode mode)
bool IsDeclared(Handle< String > name)
const char * argument_opt()
uc32 ParseClassCharacterEscape()
static Handle< FixedArray > GetValue(Expression *expression)
const char * BuildMessage()
Handle< JSArray > NewJSArrayWithElements(Handle< FixedArrayBase > elements, ElementsKind elements_kind=TERMINAL_FAST_ELEMENTS_KIND, PretenureFlag pretenure=NOT_TENURED)
static Location invalid()
LanguageMode language_mode()
void PushEnclosingName(Handle< String > name)
int ArithmeticShiftRight(int x, int s)
uint32_t DoubleToUint32(double x)
void PushLiteralName(Handle< String > name)
int32_t DoubleToInt32(double x)
VariableProxy * NewUnresolved(AstNodeFactory< Visitor > *factory, Handle< String > name, int position=RelocInfo::kNoPosition, Interface *interface=Interface::NewValue())
void SetLanguageMode(LanguageMode language_mode)
Location location() const
void ReportMessageAt(Scanner::Location loc, const char *message, Vector< const char * > args)
virtual int function_position()
static const unsigned kCurrentVersion
virtual const char * Data()
Target(Target **variable, AstNode *node)
void AddCharacter(uc16 character)
Local< Function > GetFunction()
void Update(Statement *stat)
void clear_octal_position()
Scanner::Location MessageLocation()
void Add(Handle< String > name, Interface *interface, Zone *zone, bool *ok)
static const unsigned char kNumberTerminator
static Handle< String > null()
TemplateHashMapImpl< FreeStoreAllocationPolicy > HashMap
bool fast_elements() const
#define ASSERT_EQ(v1, v2)
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination trace on stack replacement optimize closures functions with arguments object optimize functions containing for in loops profiler considers IC stability primitive functions trigger their own optimization re try self optimization if it failed insert an interrupt check at function exit execution budget before interrupt is triggered call count before self optimization self_optimization count_based_interrupts weighted_back_edges trace_opt emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 enable use of ARMv7 instructions if enable use of MIPS FPU instructions if NULL
ZoneList< Handle< Object > > ZoneObjectList
static PreParseResult PreParseProgram(i::Scanner *scanner, i::ParserRecorder *log, int flags, uintptr_t stack_limit)
Vector< const char > literal_ascii_string()
void BindTo(Variable *var)
void set_ast_properties(AstProperties *ast_properties)
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping true
#define ASSERT_NE(v1, v2)
static FixedArray * cast(Object *obj)
static Vector< const char * > empty()
Parser(Handle< Script > script, int parsing_flags, v8::Extension *extension, ScriptDataImpl *pre_data, Zone *zone)
void Add(const T &element, AllocationPolicy allocator=AllocationPolicy())
Location octal_position() const
void AddFunction(FunctionLiteral *func_to_infer)
Handle< String > LookupTwoByteSymbol(Vector< const uc16 > str)
static const int kMaxCaptures
ZoneList< Handle< String > > ZoneStringList
virtual void LogMessage(int start, int end, const char *message, const char *argument_opt)
LanguageMode language_mode() const
bool is_function_scope() const
bool ParseIntervalQuantifier(int *min_out, int *max_out)
virtual void ResumeRecording()
void DeleteArray(T *array)
void RecordWithStatement()
virtual int max_match()=0
static const int kHeaderSize
static bool IsCountOp(Value op)
RegExpBuilder(Zone *zone)
void check(i::Vector< const char > string)
bool is_extended_mode() const
static Scope * DeserializeScopeChain(Context *context, Scope *global_scope, Zone *zone)
static const char *const kStackOverflowMessage
ElementsKind GetHoleyElementsKind(ElementsKind packed_kind)
static void AddClassEscape(uc16 type, ZoneList< CharacterRange > *ranges, Zone *zone)
bool IsDecimalDigit(uc32 c)
virtual ~SingletonLogger()
void RemoveUnresolved(VariableProxy *var)
static CharacterRange Singleton(uc16 value)
Location peek_location() const
Vector< T > AddBlock(T value, int count, AllocationPolicy allocator=AllocationPolicy())
ZoneList< Declaration * > * declarations()
static bool ArrayLiteralElementNeedsInitialization(Expression *value)
static v8::internal::Handle< v8::internal::TemplateInfo > OpenHandle(const Template *that)
void set_inferred_name(Handle< String > inferred_name)