Revision f230a1cf deps/v8/src/parser.cc
deps/v8/src/parser.cc | ||
---|---|---|
536 | 536 |
// Implementation of Parser |
537 | 537 |
|
538 | 538 |
Parser::Parser(CompilationInfo* info) |
539 |
: isolate_(info->isolate()), |
|
539 |
: ParserBase(&scanner_, info->isolate()->stack_guard()->real_climit()), |
|
540 |
isolate_(info->isolate()), |
|
540 | 541 |
symbol_cache_(0, info->zone()), |
541 | 542 |
script_(info->script()), |
542 | 543 |
scanner_(isolate_->unicode_cache()), |
... | ... | |
548 | 549 |
extension_(info->extension()), |
549 | 550 |
pre_parse_data_(NULL), |
550 | 551 |
fni_(NULL), |
551 |
allow_natives_syntax_(false), |
|
552 |
allow_lazy_(false), |
|
553 |
allow_generators_(false), |
|
554 |
allow_for_of_(false), |
|
555 |
stack_overflow_(false), |
|
556 | 552 |
parenthesized_function_(false), |
557 | 553 |
zone_(info->zone()), |
558 | 554 |
info_(info) { |
... | ... | |
569 | 565 |
|
570 | 566 |
|
571 | 567 |
FunctionLiteral* Parser::ParseProgram() { |
572 |
HistogramTimerScope timer_scope(isolate()->counters()->parse()); |
|
568 |
// TODO(bmeurer): We temporarily need to pass allow_nesting = true here, |
|
569 |
// see comment for HistogramTimerScope class. |
|
570 |
HistogramTimerScope timer_scope(isolate()->counters()->parse(), true); |
|
573 | 571 |
Handle<String> source(String::cast(script_->source())); |
574 | 572 |
isolate()->counters()->total_parse_size()->Increment(source->length()); |
575 | 573 |
ElapsedTimer timer; |
... | ... | |
652 | 650 |
top_scope_->SetLanguageMode(info->language_mode()); |
653 | 651 |
ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); |
654 | 652 |
bool ok = true; |
655 |
int beg_loc = scanner().location().beg_pos;
|
|
653 |
int beg_pos = scanner().location().beg_pos;
|
|
656 | 654 |
ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok); |
657 | 655 |
if (ok && !top_scope_->is_classic_mode()) { |
658 |
CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok);
|
|
656 |
CheckOctalLiteral(beg_pos, scanner().location().end_pos, &ok);
|
|
659 | 657 |
} |
660 | 658 |
|
661 | 659 |
if (ok && is_extended_mode()) { |
... | ... | |
685 | 683 |
FunctionLiteral::ANONYMOUS_EXPRESSION, |
686 | 684 |
FunctionLiteral::kGlobalOrEval, |
687 | 685 |
FunctionLiteral::kNotParenthesized, |
688 |
FunctionLiteral::kNotGenerator); |
|
686 |
FunctionLiteral::kNotGenerator, |
|
687 |
0); |
|
689 | 688 |
result->set_ast_properties(factory()->visitor()->ast_properties()); |
690 | 689 |
result->set_dont_optimize_reason( |
691 | 690 |
factory()->visitor()->dont_optimize_reason()); |
692 |
} else if (stack_overflow_) {
|
|
691 |
} else if (stack_overflow()) {
|
|
693 | 692 |
isolate()->StackOverflow(); |
694 | 693 |
} |
695 | 694 |
} |
... | ... | |
786 | 785 |
ASSERT(target_stack_ == NULL); |
787 | 786 |
|
788 | 787 |
if (result == NULL) { |
789 |
if (stack_overflow_) isolate()->StackOverflow();
|
|
788 |
if (stack_overflow()) isolate()->StackOverflow();
|
|
790 | 789 |
} else { |
791 | 790 |
Handle<String> inferred_name(shared_info->inferred_name()); |
792 | 791 |
result->set_inferred_name(inferred_name); |
... | ... | |
984 | 983 |
// ModuleDeclaration: |
985 | 984 |
// 'module' Identifier Module |
986 | 985 |
|
986 |
int pos = peek_position(); |
|
987 | 987 |
Handle<String> name = ParseIdentifier(CHECK_OK); |
988 | 988 |
|
989 | 989 |
#ifdef DEBUG |
... | ... | |
994 | 994 |
Module* module = ParseModule(CHECK_OK); |
995 | 995 |
VariableProxy* proxy = NewUnresolved(name, MODULE, module->interface()); |
996 | 996 |
Declaration* declaration = |
997 |
factory()->NewModuleDeclaration(proxy, module, top_scope_); |
|
997 |
factory()->NewModuleDeclaration(proxy, module, top_scope_, pos);
|
|
998 | 998 |
Declare(declaration, true, CHECK_OK); |
999 | 999 |
|
1000 | 1000 |
#ifdef DEBUG |
... | ... | |
1009 | 1009 |
|
1010 | 1010 |
if (names) names->Add(name, zone()); |
1011 | 1011 |
if (module->body() == NULL) |
1012 |
return factory()->NewEmptyStatement(); |
|
1012 |
return factory()->NewEmptyStatement(pos);
|
|
1013 | 1013 |
else |
1014 |
return factory()->NewModuleStatement(proxy, module->body()); |
|
1014 |
return factory()->NewModuleStatement(proxy, module->body(), pos);
|
|
1015 | 1015 |
} |
1016 | 1016 |
|
1017 | 1017 |
|
... | ... | |
1046 | 1046 |
// Module: |
1047 | 1047 |
// '{' ModuleElement '}' |
1048 | 1048 |
|
1049 |
int pos = peek_position(); |
|
1049 | 1050 |
// Construct block expecting 16 statements. |
1050 |
Block* body = factory()->NewBlock(NULL, 16, false); |
|
1051 |
Block* body = factory()->NewBlock(NULL, 16, false, RelocInfo::kNoPosition);
|
|
1051 | 1052 |
#ifdef DEBUG |
1052 | 1053 |
if (FLAG_print_interface_details) PrintF("# Literal "); |
1053 | 1054 |
#endif |
... | ... | |
1092 | 1093 |
ASSERT(*ok); |
1093 | 1094 |
interface->Freeze(ok); |
1094 | 1095 |
ASSERT(*ok); |
1095 |
return factory()->NewModuleLiteral(body, interface); |
|
1096 |
return factory()->NewModuleLiteral(body, interface, pos);
|
|
1096 | 1097 |
} |
1097 | 1098 |
|
1098 | 1099 |
|
... | ... | |
1101 | 1102 |
// Identifier |
1102 | 1103 |
// ModulePath '.' Identifier |
1103 | 1104 |
|
1105 |
int pos = peek_position(); |
|
1104 | 1106 |
Module* result = ParseModuleVariable(CHECK_OK); |
1105 | 1107 |
while (Check(Token::PERIOD)) { |
1106 | 1108 |
Handle<String> name = ParseIdentifierName(CHECK_OK); |
... | ... | |
1108 | 1110 |
if (FLAG_print_interface_details) |
1109 | 1111 |
PrintF("# Path .%s ", name->ToAsciiArray()); |
1110 | 1112 |
#endif |
1111 |
Module* member = factory()->NewModulePath(result, name); |
|
1113 |
Module* member = factory()->NewModulePath(result, name, pos);
|
|
1112 | 1114 |
result->interface()->Add(name, member->interface(), zone(), ok); |
1113 | 1115 |
if (!*ok) { |
1114 | 1116 |
#ifdef DEBUG |
... | ... | |
1134 | 1136 |
// ModulePath: |
1135 | 1137 |
// Identifier |
1136 | 1138 |
|
1139 |
int pos = peek_position(); |
|
1137 | 1140 |
Handle<String> name = ParseIdentifier(CHECK_OK); |
1138 | 1141 |
#ifdef DEBUG |
1139 | 1142 |
if (FLAG_print_interface_details) |
... | ... | |
1143 | 1146 |
factory(), name, Interface::NewModule(zone()), |
1144 | 1147 |
scanner().location().beg_pos); |
1145 | 1148 |
|
1146 |
return factory()->NewModuleVariable(proxy); |
|
1149 |
return factory()->NewModuleVariable(proxy, pos);
|
|
1147 | 1150 |
} |
1148 | 1151 |
|
1149 | 1152 |
|
... | ... | |
1151 | 1154 |
// Module: |
1152 | 1155 |
// String |
1153 | 1156 |
|
1157 |
int pos = peek_position(); |
|
1154 | 1158 |
Expect(Token::STRING, CHECK_OK); |
1155 | 1159 |
Handle<String> symbol = GetSymbol(); |
1156 | 1160 |
|
... | ... | |
1163 | 1167 |
// Create an empty literal as long as the feature isn't finished. |
1164 | 1168 |
USE(symbol); |
1165 | 1169 |
Scope* scope = NewScope(top_scope_, MODULE_SCOPE); |
1166 |
Block* body = factory()->NewBlock(NULL, 1, false); |
|
1170 |
Block* body = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
|
|
1167 | 1171 |
body->set_scope(scope); |
1168 | 1172 |
Interface* interface = scope->interface(); |
1169 |
Module* result = factory()->NewModuleLiteral(body, interface); |
|
1173 |
Module* result = factory()->NewModuleLiteral(body, interface, pos);
|
|
1170 | 1174 |
interface->Freeze(ok); |
1171 | 1175 |
ASSERT(*ok); |
1172 | 1176 |
interface->Unify(scope->interface(), zone(), ok); |
... | ... | |
1194 | 1198 |
// |
1195 | 1199 |
// TODO(ES6): implement destructuring ImportSpecifiers |
1196 | 1200 |
|
1201 |
int pos = peek_position(); |
|
1197 | 1202 |
Expect(Token::IMPORT, CHECK_OK); |
1198 | 1203 |
ZoneStringList names(1, zone()); |
1199 | 1204 |
|
... | ... | |
1211 | 1216 |
|
1212 | 1217 |
// Generate a separate declaration for each identifier. |
1213 | 1218 |
// TODO(ES6): once we implement destructuring, make that one declaration. |
1214 |
Block* block = factory()->NewBlock(NULL, 1, true); |
|
1219 |
Block* block = factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition);
|
|
1215 | 1220 |
for (int i = 0; i < names.length(); ++i) { |
1216 | 1221 |
#ifdef DEBUG |
1217 | 1222 |
if (FLAG_print_interface_details) |
... | ... | |
1232 | 1237 |
} |
1233 | 1238 |
VariableProxy* proxy = NewUnresolved(names[i], LET, interface); |
1234 | 1239 |
Declaration* declaration = |
1235 |
factory()->NewImportDeclaration(proxy, module, top_scope_); |
|
1240 |
factory()->NewImportDeclaration(proxy, module, top_scope_, pos);
|
|
1236 | 1241 |
Declare(declaration, true, CHECK_OK); |
1237 | 1242 |
} |
1238 | 1243 |
|
... | ... | |
1256 | 1261 |
ZoneStringList names(1, zone()); |
1257 | 1262 |
switch (peek()) { |
1258 | 1263 |
case Token::IDENTIFIER: { |
1264 |
int pos = position(); |
|
1259 | 1265 |
Handle<String> name = ParseIdentifier(CHECK_OK); |
1260 | 1266 |
// Handle 'module' as a context-sensitive keyword. |
1261 | 1267 |
if (!name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("module"))) { |
... | ... | |
1266 | 1272 |
names.Add(name, zone()); |
1267 | 1273 |
} |
1268 | 1274 |
ExpectSemicolon(CHECK_OK); |
1269 |
result = factory()->NewEmptyStatement(); |
|
1275 |
result = factory()->NewEmptyStatement(pos);
|
|
1270 | 1276 |
} else { |
1271 | 1277 |
result = ParseModuleDeclaration(&names, CHECK_OK); |
1272 | 1278 |
} |
... | ... | |
1305 | 1311 |
// TODO(rossberg): Rethink whether we actually need to store export |
1306 | 1312 |
// declarations (for compilation?). |
1307 | 1313 |
// ExportDeclaration* declaration = |
1308 |
// factory()->NewExportDeclaration(proxy, top_scope_); |
|
1314 |
// factory()->NewExportDeclaration(proxy, top_scope_, position);
|
|
1309 | 1315 |
// top_scope_->AddDeclaration(declaration); |
1310 | 1316 |
} |
1311 | 1317 |
|
... | ... | |
1363 | 1369 |
// labels can be simply ignored in all other cases; except for |
1364 | 1370 |
// trivial labeled break statements 'label: break label' which is |
1365 | 1371 |
// parsed into an empty statement. |
1366 |
|
|
1367 |
// Keep the source position of the statement |
|
1368 |
int statement_pos = scanner().peek_location().beg_pos; |
|
1369 |
Statement* stmt = NULL; |
|
1370 | 1372 |
switch (peek()) { |
1371 | 1373 |
case Token::LBRACE: |
1372 | 1374 |
return ParseBlock(labels, ok); |
... | ... | |
1374 | 1376 |
case Token::CONST: // fall through |
1375 | 1377 |
case Token::LET: |
1376 | 1378 |
case Token::VAR: |
1377 |
stmt = ParseVariableStatement(kStatement, NULL, ok); |
|
1378 |
break; |
|
1379 |
return ParseVariableStatement(kStatement, NULL, ok); |
|
1379 | 1380 |
|
1380 | 1381 |
case Token::SEMICOLON: |
1381 | 1382 |
Next(); |
1382 |
return factory()->NewEmptyStatement(); |
|
1383 |
return factory()->NewEmptyStatement(RelocInfo::kNoPosition);
|
|
1383 | 1384 |
|
1384 | 1385 |
case Token::IF: |
1385 |
stmt = ParseIfStatement(labels, ok); |
|
1386 |
break; |
|
1386 |
return ParseIfStatement(labels, ok); |
|
1387 | 1387 |
|
1388 | 1388 |
case Token::DO: |
1389 |
stmt = ParseDoWhileStatement(labels, ok); |
|
1390 |
break; |
|
1389 |
return ParseDoWhileStatement(labels, ok); |
|
1391 | 1390 |
|
1392 | 1391 |
case Token::WHILE: |
1393 |
stmt = ParseWhileStatement(labels, ok); |
|
1394 |
break; |
|
1392 |
return ParseWhileStatement(labels, ok); |
|
1395 | 1393 |
|
1396 | 1394 |
case Token::FOR: |
1397 |
stmt = ParseForStatement(labels, ok); |
|
1398 |
break; |
|
1395 |
return ParseForStatement(labels, ok); |
|
1399 | 1396 |
|
1400 | 1397 |
case Token::CONTINUE: |
1401 |
stmt = ParseContinueStatement(ok); |
|
1402 |
break; |
|
1398 |
return ParseContinueStatement(ok); |
|
1403 | 1399 |
|
1404 | 1400 |
case Token::BREAK: |
1405 |
stmt = ParseBreakStatement(labels, ok); |
|
1406 |
break; |
|
1401 |
return ParseBreakStatement(labels, ok); |
|
1407 | 1402 |
|
1408 | 1403 |
case Token::RETURN: |
1409 |
stmt = ParseReturnStatement(ok); |
|
1410 |
break; |
|
1404 |
return ParseReturnStatement(ok); |
|
1411 | 1405 |
|
1412 | 1406 |
case Token::WITH: |
1413 |
stmt = ParseWithStatement(labels, ok); |
|
1414 |
break; |
|
1407 |
return ParseWithStatement(labels, ok); |
|
1415 | 1408 |
|
1416 | 1409 |
case Token::SWITCH: |
1417 |
stmt = ParseSwitchStatement(labels, ok); |
|
1418 |
break; |
|
1410 |
return ParseSwitchStatement(labels, ok); |
|
1419 | 1411 |
|
1420 | 1412 |
case Token::THROW: |
1421 |
stmt = ParseThrowStatement(ok); |
|
1422 |
break; |
|
1413 |
return ParseThrowStatement(ok); |
|
1423 | 1414 |
|
1424 | 1415 |
case Token::TRY: { |
1425 | 1416 |
// NOTE: It is somewhat complicated to have labels on |
... | ... | |
1427 | 1418 |
// one must take great care not to treat it as a |
1428 | 1419 |
// fall-through. It is much easier just to wrap the entire |
1429 | 1420 |
// try-statement in a statement block and put the labels there |
1430 |
Block* result = factory()->NewBlock(labels, 1, false); |
|
1421 |
Block* result = |
|
1422 |
factory()->NewBlock(labels, 1, false, RelocInfo::kNoPosition); |
|
1431 | 1423 |
Target target(&this->target_stack_, result); |
1432 | 1424 |
TryStatement* statement = ParseTryStatement(CHECK_OK); |
1433 |
if (statement) { |
|
1434 |
statement->set_statement_pos(statement_pos); |
|
1435 |
} |
|
1436 | 1425 |
if (result) result->AddStatement(statement, zone()); |
1437 | 1426 |
return result; |
1438 | 1427 |
} |
... | ... | |
1459 | 1448 |
} |
1460 | 1449 |
|
1461 | 1450 |
case Token::DEBUGGER: |
1462 |
stmt = ParseDebuggerStatement(ok); |
|
1463 |
break; |
|
1451 |
return ParseDebuggerStatement(ok); |
|
1464 | 1452 |
|
1465 | 1453 |
default: |
1466 |
stmt = ParseExpressionOrLabelledStatement(labels, ok);
|
|
1454 |
return ParseExpressionOrLabelledStatement(labels, ok);
|
|
1467 | 1455 |
} |
1468 |
|
|
1469 |
// Store the source position of the statement |
|
1470 |
if (stmt != NULL) stmt->set_statement_pos(statement_pos); |
|
1471 |
return stmt; |
|
1472 | 1456 |
} |
1473 | 1457 |
|
1474 | 1458 |
|
... | ... | |
1480 | 1464 |
// Let/const variables in harmony mode are always added to the immediately |
1481 | 1465 |
// enclosing scope. |
1482 | 1466 |
return DeclarationScope(mode)->NewUnresolved( |
1483 |
factory(), name, interface, scanner().location().beg_pos);
|
|
1467 |
factory(), name, interface, position());
|
|
1484 | 1468 |
} |
1485 | 1469 |
|
1486 | 1470 |
|
... | ... | |
1647 | 1631 |
// declaration is resolved by looking up the function through a |
1648 | 1632 |
// callback provided by the extension. |
1649 | 1633 |
Statement* Parser::ParseNativeDeclaration(bool* ok) { |
1634 |
int pos = peek_position(); |
|
1650 | 1635 |
Expect(Token::FUNCTION, CHECK_OK); |
1651 | 1636 |
Handle<String> name = ParseIdentifier(CHECK_OK); |
1652 | 1637 |
Expect(Token::LPAREN, CHECK_OK); |
... | ... | |
1667 | 1652 |
// because of lazy compilation. |
1668 | 1653 |
DeclarationScope(VAR)->ForceEagerCompilation(); |
1669 | 1654 |
|
1670 |
// Compute the function template for the native function. |
|
1671 |
v8::Handle<v8::FunctionTemplate> fun_template = |
|
1672 |
extension_->GetNativeFunction(v8::Utils::ToLocal(name)); |
|
1673 |
ASSERT(!fun_template.IsEmpty()); |
|
1674 |
|
|
1675 |
// Instantiate the function and create a shared function info from it. |
|
1676 |
Handle<JSFunction> fun = Utils::OpenHandle(*fun_template->GetFunction()); |
|
1677 |
const int literals = fun->NumberOfLiterals(); |
|
1678 |
Handle<Code> code = Handle<Code>(fun->shared()->code()); |
|
1679 |
Handle<Code> construct_stub = Handle<Code>(fun->shared()->construct_stub()); |
|
1680 |
bool is_generator = false; |
|
1681 |
Handle<SharedFunctionInfo> shared = |
|
1682 |
isolate()->factory()->NewSharedFunctionInfo(name, literals, is_generator, |
|
1683 |
code, Handle<ScopeInfo>(fun->shared()->scope_info())); |
|
1684 |
shared->set_construct_stub(*construct_stub); |
|
1685 |
|
|
1686 |
// Copy the function data to the shared function info. |
|
1687 |
shared->set_function_data(fun->shared()->function_data()); |
|
1688 |
int parameters = fun->shared()->formal_parameter_count(); |
|
1689 |
shared->set_formal_parameter_count(parameters); |
|
1690 |
|
|
1691 | 1655 |
// TODO(1240846): It's weird that native function declarations are |
1692 | 1656 |
// introduced dynamically when we meet their declarations, whereas |
1693 | 1657 |
// other functions are set up when entering the surrounding scope. |
1694 | 1658 |
VariableProxy* proxy = NewUnresolved(name, VAR, Interface::NewValue()); |
1695 | 1659 |
Declaration* declaration = |
1696 |
factory()->NewVariableDeclaration(proxy, VAR, top_scope_); |
|
1660 |
factory()->NewVariableDeclaration(proxy, VAR, top_scope_, pos);
|
|
1697 | 1661 |
Declare(declaration, true, CHECK_OK); |
1698 |
SharedFunctionInfoLiteral* lit =
|
|
1699 |
factory()->NewSharedFunctionInfoLiteral(shared);
|
|
1662 |
NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral(
|
|
1663 |
name, extension_, RelocInfo::kNoPosition);
|
|
1700 | 1664 |
return factory()->NewExpressionStatement( |
1701 | 1665 |
factory()->NewAssignment( |
1702 |
Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition)); |
|
1666 |
Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition), |
|
1667 |
pos); |
|
1703 | 1668 |
} |
1704 | 1669 |
|
1705 | 1670 |
|
... | ... | |
1710 | 1675 |
// 'function' '*' Identifier '(' FormalParameterListopt ')' |
1711 | 1676 |
// '{' FunctionBody '}' |
1712 | 1677 |
Expect(Token::FUNCTION, CHECK_OK); |
1713 |
int function_token_position = scanner().location().beg_pos;
|
|
1678 |
int pos = position();
|
|
1714 | 1679 |
bool is_generator = allow_generators() && Check(Token::MUL); |
1715 | 1680 |
bool is_strict_reserved = false; |
1716 | 1681 |
Handle<String> name = ParseIdentifierOrStrictReservedWord( |
... | ... | |
1718 | 1683 |
FunctionLiteral* fun = ParseFunctionLiteral(name, |
1719 | 1684 |
is_strict_reserved, |
1720 | 1685 |
is_generator, |
1721 |
function_token_position,
|
|
1686 |
pos,
|
|
1722 | 1687 |
FunctionLiteral::DECLARATION, |
1723 | 1688 |
CHECK_OK); |
1724 | 1689 |
// Even if we're not at the top-level of the global or a function |
... | ... | |
1730 | 1695 |
is_extended_mode() && !top_scope_->is_global_scope() ? LET : VAR; |
1731 | 1696 |
VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue()); |
1732 | 1697 |
Declaration* declaration = |
1733 |
factory()->NewFunctionDeclaration(proxy, mode, fun, top_scope_); |
|
1698 |
factory()->NewFunctionDeclaration(proxy, mode, fun, top_scope_, pos);
|
|
1734 | 1699 |
Declare(declaration, true, CHECK_OK); |
1735 | 1700 |
if (names) names->Add(name, zone()); |
1736 |
return factory()->NewEmptyStatement(); |
|
1701 |
return factory()->NewEmptyStatement(RelocInfo::kNoPosition);
|
|
1737 | 1702 |
} |
1738 | 1703 |
|
1739 | 1704 |
|
... | ... | |
1747 | 1712 |
// (ECMA-262, 3rd, 12.2) |
1748 | 1713 |
// |
1749 | 1714 |
// Construct block expecting 16 statements. |
1750 |
Block* result = factory()->NewBlock(labels, 16, false); |
|
1715 |
Block* result = |
|
1716 |
factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); |
|
1751 | 1717 |
Target target(&this->target_stack_, result); |
1752 | 1718 |
Expect(Token::LBRACE, CHECK_OK); |
1753 | 1719 |
while (peek() != Token::RBRACE) { |
... | ... | |
1768 | 1734 |
// '{' BlockElement* '}' |
1769 | 1735 |
|
1770 | 1736 |
// Construct block expecting 16 statements. |
1771 |
Block* body = factory()->NewBlock(labels, 16, false); |
|
1737 |
Block* body = |
|
1738 |
factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); |
|
1772 | 1739 |
Scope* block_scope = NewScope(top_scope_, BLOCK_SCOPE); |
1773 | 1740 |
|
1774 | 1741 |
// Parse the statements and collect escaping labels. |
... | ... | |
1838 | 1805 |
// TODO(ES6): |
1839 | 1806 |
// ConstBinding :: |
1840 | 1807 |
// BindingPattern '=' AssignmentExpression |
1808 |
|
|
1809 |
int pos = peek_position(); |
|
1841 | 1810 |
VariableMode mode = VAR; |
1842 | 1811 |
// True if the binding needs initialization. 'let' and 'const' declared |
1843 | 1812 |
// bindings are created uninitialized by their declaration nodes and |
... | ... | |
1923 | 1892 |
// is inside an initializer block, it is ignored. |
1924 | 1893 |
// |
1925 | 1894 |
// Create new block with one expected declaration. |
1926 |
Block* block = factory()->NewBlock(NULL, 1, true); |
|
1895 |
Block* block = factory()->NewBlock(NULL, 1, true, pos);
|
|
1927 | 1896 |
int nvars = 0; // the number of variables declared |
1928 | 1897 |
Handle<String> name; |
1929 | 1898 |
do { |
... | ... | |
1960 | 1929 |
is_const ? Interface::NewConst() : Interface::NewValue(); |
1961 | 1930 |
VariableProxy* proxy = NewUnresolved(name, mode, interface); |
1962 | 1931 |
Declaration* declaration = |
1963 |
factory()->NewVariableDeclaration(proxy, mode, top_scope_); |
|
1932 |
factory()->NewVariableDeclaration(proxy, mode, top_scope_, pos);
|
|
1964 | 1933 |
Declare(declaration, mode != VAR, CHECK_OK); |
1965 | 1934 |
nvars++; |
1966 | 1935 |
if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) { |
... | ... | |
2000 | 1969 |
|
2001 | 1970 |
Scope* initialization_scope = is_const ? declaration_scope : top_scope_; |
2002 | 1971 |
Expression* value = NULL; |
2003 |
int position = -1;
|
|
1972 |
int pos = -1; |
|
2004 | 1973 |
// Harmony consts have non-optional initializers. |
2005 | 1974 |
if (peek() == Token::ASSIGN || mode == CONST_HARMONY) { |
2006 | 1975 |
Expect(Token::ASSIGN, CHECK_OK); |
2007 |
position = scanner().location().beg_pos;
|
|
1976 |
pos = position();
|
|
2008 | 1977 |
value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); |
2009 | 1978 |
// Don't infer if it is "a = function(){...}();"-like expression. |
2010 | 1979 |
if (fni_ != NULL && |
... | ... | |
2019 | 1988 |
|
2020 | 1989 |
// Record the end position of the initializer. |
2021 | 1990 |
if (proxy->var() != NULL) { |
2022 |
proxy->var()->set_initializer_position(scanner().location().end_pos);
|
|
1991 |
proxy->var()->set_initializer_position(position());
|
|
2023 | 1992 |
} |
2024 | 1993 |
|
2025 | 1994 |
// Make sure that 'const x' and 'let x' initialize 'x' to undefined. |
2026 | 1995 |
if (value == NULL && needs_init) { |
2027 |
value = GetLiteralUndefined(); |
|
1996 |
value = GetLiteralUndefined(position());
|
|
2028 | 1997 |
} |
2029 | 1998 |
|
2030 | 1999 |
// Global variable declarations must be compiled in a specific |
... | ... | |
2052 | 2021 |
ZoneList<Expression*>* arguments = |
2053 | 2022 |
new(zone()) ZoneList<Expression*>(3, zone()); |
2054 | 2023 |
// We have at least 1 parameter. |
2055 |
arguments->Add(factory()->NewLiteral(name), zone()); |
|
2024 |
arguments->Add(factory()->NewLiteral(name, pos), zone());
|
|
2056 | 2025 |
CallRuntime* initialize; |
2057 | 2026 |
|
2058 | 2027 |
if (is_const) { |
... | ... | |
2066 | 2035 |
initialize = factory()->NewCallRuntime( |
2067 | 2036 |
isolate()->factory()->InitializeConstGlobal_string(), |
2068 | 2037 |
Runtime::FunctionForId(Runtime::kInitializeConstGlobal), |
2069 |
arguments); |
|
2038 |
arguments, pos);
|
|
2070 | 2039 |
} else { |
2071 | 2040 |
// Add strict mode. |
2072 | 2041 |
// We may want to pass singleton to avoid Literal allocations. |
2073 | 2042 |
LanguageMode language_mode = initialization_scope->language_mode(); |
2074 |
arguments->Add(factory()->NewNumberLiteral(language_mode), zone()); |
|
2043 |
arguments->Add(factory()->NewNumberLiteral(language_mode, pos), zone());
|
|
2075 | 2044 |
|
2076 | 2045 |
// Be careful not to assign a value to the global variable if |
2077 | 2046 |
// we're in a with. The initialization value should not |
... | ... | |
2089 | 2058 |
initialize = factory()->NewCallRuntime( |
2090 | 2059 |
isolate()->factory()->InitializeVarGlobal_string(), |
2091 | 2060 |
Runtime::FunctionForId(Runtime::kInitializeVarGlobal), |
2092 |
arguments); |
|
2061 |
arguments, pos);
|
|
2093 | 2062 |
} |
2094 | 2063 |
|
2095 |
block->AddStatement(factory()->NewExpressionStatement(initialize), |
|
2096 |
zone()); |
|
2064 |
block->AddStatement( |
|
2065 |
factory()->NewExpressionStatement(initialize, RelocInfo::kNoPosition), |
|
2066 |
zone()); |
|
2097 | 2067 |
} else if (needs_init) { |
2098 | 2068 |
// Constant initializations always assign to the declared constant which |
2099 | 2069 |
// is always at the function scope level. This is only relevant for |
... | ... | |
2106 | 2076 |
ASSERT(proxy->var() != NULL); |
2107 | 2077 |
ASSERT(value != NULL); |
2108 | 2078 |
Assignment* assignment = |
2109 |
factory()->NewAssignment(init_op, proxy, value, position); |
|
2110 |
block->AddStatement(factory()->NewExpressionStatement(assignment), |
|
2111 |
zone()); |
|
2079 |
factory()->NewAssignment(init_op, proxy, value, pos); |
|
2080 |
block->AddStatement( |
|
2081 |
factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition), |
|
2082 |
zone()); |
|
2112 | 2083 |
value = NULL; |
2113 | 2084 |
} |
2114 | 2085 |
|
... | ... | |
2122 | 2093 |
VariableProxy* proxy = |
2123 | 2094 |
initialization_scope->NewUnresolved(factory(), name, interface); |
2124 | 2095 |
Assignment* assignment = |
2125 |
factory()->NewAssignment(init_op, proxy, value, position); |
|
2126 |
block->AddStatement(factory()->NewExpressionStatement(assignment), |
|
2127 |
zone()); |
|
2096 |
factory()->NewAssignment(init_op, proxy, value, pos); |
|
2097 |
block->AddStatement( |
|
2098 |
factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition), |
|
2099 |
zone()); |
|
2128 | 2100 |
} |
2129 | 2101 |
|
2130 | 2102 |
if (fni_ != NULL) fni_->Leave(); |
... | ... | |
2156 | 2128 |
// ExpressionStatement | LabelledStatement :: |
2157 | 2129 |
// Expression ';' |
2158 | 2130 |
// Identifier ':' Statement |
2131 |
int pos = peek_position(); |
|
2159 | 2132 |
bool starts_with_idenfifier = peek_any_identifier(); |
2160 | 2133 |
Expression* expr = ParseExpression(true, CHECK_OK); |
2161 | 2134 |
if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL && |
... | ... | |
2215 | 2188 |
scanner().literal_contains_escapes()) { |
2216 | 2189 |
ExpectSemicolon(CHECK_OK); |
2217 | 2190 |
} |
2218 |
return factory()->NewExpressionStatement(expr); |
|
2191 |
return factory()->NewExpressionStatement(expr, pos);
|
|
2219 | 2192 |
} |
2220 | 2193 |
|
2221 | 2194 |
|
... | ... | |
2223 | 2196 |
// IfStatement :: |
2224 | 2197 |
// 'if' '(' Expression ')' Statement ('else' Statement)? |
2225 | 2198 |
|
2199 |
int pos = peek_position(); |
|
2226 | 2200 |
Expect(Token::IF, CHECK_OK); |
2227 | 2201 |
Expect(Token::LPAREN, CHECK_OK); |
2228 | 2202 |
Expression* condition = ParseExpression(true, CHECK_OK); |
... | ... | |
2233 | 2207 |
Next(); |
2234 | 2208 |
else_statement = ParseStatement(labels, CHECK_OK); |
2235 | 2209 |
} else { |
2236 |
else_statement = factory()->NewEmptyStatement(); |
|
2210 |
else_statement = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
|
|
2237 | 2211 |
} |
2238 |
return factory()->NewIfStatement(condition, then_statement, else_statement); |
|
2212 |
return factory()->NewIfStatement( |
|
2213 |
condition, then_statement, else_statement, pos); |
|
2239 | 2214 |
} |
2240 | 2215 |
|
2241 | 2216 |
|
... | ... | |
2243 | 2218 |
// ContinueStatement :: |
2244 | 2219 |
// 'continue' Identifier? ';' |
2245 | 2220 |
|
2221 |
int pos = peek_position(); |
|
2246 | 2222 |
Expect(Token::CONTINUE, CHECK_OK); |
2247 | 2223 |
Handle<String> label = Handle<String>::null(); |
2248 | 2224 |
Token::Value tok = peek(); |
... | ... | |
2265 | 2241 |
return NULL; |
2266 | 2242 |
} |
2267 | 2243 |
ExpectSemicolon(CHECK_OK); |
2268 |
return factory()->NewContinueStatement(target); |
|
2244 |
return factory()->NewContinueStatement(target, pos);
|
|
2269 | 2245 |
} |
2270 | 2246 |
|
2271 | 2247 |
|
... | ... | |
2273 | 2249 |
// BreakStatement :: |
2274 | 2250 |
// 'break' Identifier? ';' |
2275 | 2251 |
|
2252 |
int pos = peek_position(); |
|
2276 | 2253 |
Expect(Token::BREAK, CHECK_OK); |
2277 | 2254 |
Handle<String> label; |
2278 | 2255 |
Token::Value tok = peek(); |
... | ... | |
2284 | 2261 |
// empty statements, e.g. 'l1: l2: l3: break l2;' |
2285 | 2262 |
if (!label.is_null() && ContainsLabel(labels, label)) { |
2286 | 2263 |
ExpectSemicolon(CHECK_OK); |
2287 |
return factory()->NewEmptyStatement(); |
|
2264 |
return factory()->NewEmptyStatement(pos);
|
|
2288 | 2265 |
} |
2289 | 2266 |
BreakableStatement* target = NULL; |
2290 | 2267 |
target = LookupBreakTarget(label, CHECK_OK); |
... | ... | |
2301 | 2278 |
return NULL; |
2302 | 2279 |
} |
2303 | 2280 |
ExpectSemicolon(CHECK_OK); |
2304 |
return factory()->NewBreakStatement(target); |
|
2281 |
return factory()->NewBreakStatement(target, pos);
|
|
2305 | 2282 |
} |
2306 | 2283 |
|
2307 | 2284 |
|
... | ... | |
2309 | 2286 |
// ReturnStatement :: |
2310 | 2287 |
// 'return' Expression? ';' |
2311 | 2288 |
|
2312 |
// Consume the return token. It is necessary to do the before
|
|
2289 |
// Consume the return token. It is necessary to do that before
|
|
2313 | 2290 |
// reporting any errors on it, because of the way errors are |
2314 | 2291 |
// reported (underlining). |
2315 | 2292 |
Expect(Token::RETURN, CHECK_OK); |
2293 |
int pos = position(); |
|
2316 | 2294 |
|
2317 | 2295 |
Token::Value tok = peek(); |
2318 | 2296 |
Statement* result; |
... | ... | |
2321 | 2299 |
tok == Token::SEMICOLON || |
2322 | 2300 |
tok == Token::RBRACE || |
2323 | 2301 |
tok == Token::EOS) { |
2324 |
return_value = GetLiteralUndefined(); |
|
2302 |
return_value = GetLiteralUndefined(position());
|
|
2325 | 2303 |
} else { |
2326 | 2304 |
return_value = ParseExpression(true, CHECK_OK); |
2327 | 2305 |
} |
... | ... | |
2330 | 2308 |
Expression* generator = factory()->NewVariableProxy( |
2331 | 2309 |
current_function_state_->generator_object_variable()); |
2332 | 2310 |
Expression* yield = factory()->NewYield( |
2333 |
generator, return_value, Yield::FINAL, RelocInfo::kNoPosition);
|
|
2334 |
result = factory()->NewExpressionStatement(yield); |
|
2311 |
generator, return_value, Yield::FINAL, pos);
|
|
2312 |
result = factory()->NewExpressionStatement(yield, pos);
|
|
2335 | 2313 |
} else { |
2336 |
result = factory()->NewReturnStatement(return_value); |
|
2314 |
result = factory()->NewReturnStatement(return_value, pos);
|
|
2337 | 2315 |
} |
2338 | 2316 |
|
2339 | 2317 |
// An ECMAScript program is considered syntactically incorrect if it |
... | ... | |
2347 | 2325 |
Handle<String> message = isolate()->factory()->illegal_return_string(); |
2348 | 2326 |
Expression* throw_error = |
2349 | 2327 |
NewThrowSyntaxError(message, Handle<Object>::null()); |
2350 |
return factory()->NewExpressionStatement(throw_error); |
|
2328 |
return factory()->NewExpressionStatement(throw_error, pos);
|
|
2351 | 2329 |
} |
2352 | 2330 |
return result; |
2353 | 2331 |
} |
... | ... | |
2358 | 2336 |
// 'with' '(' Expression ')' Statement |
2359 | 2337 |
|
2360 | 2338 |
Expect(Token::WITH, CHECK_OK); |
2339 |
int pos = position(); |
|
2361 | 2340 |
|
2362 | 2341 |
if (!top_scope_->is_classic_mode()) { |
2363 | 2342 |
ReportMessage("strict_mode_with", Vector<const char*>::empty()); |
... | ... | |
2377 | 2356 |
stmt = ParseStatement(labels, CHECK_OK); |
2378 | 2357 |
with_scope->set_end_position(scanner().location().end_pos); |
2379 | 2358 |
} |
2380 |
return factory()->NewWithStatement(with_scope, expr, stmt); |
|
2359 |
return factory()->NewWithStatement(with_scope, expr, stmt, pos);
|
|
2381 | 2360 |
} |
2382 | 2361 |
|
2383 | 2362 |
|
... | ... | |
2401 | 2380 |
*default_seen_ptr = true; |
2402 | 2381 |
} |
2403 | 2382 |
Expect(Token::COLON, CHECK_OK); |
2404 |
int pos = scanner().location().beg_pos;
|
|
2383 |
int pos = position();
|
|
2405 | 2384 |
ZoneList<Statement*>* statements = |
2406 | 2385 |
new(zone()) ZoneList<Statement*>(5, zone()); |
2407 | 2386 |
while (peek() != Token::CASE && |
... | ... | |
2411 | 2390 |
statements->Add(stat, zone()); |
2412 | 2391 |
} |
2413 | 2392 |
|
2414 |
return new(zone()) CaseClause(isolate(), label, statements, pos);
|
|
2393 |
return factory()->NewCaseClause(label, statements, pos);
|
|
2415 | 2394 |
} |
2416 | 2395 |
|
2417 | 2396 |
|
... | ... | |
2420 | 2399 |
// SwitchStatement :: |
2421 | 2400 |
// 'switch' '(' Expression ')' '{' CaseClause* '}' |
2422 | 2401 |
|
2423 |
SwitchStatement* statement = factory()->NewSwitchStatement(labels); |
|
2402 |
SwitchStatement* statement = |
|
2403 |
factory()->NewSwitchStatement(labels, peek_position()); |
|
2424 | 2404 |
Target target(&this->target_stack_, statement); |
2425 | 2405 |
|
2426 | 2406 |
Expect(Token::SWITCH, CHECK_OK); |
... | ... | |
2447 | 2427 |
// 'throw' Expression ';' |
2448 | 2428 |
|
2449 | 2429 |
Expect(Token::THROW, CHECK_OK); |
2450 |
int pos = scanner().location().beg_pos;
|
|
2430 |
int pos = position();
|
|
2451 | 2431 |
if (scanner().HasAnyLineTerminatorBeforeNext()) { |
2452 | 2432 |
ReportMessage("newline_after_throw", Vector<const char*>::empty()); |
2453 | 2433 |
*ok = false; |
... | ... | |
2456 | 2436 |
Expression* exception = ParseExpression(true, CHECK_OK); |
2457 | 2437 |
ExpectSemicolon(CHECK_OK); |
2458 | 2438 |
|
2459 |
return factory()->NewExpressionStatement(factory()->NewThrow(exception, pos)); |
|
2439 |
return factory()->NewExpressionStatement( |
|
2440 |
factory()->NewThrow(exception, pos), pos); |
|
2460 | 2441 |
} |
2461 | 2442 |
|
2462 | 2443 |
|
... | ... | |
2473 | 2454 |
// 'finally' Block |
2474 | 2455 |
|
2475 | 2456 |
Expect(Token::TRY, CHECK_OK); |
2457 |
int pos = position(); |
|
2476 | 2458 |
|
2477 | 2459 |
TargetCollector try_collector(zone()); |
2478 | 2460 |
Block* try_block; |
... | ... | |
2544 | 2526 |
ASSERT(catch_scope != NULL && catch_variable != NULL); |
2545 | 2527 |
int index = current_function_state_->NextHandlerIndex(); |
2546 | 2528 |
TryCatchStatement* statement = factory()->NewTryCatchStatement( |
2547 |
index, try_block, catch_scope, catch_variable, catch_block); |
|
2529 |
index, try_block, catch_scope, catch_variable, catch_block, |
|
2530 |
RelocInfo::kNoPosition); |
|
2548 | 2531 |
statement->set_escaping_targets(try_collector.targets()); |
2549 |
try_block = factory()->NewBlock(NULL, 1, false); |
|
2532 |
try_block = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
|
|
2550 | 2533 |
try_block->AddStatement(statement, zone()); |
2551 | 2534 |
catch_block = NULL; // Clear to indicate it's been handled. |
2552 | 2535 |
} |
... | ... | |
2557 | 2540 |
ASSERT(catch_scope != NULL && catch_variable != NULL); |
2558 | 2541 |
int index = current_function_state_->NextHandlerIndex(); |
2559 | 2542 |
result = factory()->NewTryCatchStatement( |
2560 |
index, try_block, catch_scope, catch_variable, catch_block); |
|
2543 |
index, try_block, catch_scope, catch_variable, catch_block, pos);
|
|
2561 | 2544 |
} else { |
2562 | 2545 |
ASSERT(finally_block != NULL); |
2563 | 2546 |
int index = current_function_state_->NextHandlerIndex(); |
2564 |
result = factory()->NewTryFinallyStatement(index, try_block, finally_block); |
|
2547 |
result = factory()->NewTryFinallyStatement( |
|
2548 |
index, try_block, finally_block, pos); |
|
2565 | 2549 |
// Combine the jump targets of the try block and the possible catch block. |
2566 | 2550 |
try_collector.targets()->AddAll(*catch_collector.targets(), zone()); |
2567 | 2551 |
} |
... | ... | |
2576 | 2560 |
// DoStatement :: |
2577 | 2561 |
// 'do' Statement 'while' '(' Expression ')' ';' |
2578 | 2562 |
|
2579 |
DoWhileStatement* loop = factory()->NewDoWhileStatement(labels); |
|
2563 |
DoWhileStatement* loop = |
|
2564 |
factory()->NewDoWhileStatement(labels, peek_position()); |
|
2580 | 2565 |
Target target(&this->target_stack_, loop); |
2581 | 2566 |
|
2582 | 2567 |
Expect(Token::DO, CHECK_OK); |
... | ... | |
2584 | 2569 |
Expect(Token::WHILE, CHECK_OK); |
2585 | 2570 |
Expect(Token::LPAREN, CHECK_OK); |
2586 | 2571 |
|
2587 |
if (loop != NULL) { |
|
2588 |
int position = scanner().location().beg_pos; |
|
2589 |
loop->set_condition_position(position); |
|
2590 |
} |
|
2591 |
|
|
2592 | 2572 |
Expression* cond = ParseExpression(true, CHECK_OK); |
2593 | 2573 |
Expect(Token::RPAREN, CHECK_OK); |
2594 | 2574 |
|
... | ... | |
2607 | 2587 |
// WhileStatement :: |
2608 | 2588 |
// 'while' '(' Expression ')' Statement |
2609 | 2589 |
|
2610 |
WhileStatement* loop = factory()->NewWhileStatement(labels); |
|
2590 |
WhileStatement* loop = factory()->NewWhileStatement(labels, peek_position());
|
|
2611 | 2591 |
Target target(&this->target_stack_, loop); |
2612 | 2592 |
|
2613 | 2593 |
Expect(Token::WHILE, CHECK_OK); |
... | ... | |
2666 | 2646 |
// var result = iterator.next(); |
2667 | 2647 |
{ |
2668 | 2648 |
Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
2669 |
Expression* next_literal = |
|
2670 |
factory()->NewLiteral(heap_factory->next_string());
|
|
2649 |
Expression* next_literal = factory()->NewLiteral(
|
|
2650 |
heap_factory->next_string(), RelocInfo::kNoPosition);
|
|
2671 | 2651 |
Expression* next_property = factory()->NewProperty( |
2672 | 2652 |
iterator_proxy, next_literal, RelocInfo::kNoPosition); |
2673 | 2653 |
ZoneList<Expression*>* next_arguments = |
... | ... | |
2681 | 2661 |
|
2682 | 2662 |
// result.done |
2683 | 2663 |
{ |
2684 |
Expression* done_literal = |
|
2685 |
factory()->NewLiteral(heap_factory->done_string());
|
|
2664 |
Expression* done_literal = factory()->NewLiteral(
|
|
2665 |
heap_factory->done_string(), RelocInfo::kNoPosition);
|
|
2686 | 2666 |
Expression* result_proxy = factory()->NewVariableProxy(result); |
2687 | 2667 |
result_done = factory()->NewProperty( |
2688 | 2668 |
result_proxy, done_literal, RelocInfo::kNoPosition); |
... | ... | |
2690 | 2670 |
|
2691 | 2671 |
// each = result.value |
2692 | 2672 |
{ |
2693 |
Expression* value_literal = |
|
2694 |
factory()->NewLiteral(heap_factory->value_string());
|
|
2673 |
Expression* value_literal = factory()->NewLiteral(
|
|
2674 |
heap_factory->value_string(), RelocInfo::kNoPosition);
|
|
2695 | 2675 |
Expression* result_proxy = factory()->NewVariableProxy(result); |
2696 | 2676 |
Expression* result_value = factory()->NewProperty( |
2697 | 2677 |
result_proxy, value_literal, RelocInfo::kNoPosition); |
... | ... | |
2711 | 2691 |
// ForStatement :: |
2712 | 2692 |
// 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement |
2713 | 2693 |
|
2694 |
int pos = peek_position(); |
|
2714 | 2695 |
Statement* init = NULL; |
2715 | 2696 |
|
2716 | 2697 |
// Create an in-between scope for let-bound iteration variables. |
... | ... | |
2735 | 2716 |
if (!name.is_null() && CheckInOrOf(accept_OF, &mode)) { |
2736 | 2717 |
Interface* interface = |
2737 | 2718 |
is_const ? Interface::NewConst() : Interface::NewValue(); |
2738 |
ForEachStatement* loop = factory()->NewForEachStatement(mode, labels); |
|
2719 |
ForEachStatement* loop = |
|
2720 |
factory()->NewForEachStatement(mode, labels, pos); |
|
2739 | 2721 |
Target target(&this->target_stack_, loop); |
2740 | 2722 |
|
2741 | 2723 |
Expression* enumerable = ParseExpression(true, CHECK_OK); |
... | ... | |
2745 | 2727 |
top_scope_->NewUnresolved(factory(), name, interface); |
2746 | 2728 |
Statement* body = ParseStatement(NULL, CHECK_OK); |
2747 | 2729 |
InitializeForEachStatement(loop, each, enumerable, body); |
2748 |
Block* result = factory()->NewBlock(NULL, 2, false); |
|
2730 |
Block* result = |
|
2731 |
factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); |
|
2749 | 2732 |
result->AddStatement(variable_statement, zone()); |
2750 | 2733 |
result->AddStatement(loop, zone()); |
2751 | 2734 |
top_scope_ = saved_scope; |
... | ... | |
2789 | 2772 |
Handle<String> tempname = heap_factory->InternalizeString(tempstr); |
2790 | 2773 |
Variable* temp = top_scope_->DeclarationScope()->NewTemporary(tempname); |
2791 | 2774 |
VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); |
2792 |
ForEachStatement* loop = factory()->NewForEachStatement(mode, labels); |
|
2775 |
ForEachStatement* loop = |
|
2776 |
factory()->NewForEachStatement(mode, labels, pos); |
|
2793 | 2777 |
Target target(&this->target_stack_, loop); |
2794 | 2778 |
|
2795 | 2779 |
// The expression does not see the loop variable. |
... | ... | |
2801 | 2785 |
VariableProxy* each = |
2802 | 2786 |
top_scope_->NewUnresolved(factory(), name, Interface::NewValue()); |
2803 | 2787 |
Statement* body = ParseStatement(NULL, CHECK_OK); |
2804 |
Block* body_block = factory()->NewBlock(NULL, 3, false); |
|
2788 |
Block* body_block = |
|
2789 |
factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition); |
|
2805 | 2790 |
Assignment* assignment = factory()->NewAssignment( |
2806 | 2791 |
Token::ASSIGN, each, temp_proxy, RelocInfo::kNoPosition); |
2807 |
Statement* assignment_statement = |
|
2808 |
factory()->NewExpressionStatement(assignment);
|
|
2792 |
Statement* assignment_statement = factory()->NewExpressionStatement(
|
|
2793 |
assignment, RelocInfo::kNoPosition);
|
|
2809 | 2794 |
body_block->AddStatement(variable_statement, zone()); |
2810 | 2795 |
body_block->AddStatement(assignment_statement, zone()); |
2811 | 2796 |
body_block->AddStatement(body, zone()); |
... | ... | |
2835 | 2820 |
isolate()->factory()->invalid_lhs_in_for_in_string(); |
2836 | 2821 |
expression = NewThrowReferenceError(message); |
2837 | 2822 |
} |
2838 |
ForEachStatement* loop = factory()->NewForEachStatement(mode, labels); |
|
2823 |
ForEachStatement* loop = |
|
2824 |
factory()->NewForEachStatement(mode, labels, pos); |
|
2839 | 2825 |
Target target(&this->target_stack_, loop); |
2840 | 2826 |
|
2841 | 2827 |
Expression* enumerable = ParseExpression(true, CHECK_OK); |
... | ... | |
2851 | 2837 |
return loop; |
2852 | 2838 |
|
2853 | 2839 |
} else { |
2854 |
init = factory()->NewExpressionStatement(expression); |
|
2840 |
init = factory()->NewExpressionStatement( |
|
2841 |
expression, RelocInfo::kNoPosition); |
|
2855 | 2842 |
} |
2856 | 2843 |
} |
2857 | 2844 |
} |
2858 | 2845 |
|
2859 | 2846 |
// Standard 'for' loop |
2860 |
ForStatement* loop = factory()->NewForStatement(labels); |
|
2847 |
ForStatement* loop = factory()->NewForStatement(labels, pos);
|
|
2861 | 2848 |
Target target(&this->target_stack_, loop); |
2862 | 2849 |
|
2863 | 2850 |
// Parsed initializer at this point. |
... | ... | |
2872 | 2859 |
Statement* next = NULL; |
2873 | 2860 |
if (peek() != Token::RPAREN) { |
2874 | 2861 |
Expression* exp = ParseExpression(true, CHECK_OK); |
2875 |
next = factory()->NewExpressionStatement(exp); |
|
2862 |
next = factory()->NewExpressionStatement(exp, RelocInfo::kNoPosition);
|
|
2876 | 2863 |
} |
2877 | 2864 |
Expect(Token::RPAREN, CHECK_OK); |
2878 | 2865 |
|
... | ... | |
2892 | 2879 |
// for (; c; n) b |
2893 | 2880 |
// } |
2894 | 2881 |
ASSERT(init != NULL); |
2895 |
Block* result = factory()->NewBlock(NULL, 2, false); |
|
2882 |
Block* result = factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition);
|
|
2896 | 2883 |
result->AddStatement(init, zone()); |
2897 | 2884 |
result->AddStatement(loop, zone()); |
2898 | 2885 |
result->set_scope(for_scope); |
... | ... | |
2914 | 2901 |
Expression* result = ParseAssignmentExpression(accept_IN, CHECK_OK); |
2915 | 2902 |
while (peek() == Token::COMMA) { |
2916 | 2903 |
Expect(Token::COMMA, CHECK_OK); |
2917 |
int position = scanner().location().beg_pos;
|
|
2904 |
int pos = position();
|
|
2918 | 2905 |
Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); |
2919 |
result = |
|
2920 |
factory()->NewBinaryOperation(Token::COMMA, result, right, position); |
|
2906 |
result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); |
|
2921 | 2907 |
} |
2922 | 2908 |
return result; |
2923 | 2909 |
} |
... | ... | |
2961 | 2947 |
MarkAsLValue(expression); |
2962 | 2948 |
|
2963 | 2949 |
Token::Value op = Next(); // Get assignment operator. |
2964 |
int pos = scanner().location().beg_pos;
|
|
2950 |
int pos = position();
|
|
2965 | 2951 |
Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); |
2966 | 2952 |
|
2967 | 2953 |
// TODO(1231235): We try to estimate the set of properties set by |
... | ... | |
3005 | 2991 |
Expression* Parser::ParseYieldExpression(bool* ok) { |
3006 | 2992 |
// YieldExpression :: |
3007 | 2993 |
// 'yield' '*'? AssignmentExpression |
3008 |
int position = scanner().peek_location().beg_pos;
|
|
2994 |
int pos = peek_position();
|
|
3009 | 2995 |
Expect(Token::YIELD, CHECK_OK); |
3010 | 2996 |
Yield::Kind kind = |
3011 | 2997 |
Check(Token::MUL) ? Yield::DELEGATING : Yield::SUSPEND; |
3012 | 2998 |
Expression* generator_object = factory()->NewVariableProxy( |
3013 | 2999 |
current_function_state_->generator_object_variable()); |
3014 | 3000 |
Expression* expression = ParseAssignmentExpression(false, CHECK_OK); |
3015 |
Yield* yield = |
|
3016 |
factory()->NewYield(generator_object, expression, kind, position); |
|
3001 |
Yield* yield = factory()->NewYield(generator_object, expression, kind, pos); |
|
3017 | 3002 |
if (kind == Yield::DELEGATING) { |
3018 | 3003 |
yield->set_index(current_function_state_->NextHandlerIndex()); |
3019 | 3004 |
} |
... | ... | |
3027 | 3012 |
// LogicalOrExpression |
3028 | 3013 |
// LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression |
3029 | 3014 |
|
3015 |
int pos = peek_position(); |
|
3030 | 3016 |
// We start using the binary expression parser for prec >= 4 only! |
3031 | 3017 |
Expression* expression = ParseBinaryExpression(4, accept_IN, CHECK_OK); |
3032 | 3018 |
if (peek() != Token::CONDITIONAL) return expression; |
... | ... | |
3034 | 3020 |
// In parsing the first assignment expression in conditional |
3035 | 3021 |
// expressions we always accept the 'in' keyword; see ECMA-262, |
3036 | 3022 |
// section 11.12, page 58. |
3037 |
int left_position = scanner().peek_location().beg_pos; |
|
3038 | 3023 |
Expression* left = ParseAssignmentExpression(true, CHECK_OK); |
3039 | 3024 |
Expect(Token::COLON, CHECK_OK); |
3040 |
int right_position = scanner().peek_location().beg_pos; |
|
3041 | 3025 |
Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); |
3042 |
return factory()->NewConditional( |
|
3043 |
expression, left, right, left_position, right_position); |
|
3026 |
return factory()->NewConditional(expression, left, right, pos); |
|
3044 | 3027 |
} |
3045 | 3028 |
|
3046 | 3029 |
|
3047 |
static int Precedence(Token::Value tok, bool accept_IN) {
|
|
3030 |
int ParserBase::Precedence(Token::Value tok, bool accept_IN) {
|
|
3048 | 3031 |
if (tok == Token::IN && !accept_IN) |
3049 | 3032 |
return 0; // 0 precedence will terminate binary expression parsing |
3050 | 3033 |
|
... | ... | |
3060 | 3043 |
// prec1 >= 4 |
3061 | 3044 |
while (Precedence(peek(), accept_IN) == prec1) { |
3062 | 3045 |
Token::Value op = Next(); |
3063 |
int position = scanner().location().beg_pos;
|
|
3046 |
int pos = position();
|
|
3064 | 3047 |
Expression* y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); |
3065 | 3048 |
|
3066 | 3049 |
// Compute some expressions involving only number literals. |
... | ... | |
3071 | 3054 |
|
3072 | 3055 |
switch (op) { |
3073 | 3056 |
case Token::ADD: |
3074 |
x = factory()->NewNumberLiteral(x_val + y_val); |
|
3057 |
x = factory()->NewNumberLiteral(x_val + y_val, pos);
|
|
3075 | 3058 |
continue; |
3076 | 3059 |
case Token::SUB: |
3077 |
x = factory()->NewNumberLiteral(x_val - y_val); |
|
3060 |
x = factory()->NewNumberLiteral(x_val - y_val, pos);
|
|
3078 | 3061 |
continue; |
3079 | 3062 |
case Token::MUL: |
3080 |
x = factory()->NewNumberLiteral(x_val * y_val); |
|
3063 |
x = factory()->NewNumberLiteral(x_val * y_val, pos);
|
|
3081 | 3064 |
continue; |
3082 | 3065 |
case Token::DIV: |
3083 |
x = factory()->NewNumberLiteral(x_val / y_val); |
|
3066 |
x = factory()->NewNumberLiteral(x_val / y_val, pos);
|
|
3084 | 3067 |
continue; |
3085 | 3068 |
case Token::BIT_OR: { |
3086 | 3069 |
int value = DoubleToInt32(x_val) | DoubleToInt32(y_val); |
3087 |
x = factory()->NewNumberLiteral(value); |
|
3070 |
x = factory()->NewNumberLiteral(value, pos);
|
|
3088 | 3071 |
continue; |
3089 | 3072 |
} |
3090 | 3073 |
case Token::BIT_AND: { |
3091 | 3074 |
int value = DoubleToInt32(x_val) & DoubleToInt32(y_val); |
3092 |
x = factory()->NewNumberLiteral(value); |
|
3075 |
x = factory()->NewNumberLiteral(value, pos);
|
|
3093 | 3076 |
continue; |
3094 | 3077 |
} |
3095 | 3078 |
case Token::BIT_XOR: { |
3096 | 3079 |
int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val); |
3097 |
x = factory()->NewNumberLiteral(value); |
|
3080 |
x = factory()->NewNumberLiteral(value, pos);
|
|
3098 | 3081 |
continue; |
3099 | 3082 |
} |
3100 | 3083 |
case Token::SHL: { |
3101 | 3084 |
int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f); |
3102 |
x = factory()->NewNumberLiteral(value); |
|
3085 |
x = factory()->NewNumberLiteral(value, pos);
|
|
3103 | 3086 |
continue; |
3104 | 3087 |
} |
3105 | 3088 |
case Token::SHR: { |
3106 | 3089 |
uint32_t shift = DoubleToInt32(y_val) & 0x1f; |
3107 | 3090 |
uint32_t value = DoubleToUint32(x_val) >> shift; |
3108 |
x = factory()->NewNumberLiteral(value); |
|
3091 |
x = factory()->NewNumberLiteral(value, pos);
|
|
3109 | 3092 |
continue; |
3110 | 3093 |
} |
3111 | 3094 |
case Token::SAR: { |
3112 | 3095 |
uint32_t shift = DoubleToInt32(y_val) & 0x1f; |
3113 | 3096 |
int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift); |
3114 |
x = factory()->NewNumberLiteral(value); |
|
3097 |
x = factory()->NewNumberLiteral(value, pos);
|
|
3115 | 3098 |
continue; |
3116 | 3099 |
} |
3117 | 3100 |
default: |
... | ... | |
3130 | 3113 |
case Token::NE_STRICT: cmp = Token::EQ_STRICT; break; |
3131 | 3114 |
default: break; |
3132 | 3115 |
} |
3133 |
x = factory()->NewCompareOperation(cmp, x, y, position);
|
|
3116 |
x = factory()->NewCompareOperation(cmp, x, y, pos); |
|
3134 | 3117 |
if (cmp != op) { |
3135 | 3118 |
// The comparison was negated - add a NOT. |
3136 |
x = factory()->NewUnaryOperation(Token::NOT, x, position);
|
|
3119 |
x = factory()->NewUnaryOperation(Token::NOT, x, pos); |
|
3137 | 3120 |
} |
3138 | 3121 |
|
3139 | 3122 |
} else { |
3140 | 3123 |
// We have a "normal" binary operation. |
3141 |
x = factory()->NewBinaryOperation(op, x, y, position);
|
|
3124 |
x = factory()->NewBinaryOperation(op, x, y, pos); |
|
3142 | 3125 |
} |
3143 | 3126 |
} |
3144 | 3127 |
} |
... | ... | |
3162 | 3145 |
Token::Value op = peek(); |
3163 | 3146 |
if (Token::IsUnaryOp(op)) { |
3164 | 3147 |
op = Next(); |
3165 |
int position = scanner().location().beg_pos;
|
|
3148 |
int pos = position();
|
|
3166 | 3149 |
Expression* expression = ParseUnaryExpression(CHECK_OK); |
3167 | 3150 |
|
3168 | 3151 |
if (expression != NULL && (expression->AsLiteral() != NULL)) { |
... | ... | |
3170 | 3153 |
if (op == Token::NOT) { |
3171 | 3154 |
// Convert the literal to a boolean condition and negate it. |
3172 | 3155 |
bool condition = literal->BooleanValue(); |
3173 |
Handle<Object> result(isolate()->heap()->ToBoolean(!condition), |
|
3174 |
isolate()); |
|
3175 |
return factory()->NewLiteral(result); |
|
3156 |
Handle<Object> result = isolate()->factory()->ToBoolean(!condition); |
|
3157 |
return factory()->NewLiteral(result, pos); |
|
3176 | 3158 |
} else if (literal->IsNumber()) { |
3177 | 3159 |
// Compute some expressions involving only number literals. |
3178 | 3160 |
double value = literal->Number(); |
... | ... | |
3180 | 3162 |
case Token::ADD: |
3181 | 3163 |
return expression; |
3182 | 3164 |
case Token::SUB: |
3183 |
return factory()->NewNumberLiteral(-value); |
|
3165 |
return factory()->NewNumberLiteral(-value, pos);
|
|
3184 | 3166 |
case Token::BIT_NOT: |
3185 |
return factory()->NewNumberLiteral(~DoubleToInt32(value)); |
|
3167 |
return factory()->NewNumberLiteral(~DoubleToInt32(value), pos);
|
|
3186 | 3168 |
default: |
3187 | 3169 |
break; |
3188 | 3170 |
} |
... | ... | |
3205 | 3187 |
if (op == Token::ADD) { |
3206 | 3188 |
return factory()->NewBinaryOperation(Token::MUL, |
3207 | 3189 |
expression, |
3208 |
factory()->NewNumberLiteral(1), |
|
3209 |
position);
|
|
3190 |
factory()->NewNumberLiteral(1, pos),
|
|
3191 |
pos); |
|
3210 | 3192 |
} |
3211 | 3193 |
// The same idea for '-foo' => 'foo*(-1)'. |
3212 | 3194 |
if (op == Token::SUB) { |
3213 | 3195 |
return factory()->NewBinaryOperation(Token::MUL, |
3214 | 3196 |
expression, |
3215 |
factory()->NewNumberLiteral(-1), |
|
3216 |
position);
|
|
3197 |
factory()->NewNumberLiteral(-1, pos),
|
|
3198 |
pos); |
|
3217 | 3199 |
} |
3218 | 3200 |
// ...and one more time for '~foo' => 'foo^(~0)'. |
3219 | 3201 |
if (op == Token::BIT_NOT) { |
3220 | 3202 |
return factory()->NewBinaryOperation(Token::BIT_XOR, |
3221 | 3203 |
expression, |
3222 |
factory()->NewNumberLiteral(~0), |
|
3223 |
position);
|
|
3204 |
factory()->NewNumberLiteral(~0, pos),
|
|
3205 |
pos); |
|
3224 | 3206 |
} |
3225 | 3207 |
|
3226 |
return factory()->NewUnaryOperation(op, expression, position);
|
|
3208 |
return factory()->NewUnaryOperation(op, expression, pos); |
|
3227 | 3209 |
|
3228 | 3210 |
} else if (Token::IsCountOp(op)) { |
3229 | 3211 |
op = Next(); |
... | ... | |
3244 | 3226 |
} |
3245 | 3227 |
MarkAsLValue(expression); |
3246 | 3228 |
|
3247 |
int position = scanner().location().beg_pos; |
|
3248 | 3229 |
return factory()->NewCountOperation(op, |
3249 | 3230 |
true /* prefix */, |
3250 | 3231 |
expression, |
3251 |
position); |
|
3232 |
position());
|
|
3252 | 3233 |
|
3253 | 3234 |
} else { |
3254 | 3235 |
return ParsePostfixExpression(ok); |
... | ... | |
3280 | 3261 |
MarkAsLValue(expression); |
3281 | 3262 |
|
3282 | 3263 |
Token::Value next = Next(); |
3283 |
int position = scanner().location().beg_pos; |
|
3284 | 3264 |
expression = |
3285 | 3265 |
factory()->NewCountOperation(next, |
3286 | 3266 |
false /* postfix */, |
3287 | 3267 |
expression, |
3288 |
position); |
|
3268 |
position());
|
|
3289 | 3269 |
} |
3290 | 3270 |
return expression; |
3291 | 3271 |
} |
... | ... | |
3306 | 3286 |
switch (peek()) { |
3307 | 3287 |
case Token::LBRACK: { |
3308 | 3288 |
Consume(Token::LBRACK); |
3309 |
int pos = scanner().location().beg_pos;
|
|
3289 |
int pos = position();
|
|
3310 | 3290 |
Expression* index = ParseExpression(true, CHECK_OK); |
3311 | 3291 |
result = factory()->NewProperty(result, index, pos); |
3312 | 3292 |
Expect(Token::RBRACK, CHECK_OK); |
... | ... | |
3318 | 3298 |
if (scanner().current_token() == Token::IDENTIFIER) { |
3319 | 3299 |
// For call of an identifier we want to report position of |
3320 | 3300 |
// the identifier as position of the call in the stack trace. |
3321 |
pos = scanner().location().beg_pos;
|
|
3301 |
pos = position();
|
|
3322 | 3302 |
} else { |
3323 | 3303 |
// For other kinds of calls we record position of the parenthesis as |
3324 | 3304 |
// position of the call. Note that this is extremely important for |
3325 | 3305 |
// expressions of the form function(){...}() for which call position |
3326 | 3306 |
// should not point to the closing brace otherwise it will intersect |
3327 | 3307 |
// with positions recorded for function literal and confuse debugger. |
3328 |
pos = scanner().peek_location().beg_pos;
|
|
3308 |
pos = peek_position();
|
|
3329 | 3309 |
// Also the trailing parenthesis are a hint that the function will |
3330 | 3310 |
// be called immediately. If we happen to have parsed a preceding |
3331 | 3311 |
// function literal eagerly, we can also compile it eagerly. |
... | ... | |
3354 | 3334 |
|
3355 | 3335 |
case Token::PERIOD: { |
3356 | 3336 |
Consume(Token::PERIOD); |
3357 |
int pos = scanner().location().beg_pos;
|
|
3337 |
int pos = position();
|
|
3358 | 3338 |
Handle<String> name = ParseIdentifierName(CHECK_OK); |
3359 |
result = |
|
3360 |
factory()->NewProperty(result, factory()->NewLiteral(name), pos);
|
|
3339 |
result = factory()->NewProperty(
|
|
3340 |
result, factory()->NewLiteral(name, pos), pos);
|
|
3361 | 3341 |
if (fni_ != NULL) fni_->PushLiteralName(name); |
3362 | 3342 |
break; |
3363 | 3343 |
} |
... | ... | |
3382 | 3362 |
// member expression parser, which is only allowed to match argument |
3383 | 3363 |
// lists as long as it has 'new' prefixes left |
3384 | 3364 |
Expect(Token::NEW, CHECK_OK); |
3385 |
PositionStack::Element pos(stack, scanner().location().beg_pos);
|
|
3365 |
PositionStack::Element pos(stack, position());
|
|
3386 | 3366 |
|
3387 | 3367 |
Expression* result; |
3388 | 3368 |
if (peek() == Token::NEW) { |
... | ... | |
3421 | 3401 |
Expression* result = NULL; |
3422 | 3402 |
if (peek() == Token::FUNCTION) { |
3423 | 3403 |
Expect(Token::FUNCTION, CHECK_OK); |
3424 |
int function_token_position = scanner().location().beg_pos;
|
|
3404 |
int function_token_position = position();
|
|
3425 | 3405 |
bool is_generator = allow_generators() && Check(Token::MUL); |
3426 | 3406 |
Handle<String> name; |
3427 | 3407 |
bool is_strict_reserved_name = false; |
... | ... | |
3446 | 3426 |
switch (peek()) { |
3447 | 3427 |
case Token::LBRACK: { |
3448 | 3428 |
Consume(Token::LBRACK); |
3449 |
int pos = scanner().location().beg_pos;
|
|
3429 |
int pos = position();
|
|
3450 | 3430 |
Expression* index = ParseExpression(true, CHECK_OK); |
3451 | 3431 |
result = factory()->NewProperty(result, index, pos); |
3452 | 3432 |
if (fni_ != NULL) { |
... | ... | |
3462 | 3442 |
} |
3463 | 3443 |
case Token::PERIOD: { |
3464 | 3444 |
Consume(Token::PERIOD); |
3465 |
int pos = scanner().location().beg_pos;
|
|
3445 |
int pos = position();
|
|
3466 | 3446 |
Handle<String> name = ParseIdentifierName(CHECK_OK); |
3467 |
result = |
|
3468 |
factory()->NewProperty(result, factory()->NewLiteral(name), pos);
|
|
3447 |
result = factory()->NewProperty(
|
|
3448 |
result, factory()->NewLiteral(name, pos), pos);
|
|
3469 | 3449 |
if (fni_ != NULL) fni_->PushLiteralName(name); |
3470 | 3450 |
break; |
3471 | 3451 |
} |
... | ... | |
3473 | 3453 |
if ((stack == NULL) || stack->is_empty()) return result; |
3474 | 3454 |
// Consume one of the new prefixes (already parsed). |
3475 | 3455 |
ZoneList<Expression*>* args = ParseArguments(CHECK_OK); |
3476 |
int last = stack->pop();
|
|
3477 |
result = factory()->NewCallNew(result, args, last);
|
|
3456 |
int pos = stack->pop();
|
|
3457 |
result = factory()->NewCallNew(result, args, pos);
|
|
3478 | 3458 |
break; |
3479 | 3459 |
} |
3480 | 3460 |
default: |
... | ... | |
3491 | 3471 |
// DebuggerStatement :: |
3492 | 3472 |
// 'debugger' ';' |
3493 | 3473 |
|
3474 |
int pos = peek_position(); |
|
3494 | 3475 |
Expect(Token::DEBUGGER, CHECK_OK); |
3495 | 3476 |
ExpectSemicolon(CHECK_OK); |
3496 |
return factory()->NewDebuggerStatement(); |
|
3477 |
return factory()->NewDebuggerStatement(pos);
|
|
3497 | 3478 |
} |
3498 | 3479 |
|
3499 | 3480 |
|
... | ... | |
3501 | 3482 |
// We don't report stack overflows here, to avoid increasing the |
3502 | 3483 |
// stack depth even further. Instead we report it after parsing is |
3503 | 3484 |
// over, in ParseProgram/ParseJson. |
3504 |
if (token == Token::ILLEGAL && stack_overflow_) return;
|
|
3485 |
if (token == Token::ILLEGAL && stack_overflow()) return;
|
|
3505 | 3486 |
// Four of the tokens are treated specially |
3506 | 3487 |
switch (token) { |
3507 | 3488 |
case Token::EOS: |
... | ... | |
3555 | 3536 |
// RegExpLiteral |
3556 | 3537 |
// '(' Expression ')' |
3557 | 3538 |
|
3539 |
int pos = peek_position(); |
|
3558 | 3540 |
Expression* result = NULL; |
3559 | 3541 |
switch (peek()) { |
3560 | 3542 |
case Token::THIS: { |
... | ... | |
3565 | 3547 |
|
3566 | 3548 |
case Token::NULL_LITERAL: |
3567 | 3549 |
Consume(Token::NULL_LITERAL); |
3568 |
result = factory()->NewLiteral(isolate()->factory()->null_value()); |
|
3550 |
result = factory()->NewLiteral(isolate()->factory()->null_value(), pos);
|
|
3569 | 3551 |
break; |
3570 | 3552 |
|
3571 | 3553 |
case Token::TRUE_LITERAL: |
3572 | 3554 |
Consume(Token::TRUE_LITERAL); |
3573 |
result = factory()->NewLiteral(isolate()->factory()->true_value()); |
|
3555 |
result = factory()->NewLiteral(isolate()->factory()->true_value(), pos);
|
|
3574 | 3556 |
break; |
3575 | 3557 |
|
3576 | 3558 |
case Token::FALSE_LITERAL: |
3577 | 3559 |
Consume(Token::FALSE_LITERAL); |
3578 |
result = factory()->NewLiteral(isolate()->factory()->false_value()); |
|
3560 |
result = factory()->NewLiteral(isolate()->factory()->false_value(), pos);
|
|
3579 | 3561 |
break; |
3580 | 3562 |
|
3581 | 3563 |
case Token::IDENTIFIER: |
... | ... | |
3589 | 3571 |
PrintF("# Variable %s ", name->ToAsciiArray()); |
3590 | 3572 |
#endif |
3591 | 3573 |
Interface* interface = Interface::NewUnknown(zone()); |
3592 |
result = top_scope_->NewUnresolved( |
|
3593 |
factory(), name, interface, scanner().location().beg_pos); |
|
3574 |
result = top_scope_->NewUnresolved(factory(), name, interface, pos); |
|
3594 | 3575 |
break; |
3595 | 3576 |
} |
3596 | 3577 |
|
... | ... | |
3601 | 3582 |
scanner().literal_ascii_string(), |
3602 | 3583 |
ALLOW_HEX | ALLOW_OCTAL | |
3603 | 3584 |
ALLOW_IMPLICIT_OCTAL | ALLOW_BINARY); |
3604 |
result = factory()->NewNumberLiteral(value); |
|
3585 |
result = factory()->NewNumberLiteral(value, pos);
|
|
3605 | 3586 |
break; |
3606 | 3587 |
} |
3607 | 3588 |
|
3608 | 3589 |
case Token::STRING: { |
3609 | 3590 |
Consume(Token::STRING); |
3610 | 3591 |
Handle<String> symbol = GetSymbol(); |
3611 |
result = factory()->NewLiteral(symbol); |
|
3592 |
result = factory()->NewLiteral(symbol, pos);
|
|
3612 | 3593 |
if (fni_ != NULL) fni_->PushLiteralName(symbol); |
3613 | 3594 |
break; |
3614 | 3595 |
} |
... | ... | |
3662 | 3643 |
// ArrayLiteral :: |
3663 | 3644 |
// '[' Expression? (',' Expression?)* ']' |
3664 | 3645 |
|
3646 |
int pos = peek_position(); |
|
3665 | 3647 |
ZoneList<Expression*>* values = new(zone()) ZoneList<Expression*>(4, zone()); |
3666 | 3648 |
Expect(Token::LBRACK, CHECK_OK); |
3667 | 3649 |
while (peek() != Token::RBRACK) { |
3668 | 3650 |
Expression* elem; |
3669 | 3651 |
if (peek() == Token::COMMA) { |
3670 |
elem = GetLiteralTheHole(); |
|
3652 |
elem = GetLiteralTheHole(peek_position());
|
|
3671 | 3653 |
} else { |
3672 | 3654 |
elem = ParseAssignmentExpression(true, CHECK_OK); |
3673 | 3655 |
} |
... | ... | |
3729 | 3711 |
literals->set(1, *element_values); |
3730 | 3712 |
|
3731 | 3713 |
return factory()->NewArrayLiteral( |
3732 |
literals, values, literal_index, is_simple, depth); |
|
3714 |
literals, values, literal_index, is_simple, depth, pos);
|
|
3733 | 3715 |
} |
3734 | 3716 |
|
3735 | 3717 |
|
... | ... | |
3793 | 3775 |
} |
3794 | 3776 |
|
3795 | 3777 |
|
3796 |
// Validation per 11.1.5 Object Initialiser |
|
3797 |
class ObjectLiteralPropertyChecker { |
|
3798 |
public: |
|
3799 |
ObjectLiteralPropertyChecker(Parser* parser, LanguageMode language_mode) : |
|
3800 |
props_(Literal::Match), |
|
3801 |
parser_(parser), |
|
3802 |
language_mode_(language_mode) { |
|
3803 |
} |
|
3804 |
|
|
3805 |
void CheckProperty( |
|
3806 |
ObjectLiteral::Property* property, |
|
3807 |
Scanner::Location loc, |
|
3808 |
bool* ok); |
|
3809 |
|
|
3810 |
private: |
|
3811 |
enum PropertyKind { |
|
3812 |
kGetAccessor = 0x01, |
|
3813 |
kSetAccessor = 0x02, |
|
3814 |
kAccessor = kGetAccessor | kSetAccessor, |
|
3815 |
kData = 0x04 |
|
3816 |
}; |
|
3817 |
|
|
3818 |
static intptr_t GetPropertyKind(ObjectLiteral::Property* property) { |
|
3819 |
switch (property->kind()) { |
|
3820 |
case ObjectLiteral::Property::GETTER: |
|
3821 |
return kGetAccessor; |
|
3822 |
case ObjectLiteral::Property::SETTER: |
|
3823 |
return kSetAccessor; |
|
3824 |
default: |
|
3825 |
return kData; |
|
3826 |
} |
|
3827 |
} |
|
3828 |
|
|
3829 |
HashMap props_; |
|
3830 |
Parser* parser_; |
|
3831 |
LanguageMode language_mode_; |
|
3832 |
}; |
|
3833 |
|
|
3834 |
|
|
3835 |
void ObjectLiteralPropertyChecker::CheckProperty( |
|
3836 |
ObjectLiteral::Property* property, |
|
3837 |
Scanner::Location loc, |
|
3838 |
bool* ok) { |
|
3839 |
ASSERT(property != NULL); |
|
3840 |
Literal* literal = property->key(); |
|
3841 |
HashMap::Entry* entry = props_.Lookup(literal, literal->Hash(), true); |
|
3842 |
intptr_t prev = reinterpret_cast<intptr_t> (entry->value); |
|
3843 |
intptr_t curr = GetPropertyKind(property); |
|
3844 |
|
|
3845 |
// Duplicate data properties are illegal in strict or extended mode. |
|
3846 |
if (language_mode_ != CLASSIC_MODE && (curr & prev & kData) != 0) { |
|
3847 |
parser_->ReportMessageAt(loc, "strict_duplicate_property", |
|
3848 |
Vector<const char*>::empty()); |
|
3849 |
*ok = false; |
|
3850 |
return; |
|
3851 |
} |
|
3852 |
// Data property conflicting with an accessor. |
|
3853 |
if (((curr & kData) && (prev & kAccessor)) || |
|
3854 |
((prev & kData) && (curr & kAccessor))) { |
|
3855 |
parser_->ReportMessageAt(loc, "accessor_data_property", |
|
3856 |
Vector<const char*>::empty()); |
|
3857 |
*ok = false; |
|
3858 |
return; |
|
3859 |
} |
|
3860 |
// Two accessors of the same type conflicting |
|
3861 |
if ((curr & prev & kAccessor) != 0) { |
|
3862 |
parser_->ReportMessageAt(loc, "accessor_get_set", |
|
3863 |
Vector<const char*>::empty()); |
|
3864 |
*ok = false; |
|
3865 |
return; |
|
3866 |
} |
|
3867 |
|
|
3868 |
// Update map |
|
3869 |
entry->value = reinterpret_cast<void*> (prev | curr); |
|
3870 |
*ok = true; |
|
3871 |
} |
|
3872 |
|
|
3873 |
|
Also available in: Unified diff