| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/api.h" | 7 #include "src/api.h" |
| 8 #include "src/ast.h" | 8 #include "src/ast.h" |
| 9 #include "src/bailout-reason.h" | 9 #include "src/bailout-reason.h" |
| 10 #include "src/base/platform/platform.h" | 10 #include "src/base/platform/platform.h" |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 258 DCHECK(info_->cached_data() != NULL); | 258 DCHECK(info_->cached_data() != NULL); |
| 259 if (compile_options() == ScriptCompiler::kConsumeParserCache) { | 259 if (compile_options() == ScriptCompiler::kConsumeParserCache) { |
| 260 cached_parse_data_ = ParseData::FromCachedData(*info_->cached_data()); | 260 cached_parse_data_ = ParseData::FromCachedData(*info_->cached_data()); |
| 261 } | 261 } |
| 262 } | 262 } |
| 263 } | 263 } |
| 264 | 264 |
| 265 | 265 |
| 266 Scope* Parser::NewScope(Scope* parent, ScopeType scope_type) { | 266 Scope* Parser::NewScope(Scope* parent, ScopeType scope_type) { |
| 267 DCHECK(ast_value_factory()); | 267 DCHECK(ast_value_factory()); |
| 268 DCHECK(scope_type != MODULE_SCOPE || allow_harmony_modules()); |
| 268 Scope* result = new (zone()) | 269 Scope* result = new (zone()) |
| 269 Scope(isolate(), zone(), parent, scope_type, ast_value_factory()); | 270 Scope(isolate(), zone(), parent, scope_type, ast_value_factory()); |
| 270 result->Initialize(); | 271 result->Initialize(); |
| 271 return result; | 272 return result; |
| 272 } | 273 } |
| 273 | 274 |
| 274 | 275 |
| 275 FunctionLiteral* Parser::DefaultConstructor(bool call_super, Scope* scope, | 276 FunctionLiteral* Parser::DefaultConstructor(bool call_super, Scope* scope, |
| 276 int pos, int end_pos) { | 277 int pos, int end_pos) { |
| 277 int materialized_literal_count = -1; | 278 int materialized_literal_count = -1; |
| (...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 927 | 928 |
| 928 // Enters 'scope'. | 929 // Enters 'scope'. |
| 929 AstNodeFactory function_factory(ast_value_factory()); | 930 AstNodeFactory function_factory(ast_value_factory()); |
| 930 FunctionState function_state(&function_state_, &scope_, *scope, | 931 FunctionState function_state(&function_state_, &scope_, *scope, |
| 931 &function_factory); | 932 &function_factory); |
| 932 | 933 |
| 933 scope_->SetStrictMode(info->strict_mode()); | 934 scope_->SetStrictMode(info->strict_mode()); |
| 934 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); | 935 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); |
| 935 bool ok = true; | 936 bool ok = true; |
| 936 int beg_pos = scanner()->location().beg_pos; | 937 int beg_pos = scanner()->location().beg_pos; |
| 937 ParseSourceElements(body, Token::EOS, info->is_eval(), true, eval_scope, | 938 if (info->is_module()) { |
| 938 &ok); | 939 DCHECK(allow_harmony_modules()); |
| 940 Module* module = ParseModule(&ok); |
| 941 if (ok) { |
| 942 // TODO(adamk): Do something with returned Module |
| 943 CHECK(module); |
| 944 body->Add(factory()->NewEmptyStatement(RelocInfo::kNoPosition), zone()); |
| 945 } |
| 946 } else { |
| 947 ParseStatementList(body, Token::EOS, info->is_eval(), eval_scope, &ok); |
| 948 } |
| 939 | 949 |
| 940 if (ok && strict_mode() == STRICT) { | 950 if (ok && strict_mode() == STRICT) { |
| 941 CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); | 951 CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); |
| 942 } | 952 } |
| 943 | 953 |
| 944 if (ok && allow_harmony_scoping() && strict_mode() == STRICT) { | 954 if (ok && allow_harmony_scoping() && strict_mode() == STRICT) { |
| 945 CheckConflictingVarDeclarations(scope_, &ok); | 955 CheckConflictingVarDeclarations(scope_, &ok); |
| 946 } | 956 } |
| 947 | 957 |
| 948 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { | 958 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1073 DCHECK(target_stack_ == NULL); | 1083 DCHECK(target_stack_ == NULL); |
| 1074 | 1084 |
| 1075 if (result != NULL) { | 1085 if (result != NULL) { |
| 1076 Handle<String> inferred_name(shared_info->inferred_name()); | 1086 Handle<String> inferred_name(shared_info->inferred_name()); |
| 1077 result->set_inferred_name(inferred_name); | 1087 result->set_inferred_name(inferred_name); |
| 1078 } | 1088 } |
| 1079 return result; | 1089 return result; |
| 1080 } | 1090 } |
| 1081 | 1091 |
| 1082 | 1092 |
| 1083 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor, | 1093 void* Parser::ParseStatementList(ZoneList<Statement*>* body, int end_token, |
| 1084 int end_token, bool is_eval, bool is_global, | 1094 bool is_eval, Scope** eval_scope, bool* ok) { |
| 1085 Scope** eval_scope, bool* ok) { | 1095 // StatementList :: |
| 1086 // SourceElements :: | 1096 // (StatementListItem)* <end_token> |
| 1087 // (ModuleElement)* <end_token> | |
| 1088 | 1097 |
| 1089 // Allocate a target stack to use for this set of source | 1098 // Allocate a target stack to use for this set of source |
| 1090 // elements. This way, all scripts and functions get their own | 1099 // elements. This way, all scripts and functions get their own |
| 1091 // target stack thus avoiding illegal breaks and continues across | 1100 // target stack thus avoiding illegal breaks and continues across |
| 1092 // functions. | 1101 // functions. |
| 1093 TargetScope scope(&this->target_stack_); | 1102 TargetScope scope(&this->target_stack_); |
| 1094 | 1103 |
| 1095 DCHECK(processor != NULL); | 1104 DCHECK(body != NULL); |
| 1096 bool directive_prologue = true; // Parsing directive prologue. | 1105 bool directive_prologue = true; // Parsing directive prologue. |
| 1097 | 1106 |
| 1098 while (peek() != end_token) { | 1107 while (peek() != end_token) { |
| 1099 if (directive_prologue && peek() != Token::STRING) { | 1108 if (directive_prologue && peek() != Token::STRING) { |
| 1100 directive_prologue = false; | 1109 directive_prologue = false; |
| 1101 } | 1110 } |
| 1102 | 1111 |
| 1103 Scanner::Location token_loc = scanner()->peek_location(); | 1112 Scanner::Location token_loc = scanner()->peek_location(); |
| 1104 Statement* stat; | 1113 Statement* stat = ParseStatementListItem(CHECK_OK); |
| 1105 if (is_global && !is_eval) { | |
| 1106 stat = ParseModuleElement(NULL, CHECK_OK); | |
| 1107 } else { | |
| 1108 stat = ParseBlockElement(NULL, CHECK_OK); | |
| 1109 } | |
| 1110 if (stat == NULL || stat->IsEmpty()) { | 1114 if (stat == NULL || stat->IsEmpty()) { |
| 1111 directive_prologue = false; // End of directive prologue. | 1115 directive_prologue = false; // End of directive prologue. |
| 1112 continue; | 1116 continue; |
| 1113 } | 1117 } |
| 1114 | 1118 |
| 1115 if (directive_prologue) { | 1119 if (directive_prologue) { |
| 1116 // A shot at a directive. | 1120 // A shot at a directive. |
| 1117 ExpressionStatement* e_stat; | 1121 ExpressionStatement* e_stat; |
| 1118 Literal* literal; | 1122 Literal* literal; |
| 1119 // Still processing directive prologue? | 1123 // Still processing directive prologue? |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1155 // incremented after parsing is done. | 1159 // incremented after parsing is done. |
| 1156 ++use_counts_[v8::Isolate::kUseAsm]; | 1160 ++use_counts_[v8::Isolate::kUseAsm]; |
| 1157 scope_->SetAsmModule(); | 1161 scope_->SetAsmModule(); |
| 1158 } | 1162 } |
| 1159 } else { | 1163 } else { |
| 1160 // End of the directive prologue. | 1164 // End of the directive prologue. |
| 1161 directive_prologue = false; | 1165 directive_prologue = false; |
| 1162 } | 1166 } |
| 1163 } | 1167 } |
| 1164 | 1168 |
| 1165 processor->Add(stat, zone()); | 1169 body->Add(stat, zone()); |
| 1166 } | 1170 } |
| 1167 | 1171 |
| 1168 return 0; | 1172 return 0; |
| 1169 } | 1173 } |
| 1170 | 1174 |
| 1171 | 1175 |
| 1172 Statement* Parser::ParseModuleElement(ZoneList<const AstRawString*>* labels, | 1176 Statement* Parser::ParseStatementListItem(bool* ok) { |
| 1173 bool* ok) { | 1177 // (Ecma 262 6th Edition, 13.1): |
| 1174 // (Ecma 262 5th Edition, clause 14): | 1178 // StatementListItem: |
| 1175 // SourceElement: | |
| 1176 // Statement | 1179 // Statement |
| 1177 // FunctionDeclaration | 1180 // Declaration |
| 1178 // | |
| 1179 // In harmony mode we allow additionally the following productions | |
| 1180 // ModuleElement: | |
| 1181 // LetDeclaration | |
| 1182 // ConstDeclaration | |
| 1183 // ModuleDeclaration | |
| 1184 // ImportDeclaration | |
| 1185 // ExportDeclaration | |
| 1186 // GeneratorDeclaration | |
| 1187 | 1181 |
| 1188 switch (peek()) { | 1182 switch (peek()) { |
| 1189 case Token::FUNCTION: | 1183 case Token::FUNCTION: |
| 1190 return ParseFunctionDeclaration(NULL, ok); | 1184 return ParseFunctionDeclaration(NULL, ok); |
| 1191 case Token::CLASS: | 1185 case Token::CLASS: |
| 1192 return ParseClassDeclaration(NULL, ok); | 1186 return ParseClassDeclaration(NULL, ok); |
| 1187 case Token::CONST: |
| 1188 case Token::VAR: |
| 1189 return ParseVariableStatement(kStatementListItem, NULL, ok); |
| 1190 case Token::LET: |
| 1191 DCHECK(allow_harmony_scoping()); |
| 1192 if (strict_mode() == STRICT) { |
| 1193 return ParseVariableStatement(kStatementListItem, NULL, ok); |
| 1194 } |
| 1195 // Fall through. |
| 1196 default: |
| 1197 return ParseStatement(NULL, ok); |
| 1198 } |
| 1199 } |
| 1200 |
| 1201 |
| 1202 Statement* Parser::ParseModuleItem(bool* ok) { |
| 1203 // (Ecma 262 6th Edition, 15.2): |
| 1204 // ModuleItem : |
| 1205 // ImportDeclaration |
| 1206 // ExportDeclaration |
| 1207 // StatementListItem |
| 1208 |
| 1209 switch (peek()) { |
| 1193 case Token::IMPORT: | 1210 case Token::IMPORT: |
| 1194 return ParseImportDeclaration(ok); | 1211 return ParseImportDeclaration(ok); |
| 1195 case Token::EXPORT: | 1212 case Token::EXPORT: |
| 1196 return ParseExportDeclaration(ok); | 1213 return ParseExportDeclaration(ok); |
| 1197 case Token::CONST: | 1214 default: |
| 1198 return ParseVariableStatement(kModuleElement, NULL, ok); | 1215 return ParseStatementListItem(ok); |
| 1199 case Token::LET: | |
| 1200 DCHECK(allow_harmony_scoping()); | |
| 1201 if (strict_mode() == STRICT) { | |
| 1202 return ParseVariableStatement(kModuleElement, NULL, ok); | |
| 1203 } | |
| 1204 // Fall through. | |
| 1205 default: { | |
| 1206 Statement* stmt = ParseStatement(labels, CHECK_OK); | |
| 1207 // Handle 'module' as a context-sensitive keyword. | |
| 1208 if (FLAG_harmony_modules && | |
| 1209 peek() == Token::IDENTIFIER && | |
| 1210 !scanner()->HasAnyLineTerminatorBeforeNext() && | |
| 1211 stmt != NULL) { | |
| 1212 ExpressionStatement* estmt = stmt->AsExpressionStatement(); | |
| 1213 if (estmt != NULL && estmt->expression()->AsVariableProxy() != NULL && | |
| 1214 estmt->expression()->AsVariableProxy()->raw_name() == | |
| 1215 ast_value_factory()->module_string() && | |
| 1216 !scanner()->literal_contains_escapes()) { | |
| 1217 return ParseModuleDeclaration(NULL, ok); | |
| 1218 } | |
| 1219 } | |
| 1220 return stmt; | |
| 1221 } | |
| 1222 } | 1216 } |
| 1223 } | 1217 } |
| 1224 | 1218 |
| 1225 | 1219 |
| 1226 Statement* Parser::ParseModuleDeclaration(ZoneList<const AstRawString*>* names, | |
| 1227 bool* ok) { | |
| 1228 // ModuleDeclaration: | |
| 1229 // 'module' Identifier Module | |
| 1230 | |
| 1231 int pos = peek_position(); | |
| 1232 const AstRawString* name = | |
| 1233 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | |
| 1234 | |
| 1235 #ifdef DEBUG | |
| 1236 if (FLAG_print_interface_details) | |
| 1237 PrintF("# Module %.*s ", name->length(), name->raw_data()); | |
| 1238 #endif | |
| 1239 | |
| 1240 Module* module = ParseModule(CHECK_OK); | |
| 1241 VariableProxy* proxy = NewUnresolved(name, MODULE, module->interface()); | |
| 1242 Declaration* declaration = | |
| 1243 factory()->NewModuleDeclaration(proxy, module, scope_, pos); | |
| 1244 Declare(declaration, true, CHECK_OK); | |
| 1245 | |
| 1246 #ifdef DEBUG | |
| 1247 if (FLAG_print_interface_details) | |
| 1248 PrintF("# Module %.*s ", name->length(), name->raw_data()); | |
| 1249 if (FLAG_print_interfaces) { | |
| 1250 PrintF("module %.*s: ", name->length(), name->raw_data()); | |
| 1251 module->interface()->Print(); | |
| 1252 } | |
| 1253 #endif | |
| 1254 | |
| 1255 if (names) names->Add(name, zone()); | |
| 1256 if (module->body() == NULL) | |
| 1257 return factory()->NewEmptyStatement(pos); | |
| 1258 else | |
| 1259 return factory()->NewModuleStatement(proxy, module->body(), pos); | |
| 1260 } | |
| 1261 | |
| 1262 | |
| 1263 Module* Parser::ParseModule(bool* ok) { | 1220 Module* Parser::ParseModule(bool* ok) { |
| 1264 // Module: | 1221 // (Ecma 262 6th Edition, 15.2): |
| 1265 // '{' ModuleElement '}' | 1222 // Module : |
| 1266 // '=' ModulePath ';' | 1223 // ModuleBody? |
| 1267 // 'at' String ';' | 1224 // |
| 1268 | 1225 // ModuleBody : |
| 1269 switch (peek()) { | 1226 // ModuleItem* |
| 1270 case Token::LBRACE: | |
| 1271 return ParseModuleLiteral(ok); | |
| 1272 | |
| 1273 case Token::ASSIGN: { | |
| 1274 Expect(Token::ASSIGN, CHECK_OK); | |
| 1275 Module* result = ParseModulePath(CHECK_OK); | |
| 1276 ExpectSemicolon(CHECK_OK); | |
| 1277 return result; | |
| 1278 } | |
| 1279 | |
| 1280 default: { | |
| 1281 ExpectContextualKeyword(CStrVector("at"), CHECK_OK); | |
| 1282 Module* result = ParseModuleUrl(CHECK_OK); | |
| 1283 ExpectSemicolon(CHECK_OK); | |
| 1284 return result; | |
| 1285 } | |
| 1286 } | |
| 1287 } | |
| 1288 | |
| 1289 | |
| 1290 Module* Parser::ParseModuleLiteral(bool* ok) { | |
| 1291 // Module: | |
| 1292 // '{' ModuleElement '}' | |
| 1293 | 1227 |
| 1294 int pos = peek_position(); | 1228 int pos = peek_position(); |
| 1295 // Construct block expecting 16 statements. | 1229 // Construct block expecting 16 statements. |
| 1296 Block* body = factory()->NewBlock(NULL, 16, false, RelocInfo::kNoPosition); | 1230 Block* body = factory()->NewBlock(NULL, 16, false, RelocInfo::kNoPosition); |
| 1297 #ifdef DEBUG | 1231 #ifdef DEBUG |
| 1298 if (FLAG_print_interface_details) PrintF("# Literal "); | 1232 if (FLAG_print_interface_details) PrintF("# Literal "); |
| 1299 #endif | 1233 #endif |
| 1300 Scope* scope = NewScope(scope_, MODULE_SCOPE); | 1234 Scope* scope = NewScope(scope_, MODULE_SCOPE); |
| 1301 | 1235 |
| 1302 Expect(Token::LBRACE, CHECK_OK); | |
| 1303 scope->set_start_position(scanner()->location().beg_pos); | 1236 scope->set_start_position(scanner()->location().beg_pos); |
| 1304 scope->SetStrictMode(STRICT); | 1237 scope->SetStrictMode(STRICT); |
| 1305 | 1238 |
| 1306 { | 1239 { |
| 1307 BlockState block_state(&scope_, scope); | 1240 BlockState block_state(&scope_, scope); |
| 1308 Target target(&this->target_stack_, body); | 1241 Target target(&this->target_stack_, body); |
| 1309 | 1242 |
| 1310 while (peek() != Token::RBRACE) { | 1243 while (peek() != Token::EOS) { |
| 1311 Statement* stat = ParseModuleElement(NULL, CHECK_OK); | 1244 Statement* stat = ParseModuleItem(CHECK_OK); |
| 1312 if (stat && !stat->IsEmpty()) { | 1245 if (stat && !stat->IsEmpty()) { |
| 1313 body->AddStatement(stat, zone()); | 1246 body->AddStatement(stat, zone()); |
| 1314 } | 1247 } |
| 1315 } | 1248 } |
| 1316 } | 1249 } |
| 1317 | 1250 |
| 1318 Expect(Token::RBRACE, CHECK_OK); | |
| 1319 scope->set_end_position(scanner()->location().end_pos); | 1251 scope->set_end_position(scanner()->location().end_pos); |
| 1320 body->set_scope(scope); | 1252 body->set_scope(scope); |
| 1321 | 1253 |
| 1322 // Check that all exports are bound. | 1254 // Check that all exports are bound. |
| 1323 Interface* interface = scope->interface(); | 1255 Interface* interface = scope->interface(); |
| 1324 for (Interface::Iterator it = interface->iterator(); | 1256 for (Interface::Iterator it = interface->iterator(); |
| 1325 !it.done(); it.Advance()) { | 1257 !it.done(); it.Advance()) { |
| 1326 if (scope->LookupLocal(it.name()) == NULL) { | 1258 if (scope->LookupLocal(it.name()) == NULL) { |
| 1327 ParserTraits::ReportMessage("module_export_undefined", it.name()); | 1259 ParserTraits::ReportMessage("module_export_undefined", it.name()); |
| 1328 *ok = false; | 1260 *ok = false; |
| 1329 return NULL; | 1261 return NULL; |
| 1330 } | 1262 } |
| 1331 } | 1263 } |
| 1332 | 1264 |
| 1333 interface->MakeModule(ok); | 1265 interface->MakeModule(ok); |
| 1334 DCHECK(*ok); | 1266 DCHECK(*ok); |
| 1335 interface->Freeze(ok); | 1267 interface->Freeze(ok); |
| 1336 DCHECK(*ok); | 1268 DCHECK(*ok); |
| 1337 return factory()->NewModuleLiteral(body, interface, pos); | 1269 return factory()->NewModuleLiteral(body, interface, pos); |
| 1338 } | 1270 } |
| 1339 | 1271 |
| 1340 | 1272 |
| 1341 Module* Parser::ParseModulePath(bool* ok) { | |
| 1342 // ModulePath: | |
| 1343 // Identifier | |
| 1344 // ModulePath '.' Identifier | |
| 1345 | |
| 1346 int pos = peek_position(); | |
| 1347 Module* result = ParseModuleVariable(CHECK_OK); | |
| 1348 while (Check(Token::PERIOD)) { | |
| 1349 const AstRawString* name = ParseIdentifierName(CHECK_OK); | |
| 1350 #ifdef DEBUG | |
| 1351 if (FLAG_print_interface_details) | |
| 1352 PrintF("# Path .%.*s ", name->length(), name->raw_data()); | |
| 1353 #endif | |
| 1354 Module* member = factory()->NewModulePath(result, name, pos); | |
| 1355 result->interface()->Add(name, member->interface(), zone(), ok); | |
| 1356 if (!*ok) { | |
| 1357 #ifdef DEBUG | |
| 1358 if (FLAG_print_interfaces) { | |
| 1359 PrintF("PATH TYPE ERROR at '%.*s'\n", name->length(), name->raw_data()); | |
| 1360 PrintF("result: "); | |
| 1361 result->interface()->Print(); | |
| 1362 PrintF("member: "); | |
| 1363 member->interface()->Print(); | |
| 1364 } | |
| 1365 #endif | |
| 1366 ParserTraits::ReportMessage("invalid_module_path", name); | |
| 1367 return NULL; | |
| 1368 } | |
| 1369 result = member; | |
| 1370 } | |
| 1371 | |
| 1372 return result; | |
| 1373 } | |
| 1374 | |
| 1375 | |
| 1376 Module* Parser::ParseModuleVariable(bool* ok) { | |
| 1377 // ModulePath: | |
| 1378 // Identifier | |
| 1379 | |
| 1380 int pos = peek_position(); | |
| 1381 const AstRawString* name = | |
| 1382 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | |
| 1383 #ifdef DEBUG | |
| 1384 if (FLAG_print_interface_details) | |
| 1385 PrintF("# Module variable %.*s ", name->length(), name->raw_data()); | |
| 1386 #endif | |
| 1387 VariableProxy* proxy = scope_->NewUnresolved( | |
| 1388 factory(), name, Interface::NewModule(zone()), | |
| 1389 scanner()->location().beg_pos); | |
| 1390 | |
| 1391 return factory()->NewModuleVariable(proxy, pos); | |
| 1392 } | |
| 1393 | |
| 1394 | |
| 1395 Module* Parser::ParseModuleUrl(bool* ok) { | 1273 Module* Parser::ParseModuleUrl(bool* ok) { |
| 1396 // Module: | 1274 // Module: |
| 1397 // String | 1275 // String |
| 1398 | 1276 |
| 1399 int pos = peek_position(); | 1277 int pos = peek_position(); |
| 1400 Expect(Token::STRING, CHECK_OK); | 1278 Expect(Token::STRING, CHECK_OK); |
| 1401 const AstRawString* symbol = GetSymbol(scanner()); | 1279 const AstRawString* symbol = GetSymbol(scanner()); |
| 1402 | 1280 |
| 1403 // TODO(ES6): Request JS resource from environment... | 1281 // TODO(ES6): Request JS resource from environment... |
| 1404 | 1282 |
| 1405 #ifdef DEBUG | 1283 #ifdef DEBUG |
| 1406 if (FLAG_print_interface_details) PrintF("# Url "); | 1284 if (FLAG_print_interface_details) PrintF("# Url "); |
| 1407 #endif | 1285 #endif |
| 1408 | 1286 |
| 1409 // Create an empty literal as long as the feature isn't finished. | 1287 // Create an empty literal as long as the feature isn't finished. |
| 1410 USE(symbol); | 1288 USE(symbol); |
| 1411 Scope* scope = NewScope(scope_, MODULE_SCOPE); | 1289 Scope* scope = NewScope(scope_, MODULE_SCOPE); |
| 1412 Block* body = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); | 1290 Block* body = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); |
| 1413 body->set_scope(scope); | 1291 body->set_scope(scope); |
| 1414 Interface* interface = scope->interface(); | 1292 Interface* interface = scope->interface(); |
| 1415 Module* result = factory()->NewModuleLiteral(body, interface, pos); | 1293 Module* result = factory()->NewModuleLiteral(body, interface, pos); |
| 1416 interface->Freeze(ok); | 1294 interface->Freeze(ok); |
| 1417 DCHECK(*ok); | 1295 DCHECK(*ok); |
| 1418 interface->Unify(scope->interface(), zone(), ok); | 1296 interface->Unify(scope->interface(), zone(), ok); |
| 1419 DCHECK(*ok); | 1297 DCHECK(*ok); |
| 1420 return result; | 1298 return result; |
| 1421 } | 1299 } |
| 1422 | 1300 |
| 1423 | 1301 |
| 1424 Module* Parser::ParseModuleSpecifier(bool* ok) { | 1302 Statement* Parser::ParseImportDeclaration(bool* ok) { |
| 1425 // ModuleSpecifier: | |
| 1426 // String | |
| 1427 // ModulePath | |
| 1428 | |
| 1429 if (peek() == Token::STRING) { | |
| 1430 return ParseModuleUrl(ok); | |
| 1431 } else { | |
| 1432 return ParseModulePath(ok); | |
| 1433 } | |
| 1434 } | |
| 1435 | |
| 1436 | |
| 1437 Block* Parser::ParseImportDeclaration(bool* ok) { | |
| 1438 // ImportDeclaration: | 1303 // ImportDeclaration: |
| 1439 // 'import' IdentifierName (',' IdentifierName)* 'from' ModuleSpecifier ';' | 1304 // 'import' IdentifierName (',' IdentifierName)* 'from' ModuleUrl ';' |
| 1440 // | 1305 // |
| 1441 // TODO(ES6): implement destructuring ImportSpecifiers | 1306 // TODO(ES6): implement current syntax |
| 1442 | 1307 |
| 1443 int pos = peek_position(); | 1308 int pos = peek_position(); |
| 1444 Expect(Token::IMPORT, CHECK_OK); | 1309 Expect(Token::IMPORT, CHECK_OK); |
| 1445 ZoneList<const AstRawString*> names(1, zone()); | 1310 ZoneList<const AstRawString*> names(1, zone()); |
| 1446 | 1311 |
| 1447 const AstRawString* name = ParseIdentifierName(CHECK_OK); | 1312 const AstRawString* name = ParseIdentifierName(CHECK_OK); |
| 1448 names.Add(name, zone()); | 1313 names.Add(name, zone()); |
| 1449 while (peek() == Token::COMMA) { | 1314 while (peek() == Token::COMMA) { |
| 1450 Consume(Token::COMMA); | 1315 Consume(Token::COMMA); |
| 1451 name = ParseIdentifierName(CHECK_OK); | 1316 name = ParseIdentifierName(CHECK_OK); |
| 1452 names.Add(name, zone()); | 1317 names.Add(name, zone()); |
| 1453 } | 1318 } |
| 1454 | 1319 |
| 1455 ExpectContextualKeyword(CStrVector("from"), CHECK_OK); | 1320 ExpectContextualKeyword(CStrVector("from"), CHECK_OK); |
| 1456 Module* module = ParseModuleSpecifier(CHECK_OK); | 1321 Module* module = ParseModuleUrl(CHECK_OK); |
| 1457 ExpectSemicolon(CHECK_OK); | 1322 ExpectSemicolon(CHECK_OK); |
| 1458 | 1323 |
| 1459 // Generate a separate declaration for each identifier. | 1324 // TODO(ES6): Do something with ParseModuleUrl's return value. |
| 1460 // TODO(ES6): once we implement destructuring, make that one declaration. | 1325 USE(module); |
| 1461 Block* block = factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition); | 1326 |
| 1462 for (int i = 0; i < names.length(); ++i) { | 1327 for (int i = 0; i < names.length(); ++i) { |
| 1463 #ifdef DEBUG | 1328 // TODO(ES6): Add an appropriate declaration for each name |
| 1464 if (FLAG_print_interface_details) | |
| 1465 PrintF("# Import %.*s ", name->length(), name->raw_data()); | |
| 1466 #endif | |
| 1467 Interface* interface = Interface::NewUnknown(zone()); | |
| 1468 module->interface()->Add(names[i], interface, zone(), ok); | |
| 1469 if (!*ok) { | |
| 1470 #ifdef DEBUG | |
| 1471 if (FLAG_print_interfaces) { | |
| 1472 PrintF("IMPORT TYPE ERROR at '%.*s'\n", name->length(), | |
| 1473 name->raw_data()); | |
| 1474 PrintF("module: "); | |
| 1475 module->interface()->Print(); | |
| 1476 } | |
| 1477 #endif | |
| 1478 ParserTraits::ReportMessage("invalid_module_path", name); | |
| 1479 return NULL; | |
| 1480 } | |
| 1481 VariableProxy* proxy = NewUnresolved(names[i], LET, interface); | |
| 1482 Declaration* declaration = | |
| 1483 factory()->NewImportDeclaration(proxy, module, scope_, pos); | |
| 1484 Declare(declaration, true, CHECK_OK); | |
| 1485 } | 1329 } |
| 1486 | 1330 |
| 1487 return block; | 1331 return factory()->NewEmptyStatement(pos); |
| 1488 } | 1332 } |
| 1489 | 1333 |
| 1490 | 1334 |
| 1491 Statement* Parser::ParseExportDeclaration(bool* ok) { | 1335 Statement* Parser::ParseExportDeclaration(bool* ok) { |
| 1492 // ExportDeclaration: | 1336 // ExportDeclaration: |
| 1493 // 'export' Identifier (',' Identifier)* ';' | 1337 // 'export' Identifier (',' Identifier)* ';' |
| 1494 // 'export' VariableDeclaration | 1338 // 'export' VariableDeclaration |
| 1495 // 'export' FunctionDeclaration | 1339 // 'export' FunctionDeclaration |
| 1496 // 'export' GeneratorDeclaration | 1340 // 'export' GeneratorDeclaration |
| 1497 // 'export' ModuleDeclaration | 1341 // 'export' ModuleDeclaration |
| 1498 // | 1342 // |
| 1499 // TODO(ES6): implement structuring ExportSpecifiers | 1343 // TODO(ES6): implement current syntax |
| 1500 | 1344 |
| 1501 Expect(Token::EXPORT, CHECK_OK); | 1345 Expect(Token::EXPORT, CHECK_OK); |
| 1502 | 1346 |
| 1503 Statement* result = NULL; | 1347 Statement* result = NULL; |
| 1504 ZoneList<const AstRawString*> names(1, zone()); | 1348 ZoneList<const AstRawString*> names(1, zone()); |
| 1505 switch (peek()) { | 1349 switch (peek()) { |
| 1506 case Token::IDENTIFIER: { | 1350 case Token::IDENTIFIER: { |
| 1507 int pos = position(); | 1351 int pos = position(); |
| 1508 const AstRawString* name = | 1352 const AstRawString* name = |
| 1509 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 1353 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 1510 // Handle 'module' as a context-sensitive keyword. | 1354 names.Add(name, zone()); |
| 1511 if (name != ast_value_factory()->module_string()) { | 1355 while (peek() == Token::COMMA) { |
| 1356 Consume(Token::COMMA); |
| 1357 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 1512 names.Add(name, zone()); | 1358 names.Add(name, zone()); |
| 1513 while (peek() == Token::COMMA) { | |
| 1514 Consume(Token::COMMA); | |
| 1515 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | |
| 1516 names.Add(name, zone()); | |
| 1517 } | |
| 1518 ExpectSemicolon(CHECK_OK); | |
| 1519 result = factory()->NewEmptyStatement(pos); | |
| 1520 } else { | |
| 1521 result = ParseModuleDeclaration(&names, CHECK_OK); | |
| 1522 } | 1359 } |
| 1360 ExpectSemicolon(CHECK_OK); |
| 1361 result = factory()->NewEmptyStatement(pos); |
| 1523 break; | 1362 break; |
| 1524 } | 1363 } |
| 1525 | 1364 |
| 1526 case Token::FUNCTION: | 1365 case Token::FUNCTION: |
| 1527 result = ParseFunctionDeclaration(&names, CHECK_OK); | 1366 result = ParseFunctionDeclaration(&names, CHECK_OK); |
| 1528 break; | 1367 break; |
| 1529 | 1368 |
| 1530 case Token::CLASS: | 1369 case Token::CLASS: |
| 1531 result = ParseClassDeclaration(&names, CHECK_OK); | 1370 result = ParseClassDeclaration(&names, CHECK_OK); |
| 1532 break; | 1371 break; |
| 1533 | 1372 |
| 1534 case Token::VAR: | 1373 case Token::VAR: |
| 1535 case Token::LET: | 1374 case Token::LET: |
| 1536 case Token::CONST: | 1375 case Token::CONST: |
| 1537 result = ParseVariableStatement(kModuleElement, &names, CHECK_OK); | 1376 result = ParseVariableStatement(kStatementListItem, &names, CHECK_OK); |
| 1538 break; | 1377 break; |
| 1539 | 1378 |
| 1540 default: | 1379 default: |
| 1541 *ok = false; | 1380 *ok = false; |
| 1542 ReportUnexpectedToken(scanner()->current_token()); | 1381 ReportUnexpectedToken(scanner()->current_token()); |
| 1543 return NULL; | 1382 return NULL; |
| 1544 } | 1383 } |
| 1545 | 1384 |
| 1546 // Every export of a module may be assigned. | 1385 // Every export of a module may be assigned. |
| 1547 for (int i = 0; i < names.length(); ++i) { | 1386 for (int i = 0; i < names.length(); ++i) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1574 // ExportDeclaration* declaration = | 1413 // ExportDeclaration* declaration = |
| 1575 // factory()->NewExportDeclaration(proxy, scope_, position); | 1414 // factory()->NewExportDeclaration(proxy, scope_, position); |
| 1576 // scope_->AddDeclaration(declaration); | 1415 // scope_->AddDeclaration(declaration); |
| 1577 } | 1416 } |
| 1578 | 1417 |
| 1579 DCHECK(result != NULL); | 1418 DCHECK(result != NULL); |
| 1580 return result; | 1419 return result; |
| 1581 } | 1420 } |
| 1582 | 1421 |
| 1583 | 1422 |
| 1584 Statement* Parser::ParseBlockElement(ZoneList<const AstRawString*>* labels, | |
| 1585 bool* ok) { | |
| 1586 // (Ecma 262 5th Edition, clause 14): | |
| 1587 // SourceElement: | |
| 1588 // Statement | |
| 1589 // FunctionDeclaration | |
| 1590 // | |
| 1591 // In harmony mode we allow additionally the following productions | |
| 1592 // BlockElement (aka SourceElement): | |
| 1593 // LetDeclaration | |
| 1594 // ConstDeclaration | |
| 1595 // GeneratorDeclaration | |
| 1596 // ClassDeclaration | |
| 1597 | |
| 1598 switch (peek()) { | |
| 1599 case Token::FUNCTION: | |
| 1600 return ParseFunctionDeclaration(NULL, ok); | |
| 1601 case Token::CLASS: | |
| 1602 return ParseClassDeclaration(NULL, ok); | |
| 1603 case Token::CONST: | |
| 1604 return ParseVariableStatement(kModuleElement, NULL, ok); | |
| 1605 case Token::LET: | |
| 1606 DCHECK(allow_harmony_scoping()); | |
| 1607 if (strict_mode() == STRICT) { | |
| 1608 return ParseVariableStatement(kModuleElement, NULL, ok); | |
| 1609 } | |
| 1610 // Fall through. | |
| 1611 default: | |
| 1612 return ParseStatement(labels, ok); | |
| 1613 } | |
| 1614 } | |
| 1615 | |
| 1616 | |
| 1617 Statement* Parser::ParseStatement(ZoneList<const AstRawString*>* labels, | 1423 Statement* Parser::ParseStatement(ZoneList<const AstRawString*>* labels, |
| 1618 bool* ok) { | 1424 bool* ok) { |
| 1619 // Statement :: | 1425 // Statement :: |
| 1620 // Block | 1426 // Block |
| 1621 // VariableStatement | 1427 // VariableStatement |
| 1622 // EmptyStatement | 1428 // EmptyStatement |
| 1623 // ExpressionStatement | 1429 // ExpressionStatement |
| 1624 // IfStatement | 1430 // IfStatement |
| 1625 // IterationStatement | 1431 // IterationStatement |
| 1626 // ContinueStatement | 1432 // ContinueStatement |
| (...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2060 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); | 1866 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); |
| 2061 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE); | 1867 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE); |
| 2062 | 1868 |
| 2063 // Parse the statements and collect escaping labels. | 1869 // Parse the statements and collect escaping labels. |
| 2064 Expect(Token::LBRACE, CHECK_OK); | 1870 Expect(Token::LBRACE, CHECK_OK); |
| 2065 block_scope->set_start_position(scanner()->location().beg_pos); | 1871 block_scope->set_start_position(scanner()->location().beg_pos); |
| 2066 { BlockState block_state(&scope_, block_scope); | 1872 { BlockState block_state(&scope_, block_scope); |
| 2067 Target target(&this->target_stack_, body); | 1873 Target target(&this->target_stack_, body); |
| 2068 | 1874 |
| 2069 while (peek() != Token::RBRACE) { | 1875 while (peek() != Token::RBRACE) { |
| 2070 Statement* stat = ParseBlockElement(NULL, CHECK_OK); | 1876 Statement* stat = ParseStatementListItem(CHECK_OK); |
| 2071 if (stat && !stat->IsEmpty()) { | 1877 if (stat && !stat->IsEmpty()) { |
| 2072 body->AddStatement(stat, zone()); | 1878 body->AddStatement(stat, zone()); |
| 2073 } | 1879 } |
| 2074 } | 1880 } |
| 2075 } | 1881 } |
| 2076 Expect(Token::RBRACE, CHECK_OK); | 1882 Expect(Token::RBRACE, CHECK_OK); |
| 2077 block_scope->set_end_position(scanner()->location().end_pos); | 1883 block_scope->set_end_position(scanner()->location().end_pos); |
| 2078 block_scope = block_scope->FinalizeBlockScope(); | 1884 block_scope = block_scope->FinalizeBlockScope(); |
| 2079 body->set_scope(block_scope); | 1885 body->set_scope(block_scope); |
| 2080 return body; | 1886 return body; |
| (...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2475 // no line-terminator between the two words. | 2281 // no line-terminator between the two words. |
| 2476 if (extension_ != NULL && peek() == Token::FUNCTION && | 2282 if (extension_ != NULL && peek() == Token::FUNCTION && |
| 2477 !scanner()->HasAnyLineTerminatorBeforeNext() && expr != NULL && | 2283 !scanner()->HasAnyLineTerminatorBeforeNext() && expr != NULL && |
| 2478 expr->AsVariableProxy() != NULL && | 2284 expr->AsVariableProxy() != NULL && |
| 2479 expr->AsVariableProxy()->raw_name() == | 2285 expr->AsVariableProxy()->raw_name() == |
| 2480 ast_value_factory()->native_string() && | 2286 ast_value_factory()->native_string() && |
| 2481 !scanner()->literal_contains_escapes()) { | 2287 !scanner()->literal_contains_escapes()) { |
| 2482 return ParseNativeDeclaration(ok); | 2288 return ParseNativeDeclaration(ok); |
| 2483 } | 2289 } |
| 2484 | 2290 |
| 2485 // Parsed expression statement, or the context-sensitive 'module' keyword. | 2291 // Parsed expression statement, followed by semicolon. |
| 2486 // Only expect semicolon in the former case. | 2292 // Detect attempts at 'let' declarations in sloppy mode. |
| 2487 // Also detect attempts at 'let' declarations in sloppy mode. | 2293 if (peek() == Token::IDENTIFIER && expr->AsVariableProxy() != NULL && |
| 2488 if (!FLAG_harmony_modules || peek() != Token::IDENTIFIER || | 2294 expr->AsVariableProxy()->raw_name() == |
| 2489 scanner()->HasAnyLineTerminatorBeforeNext() || | 2295 ast_value_factory()->let_string()) { |
| 2490 expr->AsVariableProxy() == NULL || | 2296 ReportMessage("sloppy_lexical", NULL); |
| 2491 expr->AsVariableProxy()->raw_name() != | 2297 *ok = false; |
| 2492 ast_value_factory()->module_string() || | 2298 return NULL; |
| 2493 scanner()->literal_contains_escapes()) { | |
| 2494 if (peek() == Token::IDENTIFIER && expr->AsVariableProxy() != NULL && | |
| 2495 expr->AsVariableProxy()->raw_name() == | |
| 2496 ast_value_factory()->let_string()) { | |
| 2497 ReportMessage("sloppy_lexical", NULL); | |
| 2498 *ok = false; | |
| 2499 return NULL; | |
| 2500 } | |
| 2501 ExpectSemicolon(CHECK_OK); | |
| 2502 } | 2299 } |
| 2300 ExpectSemicolon(CHECK_OK); |
| 2503 return factory()->NewExpressionStatement(expr, pos); | 2301 return factory()->NewExpressionStatement(expr, pos); |
| 2504 } | 2302 } |
| 2505 | 2303 |
| 2506 | 2304 |
| 2507 IfStatement* Parser::ParseIfStatement(ZoneList<const AstRawString*>* labels, | 2305 IfStatement* Parser::ParseIfStatement(ZoneList<const AstRawString*>* labels, |
| 2508 bool* ok) { | 2306 bool* ok) { |
| 2509 // IfStatement :: | 2307 // IfStatement :: |
| 2510 // 'if' '(' Expression ')' Statement ('else' Statement)? | 2308 // 'if' '(' Expression ')' Statement ('else' Statement)? |
| 2511 | 2309 |
| 2512 int pos = peek_position(); | 2310 int pos = peek_position(); |
| (...skipping 1393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3906 Assignment* assignment = factory()->NewAssignment( | 3704 Assignment* assignment = factory()->NewAssignment( |
| 3907 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition); | 3705 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition); |
| 3908 VariableProxy* get_proxy = factory()->NewVariableProxy( | 3706 VariableProxy* get_proxy = factory()->NewVariableProxy( |
| 3909 function_state_->generator_object_variable()); | 3707 function_state_->generator_object_variable()); |
| 3910 Yield* yield = factory()->NewYield( | 3708 Yield* yield = factory()->NewYield( |
| 3911 get_proxy, assignment, Yield::kInitial, RelocInfo::kNoPosition); | 3709 get_proxy, assignment, Yield::kInitial, RelocInfo::kNoPosition); |
| 3912 body->Add(factory()->NewExpressionStatement( | 3710 body->Add(factory()->NewExpressionStatement( |
| 3913 yield, RelocInfo::kNoPosition), zone()); | 3711 yield, RelocInfo::kNoPosition), zone()); |
| 3914 } | 3712 } |
| 3915 | 3713 |
| 3916 ParseSourceElements(body, Token::RBRACE, false, false, NULL, CHECK_OK); | 3714 ParseStatementList(body, Token::RBRACE, false, NULL, CHECK_OK); |
| 3917 | 3715 |
| 3918 if (is_generator) { | 3716 if (is_generator) { |
| 3919 VariableProxy* get_proxy = factory()->NewVariableProxy( | 3717 VariableProxy* get_proxy = factory()->NewVariableProxy( |
| 3920 function_state_->generator_object_variable()); | 3718 function_state_->generator_object_variable()); |
| 3921 Expression* undefined = | 3719 Expression* undefined = |
| 3922 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition); | 3720 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition); |
| 3923 Yield* yield = factory()->NewYield(get_proxy, undefined, Yield::kFinal, | 3721 Yield* yield = factory()->NewYield(get_proxy, undefined, Yield::kFinal, |
| 3924 RelocInfo::kNoPosition); | 3722 RelocInfo::kNoPosition); |
| 3925 body->Add(factory()->NewExpressionStatement( | 3723 body->Add(factory()->NewExpressionStatement( |
| 3926 yield, RelocInfo::kNoPosition), zone()); | 3724 yield, RelocInfo::kNoPosition), zone()); |
| (...skipping 1418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5345 } else { | 5143 } else { |
| 5346 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data()); | 5144 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data()); |
| 5347 running_hash = StringHasher::ComputeRunningHash(running_hash, data, | 5145 running_hash = StringHasher::ComputeRunningHash(running_hash, data, |
| 5348 raw_string->length()); | 5146 raw_string->length()); |
| 5349 } | 5147 } |
| 5350 } | 5148 } |
| 5351 | 5149 |
| 5352 return running_hash; | 5150 return running_hash; |
| 5353 } | 5151 } |
| 5354 } } // namespace v8::internal | 5152 } } // namespace v8::internal |
| OLD | NEW |