| 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 |