OLD | NEW |
---|---|
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
84 Element* top() { return top_; } | 84 Element* top() { return top_; } |
85 void set_top(Element* value) { top_ = value; } | 85 void set_top(Element* value) { top_ = value; } |
86 Element* top_; | 86 Element* top_; |
87 bool* ok_; | 87 bool* ok_; |
88 }; | 88 }; |
89 | 89 |
90 | 90 |
91 class Parser { | 91 class Parser { |
92 public: | 92 public: |
93 Parser(Handle<Script> script, bool allow_natives_syntax, | 93 Parser(Handle<Script> script, bool allow_natives_syntax, |
94 v8::Extension* extension, bool is_pre_parsing, | 94 v8::Extension* extension, ParserMode is_pre_parsing, |
95 ParserFactory* factory, ParserLog* log, ScriptDataImpl* pre_data); | 95 ParserFactory* factory, ParserLog* log, ScriptDataImpl* pre_data); |
96 virtual ~Parser() { } | 96 virtual ~Parser() { } |
97 | 97 |
98 // Pre-parse the program from the character stream; returns true on | 98 // Pre-parse the program from the character stream; returns true on |
99 // success, false if a stack-overflow happened during parsing. | 99 // success, false if a stack-overflow happened during parsing. |
100 bool PreParseProgram(Handle<String> source, unibrow::CharacterStream* stream); | 100 bool PreParseProgram(Handle<String> source, unibrow::CharacterStream* stream); |
101 | 101 |
102 void ReportMessage(const char* message, Vector<const char*> args); | 102 void ReportMessage(const char* message, Vector<const char*> args); |
103 virtual void ReportMessageAt(Scanner::Location loc, | 103 virtual void ReportMessageAt(Scanner::Location loc, |
104 const char* message, | 104 const char* message, |
105 Vector<const char*> args) = 0; | 105 Vector<const char*> args) = 0; |
106 | 106 |
107 | 107 |
108 // Returns NULL if parsing failed. | 108 // Returns NULL if parsing failed. |
109 FunctionLiteral* ParseProgram(Handle<String> source, | 109 FunctionLiteral* ParseProgram(Handle<String> source, |
110 unibrow::CharacterStream* stream, | 110 unibrow::CharacterStream* stream, |
111 bool in_global_context); | 111 bool in_global_context); |
112 FunctionLiteral* ParseLazy(Handle<String> source, | 112 FunctionLiteral* ParseLazy(Handle<String> source, |
113 Handle<String> name, | 113 Handle<String> name, |
114 int start_position, bool is_expression); | 114 int start_position, bool is_expression); |
115 FunctionLiteral* ParseJson(Handle<String> source, | |
116 unibrow::CharacterStream* stream); | |
115 | 117 |
116 // The minimum number of contiguous assignment that will | 118 // The minimum number of contiguous assignment that will |
117 // be treated as an initialization block. Benchmarks show that | 119 // be treated as an initialization block. Benchmarks show that |
118 // the overhead exceeds the savings below this limit. | 120 // the overhead exceeds the savings below this limit. |
119 static const int kMinInitializationBlock = 3; | 121 static const int kMinInitializationBlock = 3; |
120 | 122 |
121 protected: | 123 protected: |
122 | 124 |
123 enum Mode { | 125 enum Mode { |
124 PARSE_LAZILY, | 126 PARSE_LAZILY, |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
195 Expression* ParseNewExpression(bool* ok); | 197 Expression* ParseNewExpression(bool* ok); |
196 Expression* ParseMemberExpression(bool* ok); | 198 Expression* ParseMemberExpression(bool* ok); |
197 Expression* ParseNewPrefix(PositionStack* stack, bool* ok); | 199 Expression* ParseNewPrefix(PositionStack* stack, bool* ok); |
198 Expression* ParseMemberWithNewPrefixesExpression(PositionStack* stack, | 200 Expression* ParseMemberWithNewPrefixesExpression(PositionStack* stack, |
199 bool* ok); | 201 bool* ok); |
200 Expression* ParsePrimaryExpression(bool* ok); | 202 Expression* ParsePrimaryExpression(bool* ok); |
201 Expression* ParseArrayLiteral(bool* ok); | 203 Expression* ParseArrayLiteral(bool* ok); |
202 Expression* ParseObjectLiteral(bool* ok); | 204 Expression* ParseObjectLiteral(bool* ok); |
203 Expression* ParseRegExpLiteral(bool seen_equal, bool* ok); | 205 Expression* ParseRegExpLiteral(bool seen_equal, bool* ok); |
204 | 206 |
205 // Decide if a property should be the object boilerplate. | 207 // Populate the constant properties fixed array for a materialized object |
208 // literal. | |
209 void BuildObjectLiteralConstantProperties( | |
210 ZoneList<ObjectLiteral::Property*>* properties, | |
211 Handle<FixedArray> constants, | |
212 bool* is_simple_out, | |
Mads Ager (chromium)
2010/02/01 08:42:19
Remove the _out prefix on these out params?
Lasse Reichstein
2010/02/01 12:17:30
Done.
| |
213 int* depth_out); | |
214 | |
215 // Populate the literals fixed array for a materialized array literal. | |
216 void BuildArrayLiteralBoilerplateLiterals(ZoneList<Expression*>* properties, | |
217 Handle<FixedArray> constants, | |
218 bool* is_simple_out, | |
Mads Ager (chromium)
2010/02/01 08:42:19
Remove _out on these as well?
Lasse Reichstein
2010/02/01 12:17:30
Done, too.
| |
219 int* depth_out); | |
220 | |
221 // Decide if a property should be in the object boilerplate. | |
206 bool IsBoilerplateProperty(ObjectLiteral::Property* property); | 222 bool IsBoilerplateProperty(ObjectLiteral::Property* property); |
207 // If the expression is a literal, return the literal value; | 223 // If the expression is a literal, return the literal value; |
208 // if the expression is a materialized literal and is simple return a | 224 // if the expression is a materialized literal and is simple return a |
209 // compile time value as encoded by CompileTimeValue::GetValue(). | 225 // compile time value as encoded by CompileTimeValue::GetValue(). |
210 // Otherwise, return undefined literal as the placeholder | 226 // Otherwise, return undefined literal as the placeholder |
211 // in the object literal boilerplate. | 227 // in the object literal boilerplate. |
212 Handle<Object> GetBoilerplateValue(Expression* expression); | 228 Handle<Object> GetBoilerplateValue(Expression* expression); |
213 | 229 |
214 enum FunctionLiteralType { | 230 enum FunctionLiteralType { |
215 EXPRESSION, | 231 EXPRESSION, |
216 DECLARATION, | 232 DECLARATION, |
217 NESTED | 233 NESTED |
218 }; | 234 }; |
219 | 235 |
220 ZoneList<Expression*>* ParseArguments(bool* ok); | 236 ZoneList<Expression*>* ParseArguments(bool* ok); |
221 FunctionLiteral* ParseFunctionLiteral(Handle<String> var_name, | 237 FunctionLiteral* ParseFunctionLiteral(Handle<String> var_name, |
222 int function_token_position, | 238 int function_token_position, |
223 FunctionLiteralType type, | 239 FunctionLiteralType type, |
224 bool* ok); | 240 bool* ok); |
225 | 241 |
226 | 242 |
227 // Magical syntax support. | 243 // Magical syntax support. |
228 Expression* ParseV8Intrinsic(bool* ok); | 244 Expression* ParseV8Intrinsic(bool* ok); |
229 | 245 |
230 INLINE(Token::Value peek()) { return scanner_.peek(); } | 246 INLINE(Token::Value peek()) { return scanner_.peek(); } |
231 INLINE(Token::Value Next()) { return scanner_.Next(); } | 247 INLINE(Token::Value Next()) { return scanner_.Next(); } |
232 INLINE(void Consume(Token::Value token)); | 248 INLINE(void Consume(Token::Value token)); |
233 void Expect(Token::Value token, bool* ok); | 249 void Expect(Token::Value token, bool* ok); |
250 bool Check(Token::Value token); | |
234 void ExpectSemicolon(bool* ok); | 251 void ExpectSemicolon(bool* ok); |
235 | 252 |
236 // Get odd-ball literals. | 253 // Get odd-ball literals. |
237 Literal* GetLiteralUndefined(); | 254 Literal* GetLiteralUndefined(); |
238 Literal* GetLiteralTheHole(); | 255 Literal* GetLiteralTheHole(); |
239 Literal* GetLiteralNumber(double value); | 256 Literal* GetLiteralNumber(double value); |
240 | 257 |
241 Handle<String> ParseIdentifier(bool* ok); | 258 Handle<String> ParseIdentifier(bool* ok); |
242 Handle<String> ParseIdentifierOrGetOrSet(bool* is_get, | 259 Handle<String> ParseIdentifierOrGetOrSet(bool* is_get, |
243 bool* is_set, | 260 bool* is_set, |
(...skipping 26 matching lines...) Expand all Loading... | |
270 // type. Both arguments must be non-null (in the handle sense). | 287 // type. Both arguments must be non-null (in the handle sense). |
271 Expression* NewThrowTypeError(Handle<String> type, | 288 Expression* NewThrowTypeError(Handle<String> type, |
272 Handle<Object> first, | 289 Handle<Object> first, |
273 Handle<Object> second); | 290 Handle<Object> second); |
274 | 291 |
275 // Generic AST generator for throwing errors from compiled code. | 292 // Generic AST generator for throwing errors from compiled code. |
276 Expression* NewThrowError(Handle<String> constructor, | 293 Expression* NewThrowError(Handle<String> constructor, |
277 Handle<String> type, | 294 Handle<String> type, |
278 Vector< Handle<Object> > arguments); | 295 Vector< Handle<Object> > arguments); |
279 | 296 |
297 // Parse JSON expressions and sub-expressions. | |
298 Expression* ParseJson(bool* ok); | |
299 Expression* ParseJsonValue(bool* ok); | |
300 Expression* ParseJsonObject(bool* ok); | |
301 Expression* ParseJsonArray(bool* ok); | |
302 | |
280 friend class Target; | 303 friend class Target; |
281 friend class TargetScope; | 304 friend class TargetScope; |
282 friend class LexicalScope; | 305 friend class LexicalScope; |
283 friend class TemporaryScope; | 306 friend class TemporaryScope; |
284 }; | 307 }; |
285 | 308 |
286 | 309 |
287 template <typename T, int initial_size> | 310 template <typename T, int initial_size> |
288 class BufferedZoneList { | 311 class BufferedZoneList { |
289 public: | 312 public: |
(...skipping 686 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
976 FunctionEntry result(store()->AddBlock(0, FunctionEntry::kSize)); | 999 FunctionEntry result(store()->AddBlock(0, FunctionEntry::kSize)); |
977 result.set_start_pos(start); | 1000 result.set_start_pos(start); |
978 return result; | 1001 return result; |
979 } | 1002 } |
980 | 1003 |
981 | 1004 |
982 class AstBuildingParser : public Parser { | 1005 class AstBuildingParser : public Parser { |
983 public: | 1006 public: |
984 AstBuildingParser(Handle<Script> script, bool allow_natives_syntax, | 1007 AstBuildingParser(Handle<Script> script, bool allow_natives_syntax, |
985 v8::Extension* extension, ScriptDataImpl* pre_data) | 1008 v8::Extension* extension, ScriptDataImpl* pre_data) |
986 : Parser(script, allow_natives_syntax, extension, false, | 1009 : Parser(script, allow_natives_syntax, extension, PARSE, |
987 factory(), log(), pre_data) { } | 1010 factory(), log(), pre_data) { } |
988 virtual void ReportMessageAt(Scanner::Location loc, const char* message, | 1011 virtual void ReportMessageAt(Scanner::Location loc, const char* message, |
989 Vector<const char*> args); | 1012 Vector<const char*> args); |
990 virtual VariableProxy* Declare(Handle<String> name, Variable::Mode mode, | 1013 virtual VariableProxy* Declare(Handle<String> name, Variable::Mode mode, |
991 FunctionLiteral* fun, bool resolve, bool* ok); | 1014 FunctionLiteral* fun, bool resolve, bool* ok); |
992 AstBuildingParserFactory* factory() { return &factory_; } | 1015 AstBuildingParserFactory* factory() { return &factory_; } |
993 ParserLog* log() { return &log_; } | 1016 ParserLog* log() { return &log_; } |
994 | 1017 |
995 private: | 1018 private: |
996 ParserLog log_; | 1019 ParserLog log_; |
997 AstBuildingParserFactory factory_; | 1020 AstBuildingParserFactory factory_; |
998 }; | 1021 }; |
999 | 1022 |
1000 | 1023 |
1001 class PreParser : public Parser { | 1024 class PreParser : public Parser { |
1002 public: | 1025 public: |
1003 PreParser(Handle<Script> script, bool allow_natives_syntax, | 1026 PreParser(Handle<Script> script, bool allow_natives_syntax, |
1004 v8::Extension* extension) | 1027 v8::Extension* extension) |
1005 : Parser(script, allow_natives_syntax, extension, true, | 1028 : Parser(script, allow_natives_syntax, extension, PREPARSE, |
1006 factory(), recorder(), NULL) | 1029 factory(), recorder(), NULL), |
1007 , factory_(true) { } | 1030 factory_(true) { } |
1008 virtual void ReportMessageAt(Scanner::Location loc, const char* message, | 1031 virtual void ReportMessageAt(Scanner::Location loc, const char* message, |
1009 Vector<const char*> args); | 1032 Vector<const char*> args); |
1010 virtual VariableProxy* Declare(Handle<String> name, Variable::Mode mode, | 1033 virtual VariableProxy* Declare(Handle<String> name, Variable::Mode mode, |
1011 FunctionLiteral* fun, bool resolve, bool* ok); | 1034 FunctionLiteral* fun, bool resolve, bool* ok); |
1012 ParserFactory* factory() { return &factory_; } | 1035 ParserFactory* factory() { return &factory_; } |
1013 ParserRecorder* recorder() { return &recorder_; } | 1036 ParserRecorder* recorder() { return &recorder_; } |
1014 | 1037 |
1015 private: | 1038 private: |
1016 ParserRecorder recorder_; | 1039 ParserRecorder recorder_; |
1017 ParserFactory factory_; | 1040 ParserFactory factory_; |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1140 ((void)0 | 1163 ((void)0 |
1141 #define DUMMY ) // to make indentation work | 1164 #define DUMMY ) // to make indentation work |
1142 #undef DUMMY | 1165 #undef DUMMY |
1143 | 1166 |
1144 // ---------------------------------------------------------------------------- | 1167 // ---------------------------------------------------------------------------- |
1145 // Implementation of Parser | 1168 // Implementation of Parser |
1146 | 1169 |
1147 Parser::Parser(Handle<Script> script, | 1170 Parser::Parser(Handle<Script> script, |
1148 bool allow_natives_syntax, | 1171 bool allow_natives_syntax, |
1149 v8::Extension* extension, | 1172 v8::Extension* extension, |
1150 bool is_pre_parsing, | 1173 ParserMode is_pre_parsing, |
1151 ParserFactory* factory, | 1174 ParserFactory* factory, |
1152 ParserLog* log, | 1175 ParserLog* log, |
1153 ScriptDataImpl* pre_data) | 1176 ScriptDataImpl* pre_data) |
1154 : script_(script), | 1177 : script_(script), |
1155 scanner_(is_pre_parsing), | 1178 scanner_(is_pre_parsing), |
1156 top_scope_(NULL), | 1179 top_scope_(NULL), |
1157 with_nesting_level_(0), | 1180 with_nesting_level_(0), |
1158 temp_scope_(NULL), | 1181 temp_scope_(NULL), |
1159 target_stack_(NULL), | 1182 target_stack_(NULL), |
1160 allow_natives_syntax_(allow_natives_syntax), | 1183 allow_natives_syntax_(allow_natives_syntax), |
1161 extension_(extension), | 1184 extension_(extension), |
1162 factory_(factory), | 1185 factory_(factory), |
1163 log_(log), | 1186 log_(log), |
1164 is_pre_parsing_(is_pre_parsing), | 1187 is_pre_parsing_(is_pre_parsing == PREPARSE), |
1165 pre_data_(pre_data) { | 1188 pre_data_(pre_data) { |
1166 } | 1189 } |
1167 | 1190 |
1168 | 1191 |
1169 bool Parser::PreParseProgram(Handle<String> source, | 1192 bool Parser::PreParseProgram(Handle<String> source, |
1170 unibrow::CharacterStream* stream) { | 1193 unibrow::CharacterStream* stream) { |
1171 HistogramTimerScope timer(&Counters::pre_parse); | 1194 HistogramTimerScope timer(&Counters::pre_parse); |
1172 AssertNoZoneAllocation assert_no_zone_allocation; | 1195 AssertNoZoneAllocation assert_no_zone_allocation; |
1173 AssertNoAllocation assert_no_allocation; | 1196 AssertNoAllocation assert_no_allocation; |
1174 NoHandleAllocation no_handle_allocation; | 1197 NoHandleAllocation no_handle_allocation; |
1175 scanner_.Init(source, stream, 0); | 1198 scanner_.Init(source, stream, 0, JAVASCRIPT); |
1176 ASSERT(target_stack_ == NULL); | 1199 ASSERT(target_stack_ == NULL); |
1177 mode_ = PARSE_EAGERLY; | 1200 mode_ = PARSE_EAGERLY; |
1178 DummyScope top_scope; | 1201 DummyScope top_scope; |
1179 LexicalScope scope(this, &top_scope); | 1202 LexicalScope scope(this, &top_scope); |
1180 TemporaryScope temp_scope(this); | 1203 TemporaryScope temp_scope(this); |
1181 ZoneListWrapper<Statement> processor; | 1204 ZoneListWrapper<Statement> processor; |
1182 bool ok = true; | 1205 bool ok = true; |
1183 ParseSourceElements(&processor, Token::EOS, &ok); | 1206 ParseSourceElements(&processor, Token::EOS, &ok); |
1184 return !scanner().stack_overflow(); | 1207 return !scanner().stack_overflow(); |
1185 } | 1208 } |
1186 | 1209 |
1187 | 1210 |
1188 FunctionLiteral* Parser::ParseProgram(Handle<String> source, | 1211 FunctionLiteral* Parser::ParseProgram(Handle<String> source, |
1189 unibrow::CharacterStream* stream, | 1212 unibrow::CharacterStream* stream, |
1190 bool in_global_context) { | 1213 bool in_global_context) { |
1191 CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT); | 1214 CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT); |
1192 | 1215 |
1193 HistogramTimerScope timer(&Counters::parse); | 1216 HistogramTimerScope timer(&Counters::parse); |
1194 Counters::total_parse_size.Increment(source->length()); | 1217 Counters::total_parse_size.Increment(source->length()); |
1195 | 1218 |
1196 // Initialize parser state. | 1219 // Initialize parser state. |
1197 source->TryFlattenIfNotFlat(); | 1220 source->TryFlattenIfNotFlat(); |
1198 scanner_.Init(source, stream, 0); | 1221 scanner_.Init(source, stream, 0, JAVASCRIPT); |
1199 ASSERT(target_stack_ == NULL); | 1222 ASSERT(target_stack_ == NULL); |
1200 | 1223 |
1201 // Compute the parsing mode. | 1224 // Compute the parsing mode. |
1202 mode_ = FLAG_lazy ? PARSE_LAZILY : PARSE_EAGERLY; | 1225 mode_ = FLAG_lazy ? PARSE_LAZILY : PARSE_EAGERLY; |
1203 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY; | 1226 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY; |
1204 | 1227 |
1205 Scope::Type type = | 1228 Scope::Type type = |
1206 in_global_context | 1229 in_global_context |
1207 ? Scope::GLOBAL_SCOPE | 1230 ? Scope::GLOBAL_SCOPE |
1208 : Scope::EVAL_SCOPE; | 1231 : Scope::EVAL_SCOPE; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1247 Handle<String> name, | 1270 Handle<String> name, |
1248 int start_position, | 1271 int start_position, |
1249 bool is_expression) { | 1272 bool is_expression) { |
1250 CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT); | 1273 CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT); |
1251 HistogramTimerScope timer(&Counters::parse_lazy); | 1274 HistogramTimerScope timer(&Counters::parse_lazy); |
1252 source->TryFlattenIfNotFlat(); | 1275 source->TryFlattenIfNotFlat(); |
1253 Counters::total_parse_size.Increment(source->length()); | 1276 Counters::total_parse_size.Increment(source->length()); |
1254 SafeStringInputBuffer buffer(source.location()); | 1277 SafeStringInputBuffer buffer(source.location()); |
1255 | 1278 |
1256 // Initialize parser state. | 1279 // Initialize parser state. |
1257 scanner_.Init(source, &buffer, start_position); | 1280 scanner_.Init(source, &buffer, start_position, JAVASCRIPT); |
1258 ASSERT(target_stack_ == NULL); | 1281 ASSERT(target_stack_ == NULL); |
1259 mode_ = PARSE_EAGERLY; | 1282 mode_ = PARSE_EAGERLY; |
1260 | 1283 |
1261 // Place holder for the result. | 1284 // Place holder for the result. |
1262 FunctionLiteral* result = NULL; | 1285 FunctionLiteral* result = NULL; |
1263 | 1286 |
1264 { | 1287 { |
1265 // Parse the function literal. | 1288 // Parse the function literal. |
1266 Handle<String> no_name = factory()->EmptySymbol(); | 1289 Handle<String> no_name = factory()->EmptySymbol(); |
1267 Scope* scope = | 1290 Scope* scope = |
(...skipping 15 matching lines...) Expand all Loading... | |
1283 | 1306 |
1284 // If there was a stack overflow we have to get rid of AST and it is | 1307 // If there was a stack overflow we have to get rid of AST and it is |
1285 // not safe to do before scope has been deleted. | 1308 // not safe to do before scope has been deleted. |
1286 if (result == NULL) { | 1309 if (result == NULL) { |
1287 Top::StackOverflow(); | 1310 Top::StackOverflow(); |
1288 zone_scope.DeleteOnExit(); | 1311 zone_scope.DeleteOnExit(); |
1289 } | 1312 } |
1290 return result; | 1313 return result; |
1291 } | 1314 } |
1292 | 1315 |
1316 FunctionLiteral* Parser::ParseJson(Handle<String> source, | |
1317 unibrow::CharacterStream* stream) { | |
1318 CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT); | |
1319 | |
1320 HistogramTimerScope timer(&Counters::parse); | |
1321 Counters::total_parse_size.Increment(source->length()); | |
1322 | |
1323 // Initialize parser state. | |
1324 source->TryFlattenIfNotFlat(); | |
1325 scanner_.Init(source, stream, 0, JSON); | |
1326 ASSERT(target_stack_ == NULL); | |
1327 | |
1328 FunctionLiteral* result = NULL; | |
1329 Handle<String> no_name = factory()->EmptySymbol(); | |
1330 | |
1331 { | |
1332 Scope* scope = factory()->NewScope(top_scope_, Scope::GLOBAL_SCOPE, false); | |
1333 LexicalScope lexical_scope(this, scope); | |
1334 TemporaryScope temp_scope(this); | |
1335 bool ok = true; | |
1336 Expression* expression = ParseJson(&ok); | |
1337 if (ok) { | |
1338 ZoneListWrapper<Statement> statement = factory()->NewList<Statement>(1); | |
1339 statement.Add(new ExpressionStatement(expression)); | |
1340 result = NEW(FunctionLiteral( | |
1341 no_name, | |
1342 top_scope_, | |
1343 statement.elements(), | |
1344 temp_scope.materialized_literal_count(), | |
1345 temp_scope.expected_property_count(), | |
1346 temp_scope.only_simple_this_property_assignments(), | |
1347 temp_scope.this_property_assignments(), | |
1348 0, | |
1349 0, | |
1350 source->length(), | |
1351 false)); | |
1352 } else if (scanner().stack_overflow()) { | |
1353 Top::StackOverflow(); | |
1354 } | |
1355 } | |
1356 | |
1357 // Make sure the target stack is empty. | |
1358 ASSERT(target_stack_ == NULL); | |
1359 | |
1360 // If there was a syntax error we have to get rid of the AST | |
1361 // and it is not safe to do so before the scope has been deleted. | |
1362 if (result == NULL) zone_scope.DeleteOnExit(); | |
1363 return result; | |
1364 } | |
1293 | 1365 |
1294 void Parser::ReportMessage(const char* type, Vector<const char*> args) { | 1366 void Parser::ReportMessage(const char* type, Vector<const char*> args) { |
1295 Scanner::Location source_location = scanner_.location(); | 1367 Scanner::Location source_location = scanner_.location(); |
1296 ReportMessageAt(source_location, type, args); | 1368 ReportMessageAt(source_location, type, args); |
1297 } | 1369 } |
1298 | 1370 |
1299 | 1371 |
1300 void AstBuildingParser::ReportMessageAt(Scanner::Location source_location, | 1372 void AstBuildingParser::ReportMessageAt(Scanner::Location source_location, |
1301 const char* type, | 1373 const char* type, |
1302 Vector<const char*> args) { | 1374 Vector<const char*> args) { |
(...skipping 1812 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3115 | 3187 |
3116 Expect(Token::DEBUGGER, CHECK_OK); | 3188 Expect(Token::DEBUGGER, CHECK_OK); |
3117 ExpectSemicolon(CHECK_OK); | 3189 ExpectSemicolon(CHECK_OK); |
3118 return NEW(DebuggerStatement()); | 3190 return NEW(DebuggerStatement()); |
3119 } | 3191 } |
3120 | 3192 |
3121 | 3193 |
3122 void Parser::ReportUnexpectedToken(Token::Value token) { | 3194 void Parser::ReportUnexpectedToken(Token::Value token) { |
3123 // We don't report stack overflows here, to avoid increasing the | 3195 // We don't report stack overflows here, to avoid increasing the |
3124 // stack depth even further. Instead we report it after parsing is | 3196 // stack depth even further. Instead we report it after parsing is |
3125 // over, in ParseProgram. | 3197 // over, in ParseProgram/ParseJson. |
3126 if (token == Token::ILLEGAL && scanner().stack_overflow()) | 3198 if (token == Token::ILLEGAL && scanner().stack_overflow()) |
3127 return; | 3199 return; |
3128 // Four of the tokens are treated specially | 3200 // Four of the tokens are treated specially |
3129 switch (token) { | 3201 switch (token) { |
3130 case Token::EOS: | 3202 case Token::EOS: |
3131 return ReportMessage("unexpected_eos", Vector<const char*>::empty()); | 3203 return ReportMessage("unexpected_eos", Vector<const char*>::empty()); |
3132 case Token::NUMBER: | 3204 case Token::NUMBER: |
3133 return ReportMessage("unexpected_token_number", | 3205 return ReportMessage("unexpected_token_number", |
3134 Vector<const char*>::empty()); | 3206 Vector<const char*>::empty()); |
3135 case Token::STRING: | 3207 case Token::STRING: |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3447 // TODO(1240767): Consider allowing trailing comma. | 3519 // TODO(1240767): Consider allowing trailing comma. |
3448 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); | 3520 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); |
3449 } | 3521 } |
3450 Expect(Token::RBRACE, CHECK_OK); | 3522 Expect(Token::RBRACE, CHECK_OK); |
3451 // Computation of literal_index must happen before pre parse bailout. | 3523 // Computation of literal_index must happen before pre parse bailout. |
3452 int literal_index = temp_scope_->NextMaterializedLiteralIndex(); | 3524 int literal_index = temp_scope_->NextMaterializedLiteralIndex(); |
3453 if (is_pre_parsing_) return NULL; | 3525 if (is_pre_parsing_) return NULL; |
3454 | 3526 |
3455 Handle<FixedArray> constant_properties = | 3527 Handle<FixedArray> constant_properties = |
3456 Factory::NewFixedArray(number_of_boilerplate_properties * 2, TENURED); | 3528 Factory::NewFixedArray(number_of_boilerplate_properties * 2, TENURED); |
3457 int position = 0; | 3529 |
3458 bool is_simple = true; | 3530 bool is_simple = true; |
3459 int depth = 1; | 3531 int depth = 1; |
3460 for (int i = 0; i < properties.length(); i++) { | 3532 BuildObjectLiteralConstantProperties(properties.elements(), |
3461 ObjectLiteral::Property* property = properties.at(i); | 3533 constant_properties, |
3462 if (!IsBoilerplateProperty(property)) { | 3534 &is_simple, |
3463 is_simple = false; | 3535 &depth); |
3464 continue; | |
3465 } | |
3466 MaterializedLiteral* m_literal = property->value()->AsMaterializedLiteral(); | |
3467 if (m_literal != NULL && m_literal->depth() + 1 > depth) { | |
3468 depth = m_literal->depth() + 1; | |
3469 } | |
3470 | |
3471 // Add CONSTANT and COMPUTED properties to boilerplate. Use undefined | |
3472 // value for COMPUTED properties, the real value is filled in at | |
3473 // runtime. The enumeration order is maintained. | |
3474 Handle<Object> key = property->key()->handle(); | |
3475 Handle<Object> value = GetBoilerplateValue(property->value()); | |
3476 is_simple = is_simple && !value->IsUndefined(); | |
3477 | |
3478 // Add name, value pair to the fixed array. | |
3479 constant_properties->set(position++, *key); | |
3480 constant_properties->set(position++, *value); | |
3481 } | |
3482 | |
3483 return new ObjectLiteral(constant_properties, | 3536 return new ObjectLiteral(constant_properties, |
3484 properties.elements(), | 3537 properties.elements(), |
3485 literal_index, | 3538 literal_index, |
3486 is_simple, | 3539 is_simple, |
3487 depth); | 3540 depth); |
3488 } | 3541 } |
3489 | 3542 |
3490 | 3543 |
3491 Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) { | 3544 Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) { |
3492 if (!scanner_.ScanRegExpPattern(seen_equal)) { | 3545 if (!scanner_.ScanRegExpPattern(seen_equal)) { |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3713 | 3766 |
3714 | 3767 |
3715 void Parser::Expect(Token::Value token, bool* ok) { | 3768 void Parser::Expect(Token::Value token, bool* ok) { |
3716 Token::Value next = Next(); | 3769 Token::Value next = Next(); |
3717 if (next == token) return; | 3770 if (next == token) return; |
3718 ReportUnexpectedToken(next); | 3771 ReportUnexpectedToken(next); |
3719 *ok = false; | 3772 *ok = false; |
3720 } | 3773 } |
3721 | 3774 |
3722 | 3775 |
3776 bool Parser::Check(Token::Value token) { | |
3777 Token::Value next = peek(); | |
3778 if (next == token) { | |
3779 Consume(next); | |
3780 return true; | |
3781 } | |
3782 return false; | |
3783 } | |
3784 | |
3785 | |
3723 void Parser::ExpectSemicolon(bool* ok) { | 3786 void Parser::ExpectSemicolon(bool* ok) { |
3724 // Check for automatic semicolon insertion according to | 3787 // Check for automatic semicolon insertion according to |
3725 // the rules given in ECMA-262, section 7.9, page 21. | 3788 // the rules given in ECMA-262, section 7.9, page 21. |
3726 Token::Value tok = peek(); | 3789 Token::Value tok = peek(); |
3727 if (tok == Token::SEMICOLON) { | 3790 if (tok == Token::SEMICOLON) { |
3728 Next(); | 3791 Next(); |
3729 return; | 3792 return; |
3730 } | 3793 } |
3731 if (scanner_.has_line_terminator_before_next() || | 3794 if (scanner_.has_line_terminator_before_next() || |
3732 tok == Token::RBRACE || | 3795 tok == Token::RBRACE || |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3879 array->SetFastElement(i, *element); | 3942 array->SetFastElement(i, *element); |
3880 } | 3943 } |
3881 } | 3944 } |
3882 ZoneList<Expression*>* args = new ZoneList<Expression*>(2); | 3945 ZoneList<Expression*>* args = new ZoneList<Expression*>(2); |
3883 args->Add(new Literal(type)); | 3946 args->Add(new Literal(type)); |
3884 args->Add(new Literal(array)); | 3947 args->Add(new Literal(array)); |
3885 return new Throw(new CallRuntime(constructor, NULL, args), | 3948 return new Throw(new CallRuntime(constructor, NULL, args), |
3886 scanner().location().beg_pos); | 3949 scanner().location().beg_pos); |
3887 } | 3950 } |
3888 | 3951 |
3952 // ---------------------------------------------------------------------------- | |
3953 // JSON | |
3954 | |
3955 void Parser::BuildObjectLiteralConstantProperties( | |
Mads Ager (chromium)
2010/02/01 08:42:19
This is used for normal parsing of object literals
Lasse Reichstein
2010/02/01 12:17:30
Done.
| |
3956 ZoneList<ObjectLiteral::Property*>* properties, | |
3957 Handle<FixedArray> constant_properties, | |
3958 bool* is_simple_out, | |
3959 int* depth_out) { | |
3960 int position = 0; | |
3961 bool is_simple = true; | |
3962 int depth = 1; | |
3963 for (int i = 0; i < properties->length(); i++) { | |
3964 ObjectLiteral::Property* property = properties->at(i); | |
3965 if (!IsBoilerplateProperty(property)) { | |
3966 is_simple = false; | |
3967 continue; | |
3968 } | |
3969 MaterializedLiteral* m_literal = property->value()->AsMaterializedLiteral(); | |
3970 if (m_literal != NULL && m_literal->depth() + 1 > depth) { | |
3971 depth = m_literal->depth() + 1; | |
3972 } | |
3973 | |
3974 // Add CONSTANT and COMPUTED properties to boilerplate. Use undefined | |
3975 // value for COMPUTED properties, the real value is filled in at | |
3976 // runtime. The enumeration order is maintained. | |
3977 Handle<Object> key = property->key()->handle(); | |
3978 Handle<Object> value = GetBoilerplateValue(property->value()); | |
3979 is_simple = is_simple && !value->IsUndefined(); | |
3980 | |
3981 // Add name, value pair to the fixed array. | |
3982 constant_properties->set(position++, *key); | |
3983 constant_properties->set(position++, *value); | |
3984 } | |
3985 | |
3986 *is_simple_out = is_simple; | |
3987 *depth_out = depth; | |
3988 } | |
3989 | |
3990 | |
3991 Expression* Parser::ParseJson(bool* ok) { | |
3992 Expression* result = ParseJsonValue(CHECK_OK); | |
3993 Expect(Token::EOS, CHECK_OK); | |
3994 return result; | |
3995 } | |
3996 | |
3997 | |
3998 // Parse any JSON value. | |
3999 Expression* Parser::ParseJsonValue(bool* ok) { | |
4000 Token::Value token = peek(); | |
4001 switch (token) { | |
4002 case Token::STRING: { | |
4003 Consume(Token::STRING); | |
4004 int literal_length = scanner_.literal_length(); | |
4005 const char* literal_string = scanner_.literal_string(); | |
4006 if (literal_length == 0) { | |
4007 return NEW(Literal(Factory::empty_string())); | |
4008 } | |
4009 Vector<const char> literal(literal_string, literal_length); | |
4010 return NEW(Literal(Factory::NewStringFromUtf8(literal, TENURED))); | |
4011 } | |
4012 case Token::NUMBER: { | |
4013 Consume(Token::NUMBER); | |
4014 ASSERT(scanner_.literal_length() > 0); | |
4015 double value = StringToDouble(scanner_.literal_string(), | |
4016 NO_FLAGS, // Hex, octal or trailing junk. | |
4017 OS::nan_value()); | |
4018 return NewNumberLiteral(value); | |
4019 } | |
4020 case Token::FALSE_LITERAL: | |
4021 Consume(Token::FALSE_LITERAL); | |
4022 return NEW(Literal(Factory::false_value())); | |
4023 case Token::TRUE_LITERAL: | |
4024 Consume(Token::TRUE_LITERAL); | |
4025 return NEW(Literal(Factory::true_value())); | |
4026 case Token::NULL_LITERAL: | |
4027 Consume(Token::NULL_LITERAL); | |
4028 return NEW(Literal(Factory::null_value())); | |
4029 case Token::LBRACE: { | |
4030 Expression* result = ParseJsonObject(CHECK_OK); | |
4031 return result; | |
4032 } | |
4033 case Token::LBRACK: { | |
4034 Expression* result = ParseJsonArray(CHECK_OK); | |
4035 return result; | |
4036 } | |
4037 default: | |
4038 *ok = false; | |
4039 ReportUnexpectedToken(token); | |
4040 return NULL; | |
4041 } | |
4042 } | |
4043 | |
4044 | |
4045 // Parse a JSON object. Scanner must be right after '{' token. | |
4046 Expression* Parser::ParseJsonObject(bool* ok) { | |
4047 Consume(Token::LBRACE); | |
4048 ZoneListWrapper<ObjectLiteral::Property> properties = | |
4049 factory()->NewList<ObjectLiteral::Property>(4); | |
4050 int boilerplate_properties = 0; | |
4051 if (peek() != Token::RBRACE) { | |
4052 do { | |
4053 Expect(Token::STRING, CHECK_OK); | |
4054 Handle<String> key = factory()->LookupSymbol(scanner_.literal_string(), | |
4055 scanner_.literal_length()); | |
4056 Expect(Token::COLON, CHECK_OK); | |
4057 Expression* value = ParseJsonValue(CHECK_OK); | |
4058 Literal* key_literal; | |
4059 uint32_t index; | |
4060 if (key->AsArrayIndex(&index)) { | |
4061 key_literal = NewNumberLiteral(index); | |
4062 } else { | |
4063 key_literal = NEW(Literal(key)); | |
4064 } | |
4065 ObjectLiteral::Property* property = | |
4066 NEW(ObjectLiteral::Property(key_literal, value)); | |
4067 properties.Add(property); | |
4068 | |
4069 if (IsBoilerplateProperty(property)) { | |
4070 boilerplate_properties++; | |
4071 } | |
4072 } while (Check(Token::COMMA)); | |
4073 } | |
4074 Expect(Token::RBRACE, CHECK_OK); | |
4075 | |
4076 int literal_index = temp_scope_->NextMaterializedLiteralIndex(); | |
4077 if (is_pre_parsing_) return NULL; | |
4078 | |
4079 Handle<FixedArray> constant_properties = | |
4080 Factory::NewFixedArray(boilerplate_properties * 2, TENURED); | |
4081 bool is_simple = true; | |
4082 int depth = 1; | |
4083 BuildObjectLiteralConstantProperties(properties.elements(), | |
4084 constant_properties, | |
4085 &is_simple, | |
4086 &depth); | |
4087 return new ObjectLiteral(constant_properties, | |
4088 properties.elements(), | |
4089 literal_index, | |
4090 is_simple, | |
4091 depth); | |
4092 } | |
4093 | |
4094 | |
4095 void Parser::BuildArrayLiteralBoilerplateLiterals(ZoneList<Expression*>* values, | |
4096 Handle<FixedArray> literals, | |
4097 bool* is_simple_out, | |
4098 int* depth_out) { | |
4099 // Fill in the literals. | |
4100 bool is_simple = true; | |
4101 int depth = 1; | |
4102 for (int i = 0; i < values->length(); i++) { | |
4103 MaterializedLiteral* m_literal = values->at(i)->AsMaterializedLiteral(); | |
4104 if (m_literal != NULL && m_literal->depth() + 1 > depth) { | |
4105 depth = m_literal->depth() + 1; | |
4106 } | |
4107 Handle<Object> boilerplate_value = GetBoilerplateValue(values->at(i)); | |
4108 if (boilerplate_value->IsUndefined()) { | |
4109 literals->set_the_hole(i); | |
4110 is_simple = false; | |
4111 } else { | |
4112 literals->set(i, *boilerplate_value); | |
4113 } | |
4114 } | |
4115 | |
4116 *is_simple_out = is_simple; | |
4117 *depth_out = depth; | |
4118 } | |
4119 | |
4120 | |
4121 // Parse a JSON object. Scanner must be right after '[' token. | |
4122 Expression* Parser::ParseJsonArray(bool* ok) { | |
4123 Consume(Token::LBRACK); | |
4124 | |
4125 ZoneListWrapper<Expression> values = factory()->NewList<Expression>(4); | |
4126 if (peek() != Token::RBRACK) { | |
4127 do { | |
4128 Expression* exp = ParseJsonValue(CHECK_OK); | |
4129 values.Add(exp); | |
4130 } while (Check(Token::COMMA)); | |
4131 } | |
4132 Expect(Token::RBRACK, CHECK_OK); | |
4133 | |
4134 // Update the scope information before the pre-parsing bailout. | |
4135 int literal_index = temp_scope_->NextMaterializedLiteralIndex(); | |
4136 | |
4137 if (is_pre_parsing_) return NULL; | |
4138 | |
4139 // Allocate a fixed array with all the literals. | |
4140 Handle<FixedArray> literals = | |
4141 Factory::NewFixedArray(values.length(), TENURED); | |
4142 | |
4143 bool is_simple; | |
4144 int depth; | |
4145 BuildArrayLiteralBoilerplateLiterals(values.elements(), | |
4146 literals, | |
4147 &is_simple, | |
4148 &depth); | |
4149 return NEW(ArrayLiteral(literals, values.elements(), | |
4150 literal_index, is_simple, depth)); | |
4151 } | |
4152 | |
3889 | 4153 |
3890 // ---------------------------------------------------------------------------- | 4154 // ---------------------------------------------------------------------------- |
3891 // Regular expressions | 4155 // Regular expressions |
3892 | 4156 |
3893 | 4157 |
3894 RegExpParser::RegExpParser(FlatStringReader* in, | 4158 RegExpParser::RegExpParser(FlatStringReader* in, |
3895 Handle<String>* error, | 4159 Handle<String>* error, |
3896 bool multiline) | 4160 bool multiline) |
3897 : current_(kEndMarker), | 4161 : current_(kEndMarker), |
3898 has_more_(true), | 4162 has_more_(true), |
(...skipping 855 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4754 result->contains_anchor = parser.contains_anchor(); | 5018 result->contains_anchor = parser.contains_anchor(); |
4755 result->capture_count = capture_count; | 5019 result->capture_count = capture_count; |
4756 } | 5020 } |
4757 return !parser.failed(); | 5021 return !parser.failed(); |
4758 } | 5022 } |
4759 | 5023 |
4760 | 5024 |
4761 FunctionLiteral* MakeAST(bool compile_in_global_context, | 5025 FunctionLiteral* MakeAST(bool compile_in_global_context, |
4762 Handle<Script> script, | 5026 Handle<Script> script, |
4763 v8::Extension* extension, | 5027 v8::Extension* extension, |
4764 ScriptDataImpl* pre_data) { | 5028 ScriptDataImpl* pre_data, |
5029 bool is_json) { | |
4765 bool allow_natives_syntax = | 5030 bool allow_natives_syntax = |
4766 always_allow_natives_syntax || | 5031 always_allow_natives_syntax || |
4767 FLAG_allow_natives_syntax || | 5032 FLAG_allow_natives_syntax || |
4768 Bootstrapper::IsActive(); | 5033 Bootstrapper::IsActive(); |
4769 AstBuildingParser parser(script, allow_natives_syntax, extension, pre_data); | 5034 AstBuildingParser parser(script, allow_natives_syntax, extension, pre_data); |
4770 if (pre_data != NULL && pre_data->has_error()) { | 5035 if (pre_data != NULL && pre_data->has_error()) { |
4771 Scanner::Location loc = pre_data->MessageLocation(); | 5036 Scanner::Location loc = pre_data->MessageLocation(); |
4772 const char* message = pre_data->BuildMessage(); | 5037 const char* message = pre_data->BuildMessage(); |
4773 Vector<const char*> args = pre_data->BuildArgs(); | 5038 Vector<const char*> args = pre_data->BuildArgs(); |
4774 parser.ReportMessageAt(loc, message, args); | 5039 parser.ReportMessageAt(loc, message, args); |
4775 DeleteArray(message); | 5040 DeleteArray(message); |
4776 for (int i = 0; i < args.length(); i++) | 5041 for (int i = 0; i < args.length(); i++) { |
4777 DeleteArray(args[i]); | 5042 DeleteArray(args[i]); |
5043 } | |
4778 DeleteArray(args.start()); | 5044 DeleteArray(args.start()); |
4779 return NULL; | 5045 return NULL; |
4780 } | 5046 } |
4781 Handle<String> source = Handle<String>(String::cast(script->source())); | 5047 Handle<String> source = Handle<String>(String::cast(script->source())); |
4782 SafeStringInputBuffer input(source.location()); | 5048 SafeStringInputBuffer input(source.location()); |
4783 FunctionLiteral* result = parser.ParseProgram(source, | 5049 FunctionLiteral* result; |
4784 &input, compile_in_global_context); | 5050 if (is_json) { |
5051 ASSERT(compile_in_global_context); | |
5052 result = parser.ParseJson(source, &input); | |
5053 } else { | |
5054 result = parser.ParseProgram(source, &input, compile_in_global_context); | |
5055 } | |
4785 return result; | 5056 return result; |
4786 } | 5057 } |
4787 | 5058 |
4788 | 5059 |
4789 FunctionLiteral* MakeLazyAST(Handle<Script> script, | 5060 FunctionLiteral* MakeLazyAST(Handle<Script> script, |
4790 Handle<String> name, | 5061 Handle<String> name, |
4791 int start_position, | 5062 int start_position, |
4792 int end_position, | 5063 int end_position, |
4793 bool is_expression) { | 5064 bool is_expression) { |
4794 bool allow_natives_syntax_before = always_allow_natives_syntax; | 5065 bool allow_natives_syntax_before = always_allow_natives_syntax; |
4795 always_allow_natives_syntax = true; | 5066 always_allow_natives_syntax = true; |
4796 AstBuildingParser parser(script, true, NULL, NULL); // always allow | 5067 AstBuildingParser parser(script, true, NULL, NULL); // always allow |
4797 always_allow_natives_syntax = allow_natives_syntax_before; | 5068 always_allow_natives_syntax = allow_natives_syntax_before; |
4798 // Parse the function by pulling the function source from the script source. | 5069 // Parse the function by pulling the function source from the script source. |
4799 Handle<String> script_source(String::cast(script->source())); | 5070 Handle<String> script_source(String::cast(script->source())); |
4800 FunctionLiteral* result = | 5071 FunctionLiteral* result = |
4801 parser.ParseLazy(SubString(script_source, start_position, end_position), | 5072 parser.ParseLazy(SubString(script_source, start_position, end_position), |
4802 name, | 5073 name, |
4803 start_position, | 5074 start_position, |
4804 is_expression); | 5075 is_expression); |
4805 return result; | 5076 return result; |
4806 } | 5077 } |
4807 | 5078 |
4808 | 5079 |
4809 #undef NEW | 5080 #undef NEW |
4810 | 5081 |
4811 | 5082 |
4812 } } // namespace v8::internal | 5083 } } // namespace v8::internal |
OLD | NEW |