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 16 matching lines...) Expand all Loading... | |
27 | 27 |
28 #ifndef V8_AST_H_ | 28 #ifndef V8_AST_H_ |
29 #define V8_AST_H_ | 29 #define V8_AST_H_ |
30 | 30 |
31 #include "execution.h" | 31 #include "execution.h" |
32 #include "factory.h" | 32 #include "factory.h" |
33 #include "runtime.h" | 33 #include "runtime.h" |
34 #include "token.h" | 34 #include "token.h" |
35 #include "variables.h" | 35 #include "variables.h" |
36 #include "macro-assembler.h" | 36 #include "macro-assembler.h" |
37 #include "jsregexp.h" | |
37 | 38 |
38 namespace v8 { namespace internal { | 39 namespace v8 { namespace internal { |
39 | 40 |
40 // The abstract syntax tree is an intermediate, light-weight | 41 // The abstract syntax tree is an intermediate, light-weight |
41 // representation of the parsed JavaScript code suitable for | 42 // representation of the parsed JavaScript code suitable for |
42 // compilation to native code. | 43 // compilation to native code. |
43 | 44 |
44 // Nodes are allocated in a separate zone, which allows faster | 45 // Nodes are allocated in a separate zone, which allows faster |
45 // allocation and constant-time deallocation of the entire syntax | 46 // allocation and constant-time deallocation of the entire syntax |
46 // tree. | 47 // tree. |
(...skipping 1138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1185 }; | 1186 }; |
1186 | 1187 |
1187 | 1188 |
1188 class ThisFunction: public Expression { | 1189 class ThisFunction: public Expression { |
1189 public: | 1190 public: |
1190 virtual void Accept(Visitor* v); | 1191 virtual void Accept(Visitor* v); |
1191 }; | 1192 }; |
1192 | 1193 |
1193 | 1194 |
1194 // ---------------------------------------------------------------------------- | 1195 // ---------------------------------------------------------------------------- |
1196 // Regular expressions | |
1197 | |
1198 | |
1199 class RegExpTree: public ZoneObject { | |
1200 public: | |
1201 virtual ~RegExpTree() { } | |
1202 virtual void* Accept(RegExpVisitor* visitor, void* data) = 0; | |
1203 virtual RegExpNode* ToNode(RegExpCompiler* compiler, | |
1204 RegExpNode* on_success, | |
1205 RegExpNode* on_failure) = 0; | |
1206 virtual bool IsTextElement() { return false; } | |
1207 virtual void AppendToText(RegExpText* text); | |
1208 SmartPointer<const char> ToString(); | |
1209 #define MAKE_ASTYPE(Name) \ | |
1210 virtual RegExp##Name* As##Name(); \ | |
1211 virtual bool Is##Name(); | |
1212 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_ASTYPE) | |
1213 #undef MAKE_ASTYPE | |
1214 }; | |
1215 | |
1216 | |
1217 class RegExpDisjunction: public RegExpTree { | |
1218 public: | |
1219 explicit RegExpDisjunction(ZoneList<RegExpTree*>* alternatives) | |
1220 : alternatives_(alternatives) { } | |
Mads Ager (chromium)
2008/11/25 21:09:41
Use four space indent of initializer list. Multip
Christian Plesner Hansen
2008/11/26 06:49:56
Fixed.
| |
1221 virtual void* Accept(RegExpVisitor* visitor, void* data); | |
1222 virtual RegExpNode* ToNode(RegExpCompiler* compiler, | |
1223 RegExpNode* on_success, | |
1224 RegExpNode* on_failure); | |
1225 virtual RegExpDisjunction* AsDisjunction(); | |
1226 virtual bool IsDisjunction(); | |
1227 ZoneList<RegExpTree*>* alternatives() { return alternatives_; } | |
1228 private: | |
1229 ZoneList<RegExpTree*>* alternatives_; | |
1230 }; | |
1231 | |
1232 | |
1233 class RegExpAlternative: public RegExpTree { | |
1234 public: | |
1235 explicit RegExpAlternative(ZoneList<RegExpTree*>* nodes) : nodes_(nodes) { } | |
1236 virtual void* Accept(RegExpVisitor* visitor, void* data); | |
1237 virtual RegExpNode* ToNode(RegExpCompiler* compiler, | |
1238 RegExpNode* on_success, | |
1239 RegExpNode* on_failure); | |
1240 virtual RegExpAlternative* AsAlternative(); | |
1241 virtual bool IsAlternative(); | |
1242 ZoneList<RegExpTree*>* nodes() { return nodes_; } | |
1243 private: | |
1244 ZoneList<RegExpTree*>* nodes_; | |
1245 }; | |
1246 | |
1247 | |
1248 class RegExpText: public RegExpTree { | |
1249 public: | |
1250 RegExpText() : elements_(2) { } | |
1251 virtual void* Accept(RegExpVisitor* visitor, void* data); | |
1252 virtual RegExpNode* ToNode(RegExpCompiler* compiler, | |
1253 RegExpNode* on_success, | |
1254 RegExpNode* on_failure); | |
1255 virtual RegExpText* AsText(); | |
1256 virtual bool IsText(); | |
1257 virtual bool IsTextElement() { return true; } | |
1258 virtual void AppendToText(RegExpText* text); | |
1259 void AddElement(TextElement elm) { elements_.Add(elm); } | |
1260 ZoneList<TextElement>* elements() { return &elements_; } | |
1261 private: | |
1262 ZoneList<TextElement> elements_; | |
1263 }; | |
1264 | |
1265 | |
1266 class RegExpAssertion: public RegExpTree { | |
1267 public: | |
1268 enum Type { | |
1269 START_OF_LINE, START_OF_INPUT, END_OF_LINE, END_OF_INPUT, | |
Mads Ager (chromium)
2008/11/25 21:09:41
One enum value per line?
Christian Plesner Hansen
2008/11/26 06:49:56
Fixed. Note, however, that the style guide doesn'
| |
1270 BOUNDARY, NON_BOUNDARY | |
1271 }; | |
1272 explicit RegExpAssertion(Type type) : type_(type) { } | |
1273 virtual void* Accept(RegExpVisitor* visitor, void* data); | |
1274 virtual RegExpNode* ToNode(RegExpCompiler* compiler, | |
1275 RegExpNode* on_success, | |
1276 RegExpNode* on_failure); | |
1277 virtual RegExpAssertion* AsAssertion(); | |
1278 virtual bool IsAssertion(); | |
1279 Type type() { return type_; } | |
1280 private: | |
1281 Type type_; | |
1282 }; | |
1283 | |
1284 | |
1285 class RegExpCharacterClass: public RegExpTree { | |
1286 public: | |
1287 RegExpCharacterClass(ZoneList<CharacterRange>* ranges, bool is_negated) | |
1288 : ranges_(ranges), | |
1289 is_negated_(is_negated) { } | |
1290 explicit RegExpCharacterClass(uc16 type) | |
1291 : ranges_(new ZoneList<CharacterRange>(2)), | |
1292 is_negated_(false) { | |
1293 CharacterRange::AddClassEscape(type, ranges_); | |
1294 } | |
1295 virtual void* Accept(RegExpVisitor* visitor, void* data); | |
1296 virtual RegExpNode* ToNode(RegExpCompiler* compiler, | |
1297 RegExpNode* on_success, | |
1298 RegExpNode* on_failure); | |
1299 virtual RegExpCharacterClass* AsCharacterClass(); | |
1300 virtual bool IsCharacterClass(); | |
1301 virtual bool IsTextElement() { return true; } | |
1302 virtual void AppendToText(RegExpText* text); | |
1303 ZoneList<CharacterRange>* ranges() { return ranges_; } | |
1304 bool is_negated() { return is_negated_; } | |
1305 private: | |
1306 ZoneList<CharacterRange>* ranges_; | |
1307 bool is_negated_; | |
1308 }; | |
1309 | |
1310 | |
1311 class RegExpAtom: public RegExpTree { | |
1312 public: | |
1313 explicit RegExpAtom(Vector<const uc16> data) : data_(data) { } | |
1314 virtual void* Accept(RegExpVisitor* visitor, void* data); | |
1315 virtual RegExpNode* ToNode(RegExpCompiler* compiler, | |
1316 RegExpNode* on_success, | |
1317 RegExpNode* on_failure); | |
1318 virtual RegExpAtom* AsAtom(); | |
1319 virtual bool IsAtom(); | |
1320 virtual bool IsTextElement() { return true; } | |
1321 virtual void AppendToText(RegExpText* text); | |
1322 Vector<const uc16> data() { return data_; } | |
1323 private: | |
1324 Vector<const uc16> data_; | |
1325 }; | |
1326 | |
1327 | |
1328 class RegExpQuantifier: public RegExpTree { | |
1329 public: | |
1330 RegExpQuantifier(int min, int max, bool is_greedy, RegExpTree* body) | |
1331 : min_(min), | |
1332 max_(max), | |
1333 is_greedy_(is_greedy), | |
1334 body_(body) { } | |
1335 virtual void* Accept(RegExpVisitor* visitor, void* data); | |
1336 virtual RegExpNode* ToNode(RegExpCompiler* compiler, | |
1337 RegExpNode* on_success, | |
1338 RegExpNode* on_failure); | |
1339 static RegExpNode* ToNode(int min, | |
1340 int max, | |
1341 bool is_greedy, | |
1342 RegExpTree* body, | |
1343 RegExpCompiler* compiler, | |
1344 RegExpNode* on_success, | |
1345 RegExpNode* on_failure); | |
1346 virtual RegExpQuantifier* AsQuantifier(); | |
1347 virtual bool IsQuantifier(); | |
1348 int min() { return min_; } | |
1349 int max() { return max_; } | |
1350 bool is_greedy() { return is_greedy_; } | |
1351 RegExpTree* body() { return body_; } | |
1352 // We just use a very large integer value as infinity because 2^30 | |
1353 // is infinite in practice. | |
1354 static const int kInfinity = (1 << 30); | |
1355 private: | |
1356 int min_; | |
1357 int max_; | |
1358 bool is_greedy_; | |
1359 RegExpTree* body_; | |
1360 }; | |
1361 | |
1362 | |
1363 enum CaptureAvailability { | |
1364 CAPTURE_AVAILABLE, CAPTURE_UNREACHABLE, CAPTURE_PERMANENTLY_UNREACHABLE }; | |
Mads Ager (chromium)
2008/11/25 21:09:41
Two space indent instead of four. One enum value
| |
1365 | |
1366 class RegExpCapture: public RegExpTree { | |
1367 public: | |
1368 explicit RegExpCapture(RegExpTree* body, int index) | |
1369 : body_(body), index_(index), available_(CAPTURE_AVAILABLE) { } | |
1370 virtual void* Accept(RegExpVisitor* visitor, void* data); | |
1371 virtual RegExpNode* ToNode(RegExpCompiler* compiler, | |
1372 RegExpNode* on_success, | |
1373 RegExpNode* on_failure); | |
1374 static RegExpNode* ToNode(RegExpTree* body, | |
1375 int index, | |
1376 RegExpCompiler* compiler, | |
1377 RegExpNode* on_success, | |
1378 RegExpNode* on_failure); | |
1379 virtual RegExpCapture* AsCapture(); | |
1380 virtual bool IsCapture(); | |
1381 RegExpTree* body() { return body_; } | |
1382 int index() { return index_; } | |
1383 inline CaptureAvailability available() { return available_; } | |
1384 inline void set_available(CaptureAvailability availability) { | |
1385 available_ = availability; | |
1386 } | |
1387 static int StartRegister(int index) { return index * 2; } | |
1388 static int EndRegister(int index) { return index * 2 + 1; } | |
1389 private: | |
1390 RegExpTree* body_; | |
1391 int index_; | |
1392 CaptureAvailability available_; | |
1393 }; | |
1394 | |
1395 | |
1396 class RegExpLookahead: public RegExpTree { | |
1397 public: | |
1398 RegExpLookahead(RegExpTree* body, bool is_positive) | |
1399 : body_(body), | |
1400 is_positive_(is_positive) { } | |
1401 virtual void* Accept(RegExpVisitor* visitor, void* data); | |
1402 virtual RegExpNode* ToNode(RegExpCompiler* compiler, | |
1403 RegExpNode* on_success, | |
1404 RegExpNode* on_failure); | |
1405 virtual RegExpLookahead* AsLookahead(); | |
1406 virtual bool IsLookahead(); | |
1407 RegExpTree* body() { return body_; } | |
1408 bool is_positive() { return is_positive_; } | |
1409 private: | |
1410 RegExpTree* body_; | |
1411 bool is_positive_; | |
1412 }; | |
1413 | |
1414 | |
1415 class RegExpBackReference: public RegExpTree { | |
1416 public: | |
1417 explicit RegExpBackReference(RegExpCapture* capture) | |
1418 : capture_(capture) { } | |
1419 virtual void* Accept(RegExpVisitor* visitor, void* data); | |
1420 virtual RegExpNode* ToNode(RegExpCompiler* compiler, | |
1421 RegExpNode* on_success, | |
1422 RegExpNode* on_failure); | |
1423 virtual RegExpBackReference* AsBackReference(); | |
1424 virtual bool IsBackReference(); | |
1425 int index() { return capture_->index(); } | |
1426 RegExpCapture* capture() { return capture_; } | |
1427 private: | |
1428 RegExpCapture* capture_; | |
1429 }; | |
1430 | |
1431 | |
1432 class RegExpEmpty: public RegExpTree { | |
1433 public: | |
1434 RegExpEmpty() { } | |
1435 virtual void* Accept(RegExpVisitor* visitor, void* data); | |
1436 virtual RegExpNode* ToNode(RegExpCompiler* compiler, | |
1437 RegExpNode* on_success, | |
1438 RegExpNode* on_failure); | |
1439 virtual RegExpEmpty* AsEmpty(); | |
1440 virtual bool IsEmpty(); | |
1441 static RegExpEmpty* GetInstance() { return &kInstance; } | |
1442 private: | |
1443 static RegExpEmpty kInstance; | |
1444 }; | |
1445 | |
1446 | |
1447 class RegExpVisitor BASE_EMBEDDED { | |
1448 public: | |
1449 virtual ~RegExpVisitor() { } | |
1450 #define MAKE_CASE(Name) \ | |
1451 virtual void* Visit##Name(RegExp##Name*, void* data) = 0; | |
1452 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE) | |
1453 #undef MAKE_CASE | |
1454 }; | |
1455 | |
1456 | |
1457 // ---------------------------------------------------------------------------- | |
1195 // Basic visitor | 1458 // Basic visitor |
1196 // - leaf node visitors are abstract. | 1459 // - leaf node visitors are abstract. |
1197 | 1460 |
1198 class Visitor BASE_EMBEDDED { | 1461 class Visitor BASE_EMBEDDED { |
1199 public: | 1462 public: |
1200 Visitor() : stack_overflow_(false) { } | 1463 Visitor() : stack_overflow_(false) { } |
1201 virtual ~Visitor() { } | 1464 virtual ~Visitor() { } |
1202 | 1465 |
1203 // Dispatch | 1466 // Dispatch |
1204 void Visit(Node* node) { node->Accept(this); } | 1467 void Visit(Node* node) { node->Accept(this); } |
(...skipping 24 matching lines...) Expand all Loading... | |
1229 #undef DEF_VISIT | 1492 #undef DEF_VISIT |
1230 | 1493 |
1231 private: | 1494 private: |
1232 bool stack_overflow_; | 1495 bool stack_overflow_; |
1233 }; | 1496 }; |
1234 | 1497 |
1235 | 1498 |
1236 } } // namespace v8::internal | 1499 } } // namespace v8::internal |
1237 | 1500 |
1238 #endif // V8_AST_H_ | 1501 #endif // V8_AST_H_ |
OLD | NEW |