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 #ifndef V8_AST_AST_H_ | 5 #ifndef V8_AST_AST_H_ |
6 #define V8_AST_AST_H_ | 6 #define V8_AST_AST_H_ |
7 | 7 |
8 #include "src/ast/ast-types.h" | 8 #include "src/ast/ast-types.h" |
9 #include "src/ast/ast-value-factory.h" | 9 #include "src/ast/ast-value-factory.h" |
10 #include "src/ast/modules.h" | 10 #include "src/ast/modules.h" |
(...skipping 1220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1231 | 1231 |
1232 static int parent_num_ids() { return Expression::num_ids(); } | 1232 static int parent_num_ids() { return Expression::num_ids(); } |
1233 int local_id(int n) const { return base_id() + parent_num_ids() + n; } | 1233 int local_id(int n) const { return base_id() + parent_num_ids() + n; } |
1234 | 1234 |
1235 const AstValue* value_; | 1235 const AstValue* value_; |
1236 }; | 1236 }; |
1237 | 1237 |
1238 // Base class for literals that need space in the type feedback vector. | 1238 // Base class for literals that need space in the type feedback vector. |
1239 class MaterializedLiteral : public Expression { | 1239 class MaterializedLiteral : public Expression { |
1240 public: | 1240 public: |
| 1241 bool is_initialized() const { return 0 < depth_; } |
1241 int depth() const { | 1242 int depth() const { |
1242 // only callable after initialization. | 1243 DCHECK(is_initialized()); |
1243 DCHECK(depth_ >= 1); | |
1244 return depth_; | 1244 return depth_; |
1245 } | 1245 } |
1246 | 1246 |
1247 void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode, | 1247 void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode, |
1248 FeedbackSlotCache* cache) { | 1248 FeedbackSlotCache* cache) { |
1249 literal_slot_ = spec->AddLiteralSlot(); | 1249 literal_slot_ = spec->AddLiteralSlot(); |
1250 } | 1250 } |
1251 | 1251 |
1252 FeedbackSlot literal_slot() const { return literal_slot_; } | 1252 FeedbackSlot literal_slot() const { return literal_slot_; } |
1253 | 1253 |
1254 private: | 1254 private: |
1255 int depth_ : 31; | 1255 int depth_ : 31; |
1256 FeedbackSlot literal_slot_; | 1256 FeedbackSlot literal_slot_; |
1257 | 1257 |
1258 class IsSimpleField | 1258 class IsSimpleField |
1259 : public BitField<bool, Expression::kNextBitFieldIndex, 1> {}; | 1259 : public BitField<bool, Expression::kNextBitFieldIndex, 1> {}; |
1260 | 1260 |
1261 protected: | 1261 protected: |
1262 MaterializedLiteral(int pos, NodeType type) | 1262 MaterializedLiteral(int pos, NodeType type) |
1263 : Expression(pos, type), depth_(0) { | 1263 : Expression(pos, type), depth_(0) { |
1264 bit_field_ |= IsSimpleField::encode(false); | 1264 bit_field_ |= IsSimpleField::encode(false); |
1265 } | 1265 } |
1266 | 1266 |
1267 // A materialized literal is simple if the values consist of only | 1267 // A materialized literal is simple if the values consist of only |
1268 // constants and simple object and array literals. | 1268 // constants and simple object and array literals. |
1269 bool is_simple() const { return IsSimpleField::decode(bit_field_); } | 1269 bool is_simple() const { return IsSimpleField::decode(bit_field_); } |
1270 void set_is_simple(bool is_simple) { | 1270 void set_is_simple(bool is_simple) { |
1271 bit_field_ = IsSimpleField::update(bit_field_, is_simple); | 1271 bit_field_ = IsSimpleField::update(bit_field_, is_simple); |
1272 } | 1272 } |
| 1273 |
1273 friend class CompileTimeValue; | 1274 friend class CompileTimeValue; |
1274 | 1275 |
1275 void set_depth(int depth) { | 1276 void set_depth(int depth) { |
1276 DCHECK_LE(1, depth); | 1277 DCHECK(!is_initialized()); |
1277 depth_ = depth; | 1278 depth_ = depth; |
1278 } | 1279 } |
1279 | 1280 |
1280 // Populate the depth field and any flags the literal has. | 1281 // Populate the depth field and any flags the literal has. |
1281 void InitDepthAndFlags(); | 1282 void InitDepthAndFlags(); |
1282 | 1283 |
1283 // Populate the constant properties/elements fixed array. | 1284 // Populate the constant properties/elements fixed array. |
1284 void BuildConstants(Isolate* isolate); | 1285 void BuildConstants(Isolate* isolate); |
1285 friend class ArrayLiteral; | 1286 friend class ArrayLiteral; |
1286 friend class ObjectLiteral; | 1287 friend class ObjectLiteral; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1352 bool IsMonomorphic() const { return !receiver_type_.is_null(); } | 1353 bool IsMonomorphic() const { return !receiver_type_.is_null(); } |
1353 Handle<Map> GetReceiverType() const { return receiver_type_; } | 1354 Handle<Map> GetReceiverType() const { return receiver_type_; } |
1354 | 1355 |
1355 bool IsCompileTimeValue() const; | 1356 bool IsCompileTimeValue() const; |
1356 | 1357 |
1357 void set_emit_store(bool emit_store); | 1358 void set_emit_store(bool emit_store); |
1358 bool emit_store() const; | 1359 bool emit_store() const; |
1359 | 1360 |
1360 void set_receiver_type(Handle<Map> map) { receiver_type_ = map; } | 1361 void set_receiver_type(Handle<Map> map) { receiver_type_ = map; } |
1361 | 1362 |
| 1363 bool IsNullPrototype() const { |
| 1364 return IsPrototype() && value()->IsNullLiteral(); |
| 1365 } |
| 1366 bool IsPrototype() const { return kind() == PROTOTYPE; } |
| 1367 |
1362 private: | 1368 private: |
1363 friend class AstNodeFactory; | 1369 friend class AstNodeFactory; |
1364 | 1370 |
1365 ObjectLiteralProperty(Expression* key, Expression* value, Kind kind, | 1371 ObjectLiteralProperty(Expression* key, Expression* value, Kind kind, |
1366 bool is_computed_name); | 1372 bool is_computed_name); |
1367 ObjectLiteralProperty(AstValueFactory* ast_value_factory, Expression* key, | 1373 ObjectLiteralProperty(AstValueFactory* ast_value_factory, Expression* key, |
1368 Expression* value, bool is_computed_name); | 1374 Expression* value, bool is_computed_name); |
1369 | 1375 |
1370 Kind kind_; | 1376 Kind kind_; |
1371 bool emit_store_; | 1377 bool emit_store_; |
(...skipping 17 matching lines...) Expand all Loading... |
1389 bool may_store_doubles() const { | 1395 bool may_store_doubles() const { |
1390 return MayStoreDoublesField::decode(bit_field_); | 1396 return MayStoreDoublesField::decode(bit_field_); |
1391 } | 1397 } |
1392 bool has_elements() const { return HasElementsField::decode(bit_field_); } | 1398 bool has_elements() const { return HasElementsField::decode(bit_field_); } |
1393 bool has_shallow_properties() const { | 1399 bool has_shallow_properties() const { |
1394 return depth() == 1 && !has_elements() && !may_store_doubles(); | 1400 return depth() == 1 && !has_elements() && !may_store_doubles(); |
1395 } | 1401 } |
1396 bool has_rest_property() const { | 1402 bool has_rest_property() const { |
1397 return HasRestPropertyField::decode(bit_field_); | 1403 return HasRestPropertyField::decode(bit_field_); |
1398 } | 1404 } |
1399 | 1405 bool has_null_prototype() const { |
1400 // Decide if a property should be in the object boilerplate. | 1406 return HasNullPrototypeField::decode(bit_field_); |
1401 static bool IsBoilerplateProperty(Property* property); | 1407 } |
1402 | 1408 |
1403 // Populate the depth field and flags. | 1409 // Populate the depth field and flags. |
1404 void InitDepthAndFlags(); | 1410 void InitDepthAndFlags(); |
1405 | 1411 |
1406 // Get the constant properties fixed array, populating it if necessary. | 1412 // Get the constant properties fixed array, populating it if necessary. |
1407 Handle<BoilerplateDescription> GetOrBuildConstantProperties( | 1413 Handle<BoilerplateDescription> GetOrBuildConstantProperties( |
1408 Isolate* isolate) { | 1414 Isolate* isolate) { |
1409 if (constant_properties_.is_null()) { | 1415 if (constant_properties_.is_null()) { |
1410 BuildConstantProperties(isolate); | 1416 BuildConstantProperties(isolate); |
1411 } | 1417 } |
1412 return constant_properties(); | 1418 return constant_properties(); |
1413 } | 1419 } |
1414 | 1420 |
1415 // Populate the constant properties fixed array. | 1421 // Populate the constant properties fixed array. |
1416 void BuildConstantProperties(Isolate* isolate); | 1422 void BuildConstantProperties(Isolate* isolate); |
1417 | 1423 |
1418 // Mark all computed expressions that are bound to a key that | 1424 // Mark all computed expressions that are bound to a key that |
1419 // is shadowed by a later occurrence of the same key. For the | 1425 // is shadowed by a later occurrence of the same key. For the |
1420 // marked expressions, no store code is emitted. | 1426 // marked expressions, no store code is emitted. |
1421 void CalculateEmitStore(Zone* zone); | 1427 void CalculateEmitStore(Zone* zone); |
1422 | 1428 |
1423 // Determines whether the {FastCloneShallowObject} builtin can be used. | 1429 // Determines whether the {FastCloneShallowObject} builtin can be used. |
1424 bool IsFastCloningSupported() const; | 1430 bool IsFastCloningSupported() const; |
1425 | 1431 |
1426 // Assemble bitfield of flags for the CreateObjectLiteral helper. | 1432 // Assemble bitfield of flags for the CreateObjectLiteral helper. |
1427 int ComputeFlags(bool disable_mementos = false) const { | 1433 int ComputeFlags(bool disable_mementos = false) const { |
1428 int flags = fast_elements() ? kFastElements : kNoFlags; | 1434 int flags = fast_elements() ? kFastElements : kNoFlags; |
1429 if (has_shallow_properties()) { | 1435 if (has_shallow_properties()) flags |= kShallowProperties; |
1430 flags |= kShallowProperties; | 1436 if (disable_mementos) flags |= kDisableMementos; |
1431 } | 1437 if (has_null_prototype()) flags |= kHasNullPrototype; |
1432 if (disable_mementos) { | |
1433 flags |= kDisableMementos; | |
1434 } | |
1435 return flags; | 1438 return flags; |
1436 } | 1439 } |
1437 | 1440 |
| 1441 int EncodeLiteralType() { |
| 1442 int flags = fast_elements() ? kFastElements : kNoFlags; |
| 1443 if (has_shallow_properties()) flags |= kShallowProperties; |
| 1444 if (has_null_prototype()) flags |= kHasNullPrototype; |
| 1445 return flags; |
| 1446 } |
| 1447 |
1438 enum Flags { | 1448 enum Flags { |
1439 kNoFlags = 0, | 1449 kNoFlags = 0, |
1440 kFastElements = 1, | 1450 kFastElements = 1, |
1441 kShallowProperties = 1 << 1, | 1451 kShallowProperties = 1 << 1, |
1442 kDisableMementos = 1 << 2, | 1452 kDisableMementos = 1 << 2, |
1443 kHasRestProperty = 1 << 3, | 1453 kHasNullPrototype = 1 << 3, |
1444 }; | 1454 }; |
1445 | 1455 |
1446 struct Accessors: public ZoneObject { | 1456 struct Accessors: public ZoneObject { |
1447 Accessors() : getter(NULL), setter(NULL), bailout_id(BailoutId::None()) {} | 1457 Accessors() : getter(NULL), setter(NULL), bailout_id(BailoutId::None()) {} |
1448 ObjectLiteralProperty* getter; | 1458 ObjectLiteralProperty* getter; |
1449 ObjectLiteralProperty* setter; | 1459 ObjectLiteralProperty* setter; |
1450 BailoutId bailout_id; | 1460 BailoutId bailout_id; |
1451 }; | 1461 }; |
1452 | 1462 |
1453 BailoutId CreateLiteralId() const { return BailoutId(local_id(0)); } | 1463 BailoutId CreateLiteralId() const { return BailoutId(local_id(0)); } |
(...skipping 15 matching lines...) Expand all Loading... |
1469 | 1479 |
1470 ObjectLiteral(ZoneList<Property*>* properties, | 1480 ObjectLiteral(ZoneList<Property*>* properties, |
1471 uint32_t boilerplate_properties, int pos, | 1481 uint32_t boilerplate_properties, int pos, |
1472 bool has_rest_property) | 1482 bool has_rest_property) |
1473 : MaterializedLiteral(pos, kObjectLiteral), | 1483 : MaterializedLiteral(pos, kObjectLiteral), |
1474 boilerplate_properties_(boilerplate_properties), | 1484 boilerplate_properties_(boilerplate_properties), |
1475 properties_(properties) { | 1485 properties_(properties) { |
1476 bit_field_ |= FastElementsField::encode(false) | | 1486 bit_field_ |= FastElementsField::encode(false) | |
1477 HasElementsField::encode(false) | | 1487 HasElementsField::encode(false) | |
1478 MayStoreDoublesField::encode(false) | | 1488 MayStoreDoublesField::encode(false) | |
1479 HasRestPropertyField::encode(has_rest_property); | 1489 HasRestPropertyField::encode(has_rest_property) | |
| 1490 HasNullPrototypeField::encode(false); |
1480 } | 1491 } |
1481 | 1492 |
1482 static int parent_num_ids() { return MaterializedLiteral::num_ids(); } | 1493 static int parent_num_ids() { return MaterializedLiteral::num_ids(); } |
1483 int local_id(int n) const { return base_id() + parent_num_ids() + n; } | 1494 int local_id(int n) const { return base_id() + parent_num_ids() + n; } |
1484 | 1495 |
| 1496 void InitFlagsForPendingNullPrototype(int i); |
| 1497 |
| 1498 void set_fast_elements(bool fast_elements) { |
| 1499 bit_field_ = FastElementsField::update(bit_field_, fast_elements); |
| 1500 } |
| 1501 void set_has_elements(bool has_elements) { |
| 1502 bit_field_ = HasElementsField::update(bit_field_, has_elements); |
| 1503 } |
| 1504 void set_has_null_protoype(bool has_null_prototype) { |
| 1505 bit_field_ = HasNullPrototypeField::update(bit_field_, has_null_prototype); |
| 1506 } |
| 1507 |
1485 uint32_t boilerplate_properties_; | 1508 uint32_t boilerplate_properties_; |
1486 Handle<BoilerplateDescription> constant_properties_; | 1509 Handle<BoilerplateDescription> constant_properties_; |
1487 ZoneList<Property*>* properties_; | 1510 ZoneList<Property*>* properties_; |
1488 | 1511 |
1489 class FastElementsField | 1512 class FastElementsField |
1490 : public BitField<bool, MaterializedLiteral::kNextBitFieldIndex, 1> {}; | 1513 : public BitField<bool, MaterializedLiteral::kNextBitFieldIndex, 1> {}; |
1491 class HasElementsField : public BitField<bool, FastElementsField::kNext, 1> { | 1514 class HasElementsField : public BitField<bool, FastElementsField::kNext, 1> { |
1492 }; | 1515 }; |
1493 class MayStoreDoublesField | 1516 class MayStoreDoublesField |
1494 : public BitField<bool, HasElementsField::kNext, 1> {}; | 1517 : public BitField<bool, HasElementsField::kNext, 1> {}; |
1495 class HasRestPropertyField | 1518 class HasRestPropertyField |
1496 : public BitField<bool, MayStoreDoublesField::kNext, 1> {}; | 1519 : public BitField<bool, MayStoreDoublesField::kNext, 1> {}; |
| 1520 class HasNullPrototypeField |
| 1521 : public BitField<bool, HasRestPropertyField::kNext, 1> {}; |
1497 }; | 1522 }; |
1498 | 1523 |
1499 | 1524 |
1500 // A map from property names to getter/setter pairs allocated in the zone. | 1525 // A map from property names to getter/setter pairs allocated in the zone. |
1501 class AccessorTable | 1526 class AccessorTable |
1502 : public base::TemplateHashMap<Literal, ObjectLiteral::Accessors, | 1527 : public base::TemplateHashMap<Literal, ObjectLiteral::Accessors, |
1503 bool (*)(void*, void*), | 1528 bool (*)(void*, void*), |
1504 ZoneAllocationPolicy> { | 1529 ZoneAllocationPolicy> { |
1505 public: | 1530 public: |
1506 explicit AccessorTable(Zone* zone) | 1531 explicit AccessorTable(Zone* zone) |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1575 | 1600 |
1576 // Populate the constant elements fixed array. | 1601 // Populate the constant elements fixed array. |
1577 void BuildConstantElements(Isolate* isolate); | 1602 void BuildConstantElements(Isolate* isolate); |
1578 | 1603 |
1579 // Determines whether the {FastCloneShallowArray} builtin can be used. | 1604 // Determines whether the {FastCloneShallowArray} builtin can be used. |
1580 bool IsFastCloningSupported() const; | 1605 bool IsFastCloningSupported() const; |
1581 | 1606 |
1582 // Assemble bitfield of flags for the CreateArrayLiteral helper. | 1607 // Assemble bitfield of flags for the CreateArrayLiteral helper. |
1583 int ComputeFlags(bool disable_mementos = false) const { | 1608 int ComputeFlags(bool disable_mementos = false) const { |
1584 int flags = depth() == 1 ? kShallowElements : kNoFlags; | 1609 int flags = depth() == 1 ? kShallowElements : kNoFlags; |
1585 if (disable_mementos) { | 1610 if (disable_mementos) flags |= kDisableMementos; |
1586 flags |= kDisableMementos; | |
1587 } | |
1588 return flags; | 1611 return flags; |
1589 } | 1612 } |
1590 | 1613 |
1591 // Provide a mechanism for iterating through values to rewrite spreads. | 1614 // Provide a mechanism for iterating through values to rewrite spreads. |
1592 ZoneList<Expression*>::iterator FirstSpread() const { | 1615 ZoneList<Expression*>::iterator FirstSpread() const { |
1593 return (first_spread_index_ >= 0) ? values_->begin() + first_spread_index_ | 1616 return (first_spread_index_ >= 0) ? values_->begin() + first_spread_index_ |
1594 : values_->end(); | 1617 : values_->end(); |
1595 } | 1618 } |
1596 ZoneList<Expression*>::iterator EndValue() const { return values_->end(); } | 1619 ZoneList<Expression*>::iterator EndValue() const { return values_->end(); } |
1597 | 1620 |
(...skipping 2113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3711 : NULL; \ | 3734 : NULL; \ |
3712 } | 3735 } |
3713 AST_NODE_LIST(DECLARE_NODE_FUNCTIONS) | 3736 AST_NODE_LIST(DECLARE_NODE_FUNCTIONS) |
3714 #undef DECLARE_NODE_FUNCTIONS | 3737 #undef DECLARE_NODE_FUNCTIONS |
3715 | 3738 |
3716 | 3739 |
3717 } // namespace internal | 3740 } // namespace internal |
3718 } // namespace v8 | 3741 } // namespace v8 |
3719 | 3742 |
3720 #endif // V8_AST_AST_H_ | 3743 #endif // V8_AST_AST_H_ |
OLD | NEW |