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) {
410 Scope* Parser::NewScope(Scope* parent,
ScopeType type) {
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()),
496 factory_(isolate, parser->zone()) {
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
539 : isolate_(info->isolate()),
540 symbol_cache_(pre_data ? pre_data->symbol_count() : 0, info->zone()),
541 script_(info->script()),
542 scanner_(isolate_->unicode_cache()),
543 reusable_preparser_(
NULL),
545 current_function_state_(
NULL),
547 extension_(extension),
551 allow_lazy_((parser_flags &
kAllowLazy) != 0),
553 stack_overflow_(
false),
554 parenthesized_function_(
false),
557 ASSERT(!script_.is_null());
558 isolate_->set_ast_node_id(0);
570 HistogramTimerScope timer(isolate()->counters()->parse());
572 isolate()->counters()->total_parse_size()->Increment(source->length());
573 int64_t start = FLAG_trace_parse ?
OS::Ticks() : 0;
577 source->TryFlatten();
579 if (source->IsExternalTwoByteString()) {
586 result = DoParseProgram(info(), source, &zone_scope);
590 result = DoParseProgram(info(), source, &zone_scope);
593 if (FLAG_trace_parse && result !=
NULL) {
594 double ms =
static_cast<double>(
OS::Ticks() - start) / 1000;
597 }
else if (info()->script()->name()->IsString()) {
600 PrintF(
"[parsing script: %s", *name_chars);
602 PrintF(
"[parsing script");
604 PrintF(
" - took %0.3f ms]\n", ms);
612 ZoneScope* zone_scope) {
618 Mode mode = (FLAG_lazy && allow_lazy_) ? PARSE_LAZILY : PARSE_EAGERLY;
619 if (allow_natives_syntax_ || extension_ !=
NULL) mode = PARSE_EAGERLY;
620 ParsingModeScope parsing_mode(
this, mode);
627 if (!info->
context().is_null()) {
642 ZoneList<Statement*>* body =
new(zone()) ZoneList<Statement*>(16, zone());
645 ParseSourceElements(body, Token::EOS, info->
is_eval(),
true, &ok);
647 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok);
650 if (ok && is_extended_mode()) {
651 CheckConflictingVarDeclarations(top_scope_, &ok);
655 result = factory()->NewFunctionLiteral(
659 function_state.materialized_literal_count(),
660 function_state.expected_property_count(),
661 function_state.handler_count(),
662 function_state.only_simple_this_property_assignments(),
663 function_state.this_property_assignments(),
670 }
else if (stack_overflow_) {
671 isolate()->StackOverflow();
680 if (result ==
NULL) zone_scope->DeleteOnExit();
687 HistogramTimerScope timer(isolate()->counters()->parse_lazy());
689 isolate()->counters()->total_parse_size()->Increment(source->length());
690 int64_t start = FLAG_trace_parse ?
OS::Ticks() : 0;
694 source->TryFlatten();
696 if (source->IsExternalTwoByteString()) {
699 shared_info->start_position(),
700 shared_info->end_position());
701 result =
ParseLazy(&stream, &zone_scope);
704 shared_info->start_position(),
705 shared_info->end_position());
706 result =
ParseLazy(&stream, &zone_scope);
709 if (FLAG_trace_parse && result !=
NULL) {
710 double ms =
static_cast<double>(
OS::Ticks() - start) / 1000;
712 PrintF(
"[parsing function: %s - took %0.3f ms]\n", *name_chars, ms);
719 ZoneScope* zone_scope) {
729 ParsingModeScope parsing_mode(
this, PARSE_EAGERLY);
738 if (!info()->closure().is_null()) {
746 ASSERT(info()->language_mode() == shared_info->language_mode());
749 ? (shared_info->is_anonymous()
750 ? FunctionLiteral::ANONYMOUS_EXPRESSION
754 result = ParseFunctionLiteral(name,
756 RelocInfo::kNoPosition,
768 if (result ==
NULL) {
769 zone_scope->DeleteOnExit();
770 if (stack_overflow_) isolate()->StackOverflow();
772 Handle<String> inferred_name(shared_info->inferred_name());
779 Handle<String> Parser::GetSymbol(
bool* ok) {
781 if (pre_data() !=
NULL) {
784 return LookupSymbol(symbol_id);
788 void Parser::ReportMessage(
const char* type, Vector<const char*> args) {
789 Scanner::Location source_location = scanner().
location();
794 void Parser::ReportMessage(
const char* type, Vector<Handle<String> > args) {
795 Scanner::Location source_location = scanner().
location();
806 Factory* factory = isolate()->factory();
808 for (
int i = 0; i < args.
length(); i++) {
810 elements->set(i, *arg_string);
814 isolate()->Throw(*result, &location);
824 Factory* factory = isolate()->factory();
826 for (
int i = 0; i < args.length(); i++) {
827 elements->set(i, *args[i]);
831 isolate()->Throw(*result, &location);
842 only_simple_this_property_assignments_(
true),
844 assigned_arguments_(0, zone),
845 assigned_constants_(0, zone),
853 return exp_stat->
expression()->AsAssignment();
859 if (!only_simple_this_property_assignments_) {
865 if (IsThisPropertyAssignment(assignment)) {
866 HandleThisPropertyAssignment(scope, assignment);
868 only_simple_this_property_assignments_ =
false;
875 return only_simple_this_property_assignments_;
881 if (names_.is_empty()) {
882 return isolate_->
factory()->empty_fixed_array();
884 ASSERT_EQ(names_.length(), assigned_arguments_.length());
885 ASSERT_EQ(names_.length(), assigned_constants_.length());
888 for (
int i = 0; i < names_.length(); ++i) {
889 assignments->set(i * 3, *names_[i]);
890 assignments->set(i * 3 + 1,
Smi::FromInt(assigned_arguments_[i]));
891 assignments->set(i * 3 + 2, *assigned_constants_[i]);
897 bool IsThisPropertyAssignment(
Assignment* assignment) {
898 if (assignment !=
NULL) {
900 return assignment->
op() == Token::ASSIGN
902 &&
property->obj()->AsVariableProxy() !=
NULL
903 &&
property->obj()->AsVariableProxy()->is_this();
908 void HandleThisPropertyAssignment(Scope* scope, Assignment* assignment) {
911 Property*
property = assignment->target()->AsProperty();
913 Literal* literal =
property->key()->AsLiteral();
915 if (literal !=
NULL &&
916 literal->handle()->IsString() &&
918 isolate_->
heap()->Proto_symbol()) &&
924 if (assignment->value()->AsLiteral() !=
NULL) {
926 Literal* literal = assignment->value()->AsLiteral();
927 AssignmentFromConstant(key, literal->handle());
929 }
else if (assignment->value()->AsVariableProxy() !=
NULL) {
931 Handle<String> name =
932 assignment->value()->AsVariableProxy()->name();
934 for (
int i = 0; i < scope->num_parameters(); i++) {
935 if (*scope->parameter(i)->name() == *name) {
937 AssignmentFromParameter(key, i);
945 AssignmentFromSomethingElse();
953 void AssignmentFromParameter(Handle<String> name,
int index) {
955 for (
int i = 0; i < names_.length(); ++i) {
956 if (name->Equals(*names_[i])) {
957 assigned_arguments_[i] = index;
958 assigned_constants_[i] = isolate_->
factory()->undefined_value();
962 names_.
Add(name, zone());
963 assigned_arguments_.
Add(index, zone());
964 assigned_constants_.
Add(isolate_->
factory()->undefined_value(), zone());
967 void AssignmentFromConstant(Handle<String> name, Handle<Object> value) {
969 for (
int i = 0; i < names_.length(); ++i) {
970 if (name->Equals(*names_[i])) {
971 assigned_arguments_[i] = -1;
972 assigned_constants_[i] = value;
976 names_.
Add(name, zone());
977 assigned_arguments_.
Add(-1, zone());
978 assigned_constants_.
Add(value, zone());
981 void AssignmentFromSomethingElse() {
983 only_simple_this_property_assignments_ =
false;
986 void EnsureInitialized() {
987 if (names_.capacity() == 0) {
988 ASSERT(assigned_arguments_.capacity() == 0);
989 ASSERT(assigned_constants_.capacity() == 0);
990 names_.Initialize(4, zone());
991 assigned_arguments_.Initialize(4, zone());
992 assigned_constants_.Initialize(4, zone());
996 Zone* zone()
const {
return zone_; }
999 bool only_simple_this_property_assignments_;
1001 ZoneList<int> assigned_arguments_;
1007 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
1019 TargetScope scope(&this->target_stack_);
1022 ThisNamedPropertyAssignmentFinder this_property_assignment_finder(isolate(),
1024 bool directive_prologue =
true;
1026 while (peek() != end_token) {
1027 if (directive_prologue && peek() != Token::STRING) {
1028 directive_prologue =
false;
1033 if (is_global && !is_eval) {
1038 if (stat ==
NULL || stat->IsEmpty()) {
1039 directive_prologue =
false;
1043 if (directive_prologue) {
1045 ExpressionStatement* e_stat;
1048 if ((e_stat = stat->AsExpressionStatement()) !=
NULL &&
1049 (literal = e_stat->expression()->AsLiteral()) !=
NULL &&
1050 literal->handle()->IsString()) {
1055 directive->Equals(isolate()->heap()->use_strict()) &&
1056 token_loc.end_pos - token_loc.beg_pos ==
1057 isolate()->heap()->use_strict()->length() + 2) {
1064 Scope* scope = NewScope(top_scope_,
EVAL_SCOPE);
1073 directive_prologue =
false;
1077 directive_prologue =
false;
1083 this_property_assignment_finder.Update(top_scope_, stat);
1085 processor->Add(stat, zone());
1090 bool only_simple_this_property_assignments =
1091 this_property_assignment_finder.only_simple_this_property_assignments()
1093 if (only_simple_this_property_assignments) {
1094 current_function_state_->SetThisPropertyAssignmentInfo(
1095 only_simple_this_property_assignments,
1096 this_property_assignment_finder.GetThisPropertyAssignments());
1120 case Token::FUNCTION:
1121 return ParseFunctionDeclaration(
NULL, ok);
1124 return ParseVariableStatement(kModuleElement,
NULL, ok);
1126 return ParseImportDeclaration(ok);
1128 return ParseExportDeclaration(ok);
1130 Statement* stmt = ParseStatement(labels,
CHECK_OK);
1132 if (FLAG_harmony_modules &&
1133 peek() == Token::IDENTIFIER &&
1134 !scanner().HasAnyLineTerminatorBeforeNext() &&
1136 ExpressionStatement* estmt = stmt->AsExpressionStatement();
1137 if (estmt !=
NULL &&
1138 estmt->expression()->AsVariableProxy() !=
NULL &&
1139 estmt->expression()->AsVariableProxy()->name()->Equals(
1140 isolate()->heap()->module_symbol()) &&
1142 return ParseModuleDeclaration(
NULL, ok);
1151 Statement* Parser::ParseModuleDeclaration(
ZoneStringList* names,
bool* ok) {
1155 Handle<String> name = ParseIdentifier(
CHECK_OK);
1158 if (FLAG_print_interface_details)
1159 PrintF(
"# Module %s...\n", name->ToAsciiArray());
1162 Module* module = ParseModule(
CHECK_OK);
1163 VariableProxy* proxy = NewUnresolved(name,
LET, module->interface());
1164 Declaration* declaration =
1165 factory()->NewModuleDeclaration(proxy, module, top_scope_);
1166 Declare(declaration,
true,
CHECK_OK);
1169 if (FLAG_print_interface_details)
1170 PrintF(
"# Module %s.\n", name->ToAsciiArray());
1172 if (FLAG_print_interfaces) {
1173 PrintF(
"module %s : ", name->ToAsciiArray());
1174 module->interface()->Print();
1178 if (names) names->Add(name, zone());
1179 if (module->body() ==
NULL)
1180 return factory()->NewEmptyStatement();
1182 return module->body();
1186 Module* Parser::ParseModule(
bool* ok) {
1194 return ParseModuleLiteral(ok);
1196 case Token::ASSIGN: {
1198 Module* result = ParseModulePath(
CHECK_OK);
1204 ExpectContextualKeyword(
"at",
CHECK_OK);
1205 Module* result = ParseModuleUrl(
CHECK_OK);
1213 Module* Parser::ParseModuleLiteral(
bool* ok) {
1218 Block* body = factory()->NewBlock(
NULL, 16,
false);
1220 if (FLAG_print_interface_details)
PrintF(
"# Literal ");
1225 scope->set_start_position(scanner().location().beg_pos);
1230 TargetCollector collector(zone());
1231 Target target(&this->target_stack_, &collector);
1232 Target target_body(&this->target_stack_, body);
1234 while (peek() != Token::RBRACE) {
1236 if (stat && !stat->IsEmpty()) {
1237 body->AddStatement(stat, zone());
1243 scope->set_end_position(scanner().location().end_pos);
1244 body->set_scope(scope);
1247 Interface*
interface = scope->
interface();
1248 for (Interface::Iterator it =
interface->iterator();
1249 !it.done(); it.Advance()) {
1250 if (scope->LocalLookup(it.name()) ==
NULL) {
1251 Handle<String> name(it.name());
1252 ReportMessage(
"module_export_undefined",
1253 Vector<Handle<String> >(&name, 1));
1263 return factory()->NewModuleLiteral(body,
interface);
1267 Module* Parser::ParseModulePath(
bool* ok) {
1272 Module* result = ParseModuleVariable(
CHECK_OK);
1273 while (Check(Token::PERIOD)) {
1274 Handle<String> name = ParseIdentifierName(
CHECK_OK);
1276 if (FLAG_print_interface_details)
1277 PrintF(
"# Path .%s ", name->ToAsciiArray());
1279 Module* member = factory()->NewModulePath(result, name);
1280 result->interface()->Add(name, member->interface(), zone(), ok);
1283 if (FLAG_print_interfaces) {
1284 PrintF(
"PATH TYPE ERROR at '%s'\n", name->ToAsciiArray());
1286 result->interface()->Print();
1288 member->interface()->Print();
1291 ReportMessage(
"invalid_module_path", Vector<Handle<String> >(&name, 1));
1301 Module* Parser::ParseModuleVariable(
bool* ok) {
1305 Handle<String> name = ParseIdentifier(
CHECK_OK);
1307 if (FLAG_print_interface_details)
1308 PrintF(
"# Module variable %s ", name->ToAsciiArray());
1312 scanner().location().beg_pos);
1314 return factory()->NewModuleVariable(proxy);
1318 Module* Parser::ParseModuleUrl(
bool* ok) {
1323 Handle<String> symbol = GetSymbol(
CHECK_OK);
1328 if (FLAG_print_interface_details)
PrintF(
"# Url ");
1331 Module* result = factory()->NewModuleUrl(symbol);
1332 Interface*
interface = result->
interface();
1337 interface->Unify(scope->interface(), zone(), ok);
1343 Module* Parser::ParseModuleSpecifier(
bool* ok) {
1348 if (peek() == Token::STRING) {
1349 return ParseModuleUrl(ok);
1351 return ParseModulePath(ok);
1356 Block* Parser::ParseImportDeclaration(
bool* ok) {
1365 Handle<String> name = ParseIdentifierName(
CHECK_OK);
1366 names.Add(name, zone());
1367 while (peek() == Token::COMMA) {
1368 Consume(Token::COMMA);
1369 name = ParseIdentifierName(
CHECK_OK);
1370 names.Add(name, zone());
1373 ExpectContextualKeyword(
"from",
CHECK_OK);
1374 Module* module = ParseModuleSpecifier(
CHECK_OK);
1379 Block* block = factory()->NewBlock(
NULL, 1,
true);
1380 for (
int i = 0; i < names.length(); ++i) {
1382 if (FLAG_print_interface_details)
1383 PrintF(
"# Import %s ", names[i]->ToAsciiArray());
1386 module->interface()->
Add(names[i],
interface, zone(), ok);
1389 if (FLAG_print_interfaces) {
1390 PrintF(
"IMPORT TYPE ERROR at '%s'\n", names[i]->ToAsciiArray());
1392 module->interface()->Print();
1395 ReportMessage(
"invalid_module_path", Vector<Handle<String> >(&name, 1));
1398 VariableProxy* proxy = NewUnresolved(names[i],
LET,
interface);
1399 Declaration* declaration =
1400 factory()->NewImportDeclaration(proxy, module, top_scope_);
1401 Declare(declaration,
true,
CHECK_OK);
1408 Statement* Parser::ParseExportDeclaration(
bool* ok) {
1419 Statement* result =
NULL;
1422 case Token::IDENTIFIER: {
1423 Handle<String> name = ParseIdentifier(
CHECK_OK);
1425 if (!name->IsEqualTo(
CStrVector(
"module"))) {
1426 names.Add(name, zone());
1427 while (peek() == Token::COMMA) {
1428 Consume(Token::COMMA);
1430 names.Add(name, zone());
1433 result = factory()->NewEmptyStatement();
1435 result = ParseModuleDeclaration(&names,
CHECK_OK);
1440 case Token::FUNCTION:
1441 result = ParseFunctionDeclaration(&names,
CHECK_OK);
1447 result = ParseVariableStatement(kModuleElement, &names,
CHECK_OK);
1452 ReportUnexpectedToken(scanner().current_token());
1457 Interface*
interface = top_scope_->
interface();
1458 for (
int i = 0; i < names.length(); ++i) {
1460 if (FLAG_print_interface_details)
1461 PrintF(
"# Export %s ", names[i]->ToAsciiArray());
1467 VariableProxy* proxy = NewUnresolved(names[i],
LET, inner);
1494 case Token::FUNCTION:
1495 return ParseFunctionDeclaration(
NULL, ok);
1498 return ParseVariableStatement(kModuleElement,
NULL, ok);
1500 return ParseStatement(labels, ok);
1505 Statement* Parser::ParseStatement(
ZoneStringList* labels,
bool* ok) {
1532 Statement* stmt =
NULL;
1535 return ParseBlock(labels, ok);
1540 stmt = ParseVariableStatement(kStatement,
NULL, ok);
1543 case Token::SEMICOLON:
1545 return factory()->NewEmptyStatement();
1548 stmt = ParseIfStatement(labels, ok);
1552 stmt = ParseDoWhileStatement(labels, ok);
1556 stmt = ParseWhileStatement(labels, ok);
1560 stmt = ParseForStatement(labels, ok);
1563 case Token::CONTINUE:
1564 stmt = ParseContinueStatement(ok);
1568 stmt = ParseBreakStatement(labels, ok);
1572 stmt = ParseReturnStatement(ok);
1576 stmt = ParseWithStatement(labels, ok);
1580 stmt = ParseSwitchStatement(labels, ok);
1584 stmt = ParseThrowStatement(ok);
1593 Block* result = factory()->NewBlock(labels, 1,
false);
1594 Target target(&this->target_stack_, result);
1595 TryStatement* statement = ParseTryStatement(
CHECK_OK);
1597 statement->set_statement_pos(statement_pos);
1599 if (result) result->AddStatement(statement, zone());
1603 case Token::FUNCTION: {
1617 return ParseFunctionDeclaration(
NULL, ok);
1620 case Token::DEBUGGER:
1621 stmt = ParseDebuggerStatement(ok);
1625 stmt = ParseExpressionOrLabelledStatement(labels, ok);
1629 if (stmt !=
NULL) stmt->set_statement_pos(statement_pos);
1634 VariableProxy* Parser::NewUnresolved(
1642 factory(), name, interface, scanner().location().beg_pos);
1646 void Parser::Declare(Declaration* declaration,
bool resolve,
bool* ok) {
1647 VariableProxy* proxy = declaration->proxy();
1648 Handle<String> name = proxy->
name();
1650 Scope* declaration_scope = DeclarationScope(mode);
1651 Variable* var =
NULL;
1661 if (declaration_scope->is_function_scope() ||
1662 declaration_scope->is_strict_or_extended_eval_scope() ||
1663 declaration_scope->is_block_scope() ||
1664 declaration_scope->is_module_scope() ||
1665 declaration_scope->is_global_scope()) {
1670 var = declaration_scope->is_global_scope()
1671 ? declaration_scope->Lookup(name)
1672 : declaration_scope->LocalLookup(name);
1675 var = declaration_scope->DeclareLocal(
1676 name, mode, declaration->initialization(), proxy->interface());
1677 }
else if ((mode !=
VAR || var->mode() !=
VAR) &&
1678 (!declaration_scope->is_global_scope() ||
1695 if (is_extended_mode()) {
1698 SmartArrayPointer<char> c_string = name->ToCString(
DISALLOW_NULLS);
1699 const char* elms[2] = {
"Variable", *c_string };
1700 Vector<const char*> args(elms, 2);
1701 ReportMessage(
"redeclaration", args);
1706 (var->mode() ==
VAR) ?
"var" : var->is_const_mode() ?
"const" :
"let";
1707 Handle<String> type_string =
1709 Expression* expression =
1710 NewThrowTypeError(isolate()->factory()->redeclaration_symbol(),
1712 declaration_scope->SetIllegalRedeclaration(expression);
1732 declaration_scope->AddDeclaration(declaration);
1734 if (mode ==
CONST && declaration_scope->is_global_scope()) {
1738 var =
new(zone()) Variable(declaration_scope,
1744 }
else if (declaration_scope->is_eval_scope() &&
1745 declaration_scope->is_classic_mode()) {
1750 var =
new(zone()) Variable(declaration_scope,
1755 declaration->initialization());
1784 if (resolve && var !=
NULL) {
1787 if (FLAG_harmony_modules) {
1790 if (FLAG_print_interface_details)
1791 PrintF(
"# Declare %s\n", var->name()->ToAsciiArray());
1793 proxy->interface()->Unify(var->interface(), zone(), &ok);
1796 if (FLAG_print_interfaces) {
1797 PrintF(
"DECLARE TYPE ERROR\n");
1799 proxy->interface()->Print();
1801 var->interface()->Print();
1804 ReportMessage(
"module_type_error", Vector<Handle<String> >(&name, 1));
1815 Statement* Parser::ParseNativeDeclaration(
bool* ok) {
1817 Handle<String> name = ParseIdentifier(
CHECK_OK);
1819 bool done = (peek() == Token::RPAREN);
1822 done = (peek() == Token::RPAREN);
1828 Expect(Token::SEMICOLON,
CHECK_OK);
1842 Handle<JSFunction> fun = Utils::OpenHandle(*fun_template->
GetFunction());
1843 const int literals = fun->NumberOfLiterals();
1844 Handle<Code>
code = Handle<Code>(fun->shared()->code());
1845 Handle<Code> construct_stub = Handle<Code>(fun->shared()->construct_stub());
1846 Handle<SharedFunctionInfo> shared =
1847 isolate()->factory()->NewSharedFunctionInfo(name, literals, code,
1848 Handle<ScopeInfo>(fun->shared()->scope_info()));
1849 shared->set_construct_stub(*construct_stub);
1852 shared->set_function_data(fun->shared()->function_data());
1853 int parameters = fun->shared()->formal_parameter_count();
1854 shared->set_formal_parameter_count(parameters);
1860 Declaration* declaration =
1861 factory()->NewVariableDeclaration(proxy,
VAR, top_scope_);
1862 Declare(declaration,
true,
CHECK_OK);
1863 SharedFunctionInfoLiteral* lit =
1864 factory()->NewSharedFunctionInfoLiteral(shared);
1865 return factory()->NewExpressionStatement(
1866 factory()->NewAssignment(
1867 Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition));
1871 Statement* Parser::ParseFunctionDeclaration(
ZoneStringList* names,
bool* ok) {
1876 bool is_strict_reserved =
false;
1877 Handle<String> name = ParseIdentifierOrStrictReservedWord(
1879 FunctionLiteral* fun = ParseFunctionLiteral(name,
1881 function_token_position,
1892 Declaration* declaration =
1893 factory()->NewFunctionDeclaration(proxy, mode, fun, top_scope_);
1894 Declare(declaration,
true,
CHECK_OK);
1895 if (names) names->Add(name, zone());
1896 return factory()->NewEmptyStatement();
1910 Block* result = factory()->NewBlock(labels, 16,
false);
1911 Target target(&this->target_stack_, result);
1913 while (peek() != Token::RBRACE) {
1915 if (stat && !stat->IsEmpty()) {
1916 result->AddStatement(stat, zone());
1931 Block* body = factory()->NewBlock(labels, 16,
false);
1932 Scope* block_scope = NewScope(top_scope_,
BLOCK_SCOPE);
1936 block_scope->set_start_position(scanner().location().beg_pos);
1938 TargetCollector collector(zone());
1939 Target target(&this->target_stack_, &collector);
1940 Target target_body(&this->target_stack_, body);
1942 while (peek() != Token::RBRACE) {
1944 if (stat && !stat->IsEmpty()) {
1945 body->AddStatement(stat, zone());
1950 block_scope->set_end_position(scanner().location().end_pos);
1951 block_scope = block_scope->FinalizeBlockScope();
1952 body->set_scope(block_scope);
1957 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context,
1963 Handle<String> ignore;
1965 ParseVariableDeclarations(var_context,
NULL, names, &ignore,
CHECK_OK);
1971 bool Parser::IsEvalOrArguments(Handle<String>
string) {
1972 return string.is_identical_to(isolate()->factory()->eval_symbol()) ||
1973 string.is_identical_to(isolate()->factory()->arguments_symbol());
1982 Block* Parser::ParseVariableDeclarations(
1983 VariableDeclarationContext var_context,
1984 VariableDeclarationProperties* decl_props,
1986 Handle<String>* out,
2006 bool needs_init =
false;
2007 bool is_const =
false;
2026 init_op = Token::INIT_CONST;
2033 if (var_context == kStatement) {
2041 init_op = Token::INIT_CONST_HARMONY;
2052 if (!is_extended_mode()) {
2058 if (var_context == kStatement) {
2066 init_op = Token::INIT_LET;
2071 Scope* declaration_scope = DeclarationScope(mode);
2086 Block* block = factory()->NewBlock(
NULL, 1,
true);
2088 Handle<String> name;
2093 if (nvars > 0) Consume(Token::COMMA);
2098 if (!declaration_scope->is_classic_mode() && IsEvalOrArguments(name)) {
2119 Interface*
interface =
2121 VariableProxy* proxy = NewUnresolved(name, mode, interface);
2122 Declaration* declaration =
2123 factory()->NewVariableDeclaration(proxy, mode, top_scope_);
2124 Declare(declaration, mode != VAR, CHECK_OK);
2126 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) {
2132 if (names) names->Add(name, zone());
2161 Scope* initialization_scope = is_const ? declaration_scope : top_scope_;
2162 Expression* value =
NULL;
2168 value = ParseAssignmentExpression(var_context != kForStatement,
CHECK_OK);
2171 value->AsCall() ==
NULL &&
2172 value->AsCallNew() ==
NULL) {
2177 if (decl_props !=
NULL) *decl_props = kHasInitializers;
2181 if (proxy->var() !=
NULL) {
2182 proxy->var()->set_initializer_position(scanner().location().end_pos);
2186 if (value ==
NULL && needs_init) {
2187 value = GetLiteralUndefined();
2209 if (initialization_scope->is_global_scope() &&
2212 ZoneList<Expression*>* arguments =
2213 new(zone()) ZoneList<Expression*>(3, zone());
2215 arguments->Add(factory()->NewLiteral(name), zone());
2216 CallRuntime* initialize;
2219 arguments->Add(value, zone());
2226 initialize = factory()->NewCallRuntime(
2227 isolate()->factory()->InitializeConstGlobal_symbol(),
2233 LanguageMode language_mode = initialization_scope->language_mode();
2234 arguments->Add(factory()->NewNumberLiteral(language_mode), zone());
2240 if (value !=
NULL && !inside_with()) {
2241 arguments->Add(value, zone());
2249 initialize = factory()->NewCallRuntime(
2250 isolate()->factory()->InitializeVarGlobal_symbol(),
2255 block->AddStatement(factory()->NewExpressionStatement(initialize),
2257 }
else if (needs_init) {
2268 Assignment* assignment =
2269 factory()->NewAssignment(init_op, proxy, value, position);
2270 block->AddStatement(factory()->NewExpressionStatement(assignment),
2277 if (value !=
NULL) {
2282 VariableProxy* proxy =
2283 initialization_scope->NewUnresolved(factory(), name, interface);
2284 Assignment* assignment =
2285 factory()->NewAssignment(init_op, proxy, value, position);
2286 block->AddStatement(factory()->NewExpressionStatement(assignment),
2291 }
while (peek() == Token::COMMA);
2295 if (nvars == 1 && !is_const) {
2303 static bool ContainsLabel(
ZoneStringList* labels, Handle<String> label) {
2304 ASSERT(!label.is_null());
2306 for (
int i = labels->length(); i-- > 0; )
2307 if (labels->at(i).is_identical_to(label))
2314 Statement* Parser::ParseExpressionOrLabelledStatement(
ZoneStringList* labels,
2319 bool starts_with_idenfifier = peek_any_identifier();
2320 Expression* expr = ParseExpression(
true,
CHECK_OK);
2321 if (peek() == Token::COLON && starts_with_idenfifier && expr !=
NULL &&
2322 expr->AsVariableProxy() !=
NULL &&
2323 !expr->AsVariableProxy()->is_this()) {
2326 VariableProxy* var = expr->AsVariableProxy();
2327 Handle<String> label = var->name();
2333 if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) {
2334 SmartArrayPointer<char> c_string = label->ToCString(
DISALLOW_NULLS);
2335 const char* elms[2] = {
"Label", *c_string };
2336 Vector<const char*> args(elms, 2);
2337 ReportMessage(
"redeclaration", args);
2341 if (labels ==
NULL) {
2344 labels->
Add(label, zone());
2350 return ParseStatement(labels, ok);
2356 if (extension_ !=
NULL &&
2357 peek() == Token::FUNCTION &&
2358 !scanner().HasAnyLineTerminatorBeforeNext() &&
2360 expr->AsVariableProxy() !=
NULL &&
2361 expr->AsVariableProxy()->name()->Equals(
2362 isolate()->heap()->native_symbol()) &&
2364 return ParseNativeDeclaration(ok);
2369 if (!FLAG_harmony_modules ||
2370 peek() != Token::IDENTIFIER ||
2371 scanner().HasAnyLineTerminatorBeforeNext() ||
2372 expr->AsVariableProxy() ==
NULL ||
2373 !expr->AsVariableProxy()->name()->Equals(
2374 isolate()->heap()->module_symbol()) ||
2378 return factory()->NewExpressionStatement(expr);
2382 IfStatement* Parser::ParseIfStatement(
ZoneStringList* labels,
bool* ok) {
2388 Expression* condition = ParseExpression(
true,
CHECK_OK);
2390 Statement* then_statement = ParseStatement(labels,
CHECK_OK);
2391 Statement* else_statement =
NULL;
2392 if (peek() == Token::ELSE) {
2394 else_statement = ParseStatement(labels,
CHECK_OK);
2396 else_statement = factory()->NewEmptyStatement();
2398 return factory()->NewIfStatement(condition, then_statement, else_statement);
2402 Statement* Parser::ParseContinueStatement(
bool* ok) {
2409 if (!scanner().HasAnyLineTerminatorBeforeNext() &&
2410 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
2413 IterationStatement* target =
NULL;
2414 target = LookupContinueTarget(label,
CHECK_OK);
2415 if (target ==
NULL) {
2417 const char*
message =
"illegal_continue";
2418 Vector<Handle<String> > args;
2419 if (!label.is_null()) {
2420 message =
"unknown_label";
2421 args = Vector<Handle<String> >(&label, 1);
2428 return factory()->NewContinueStatement(target);
2432 Statement* Parser::ParseBreakStatement(
ZoneStringList* labels,
bool* ok) {
2437 Handle<String> label;
2439 if (!scanner().HasAnyLineTerminatorBeforeNext() &&
2440 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
2445 if (!label.is_null() && ContainsLabel(labels, label)) {
2447 return factory()->NewEmptyStatement();
2449 BreakableStatement* target =
NULL;
2450 target = LookupBreakTarget(label,
CHECK_OK);
2451 if (target ==
NULL) {
2453 const char* message =
"illegal_break";
2454 Vector<Handle<String> > args;
2455 if (!label.is_null()) {
2456 message =
"unknown_label";
2457 args = Vector<Handle<String> >(&label, 1);
2464 return factory()->NewBreakStatement(target);
2468 Statement* Parser::ParseReturnStatement(
bool* ok) {
2479 if (scanner().HasAnyLineTerminatorBeforeNext() ||
2480 tok == Token::SEMICOLON ||
2481 tok == Token::RBRACE ||
2482 tok == Token::EOS) {
2484 result = factory()->NewReturnStatement(GetLiteralUndefined());
2486 Expression* expr = ParseExpression(
true,
CHECK_OK);
2488 result = factory()->NewReturnStatement(expr);
2497 if (declaration_scope->is_global_scope() ||
2498 declaration_scope->is_eval_scope()) {
2499 Handle<String> type = isolate()->factory()->illegal_return_symbol();
2501 return factory()->NewExpressionStatement(throw_error);
2507 Statement* Parser::ParseWithStatement(
ZoneStringList* labels,
bool* ok) {
2520 Expression* expr = ParseExpression(
true,
CHECK_OK);
2524 Scope* with_scope = NewScope(top_scope_,
WITH_SCOPE);
2527 with_scope->set_start_position(scanner().peek_location().beg_pos);
2528 stmt = ParseStatement(labels,
CHECK_OK);
2529 with_scope->set_end_position(scanner().location().end_pos);
2531 return factory()->NewWithStatement(expr, stmt);
2535 CaseClause* Parser::ParseCaseClause(
bool* default_seen_ptr,
bool* ok) {
2540 Expression* label =
NULL;
2541 if (peek() == Token::CASE) {
2543 label = ParseExpression(
true,
CHECK_OK);
2546 if (*default_seen_ptr) {
2547 ReportMessage(
"multiple_defaults_in_switch",
2552 *default_seen_ptr =
true;
2556 ZoneList<Statement*>* statements =
2557 new(zone()) ZoneList<Statement*>(5, zone());
2558 while (peek() != Token::CASE &&
2560 peek() != Token::RBRACE) {
2562 statements->Add(stat, zone());
2565 return new(zone()) CaseClause(isolate(), label, statements, pos);
2569 SwitchStatement* Parser::ParseSwitchStatement(
ZoneStringList* labels,
2574 SwitchStatement* statement = factory()->NewSwitchStatement(labels);
2575 Target target(&this->target_stack_, statement);
2579 Expression* tag = ParseExpression(
true,
CHECK_OK);
2582 bool default_seen =
false;
2583 ZoneList<CaseClause*>* cases =
new(zone()) ZoneList<CaseClause*>(4, zone());
2585 while (peek() != Token::RBRACE) {
2586 CaseClause* clause = ParseCaseClause(&default_seen,
CHECK_OK);
2587 cases->Add(clause, zone());
2591 if (statement) statement->Initialize(tag, cases);
2596 Statement* Parser::ParseThrowStatement(
bool* ok) {
2602 if (scanner().HasAnyLineTerminatorBeforeNext()) {
2607 Expression* exception = ParseExpression(
true,
CHECK_OK);
2610 return factory()->NewExpressionStatement(factory()->NewThrow(exception, pos));
2614 TryStatement* Parser::ParseTryStatement(
bool* ok) {
2628 TargetCollector try_collector(zone());
2631 { Target target(&this->target_stack_, &try_collector);
2636 if (tok != Token::CATCH && tok != Token::FINALLY) {
2646 TargetCollector catch_collector(zone());
2647 Scope* catch_scope =
NULL;
2648 Variable* catch_variable =
NULL;
2650 Handle<String> name;
2651 if (tok == Token::CATCH) {
2652 Consume(Token::CATCH);
2656 catch_scope->set_start_position(scanner().location().beg_pos);
2667 if (peek() == Token::LBRACE) {
2668 Target target(&this->target_stack_, &catch_collector);
2678 catch_scope->set_end_position(scanner().location().end_pos);
2683 if (tok == Token::FINALLY || catch_block ==
NULL) {
2684 Consume(Token::FINALLY);
2693 if (catch_block !=
NULL && finally_block !=
NULL) {
2696 int index = current_function_state_->NextHandlerIndex();
2697 TryCatchStatement* statement = factory()->NewTryCatchStatement(
2698 index, try_block, catch_scope, catch_variable, catch_block);
2699 statement->set_escaping_targets(try_collector.targets());
2700 try_block = factory()->NewBlock(
NULL, 1,
false);
2701 try_block->AddStatement(statement, zone());
2705 TryStatement* result =
NULL;
2706 if (catch_block !=
NULL) {
2709 int index = current_function_state_->NextHandlerIndex();
2710 result = factory()->NewTryCatchStatement(
2711 index, try_block, catch_scope, catch_variable, catch_block);
2714 int index = current_function_state_->NextHandlerIndex();
2715 result = factory()->NewTryFinallyStatement(index, try_block, finally_block);
2717 try_collector.targets()->AddAll(*catch_collector.targets(), zone());
2720 result->set_escaping_targets(try_collector.targets());
2725 DoWhileStatement* Parser::ParseDoWhileStatement(
ZoneStringList* labels,
2730 DoWhileStatement* loop = factory()->NewDoWhileStatement(labels);
2731 Target target(&this->target_stack_, loop);
2740 loop->set_condition_position(position);
2743 Expression* cond = ParseExpression(
true,
CHECK_OK);
2750 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON);
2752 if (loop !=
NULL) loop->Initialize(cond, body);
2757 WhileStatement* Parser::ParseWhileStatement(
ZoneStringList* labels,
bool* ok) {
2761 WhileStatement* loop = factory()->NewWhileStatement(labels);
2762 Target target(&this->target_stack_, loop);
2766 Expression* cond = ParseExpression(
true,
CHECK_OK);
2770 if (loop !=
NULL) loop->Initialize(cond, body);
2775 Statement* Parser::ParseForStatement(
ZoneStringList* labels,
bool* ok) {
2779 Statement* init =
NULL;
2782 Scope* saved_scope = top_scope_;
2783 Scope* for_scope = NewScope(top_scope_,
BLOCK_SCOPE);
2784 top_scope_ = for_scope;
2788 for_scope->set_start_position(scanner().location().beg_pos);
2789 if (peek() != Token::SEMICOLON) {
2792 Handle<String> name;
2793 Block* variable_statement =
2796 if (peek() ==
Token::IN && !name.is_null()) {
2797 Interface*
interface =
2799 ForInStatement* loop = factory()->NewForInStatement(labels);
2800 Target target(&this->target_stack_, loop);
2802 Expect(Token::IN, CHECK_OK);
2803 Expression* enumerable = ParseExpression(true, CHECK_OK);
2804 Expect(Token::RPAREN, CHECK_OK);
2806 VariableProxy* each =
2807 top_scope_->NewUnresolved(factory(), name, interface);
2808 Statement* body = ParseStatement(NULL, CHECK_OK);
2809 loop->Initialize(each, enumerable, body);
2810 Block* result = factory()->NewBlock(NULL, 2, false);
2811 result->AddStatement(variable_statement, zone());
2812 result->AddStatement(loop, zone());
2813 top_scope_ = saved_scope;
2814 for_scope->set_end_position(scanner().location().end_pos);
2815 for_scope = for_scope->FinalizeBlockScope();
2816 ASSERT(for_scope == NULL);
2820 init = variable_statement;
2823 Handle<String> name;
2824 VariableDeclarationProperties decl_props = kHasNoInitializers;
2825 Block* variable_statement =
2826 ParseVariableDeclarations(kForStatement, &decl_props,
NULL, &name,
2828 bool accept_IN = !name.is_null() && decl_props != kHasInitializers;
2845 Factory* heap_factory = isolate()->factory();
2846 Handle<String> tempstr =
2847 heap_factory->NewConsString(heap_factory->dot_for_symbol(), name);
2848 Handle<String> tempname = heap_factory->LookupSymbol(tempstr);
2850 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
2851 ForInStatement* loop = factory()->NewForInStatement(labels);
2852 Target target(&this->target_stack_, loop);
2856 top_scope_ = saved_scope;
2857 Expression* enumerable = ParseExpression(
true,
CHECK_OK);
2858 top_scope_ = for_scope;
2861 VariableProxy* each =
2864 Block* body_block = factory()->NewBlock(
NULL, 3,
false);
2865 Assignment* assignment = factory()->NewAssignment(
2866 Token::ASSIGN, each, temp_proxy, RelocInfo::kNoPosition);
2867 Statement* assignment_statement =
2868 factory()->NewExpressionStatement(assignment);
2869 body_block->AddStatement(variable_statement, zone());
2870 body_block->AddStatement(assignment_statement, zone());
2871 body_block->AddStatement(body, zone());
2872 loop->Initialize(temp_proxy, enumerable, body_block);
2873 top_scope_ = saved_scope;
2875 for_scope = for_scope->FinalizeBlockScope();
2876 body_block->set_scope(for_scope);
2881 init = variable_statement;
2884 Expression* expression = ParseExpression(
false,
CHECK_OK);
2890 if (expression ==
NULL || !expression->IsValidLeftHandSide()) {
2891 Handle<String> type =
2892 isolate()->factory()->invalid_lhs_in_for_in_symbol();
2893 expression = NewThrowReferenceError(type);
2895 ForInStatement* loop = factory()->NewForInStatement(labels);
2896 Target target(&this->target_stack_, loop);
2899 Expression* enumerable = ParseExpression(
true,
CHECK_OK);
2903 if (loop) loop->Initialize(expression, enumerable, body);
2904 top_scope_ = saved_scope;
2906 for_scope = for_scope->FinalizeBlockScope();
2912 init = factory()->NewExpressionStatement(expression);
2918 ForStatement* loop = factory()->NewForStatement(labels);
2919 Target target(&this->target_stack_, loop);
2922 Expect(Token::SEMICOLON,
CHECK_OK);
2924 Expression* cond =
NULL;
2925 if (peek() != Token::SEMICOLON) {
2926 cond = ParseExpression(
true,
CHECK_OK);
2928 Expect(Token::SEMICOLON,
CHECK_OK);
2930 Statement* next =
NULL;
2931 if (peek() != Token::RPAREN) {
2932 Expression* exp = ParseExpression(
true,
CHECK_OK);
2933 next = factory()->NewExpressionStatement(exp);
2938 top_scope_ = saved_scope;
2940 for_scope = for_scope->FinalizeBlockScope();
2941 if (for_scope !=
NULL) {
2953 Block* result = factory()->NewBlock(
NULL, 2,
false);
2954 result->AddStatement(init, zone());
2955 result->AddStatement(loop, zone());
2956 result->set_scope(for_scope);
2957 if (loop) loop->Initialize(
NULL, cond, next, body);
2960 if (loop) loop->Initialize(init, cond, next, body);
2967 Expression* Parser::ParseExpression(
bool accept_IN,
bool* ok) {
2972 Expression* result = ParseAssignmentExpression(accept_IN,
CHECK_OK);
2973 while (peek() == Token::COMMA) {
2976 Expression* right = ParseAssignmentExpression(accept_IN,
CHECK_OK);
2978 factory()->NewBinaryOperation(Token::COMMA, result, right, position);
2985 Expression* Parser::ParseAssignmentExpression(
bool accept_IN,
bool* ok) {
2991 Expression* expression = ParseConditionalExpression(accept_IN,
CHECK_OK);
3003 if (expression ==
NULL || !expression->IsValidLeftHandSide()) {
3004 Handle<String> type =
3005 isolate()->factory()->invalid_lhs_in_assignment_symbol();
3006 expression = NewThrowReferenceError(type);
3011 CheckStrictModeLValue(expression,
"strict_lhs_assignment",
CHECK_OK);
3013 MarkAsLValue(expression);
3017 Expression* right = ParseAssignmentExpression(accept_IN,
CHECK_OK);
3024 Property*
property = expression ? expression->AsProperty() :
NULL;
3025 if (op == Token::ASSIGN &&
3027 property->obj()->AsVariableProxy() !=
NULL &&
3028 property->obj()->AsVariableProxy()->is_this()) {
3029 current_function_state_->AddProperty();
3034 if (property !=
NULL && right->AsFunctionLiteral() !=
NULL) {
3035 right->AsFunctionLiteral()->set_pretenure();
3042 if ((op == Token::INIT_VAR
3043 || op == Token::INIT_CONST
3044 || op == Token::ASSIGN)
3045 && (right->AsCall() ==
NULL && right->AsCallNew() ==
NULL)) {
3053 return factory()->NewAssignment(op, expression, right, pos);
3058 Expression* Parser::ParseConditionalExpression(
bool accept_IN,
bool* ok) {
3064 Expression* expression = ParseBinaryExpression(4, accept_IN,
CHECK_OK);
3065 if (peek() != Token::CONDITIONAL)
return expression;
3066 Consume(Token::CONDITIONAL);
3071 Expression* left = ParseAssignmentExpression(
true,
CHECK_OK);
3074 Expression* right = ParseAssignmentExpression(accept_IN,
CHECK_OK);
3075 return factory()->NewConditional(
3076 expression, left, right, left_position, right_position);
3080 static int Precedence(
Token::Value tok,
bool accept_IN) {
3089 Expression* Parser::ParseBinaryExpression(
int prec,
bool accept_IN,
bool* ok) {
3091 Expression* x = ParseUnaryExpression(
CHECK_OK);
3092 for (
int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
3094 while (Precedence(peek(), accept_IN) == prec1) {
3097 Expression* y = ParseBinaryExpression(prec1 + 1, accept_IN,
CHECK_OK);
3100 if (x && x->AsLiteral() && x->AsLiteral()->handle()->IsNumber() &&
3101 y && y->AsLiteral() && y->AsLiteral()->handle()->IsNumber()) {
3102 double x_val = x->AsLiteral()->handle()->Number();
3103 double y_val = y->AsLiteral()->handle()->Number();
3107 x = factory()->NewNumberLiteral(x_val + y_val);
3110 x = factory()->NewNumberLiteral(x_val - y_val);
3113 x = factory()->NewNumberLiteral(x_val * y_val);
3116 x = factory()->NewNumberLiteral(x_val / y_val);
3118 case Token::BIT_OR: {
3120 x = factory()->NewNumberLiteral(value);
3123 case Token::BIT_AND: {
3125 x = factory()->NewNumberLiteral(value);
3128 case Token::BIT_XOR: {
3130 x = factory()->NewNumberLiteral(value);
3135 x = factory()->NewNumberLiteral(value);
3141 x = factory()->NewNumberLiteral(value);
3147 x = factory()->NewNumberLiteral(value);
3163 case Token::NE_STRICT: cmp = Token::EQ_STRICT;
break;
3166 x = factory()->NewCompareOperation(cmp, x, y, position);
3169 x = factory()->NewUnaryOperation(Token::NOT, x, position);
3174 x = factory()->NewBinaryOperation(op, x, y, position);
3182 Expression* Parser::ParseUnaryExpression(
bool* ok) {
3199 Expression* expression = ParseUnaryExpression(
CHECK_OK);
3201 if (expression !=
NULL && (expression->AsLiteral() !=
NULL)) {
3202 Handle<Object> literal = expression->AsLiteral()->handle();
3203 if (op == Token::NOT) {
3205 bool condition = literal->ToBoolean()->IsTrue();
3206 Handle<Object> result(isolate()->heap()->ToBoolean(!condition));
3207 return factory()->NewLiteral(result);
3208 }
else if (literal->IsNumber()) {
3210 double value = literal->Number();
3215 return factory()->NewNumberLiteral(-value);
3216 case Token::BIT_NOT:
3226 VariableProxy* operand = expression->AsVariableProxy();
3227 if (operand !=
NULL && !operand->is_this()) {
3234 return factory()->NewUnaryOperation(op, expression, position);
3238 Expression* expression = ParseUnaryExpression(
CHECK_OK);
3243 if (expression ==
NULL || !expression->IsValidLeftHandSide()) {
3244 Handle<String> type =
3245 isolate()->factory()->invalid_lhs_in_prefix_op_symbol();
3246 expression = NewThrowReferenceError(type);
3251 CheckStrictModeLValue(expression,
"strict_lhs_prefix",
CHECK_OK);
3253 MarkAsLValue(expression);
3256 return factory()->NewCountOperation(op,
3262 return ParsePostfixExpression(ok);
3267 Expression* Parser::ParsePostfixExpression(
bool* ok) {
3271 Expression* expression = ParseLeftHandSideExpression(
CHECK_OK);
3272 if (!scanner().HasAnyLineTerminatorBeforeNext() &&
3278 if (expression ==
NULL || !expression->IsValidLeftHandSide()) {
3279 Handle<String> type =
3280 isolate()->factory()->invalid_lhs_in_postfix_op_symbol();
3281 expression = NewThrowReferenceError(type);
3286 CheckStrictModeLValue(expression,
"strict_lhs_prefix",
CHECK_OK);
3288 MarkAsLValue(expression);
3293 factory()->NewCountOperation(next,
3302 Expression* Parser::ParseLeftHandSideExpression(
bool* ok) {
3307 if (peek() == Token::NEW) {
3308 result = ParseNewExpression(
CHECK_OK);
3310 result = ParseMemberExpression(
CHECK_OK);
3315 case Token::LBRACK: {
3316 Consume(Token::LBRACK);
3318 Expression* index = ParseExpression(
true,
CHECK_OK);
3319 result = factory()->NewProperty(result, index, pos);
3324 case Token::LPAREN: {
3326 if (scanner().current_token() == Token::IDENTIFIER) {
3340 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) {
3341 result->AsFunctionLiteral()->set_parenthesized();
3344 ZoneList<Expression*>* args = ParseArguments(
CHECK_OK);
3353 VariableProxy* callee = result->AsVariableProxy();
3354 if (callee !=
NULL &&
3355 callee->IsVariable(isolate()->factory()->eval_symbol())) {
3358 result = factory()->NewCall(result, args, pos);
3362 case Token::PERIOD: {
3363 Consume(Token::PERIOD);
3365 Handle<String> name = ParseIdentifierName(
CHECK_OK);
3367 factory()->NewProperty(result, factory()->NewLiteral(name), pos);
3379 Expression* Parser::ParseNewPrefix(PositionStack* stack,
bool* ok) {
3392 PositionStack::Element pos(stack, scanner().location().beg_pos);
3395 if (peek() == Token::NEW) {
3396 result = ParseNewPrefix(stack,
CHECK_OK);
3398 result = ParseMemberWithNewPrefixesExpression(stack,
CHECK_OK);
3401 if (!stack->is_empty()) {
3402 int last = stack->pop();
3403 result = factory()->NewCallNew(
3404 result,
new(zone()) ZoneList<Expression*>(0, zone()), last);
3410 Expression* Parser::ParseNewExpression(
bool* ok) {
3411 PositionStack stack(ok);
3412 return ParseNewPrefix(&stack, ok);
3416 Expression* Parser::ParseMemberExpression(
bool* ok) {
3417 return ParseMemberWithNewPrefixesExpression(
NULL, ok);
3421 Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack,
3428 Expression* result =
NULL;
3429 if (peek() == Token::FUNCTION) {
3432 Handle<String> name;
3433 bool is_strict_reserved_name =
false;
3434 if (peek_any_identifier()) {
3435 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
3439 ? FunctionLiteral::ANONYMOUS_EXPRESSION
3441 result = ParseFunctionLiteral(name,
3442 is_strict_reserved_name,
3443 function_token_position,
3447 result = ParsePrimaryExpression(
CHECK_OK);
3452 case Token::LBRACK: {
3453 Consume(Token::LBRACK);
3455 Expression* index = ParseExpression(
true,
CHECK_OK);
3456 result = factory()->NewProperty(result, index, pos);
3458 if (index->IsPropertyName()) {
3462 isolate()->factory()->anonymous_function_symbol());
3468 case Token::PERIOD: {
3469 Consume(Token::PERIOD);
3471 Handle<String> name = ParseIdentifierName(
CHECK_OK);
3473 factory()->NewProperty(result, factory()->NewLiteral(name), pos);
3477 case Token::LPAREN: {
3478 if ((stack ==
NULL) || stack->is_empty())
return result;
3480 ZoneList<Expression*>* args = ParseArguments(
CHECK_OK);
3481 int last = stack->pop();
3482 result = factory()->NewCallNew(result, args, last);
3492 DebuggerStatement* Parser::ParseDebuggerStatement(
bool* ok) {
3501 return factory()->NewDebuggerStatement();
3505 void Parser::ReportUnexpectedToken(
Token::Value token) {
3509 if (token == Token::ILLEGAL && stack_overflow_)
return;
3515 return ReportMessage(
"unexpected_token_number",
3518 return ReportMessage(
"unexpected_token_string",
3520 case Token::IDENTIFIER:
3521 return ReportMessage(
"unexpected_token_identifier",
3523 case Token::FUTURE_RESERVED_WORD:
3524 return ReportMessage(
"unexpected_reserved",
3526 case Token::FUTURE_STRICT_RESERVED_WORD:
3528 "unexpected_token_identifier" :
3529 "unexpected_strict_reserved",
3534 ReportMessage(
"unexpected_token", Vector<const char*>(&name, 1));
3539 void Parser::ReportInvalidPreparseData(Handle<String> name,
bool* ok) {
3540 SmartArrayPointer<char> name_string = name->ToCString(
DISALLOW_NULLS);
3541 const char* element[1] = { *name_string };
3542 ReportMessage(
"invalid_preparser_data",
3543 Vector<const char*>(element, 1));
3548 Expression* Parser::ParsePrimaryExpression(
bool* ok) {
3562 Expression* result =
NULL;
3565 Consume(Token::THIS);
3566 result = factory()->NewVariableProxy(top_scope_->
receiver());
3570 case Token::NULL_LITERAL:
3571 Consume(Token::NULL_LITERAL);
3572 result = factory()->NewLiteral(isolate()->factory()->null_value());
3575 case Token::TRUE_LITERAL:
3576 Consume(Token::TRUE_LITERAL);
3577 result = factory()->NewLiteral(isolate()->factory()->true_value());
3580 case Token::FALSE_LITERAL:
3581 Consume(Token::FALSE_LITERAL);
3582 result = factory()->NewLiteral(isolate()->factory()->false_value());
3585 case Token::IDENTIFIER:
3586 case Token::FUTURE_STRICT_RESERVED_WORD: {
3587 Handle<String> name = ParseIdentifier(
CHECK_OK);
3591 if (FLAG_print_interface_details)
3592 PrintF(
"# Variable %s ", name->ToAsciiArray());
3596 factory(), name, interface, scanner().location().beg_pos);
3600 case Token::NUMBER: {
3601 Consume(Token::NUMBER);
3602 ASSERT(scanner().is_literal_ascii());
3604 scanner().literal_ascii_string(),
3606 result = factory()->NewNumberLiteral(value);
3610 case Token::STRING: {
3611 Consume(Token::STRING);
3612 Handle<String> symbol = GetSymbol(
CHECK_OK);
3613 result = factory()->NewLiteral(symbol);
3618 case Token::ASSIGN_DIV:
3619 result = ParseRegExpLiteral(
true,
CHECK_OK);
3623 result = ParseRegExpLiteral(
false,
CHECK_OK);
3627 result = ParseArrayLiteral(
CHECK_OK);
3631 result = ParseObjectLiteral(
CHECK_OK);
3635 Consume(Token::LPAREN);
3638 parenthesized_function_ = (peek() == Token::FUNCTION);
3639 result = ParseExpression(
true,
CHECK_OK);
3644 if (allow_natives_syntax_ || extension_ !=
NULL) {
3645 result = ParseV8Intrinsic(
CHECK_OK);
3653 ReportUnexpectedToken(tok);
3663 void Parser::BuildArrayLiteralBoilerplateLiterals(ZoneList<Expression*>* values,
3664 Handle<FixedArray> literals,
3669 bool is_simple_acc =
true;
3671 for (
int i = 0; i < values->length(); i++) {
3672 MaterializedLiteral* m_literal = values->at(i)->AsMaterializedLiteral();
3673 if (m_literal !=
NULL && m_literal->depth() >= depth_acc) {
3674 depth_acc = m_literal->depth() + 1;
3676 Handle<Object> boilerplate_value = GetBoilerplateValue(values->at(i));
3677 if (boilerplate_value->IsUndefined()) {
3678 literals->set_the_hole(i);
3679 is_simple_acc =
false;
3681 literals->set(i, *boilerplate_value);
3685 *is_simple = is_simple_acc;
3690 Expression* Parser::ParseArrayLiteral(
bool* ok) {
3694 ZoneList<Expression*>* values =
new(zone()) ZoneList<Expression*>(4, zone());
3696 while (peek() != Token::RBRACK) {
3698 if (peek() == Token::COMMA) {
3699 elem = GetLiteralTheHole();
3701 elem = ParseAssignmentExpression(
true,
CHECK_OK);
3703 values->Add(elem, zone());
3704 if (peek() != Token::RBRACK) {
3711 int literal_index = current_function_state_->NextMaterializedLiteralIndex();
3714 Handle<FixedArray> object_literals =
3715 isolate()->factory()->NewFixedArray(values->length(),
TENURED);
3716 Handle<FixedDoubleArray> double_literals;
3718 bool has_only_undefined_values =
true;
3719 bool has_hole_values =
false;
3722 Heap* heap = isolate()->heap();
3723 bool is_simple =
true;
3725 for (
int i = 0, n = values->length(); i < n; i++) {
3726 MaterializedLiteral* m_literal = values->at(i)->AsMaterializedLiteral();
3727 if (m_literal !=
NULL && m_literal->depth() + 1 > depth) {
3728 depth = m_literal->depth() + 1;
3730 Handle<Object> boilerplate_value = GetBoilerplateValue(values->at(i));
3731 if (boilerplate_value->IsTheHole()) {
3732 has_hole_values =
true;
3733 object_literals->set_the_hole(i);
3735 double_literals->set_the_hole(i);
3737 }
else if (boilerplate_value->IsUndefined()) {
3741 double_literals->set(i, 0);
3750 has_only_undefined_values =
false;
3751 object_literals->set(i, *boilerplate_value);
3755 if (!boilerplate_value->IsSmi()) {
3756 if (boilerplate_value->IsNumber() && FLAG_smi_only_arrays) {
3759 double_literals = isolate()->factory()->NewFixedDoubleArray(
3763 for (
int j = 0; j < i; ++j) {
3764 Object* smi_value = object_literals->get(j);
3765 if (smi_value->IsTheHole()) {
3766 double_literals->set_the_hole(j);
3768 double_literals->set(j,
Smi::cast(smi_value)->value());
3771 double_literals->set(i, boilerplate_value->Number());
3780 if (boilerplate_value->IsNumber()) {
3781 double_literals->set(i, boilerplate_value->Number());
3792 if (has_only_undefined_values && values->length() <= 2) {
3798 if (is_simple && depth == 1 && values->length() > 0 &&
3800 object_literals->set_map(heap->fixed_cow_array_map());
3804 ? Handle<FixedArrayBase>(double_literals)
3805 : Handle<FixedArrayBase>(object_literals);
3809 Handle<FixedArray> literals =
3810 isolate()->factory()->NewFixedArray(2,
TENURED);
3812 if (has_hole_values || !FLAG_packed_arrays) {
3817 literals->set(1, *element_values);
3819 return factory()->NewArrayLiteral(
3820 literals, values, literal_index, is_simple, depth);
3824 bool Parser::IsBoilerplateProperty(ObjectLiteral::Property* property) {
3825 return property !=
NULL &&
3831 if (expression->AsLiteral() !=
NULL)
return true;
3841 if (value->AsLiteral() !=
NULL)
return false;
3850 ASSERT(IsCompileTimeValue(expression));
3852 ObjectLiteral* object_literal = expression->AsObjectLiteral();
3853 if (object_literal !=
NULL) {
3856 result->set(kTypeSlot,
Smi::FromInt(OBJECT_LITERAL_FAST_ELEMENTS));
3858 result->set(kTypeSlot,
Smi::FromInt(OBJECT_LITERAL_SLOW_ELEMENTS));
3862 ArrayLiteral* array_literal = expression->AsArrayLiteral();
3873 return static_cast<Type>(type_value->
value());
3883 if (expression->AsLiteral() !=
NULL) {
3884 return expression->AsLiteral()->handle();
3889 return isolate()->factory()->undefined_value();
3898 language_mode_(language_mode) {
3908 kGetAccessor = 0x01,
3909 kSetAccessor = 0x02,
3910 kAccessor = kGetAccessor | kSetAccessor,
3914 static intptr_t GetPropertyKind(ObjectLiteral::Property* property) {
3915 switch (property->kind()) {
3917 return kGetAccessor;
3919 return kSetAccessor;
3936 Literal* literal =
property->key();
3937 HashMap::Entry* entry = props_.Lookup(literal, literal->
Hash(),
true);
3938 intptr_t prev =
reinterpret_cast<intptr_t
> (entry->value);
3939 intptr_t curr = GetPropertyKind(property);
3942 if (language_mode_ !=
CLASSIC_MODE && (curr & prev & kData) != 0) {
3943 parser_->ReportMessageAt(loc,
"strict_duplicate_property",
3949 if (((curr & kData) && (prev & kAccessor)) ||
3950 ((prev & kData) && (curr & kAccessor))) {
3951 parser_->ReportMessageAt(loc,
"accessor_data_property",
3957 if ((curr & prev & kAccessor) != 0) {
3958 parser_->ReportMessageAt(loc,
"accessor_get_set",
3965 entry->value =
reinterpret_cast<void*
> (prev | curr);
3970 void Parser::BuildObjectLiteralConstantProperties(
3974 bool* fast_elements,
3978 bool is_simple_acc =
true;
3980 uint32_t max_element_index = 0;
3981 uint32_t elements = 0;
3982 for (
int i = 0; i < properties->length(); i++) {
3984 if (!IsBoilerplateProperty(property)) {
3985 is_simple_acc =
false;
3988 MaterializedLiteral* m_literal =
property->value()->AsMaterializedLiteral();
3989 if (m_literal !=
NULL && m_literal->depth() >= depth_acc) {
3990 depth_acc = m_literal->depth() + 1;
3996 Handle<Object> key =
property->key()->handle();
3997 Handle<Object> value = GetBoilerplateValue(property->value());
3998 is_simple_acc = is_simple_acc && !value->IsUndefined();
4004 uint32_t element_index = 0;
4007 && element_index > max_element_index) {
4008 max_element_index = element_index;
4010 }
else if (key->IsSmi()) {
4013 && static_cast<uint32_t>(key_value) > max_element_index) {
4014 max_element_index = key_value;
4020 constant_properties->set(position++, *key);
4021 constant_properties->set(position++, *value);
4024 (max_element_index <= 32) || ((2 * elements) >= max_element_index);
4025 *is_simple = is_simple_acc;
4030 ObjectLiteral::Property* Parser::ParseObjectLiteralGetSet(
bool is_getter,
4037 if (next == Token::IDENTIFIER || next == Token::NUMBER ||
4038 next == Token::FUTURE_RESERVED_WORD ||
4039 next == Token::FUTURE_STRICT_RESERVED_WORD ||
4040 next == Token::STRING || is_keyword) {
4041 Handle<String> name;
4047 FunctionLiteral* value =
4048 ParseFunctionLiteral(name,
4050 RelocInfo::kNoPosition,
4051 FunctionLiteral::ANONYMOUS_EXPRESSION,
4055 return factory()->NewObjectLiteralProperty(is_getter, value);
4057 ReportUnexpectedToken(next);
4064 Expression* Parser::ParseObjectLiteral(
bool* ok) {
4071 ZoneList<ObjectLiteral::Property*>* properties =
4072 new(zone()) ZoneList<ObjectLiteral::Property*>(4, zone());
4073 int number_of_boilerplate_properties = 0;
4074 bool has_function =
false;
4076 ObjectLiteralPropertyChecker checker(
this, top_scope_->
language_mode());
4080 while (peek() != Token::RBRACE) {
4083 Literal* key =
NULL;
4090 case Token::FUTURE_RESERVED_WORD:
4091 case Token::FUTURE_STRICT_RESERVED_WORD:
4092 case Token::IDENTIFIER: {
4093 bool is_getter =
false;
4094 bool is_setter =
false;
4096 ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter,
CHECK_OK);
4099 if ((is_getter || is_setter) && peek() != Token::COLON) {
4102 ObjectLiteral::Property*
property =
4103 ParseObjectLiteralGetSet(is_getter,
CHECK_OK);
4104 if (IsBoilerplateProperty(property)) {
4105 number_of_boilerplate_properties++;
4108 checker.CheckProperty(property, loc,
CHECK_OK);
4109 properties->Add(property, zone());
4110 if (peek() != Token::RBRACE) Expect(Token::COMMA,
CHECK_OK);
4120 key = factory()->NewLiteral(
id);
4123 case Token::STRING: {
4124 Consume(Token::STRING);
4125 Handle<String>
string = GetSymbol(
CHECK_OK);
4128 if (!
string.is_null() && string->AsArrayIndex(&index)) {
4129 key = factory()->NewNumberLiteral(index);
4132 key = factory()->NewLiteral(
string);
4135 case Token::NUMBER: {
4136 Consume(Token::NUMBER);
4137 ASSERT(scanner().is_literal_ascii());
4139 scanner().literal_ascii_string(),
4141 key = factory()->NewNumberLiteral(value);
4147 Handle<String>
string = GetSymbol(
CHECK_OK);
4148 key = factory()->NewLiteral(
string);
4152 ReportUnexpectedToken(next);
4159 Expression* value = ParseAssignmentExpression(
true,
CHECK_OK);
4161 ObjectLiteral::Property*
property =
4162 new(zone()) ObjectLiteral::Property(key, value, isolate());
4168 value->AsFunctionLiteral() !=
NULL) {
4169 has_function =
true;
4170 value->AsFunctionLiteral()->set_pretenure();
4174 if (IsBoilerplateProperty(property)) number_of_boilerplate_properties++;
4176 checker.CheckProperty(property, loc,
CHECK_OK);
4177 properties->Add(property, zone());
4180 if (peek() != Token::RBRACE) Expect(Token::COMMA,
CHECK_OK);
4190 int literal_index = current_function_state_->NextMaterializedLiteralIndex();
4192 Handle<FixedArray> constant_properties = isolate()->factory()->NewFixedArray(
4193 number_of_boilerplate_properties * 2,
TENURED);
4195 bool is_simple =
true;
4196 bool fast_elements =
true;
4198 BuildObjectLiteralConstantProperties(properties,
4199 constant_properties,
4203 return factory()->NewObjectLiteral(constant_properties,
4213 Expression* Parser::ParseRegExpLiteral(
bool seen_equal,
bool* ok) {
4214 if (!scanner().ScanRegExpPattern(seen_equal)) {
4221 int literal_index = current_function_state_->NextMaterializedLiteralIndex();
4223 Handle<String> js_pattern = NextLiteralString(
TENURED);
4225 Handle<String> js_flags = NextLiteralString(
TENURED);
4228 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index);
4232 ZoneList<Expression*>* Parser::ParseArguments(
bool* ok) {
4236 ZoneList<Expression*>* result =
new(zone()) ZoneList<Expression*>(4, zone());
4238 bool done = (peek() == Token::RPAREN);
4240 Expression* argument = ParseAssignmentExpression(
true,
CHECK_OK);
4241 result->Add(argument, zone());
4242 if (result->length() > kMaxNumFunctionParameters) {
4248 done = (peek() == Token::RPAREN);
4249 if (!done) Expect(Token::COMMA,
CHECK_OK);
4271 literals_ = literals;
4272 properties_ = properties;
4285 const char* message,
4286 const char* argument_opt) {
4287 if (has_error_)
return;
4292 argument_opt_ = argument_opt;
4332 return argument_opt_;
4344 const char* message_;
4345 const char* argument_opt_;
4349 FunctionLiteral* Parser::ParseFunctionLiteral(
Handle<String> function_name,
4350 bool name_is_strict_reserved,
4351 int function_token_position,
4360 bool should_infer_name = function_name.is_null();
4363 if (should_infer_name) {
4364 function_name = isolate()->factory()->empty_symbol();
4367 int num_parameters = 0;
4374 ZoneList<Statement*>* body =
NULL;
4375 int materialized_literal_count = -1;
4376 int expected_property_count = -1;
4377 int handler_count = 0;
4378 bool only_simple_this_property_assignments;
4379 Handle<FixedArray> this_property_assignments;
4385 AstProperties ast_properties;
4393 scope->set_start_position(scanner().location().beg_pos);
4398 bool done = (peek() == Token::RPAREN);
4400 bool is_strict_reserved =
false;
4401 Handle<String> param_name =
4402 ParseIdentifierOrStrictReservedWord(&is_strict_reserved,
4406 if (!name_loc.IsValid() && IsEvalOrArguments(param_name)) {
4409 if (!dupe_loc.IsValid() && top_scope_->
IsDeclared(param_name)) {
4413 if (!reserved_loc.IsValid() && is_strict_reserved) {
4414 reserved_loc = scanner().
location();
4419 if (num_parameters > kMaxNumFunctionParameters) {
4425 done = (peek() == Token::RPAREN);
4426 if (!done) Expect(Token::COMMA,
CHECK_OK);
4438 Variable* fvar =
NULL;
4441 if (is_extended_mode()) fvar_init_op = Token::INIT_CONST_HARMONY;
4443 fvar =
new(zone()) Variable(top_scope_,
4444 function_name, fvar_mode,
true ,
4446 VariableProxy* proxy = factory()->NewVariableProxy(fvar);
4447 VariableDeclaration* fvar_declaration =
4448 factory()->NewVariableDeclaration(proxy, fvar_mode, top_scope_);
4463 bool is_lazily_compiled = (mode() == PARSE_LAZILY &&
4465 !parenthesized_function_);
4466 parenthesized_function_ =
false;
4468 if (is_lazily_compiled) {
4470 FunctionEntry entry;
4471 if (pre_data_ !=
NULL) {
4476 if (entry.is_valid()) {
4477 if (entry.end_pos() <= function_block_pos) {
4480 ReportInvalidPreparseData(function_name,
CHECK_OK);
4484 scope->set_end_position(entry.end_pos());
4486 isolate()->counters()->total_preparse_skipped()->Increment(
4487 scope->end_position() - function_block_pos);
4488 materialized_literal_count = entry.literal_count();
4489 expected_property_count = entry.property_count();
4491 only_simple_this_property_assignments =
false;
4492 this_property_assignments = isolate()->factory()->empty_fixed_array();
4494 is_lazily_compiled =
false;
4500 SingletonLogger logger;
4502 LazyParseFunctionLiteral(&logger);
4505 stack_overflow_ =
true;
4509 if (logger.has_error()) {
4510 const char* arg = logger.argument_opt();
4511 Vector<const char*> args;
4513 args = Vector<const char*>(&arg, 1);
4516 logger.message(), args);
4520 scope->set_end_position(logger.end());
4522 isolate()->counters()->total_preparse_skipped()->Increment(
4523 scope->end_position() - function_block_pos);
4524 materialized_literal_count = logger.literals();
4525 expected_property_count = logger.properties();
4527 only_simple_this_property_assignments =
false;
4528 this_property_assignments = isolate()->factory()->empty_fixed_array();
4532 if (!is_lazily_compiled) {
4533 ParsingModeScope parsing_mode(
this, PARSE_EAGERLY);
4534 body =
new(zone()) ZoneList<Statement*>(8, zone());
4539 body->Add(factory()->NewExpressionStatement(
4540 factory()->NewAssignment(fvar_init_op,
4542 factory()->NewThisFunction(),
4543 RelocInfo::kNoPosition)),
4546 ParseSourceElements(body, Token::RBRACE,
false,
false,
CHECK_OK);
4548 materialized_literal_count = function_state.materialized_literal_count();
4549 expected_property_count = function_state.expected_property_count();
4550 handler_count = function_state.handler_count();
4551 only_simple_this_property_assignments =
4552 function_state.only_simple_this_property_assignments();
4553 this_property_assignments = function_state.this_property_assignments();
4556 scope->set_end_position(scanner().location().end_pos);
4561 if (IsEvalOrArguments(function_name)) {
4562 int start_pos = scope->start_position();
4563 int position = function_token_position != RelocInfo::kNoPosition
4564 ? function_token_position
4565 : (start_pos > 0 ? start_pos - 1 : start_pos);
4566 Scanner::Location location = Scanner::Location(position, start_pos);
4572 if (name_loc.IsValid()) {
4578 if (dupe_loc.IsValid()) {
4584 if (name_is_strict_reserved) {
4585 int start_pos = scope->start_position();
4586 int position = function_token_position != RelocInfo::kNoPosition
4587 ? function_token_position
4588 : (start_pos > 0 ? start_pos - 1 : start_pos);
4589 Scanner::Location location = Scanner::Location(position, start_pos);
4595 if (reserved_loc.IsValid()) {
4601 CheckOctalLiteral(scope->start_position(),
4602 scope->end_position(),
4605 ast_properties = *factory()->visitor()->ast_properties();
4608 if (is_extended_mode()) {
4609 CheckConflictingVarDeclarations(scope,
CHECK_OK);
4612 FunctionLiteral* function_literal =
4613 factory()->NewFunctionLiteral(function_name,
4616 materialized_literal_count,
4617 expected_property_count,
4619 only_simple_this_property_assignments,
4620 this_property_assignments,
4622 duplicate_parameters,
4626 function_literal->set_function_token_position(function_token_position);
4627 function_literal->set_ast_properties(&ast_properties);
4629 if (fni_ !=
NULL && should_infer_name) fni_->
AddFunction(function_literal);
4630 return function_literal;
4635 SingletonLogger* logger) {
4636 HistogramTimerScope preparse_scope(isolate()->counters()->pre_parse());
4637 ASSERT_EQ(Token::LBRACE, scanner().current_token());
4639 if (reusable_preparser_ ==
NULL) {
4640 intptr_t stack_limit = isolate()->stack_guard()->real_climit();
4641 bool do_allow_lazy =
true;
4642 reusable_preparser_ =
new preparser::PreParser(&scanner_,
4646 allow_natives_syntax_,
4656 Expression* Parser::ParseV8Intrinsic(
bool* ok) {
4661 Handle<String> name = ParseIdentifier(
CHECK_OK);
4662 ZoneList<Expression*>* args = ParseArguments(
CHECK_OK);
4664 if (extension_ !=
NULL) {
4673 if (
function !=
NULL &&
4675 function->function_id == Runtime::kIS_VAR) {
4679 if (args->length() == 1 && args->at(0)->AsVariableProxy() !=
NULL) {
4689 if (
function !=
NULL &&
4690 function->nargs != -1 &&
4691 function->nargs != args->length()) {
4698 if (
function ==
NULL && name->Get(0) ==
'_') {
4699 ReportMessage(
"not_defined", Vector<Handle<String> >(&name, 1));
4705 return factory()->NewCallRuntime(name,
function, args);
4709 bool Parser::peek_any_identifier() {
4711 return next == Token::IDENTIFIER ||
4712 next == Token::FUTURE_RESERVED_WORD ||
4713 next == Token::FUTURE_STRICT_RESERVED_WORD;
4727 if (next == token)
return;
4728 ReportUnexpectedToken(next);
4735 if (next == token) {
4743 void Parser::ExpectSemicolon(
bool* ok) {
4747 if (tok == Token::SEMICOLON) {
4751 if (scanner().HasAnyLineTerminatorBeforeNext() ||
4752 tok == Token::RBRACE ||
4753 tok == Token::EOS) {
4756 Expect(Token::SEMICOLON, ok);
4760 void Parser::ExpectContextualKeyword(
const char* keyword,
bool* ok) {
4761 Expect(Token::IDENTIFIER, ok);
4763 Handle<String> symbol = GetSymbol(ok);
4765 if (!symbol->IsEqualTo(
CStrVector(keyword))) {
4767 ReportUnexpectedToken(scanner().current_token());
4772 Literal* Parser::GetLiteralUndefined() {
4773 return factory()->NewLiteral(isolate()->factory()->undefined_value());
4777 Literal* Parser::GetLiteralTheHole() {
4778 return factory()->NewLiteral(isolate()->factory()->the_hole_value());
4784 Handle<String> Parser::ParseIdentifier(
bool* ok) {
4786 Expect(Token::IDENTIFIER, ok);
4787 }
else if (!Check(Token::IDENTIFIER)) {
4788 Expect(Token::FUTURE_STRICT_RESERVED_WORD, ok);
4790 if (!*ok)
return Handle<String>();
4791 return GetSymbol(ok);
4797 Handle<String> Parser::ParseIdentifierOrStrictReservedWord(
4798 bool* is_strict_reserved,
bool* ok) {
4799 *is_strict_reserved =
false;
4800 if (!Check(Token::IDENTIFIER)) {
4801 Expect(Token::FUTURE_STRICT_RESERVED_WORD, ok);
4802 *is_strict_reserved =
true;
4804 if (!*ok)
return Handle<String>();
4805 return GetSymbol(ok);
4809 Handle<String> Parser::ParseIdentifierName(
bool* ok) {
4811 if (next != Token::IDENTIFIER &&
4812 next != Token::FUTURE_RESERVED_WORD &&
4813 next != Token::FUTURE_STRICT_RESERVED_WORD &&
4815 ReportUnexpectedToken(next);
4817 return Handle<String>();
4819 return GetSymbol(ok);
4823 void Parser::MarkAsLValue(Expression* expression) {
4824 VariableProxy* proxy = expression !=
NULL
4825 ? expression->AsVariableProxy()
4828 if (proxy !=
NULL) proxy->MarkAsLValue();
4834 void Parser::CheckStrictModeLValue(Expression* expression,
4838 VariableProxy* lhs = expression !=
NULL
4839 ? expression->AsVariableProxy()
4842 if (lhs !=
NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) {
4851 void Parser::CheckOctalLiteral(
int beg_pos,
int end_pos,
bool* ok) {
4853 if (octal.IsValid() &&
4854 beg_pos <= octal.beg_pos &&
4855 octal.end_pos <= end_pos) {
4864 void Parser::CheckConflictingVarDeclarations(Scope* scope,
bool* ok) {
4865 Declaration* decl = scope->CheckConflictingVarDeclarations();
4869 Handle<String> name = decl->proxy()->name();
4870 SmartArrayPointer<char> c_string = name->ToCString(
DISALLOW_NULLS);
4871 const char* elms[2] = {
"Variable", *c_string };
4872 Vector<const char*> args(elms, 2);
4873 int position = decl->proxy()->position();
4874 Scanner::Location location = position == RelocInfo::kNoPosition
4876 : Scanner::Location(position, position + 1);
4885 Handle<String> Parser::ParseIdentifierNameOrGetOrSet(
bool* is_get,
4888 Handle<String> result = ParseIdentifierName(ok);
4889 if (!*ok)
return Handle<String>();
4892 *is_get = strncmp(token,
"get", 3) == 0;
4893 *is_set = !*is_get && strncmp(token,
"set", 3) == 0;
4903 bool Parser::TargetStackContainsLabel(Handle<String> label) {
4904 for (Target* t = target_stack_; t !=
NULL; t = t->previous()) {
4905 BreakableStatement* stat = t->node()->AsBreakableStatement();
4906 if (stat !=
NULL && ContainsLabel(stat->labels(), label))
4913 BreakableStatement* Parser::LookupBreakTarget(Handle<String> label,
bool* ok) {
4914 bool anonymous = label.is_null();
4915 for (Target* t = target_stack_; t !=
NULL; t = t->previous()) {
4916 BreakableStatement* stat = t->node()->AsBreakableStatement();
4917 if (stat ==
NULL)
continue;
4918 if ((anonymous && stat->is_target_for_anonymous()) ||
4919 (!anonymous && ContainsLabel(stat->labels(), label))) {
4920 RegisterTargetUse(stat->break_target(), t->previous());
4928 IterationStatement* Parser::LookupContinueTarget(Handle<String> label,
4930 bool anonymous = label.is_null();
4931 for (Target* t = target_stack_; t !=
NULL; t = t->previous()) {
4932 IterationStatement* stat = t->node()->AsIterationStatement();
4933 if (stat ==
NULL)
continue;
4935 ASSERT(stat->is_target_for_anonymous());
4936 if (anonymous || ContainsLabel(stat->labels(), label)) {
4937 RegisterTargetUse(stat->continue_target(), t->previous());
4945 void Parser::RegisterTargetUse(Label* target, Target* stop) {
4949 for (Target* t = target_stack_; t != stop; t = t->previous()) {
4950 TargetCollector* collector = t->node()->AsTargetCollector();
4951 if (collector !=
NULL) collector->AddTarget(target, zone());
4956 Expression* Parser::NewThrowReferenceError(Handle<String> type) {
4957 return NewThrowError(isolate()->factory()->MakeReferenceError_symbol(),
4958 type, HandleVector<Object>(
NULL, 0));
4962 Expression* Parser::NewThrowSyntaxError(Handle<String> type,
4963 Handle<Object> first) {
4964 int argc = first.is_null() ? 0 : 1;
4965 Vector< Handle<Object> > arguments = HandleVector<Object>(&first, argc);
4966 return NewThrowError(
4967 isolate()->factory()->MakeSyntaxError_symbol(), type, arguments);
4971 Expression* Parser::NewThrowTypeError(Handle<String> type,
4972 Handle<Object> first,
4973 Handle<Object> second) {
4974 ASSERT(!first.is_null() && !second.is_null());
4975 Handle<Object> elements[] = { first, second };
4976 Vector< Handle<Object> > arguments =
4977 HandleVector<Object>(elements,
ARRAY_SIZE(elements));
4978 return NewThrowError(
4979 isolate()->factory()->MakeTypeError_symbol(), type, arguments);
4983 Expression* Parser::NewThrowError(Handle<String> constructor,
4984 Handle<String> type,
4985 Vector< Handle<Object> > arguments) {
4986 int argc = arguments.length();
4987 Handle<FixedArray> elements = isolate()->factory()->NewFixedArray(argc,
4989 for (
int i = 0; i < argc; i++) {
4990 Handle<Object> element = arguments[i];
4991 if (!element.is_null()) {
4992 elements->set(i, *element);
4995 Handle<JSArray> array = isolate()->factory()->NewJSArrayWithElements(
4998 ZoneList<Expression*>* args =
new(zone()) ZoneList<Expression*>(2, zone());
4999 args->Add(factory()->NewLiteral(type), zone());
5000 args->Add(factory()->NewLiteral(array), zone());
5001 CallRuntime* call_constructor =
5002 factory()->NewCallRuntime(constructor,
NULL, args);
5003 return factory()->NewThrow(call_constructor, scanner().location().beg_pos);
5014 : isolate_(
Isolate::Current()),
5023 multiline_(multiline),
5025 contains_anchor_(
false),
5026 is_scanned_for_captures_(
false),
5032 uc32 RegExpParser::Next() {
5034 return in()->
Get(next_pos_);
5042 if (next_pos_ < in()->length()) {
5043 StackLimitCheck
check(isolate());
5044 if (check.HasOverflowed()) {
5046 }
else if (zone()->excess_allocation()) {
5049 current_ = in()->
Get(next_pos_);
5066 next_pos_ += dist - 1;
5077 *error_ = isolate()->factory()->NewStringFromAscii(message,
NOT_TENURED);
5080 next_pos_ = in()->
length();
5092 if (result->IsAtom() && result->AsAtom()->length() == in()->
length()) {
5111 RegExpParserState initial_state(
NULL, INITIAL, 0, zone());
5112 RegExpParserState* stored_state = &initial_state;
5116 switch (current()) {
5118 if (stored_state->IsSubexpression()) {
5122 ASSERT_EQ(INITIAL, stored_state->group_type());
5126 if (!stored_state->IsSubexpression()) {
5129 ASSERT_NE(INITIAL, stored_state->group_type());
5138 int capture_index = stored_state->capture_index();
5139 SubexpressionType type = stored_state->group_type();
5142 stored_state = stored_state->previous_state();
5143 builder = stored_state->builder();
5146 if (type == CAPTURE) {
5148 captures_->at(capture_index - 1) = capture;
5150 }
else if (type != GROUPING) {
5151 ASSERT(type == POSITIVE_LOOKAHEAD || type == NEGATIVE_LOOKAHEAD);
5152 bool is_positive = (type == POSITIVE_LOOKAHEAD);
5155 end_capture_index - capture_index,
5203 SubexpressionType type = CAPTURE;
5205 if (current() ==
'?') {
5211 type = POSITIVE_LOOKAHEAD;
5214 type = NEGATIVE_LOOKAHEAD;
5222 if (captures_ ==
NULL) {
5228 captures_->Add(
NULL, zone());
5231 stored_state =
new(zone()) RegExpParserState(stored_state, type,
5233 builder = stored_state->builder();
5262 case 'd':
case 'D':
case 's':
case 'S':
case 'w':
case 'W': {
5272 case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
5273 case '7':
case '8':
case '9': {
5277 if (captures_ !=
NULL && index <= captures_->length()) {
5278 capture = captures_->at(index - 1);
5280 if (capture ==
NULL) {
5288 uc32 first_digit = Next();
5289 if (first_digit ==
'8' || first_digit ==
'9') {
5327 uc32 controlLetter = Next();
5330 uc32 letter = controlLetter & ~(
'a' ^
'A');
5331 if (letter <
'A' ||
'Z' < letter) {
5385 switch (current()) {
5420 if (current() ==
'?') {
5423 }
else if (FLAG_regexp_possessive_quantifier && current() ==
'+') {
5435 static bool IsSpecialClassEscape(
uc32 c) {
5454 void RegExpParser::ScanForCaptures() {
5472 if (c ==
']')
break;
5478 if (current() !=
'?') capture_count++;
5482 capture_count_ = capture_count;
5483 is_scanned_for_captures_ =
true;
5489 ASSERT(
'1' <= Next() && Next() <=
'9');
5493 int value = Next() -
'0';
5498 value = 10 * value + (c -
'0');
5509 if (!is_scanned_for_captures_) {
5512 Reset(saved_position);
5514 if (value > capture_count_) {
5541 int next = current() -
'0';
5550 min = 10 * min + next;
5554 if (current() ==
'}') {
5557 }
else if (current() ==
',') {
5559 if (current() ==
'}') {
5564 int next = current() -
'0';
5572 max = 10 * max + next;
5575 if (current() !=
'}') {
5592 ASSERT(
'0' <= current() && current() <=
'7');
5595 uc32 value = current() -
'0';
5597 if (
'0' <= current() && current() <=
'7') {
5598 value = value * 8 + current() -
'0';
5600 if (value < 32 &&
'0' <= current() && current() <=
'7') {
5601 value = value * 8 + current() -
'0';
5613 for (
int i = 0; !done; i++) {
5622 if (i == length - 1) {
5632 ASSERT(current() ==
'\\');
5633 ASSERT(has_next() && !IsSpecialClassEscape(Next()));
5635 switch (current()) {
5657 uc32 controlLetter = Next();
5658 uc32 letter = controlLetter & ~(
'A' ^
'a');
5661 if ((controlLetter >=
'0' && controlLetter <=
'9') ||
5662 controlLetter ==
'_' ||
5663 (letter >=
'A' && letter <=
'Z')) {
5667 return controlLetter & 0x1f;
5673 case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
5703 uc32 result = current();
5714 uc32 first = current();
5715 if (first ==
'\\') {
5717 case 'w':
case 'W':
case 'd':
case 'D':
case 's':
case 'S': {
5718 *char_class = Next();
5735 static const uc16 kNoCharClass = 0;
5744 if (char_class != kNoCharClass) {
5747 ranges->
Add(range, zone);
5753 static const char* kUnterminated =
"Unterminated character class";
5754 static const char* kRangeOutOfOrder =
"Range out of order in character class";
5758 bool is_negated =
false;
5759 if (current() ==
'^') {
5765 while (has_more() && current() !=
']') {
5766 uc16 char_class = kNoCharClass;
5768 if (current() ==
'-') {
5774 }
else if (current() ==
']') {
5775 AddRangeOrEscape(ranges, char_class, first, zone());
5779 uc16 char_class_2 = kNoCharClass;
5781 if (char_class != kNoCharClass || char_class_2 != kNoCharClass) {
5783 AddRangeOrEscape(ranges, char_class, first, zone());
5785 AddRangeOrEscape(ranges, char_class_2, next, zone());
5788 if (first.
from() > next.
to()) {
5793 AddRangeOrEscape(ranges, char_class, first, zone());
5800 if (ranges->length() == 0) {
5802 is_negated = !is_negated;
5819 if (owns_store_) store_.
Dispose();
5824 return store_.
length() *
sizeof(unsigned);
5829 return reinterpret_cast<const char*
>(store_.
start());
5844 if (store_.length() > symbol_data_offset) {
5845 symbol_data_ =
reinterpret_cast<byte*
>(&store_[symbol_data_offset]);
5848 symbol_data_ =
reinterpret_cast<byte*
>(&store_[0] + store_.length());
5850 symbol_data_end_ =
reinterpret_cast<byte*
>(&store_[0] + store_.length());
5855 int ScriptDataImpl::ReadNumber(
byte** source) {
5862 byte* data = *source;
5863 if (data >= symbol_data_end_)
return -1;
5869 int result = input & 0x7f;
5871 while ((input & 0x80u) != 0) {
5872 if (data >= symbol_data_end_)
return -1;
5874 result = (result << 7) | (input & 0x7f);
5883 static ScriptDataImpl* DoPreParse(Utf16CharacterStream* source,
5885 ParserRecorder* recorder) {
5886 Isolate* isolate = Isolate::Current();
5887 HistogramTimerScope timer(isolate->counters()->pre_parse());
5888 Scanner scanner(isolate->unicode_cache());
5889 scanner.SetHarmonyScoping(FLAG_harmony_scoping);
5890 scanner.Initialize(source);
5891 intptr_t stack_limit = isolate->stack_guard()->real_climit();
5898 isolate->StackOverflow();
5904 Vector<unsigned> store = recorder->ExtractData();
5905 return new ScriptDataImpl(store);
5913 if (FLAG_lazy && (extension ==
NULL)) {
5917 return DoPreParse(source, flags, &recorder);
5934 result->
tree = tree;
5936 result->
simple = tree->IsAtom() && parser.
simple() && capture_count == 0;
5948 if (!info->
is_native() && FLAG_harmony_scoping) {
5952 if (!info->
is_native() && FLAG_harmony_modules) {
5955 if (FLAG_allow_natives_syntax || info->
is_native()) {
5963 result = parser.ParseLazy();
5965 result = parser.ParseProgram();
5974 parser.ReportMessageAt(loc, message, args);
5976 for (
int i = 0; i < args.
length(); i++) {
5982 result = parser.ParseProgram();
5986 return (result !=
NULL);
bool is_global_scope() const
static Assignment * AsAssignment(Statement *stat)
virtual v8::Handle< v8::FunctionTemplate > GetNativeFunction(v8::Handle< v8::String > name)
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 use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra 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 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if expose natives in global object expose gc extension number of stack frames to capture disable builtin natives files print a stack trace if an assertion failure occurs use random jit cookie to mask large constants trace lazy optimization use adaptive optimizations prepare for turning on always opt minimum length for automatic enable preparsing maximum number of optimization attempts before giving up cache prototype transitions automatically set the debug break flag when debugger commands are in the queue always cause a debug break before aborting maximum length of function source code printed in a stack trace max size of the new max size of the old max size of executable always perform global GCs print one trace line following each garbage collection do not print trace line after scavenger collection print more details following each garbage collection print amount of external allocated memory after each time it is adjusted flush code that we expect not to use again before full gc do incremental marking steps track object counts and memory usage use caching Perform compaction on every full GC Never perform compaction on full GC testing only Compact code space on full incremental collections Default seed for initializing random allows verbose printing trace parsing and preparsing Check icache flushes in ARM and MIPS simulator Stack alingment in bytes in print stack trace when throwing exceptions randomize hashes to avoid predictable hash Fixed seed to use to hash property activate a timer that switches between V8 threads testing_bool_flag float flag Seed used for threading test randomness A filename with extra code to be included in the Print usage including on console Map counters to a file Enable debugger compile events enable GDBJIT interface(disables compacting GC)") DEFINE_bool(gdbjit_full
Scope * DeclarationScope()
static bool ParseRegExp(FlatStringReader *input, bool multiline, RegExpCompileData *result, Zone *zone)
static ScriptDataImpl * PreParse(Utf16CharacterStream *source, v8::Extension *extension, int flags)
virtual bool IsTextElement()
ThisNamedPropertyAssignmentFinder(Isolate *isolate, Zone *zone)
Vector< const char * > BuildArgs()
Parser(CompilationInfo *info, int parsing_flags, v8::Extension *extension, ScriptDataImpl *pre_data)
void PushVariableName(Handle< String > name)
LanguageMode language_mode() const
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
ScriptDataImpl * pre_parse_data() const
static Smi * FromInt(int value)
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)
bool ParseHexEscape(int length, uc32 *value)
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)
static Handle< FixedArray > GetElements(Handle< FixedArray > value)
Vector< T > SubVector(int from, int to)
int literal_length() const
bool is_classic_mode() const
RegExpTree * ParseCharacterClass()
VariableProxy * NewUnresolved(AstNodeFactory< Visitor > *factory, Handle< String > name, Interface *interface=Interface::NewValue(), int position=RelocInfo::kNoPosition)
RegExpParser(FlatStringReader *in, Handle< String > *error, bool multiline_mode, Zone *zone)
void DeclareParameter(Handle< String > name, VariableMode mode)
static CharacterRange Everything()
void AddAtom(RegExpTree *tree)
static const Function * FunctionForId(FunctionId id)
#define ASSERT(condition)
Variable * NewTemporary(Handle< String > name)
void ForceEagerCompilation()
static bool IsCompileTimeValue(Expression *expression)
virtual MaterializedLiteral * AsMaterializedLiteral()
static Type GetType(Handle< FixedArray > value)
void SetHarmonyModules(bool modules)
void set_end_position(int statement_pos)
Vector< const char * > args()
Handle< String > debug_name() const
virtual ~ScriptDataImpl()
Handle< String > name() const
Element(PositionStack *stack, int value)
FunctionLiteral * ParseProgram()
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)
static const int kSymbolCountOffset
FunctionEntry GetFunctionEntry(int start)
bool AllowsLazyCompilation() const
v8::Handle< v8::Value > Read(const v8::Arguments &args)
Handle< FixedArray > constant_elements() const
void DeclareFunctionVar(VariableDeclaration *declaration)
SmartArrayPointer< char > ToCString(AllowNullsFlag allow_nulls, RobustnessFlag robustness_flag, int offset, int length, int *length_output=0)
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()
static Interface * NewValue()
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)
void AddAssertion(RegExpTree *tree)
int start_position() const
static Interface * NewUnknown(Zone *zone)
v8::Extension * extension() const
friend class FunctionState
bool literal_contains_escapes() const
bool is_eval_scope() const
static CharacterRange Range(uc16 from, uc16 to)
void set_contains_anchor()
FunctionLiteral * ParseLazy()
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
FunctionLiteral * function() const
static const int kMessageTextPos
static const int kMessageArgCountPos
void SeekForward(int pos)
virtual void PauseRecording()
Handle< FixedArray > GetThisPropertyAssignments()
static const int kFunctionsSizeOffset
virtual int symbol_position()
Handle< FixedArray > NewFixedArray(int size, PretenureFlag pretenure=NOT_TENURED)
bool IsLexicalVariableMode(VariableMode mode)
TargetScope(Target **variable)
Expression * expression() const
bool has_pending_exception()
void CheckProperty(ObjectLiteral::Property *property, Scanner::Location loc, bool *ok)
static bool IsKeyword(Value tok)
bool IsDeclaredVariableMode(VariableMode mode)
activate correct semantics for inheriting readonliness false
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()
static Interface * NewConst()
bool is_classic_mode() const
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)
void SetLanguageMode(LanguageMode language_mode)
Location location() const
void ReportMessageAt(Scanner::Location loc, const char *message, Vector< const char * > args)
static BailoutId FirstUsable()
virtual int function_position()
static const unsigned kCurrentVersion
Handle< Context > context() const
virtual const char * Data()
Target(Target **variable, AstNode *node)
bool is_extended_mode() const
void AddCharacter(uc16 character)
Local< Function > GetFunction()
void clear_octal_position()
Scanner::Location MessageLocation()
Handle< SharedFunctionInfo > shared_info() const
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)
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 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 use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra 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 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if expose natives in global object expose gc extension number of stack frames to capture disable builtin natives files print a stack trace if an assertion failure occurs use random jit cookie to mask large constants trace lazy optimization use adaptive optimizations prepare for turning on always opt minimum length for automatic enable preparsing maximum number of optimization attempts before giving up cache prototype transitions automatically set the debug break flag when debugger commands are in the queue always cause a debug break before aborting maximum length of function source code printed in a stack trace max size of the new max size of the old max size of executable always perform global GCs print one trace line following each garbage collection do not print trace line after scavenger collection print more details following each garbage collection print amount of external allocated memory after each time it is adjusted flush code that we expect not to use again before full gc do incremental marking steps track object counts and memory usage use caching Perform compaction on every full GC Never perform compaction on full GC testing only Compact code space on full incremental collections Default seed for initializing random allows verbose printing trace parsing and preparsing Check icache flushes in ARM and MIPS simulator Stack alingment in bytes in print stack trace when throwing exceptions randomize hashes to avoid predictable hash Fixed seed to use to hash property activate a timer that switches between V8 threads testing_bool_flag float flag Seed used for threading test randomness A filename with extra code to be included in the Print usage message
#define ASSERT_NE(v1, v2)
static FixedArray * cast(Object *obj)
static Vector< const char * > empty()
void Add(const T &element, AllocationPolicy allocator=AllocationPolicy())
Location octal_position() const
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 use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra 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 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if NULL
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
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 use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra code(assertions) for debugging") DEFINE_bool(code_comments
bool is_function_scope() const
bool ParseIntervalQuantifier(int *min_out, int *max_out)
virtual void ResumeRecording()
void DeleteArray(T *array)
void RecordWithStatement()
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 use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra 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 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if expose natives in global object expose gc extension number of stack frames to capture disable builtin natives files print a stack trace if an assertion failure occurs use random jit cookie to mask large constants trace lazy optimization use adaptive optimizations prepare for turning on always opt minimum length for automatic enable preparsing maximum number of optimization attempts before giving up cache prototype transitions automatically set the debug break flag when debugger commands are in the queue always cause a debug break before aborting maximum length of function source code printed in a stack trace max size of the new max size of the old max size of executable always perform global GCs print one trace line following each garbage collection do not print trace line after scavenger collection print more details following each garbage collection print amount of external allocated memory after each time it is adjusted flush code that we expect not to use again before full gc do incremental marking steps track object counts and memory usage use caching Perform compaction on every full GC Never perform compaction on full GC testing only Compact code space on full incremental collections Default seed for initializing random allows verbose printing trace parsing and preparsing Check icache flushes in ARM and MIPS simulator Stack alingment in bytes in print stack trace when throwing exceptions randomize hashes to avoid predictable hash Fixed seed to use to hash property activate a timer that switches between V8 threads testing_bool_flag float flag Seed used for threading test randomness A filename with extra code to be included in the Print usage including flags
virtual int max_match()=0
void SetGlobalScope(Scope *global_scope)
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)
void SetFunction(FunctionLiteral *literal)
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)
void set_inferred_name(Handle< String > inferred_name)