OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 16 matching lines...) Expand all Loading... |
27 | 27 |
28 #include "../include/v8stdint.h" | 28 #include "../include/v8stdint.h" |
29 #include "unicode.h" | 29 #include "unicode.h" |
30 #include "globals.h" | 30 #include "globals.h" |
31 #include "checks.h" | 31 #include "checks.h" |
32 #include "allocation.h" | 32 #include "allocation.h" |
33 #include "utils.h" | 33 #include "utils.h" |
34 #include "list.h" | 34 #include "list.h" |
35 | 35 |
36 #include "scanner-base.h" | 36 #include "scanner-base.h" |
| 37 #include "preparse-data-format.h" |
37 #include "preparse-data.h" | 38 #include "preparse-data.h" |
38 #include "preparser.h" | 39 #include "preparser.h" |
39 | 40 |
40 namespace v8 { | 41 namespace v8 { |
41 namespace preparser { | 42 namespace preparser { |
42 | 43 |
43 // Preparsing checks a JavaScript program and emits preparse-data that helps | 44 // Preparsing checks a JavaScript program and emits preparse-data that helps |
44 // a later parsing to be faster. | 45 // a later parsing to be faster. |
45 // See preparser-data.h for the data. | 46 // See preparser-data.h for the data. |
46 | 47 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 return ReportMessageAt(source_location.beg_pos, source_location.end_pos, | 88 return ReportMessageAt(source_location.beg_pos, source_location.end_pos, |
88 "unexpected_token_identifier", NULL); | 89 "unexpected_token_identifier", NULL); |
89 default: | 90 default: |
90 const char* name = i::Token::String(token); | 91 const char* name = i::Token::String(token); |
91 ReportMessageAt(source_location.beg_pos, source_location.end_pos, | 92 ReportMessageAt(source_location.beg_pos, source_location.end_pos, |
92 "unexpected_token", name); | 93 "unexpected_token", name); |
93 } | 94 } |
94 } | 95 } |
95 | 96 |
96 | 97 |
| 98 // Checks whether octal literal last seen is between beg_pos and end_pos. |
| 99 // If so, reports an error. |
| 100 void PreParser::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) { |
| 101 i::Scanner::Location octal = scanner_->octal_position(); |
| 102 if (beg_pos <= octal.beg_pos && octal.end_pos <= end_pos) { |
| 103 ReportMessageAt(octal.beg_pos, octal.end_pos, "strict_octal_literal", NULL); |
| 104 scanner_->clear_octal_position(); |
| 105 *ok = false; |
| 106 } |
| 107 } |
| 108 |
| 109 |
97 PreParser::SourceElements PreParser::ParseSourceElements(int end_token, | 110 PreParser::SourceElements PreParser::ParseSourceElements(int end_token, |
98 bool* ok) { | 111 bool* ok) { |
99 // SourceElements :: | 112 // SourceElements :: |
100 // (Statement)* <end_token> | 113 // (Statement)* <end_token> |
101 | 114 |
| 115 bool allow_directive_prologue = true; |
102 while (peek() != end_token) { | 116 while (peek() != end_token) { |
103 ParseStatement(CHECK_OK); | 117 Statement statement = ParseStatement(CHECK_OK); |
| 118 if (allow_directive_prologue) { |
| 119 if (statement == kUseStrictExpressionStatement) { |
| 120 set_strict_mode(); |
| 121 } else if (statement != kStringLiteralExpressionStatement) { |
| 122 allow_directive_prologue = false; |
| 123 } |
| 124 } |
104 } | 125 } |
105 return kUnknownSourceElements; | 126 return kUnknownSourceElements; |
106 } | 127 } |
107 | 128 |
108 | 129 |
109 PreParser::Statement PreParser::ParseStatement(bool* ok) { | 130 PreParser::Statement PreParser::ParseStatement(bool* ok) { |
110 // Statement :: | 131 // Statement :: |
111 // Block | 132 // Block |
112 // VariableStatement | 133 // VariableStatement |
113 // EmptyStatement | 134 // EmptyStatement |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 | 313 |
293 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement( | 314 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement( |
294 bool* ok) { | 315 bool* ok) { |
295 // ExpressionStatement | LabelledStatement :: | 316 // ExpressionStatement | LabelledStatement :: |
296 // Expression ';' | 317 // Expression ';' |
297 // Identifier ':' Statement | 318 // Identifier ':' Statement |
298 | 319 |
299 Expression expr = ParseExpression(true, CHECK_OK); | 320 Expression expr = ParseExpression(true, CHECK_OK); |
300 if (peek() == i::Token::COLON && expr == kIdentifierExpression) { | 321 if (peek() == i::Token::COLON && expr == kIdentifierExpression) { |
301 Consume(i::Token::COLON); | 322 Consume(i::Token::COLON); |
302 return ParseStatement(ok); | 323 ParseStatement(ok); |
| 324 return kUnknownStatement; |
303 } | 325 } |
304 // Parsed expression statement. | 326 // Parsed expression statement. |
305 ExpectSemicolon(CHECK_OK); | 327 ExpectSemicolon(CHECK_OK); |
| 328 if (expr == kStringLiteralExpression) { |
| 329 return kStringLiteralExpressionStatement; |
| 330 } |
| 331 if (expr == kUseStrictString) { |
| 332 return kUseStrictExpressionStatement; |
| 333 } |
306 return kUnknownStatement; | 334 return kUnknownStatement; |
307 } | 335 } |
308 | 336 |
309 | 337 |
310 PreParser::Statement PreParser::ParseIfStatement(bool* ok) { | 338 PreParser::Statement PreParser::ParseIfStatement(bool* ok) { |
311 // IfStatement :: | 339 // IfStatement :: |
312 // 'if' '(' Expression ')' Statement ('else' Statement)? | 340 // 'if' '(' Expression ')' Statement ('else' Statement)? |
313 | 341 |
314 Expect(i::Token::IF, CHECK_OK); | 342 Expect(i::Token::IF, CHECK_OK); |
315 Expect(i::Token::LPAREN, CHECK_OK); | 343 Expect(i::Token::LPAREN, CHECK_OK); |
(...skipping 734 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1050 | 1078 |
1051 | 1079 |
1052 PreParser::Expression PreParser::ParseFunctionLiteral(bool* ok) { | 1080 PreParser::Expression PreParser::ParseFunctionLiteral(bool* ok) { |
1053 // Function :: | 1081 // Function :: |
1054 // '(' FormalParameterList? ')' '{' FunctionBody '}' | 1082 // '(' FormalParameterList? ')' '{' FunctionBody '}' |
1055 | 1083 |
1056 // Parse function body. | 1084 // Parse function body. |
1057 ScopeType outer_scope_type = scope_->type(); | 1085 ScopeType outer_scope_type = scope_->type(); |
1058 bool inside_with = scope_->IsInsideWith(); | 1086 bool inside_with = scope_->IsInsideWith(); |
1059 Scope function_scope(&scope_, kFunctionScope); | 1087 Scope function_scope(&scope_, kFunctionScope); |
1060 | |
1061 // FormalParameterList :: | 1088 // FormalParameterList :: |
1062 // '(' (Identifier)*[','] ')' | 1089 // '(' (Identifier)*[','] ')' |
1063 Expect(i::Token::LPAREN, CHECK_OK); | 1090 Expect(i::Token::LPAREN, CHECK_OK); |
| 1091 int start_position = scanner_->location().beg_pos; |
1064 bool done = (peek() == i::Token::RPAREN); | 1092 bool done = (peek() == i::Token::RPAREN); |
1065 while (!done) { | 1093 while (!done) { |
1066 ParseIdentifier(CHECK_OK); | 1094 ParseIdentifier(CHECK_OK); |
1067 done = (peek() == i::Token::RPAREN); | 1095 done = (peek() == i::Token::RPAREN); |
1068 if (!done) { | 1096 if (!done) { |
1069 Expect(i::Token::COMMA, CHECK_OK); | 1097 Expect(i::Token::COMMA, CHECK_OK); |
1070 } | 1098 } |
1071 } | 1099 } |
1072 Expect(i::Token::RPAREN, CHECK_OK); | 1100 Expect(i::Token::RPAREN, CHECK_OK); |
1073 | 1101 |
(...skipping 18 matching lines...) Expand all Loading... |
1092 | 1120 |
1093 // Position right after terminal '}'. | 1121 // Position right after terminal '}'. |
1094 int end_pos = scanner_->location().end_pos; | 1122 int end_pos = scanner_->location().end_pos; |
1095 log_->LogFunction(function_block_pos, end_pos, | 1123 log_->LogFunction(function_block_pos, end_pos, |
1096 function_scope.materialized_literal_count(), | 1124 function_scope.materialized_literal_count(), |
1097 function_scope.expected_properties()); | 1125 function_scope.expected_properties()); |
1098 } else { | 1126 } else { |
1099 ParseSourceElements(i::Token::RBRACE, CHECK_OK); | 1127 ParseSourceElements(i::Token::RBRACE, CHECK_OK); |
1100 Expect(i::Token::RBRACE, CHECK_OK); | 1128 Expect(i::Token::RBRACE, CHECK_OK); |
1101 } | 1129 } |
| 1130 |
| 1131 if (scope_->is_strict()) { |
| 1132 int end_position = scanner_->location().end_pos; |
| 1133 CheckOctalLiteral(start_position, end_position, CHECK_OK); |
| 1134 } |
| 1135 |
1102 return kUnknownExpression; | 1136 return kUnknownExpression; |
1103 } | 1137 } |
1104 | 1138 |
1105 | 1139 |
1106 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) { | 1140 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) { |
1107 // CallRuntime :: | 1141 // CallRuntime :: |
1108 // '%' Identifier Arguments | 1142 // '%' Identifier Arguments |
1109 | 1143 |
1110 Expect(i::Token::MOD, CHECK_OK); | 1144 Expect(i::Token::MOD, CHECK_OK); |
1111 ParseIdentifier(CHECK_OK); | 1145 ParseIdentifier(CHECK_OK); |
(...skipping 30 matching lines...) Expand all Loading... |
1142 } | 1176 } |
1143 | 1177 |
1144 | 1178 |
1145 PreParser::Identifier PreParser::GetIdentifierSymbol() { | 1179 PreParser::Identifier PreParser::GetIdentifierSymbol() { |
1146 LogSymbol(); | 1180 LogSymbol(); |
1147 return kUnknownIdentifier; | 1181 return kUnknownIdentifier; |
1148 } | 1182 } |
1149 | 1183 |
1150 | 1184 |
1151 PreParser::Expression PreParser::GetStringSymbol() { | 1185 PreParser::Expression PreParser::GetStringSymbol() { |
| 1186 const int kUseStrictLength = 10; |
| 1187 const char* kUseStrictChars = "use strict"; |
1152 LogSymbol(); | 1188 LogSymbol(); |
1153 return kUnknownExpression; | 1189 if (scanner_->is_literal_ascii() && |
| 1190 scanner_->literal_length() == kUseStrictLength && |
| 1191 !scanner_->literal_contains_escapes() && |
| 1192 !strncmp(scanner_->literal_ascii_string().start(), kUseStrictChars, |
| 1193 kUseStrictLength)) { |
| 1194 return kUseStrictString; |
| 1195 } |
| 1196 return kStringLiteralExpression; |
1154 } | 1197 } |
1155 | 1198 |
1156 | 1199 |
1157 PreParser::Identifier PreParser::ParseIdentifier(bool* ok) { | 1200 PreParser::Identifier PreParser::ParseIdentifier(bool* ok) { |
1158 if (!Check(i::Token::FUTURE_RESERVED_WORD)) { | 1201 if (!Check(i::Token::FUTURE_RESERVED_WORD)) { |
1159 Expect(i::Token::IDENTIFIER, ok); | 1202 Expect(i::Token::IDENTIFIER, ok); |
1160 } | 1203 } |
1161 if (!*ok) return kUnknownIdentifier; | 1204 if (!*ok) return kUnknownIdentifier; |
1162 return GetIdentifierSymbol(); | 1205 return GetIdentifierSymbol(); |
1163 } | 1206 } |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1196 } | 1239 } |
1197 | 1240 |
1198 bool PreParser::peek_any_identifier() { | 1241 bool PreParser::peek_any_identifier() { |
1199 i::Token::Value next = peek(); | 1242 i::Token::Value next = peek(); |
1200 return next == i::Token::IDENTIFIER || | 1243 return next == i::Token::IDENTIFIER || |
1201 next == i::Token::FUTURE_RESERVED_WORD; | 1244 next == i::Token::FUTURE_RESERVED_WORD; |
1202 } | 1245 } |
1203 | 1246 |
1204 #undef CHECK_OK | 1247 #undef CHECK_OK |
1205 } } // v8::preparser | 1248 } } // v8::preparser |
OLD | NEW |