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_H_ | 5 #ifndef V8_AST_H_ |
6 #define V8_AST_H_ | 6 #define V8_AST_H_ |
7 | 7 |
8 #include "src/v8.h" | 8 #include "src/v8.h" |
9 | 9 |
10 #include "src/assembler.h" | 10 #include "src/assembler.h" |
(...skipping 22 matching lines...) Expand all Loading... |
33 | 33 |
34 // Nodes are allocated in a separate zone, which allows faster | 34 // Nodes are allocated in a separate zone, which allows faster |
35 // allocation and constant-time deallocation of the entire syntax | 35 // allocation and constant-time deallocation of the entire syntax |
36 // tree. | 36 // tree. |
37 | 37 |
38 | 38 |
39 // ---------------------------------------------------------------------------- | 39 // ---------------------------------------------------------------------------- |
40 // Nodes of the abstract syntax tree. Only concrete classes are | 40 // Nodes of the abstract syntax tree. Only concrete classes are |
41 // enumerated here. | 41 // enumerated here. |
42 | 42 |
43 #define DECLARATION_NODE_LIST(V) \ | 43 #define DECLARATION_NODE_LIST(V) \ |
44 V(VariableDeclaration) \ | 44 V(VariableDeclaration) \ |
45 V(FunctionDeclaration) \ | 45 V(FunctionDeclaration) \ |
46 V(ModuleDeclaration) \ | 46 V(ClassDeclaration) \ |
47 V(ImportDeclaration) \ | 47 V(ModuleDeclaration) \ |
48 V(ExportDeclaration) \ | 48 V(ImportDeclaration) \ |
| 49 V(ExportDeclaration) |
49 | 50 |
50 #define MODULE_NODE_LIST(V) \ | 51 #define MODULE_NODE_LIST(V) \ |
51 V(ModuleLiteral) \ | 52 V(ModuleLiteral) \ |
52 V(ModuleVariable) \ | 53 V(ModuleVariable) \ |
53 V(ModulePath) \ | 54 V(ModulePath) \ |
54 V(ModuleUrl) | 55 V(ModuleUrl) |
55 | 56 |
56 #define STATEMENT_NODE_LIST(V) \ | 57 #define STATEMENT_NODE_LIST(V) \ |
57 V(Block) \ | 58 V(Block) \ |
58 V(ModuleStatement) \ | 59 V(ModuleStatement) \ |
59 V(ExpressionStatement) \ | 60 V(ExpressionStatement) \ |
60 V(EmptyStatement) \ | 61 V(EmptyStatement) \ |
61 V(IfStatement) \ | 62 V(IfStatement) \ |
62 V(ContinueStatement) \ | 63 V(ContinueStatement) \ |
63 V(BreakStatement) \ | 64 V(BreakStatement) \ |
64 V(ReturnStatement) \ | 65 V(ReturnStatement) \ |
65 V(WithStatement) \ | 66 V(WithStatement) \ |
66 V(SwitchStatement) \ | 67 V(SwitchStatement) \ |
67 V(DoWhileStatement) \ | 68 V(DoWhileStatement) \ |
68 V(WhileStatement) \ | 69 V(WhileStatement) \ |
69 V(ForStatement) \ | 70 V(ForStatement) \ |
70 V(ForInStatement) \ | 71 V(ForInStatement) \ |
71 V(ForOfStatement) \ | 72 V(ForOfStatement) \ |
72 V(TryCatchStatement) \ | 73 V(TryCatchStatement) \ |
73 V(TryFinallyStatement) \ | 74 V(TryFinallyStatement) \ |
74 V(DebuggerStatement) | 75 V(DebuggerStatement) |
75 | 76 |
76 #define EXPRESSION_NODE_LIST(V) \ | 77 #define EXPRESSION_NODE_LIST(V) \ |
77 V(FunctionLiteral) \ | 78 V(FunctionLiteral) \ |
78 V(NativeFunctionLiteral) \ | 79 V(ClassLiteral) \ |
79 V(Conditional) \ | 80 V(NativeFunctionLiteral) \ |
80 V(VariableProxy) \ | 81 V(Conditional) \ |
81 V(Literal) \ | 82 V(VariableProxy) \ |
82 V(RegExpLiteral) \ | 83 V(Literal) \ |
83 V(ObjectLiteral) \ | 84 V(RegExpLiteral) \ |
84 V(ArrayLiteral) \ | 85 V(ObjectLiteral) \ |
85 V(Assignment) \ | 86 V(ArrayLiteral) \ |
86 V(Yield) \ | 87 V(Assignment) \ |
87 V(Throw) \ | 88 V(Yield) \ |
88 V(Property) \ | 89 V(Throw) \ |
89 V(Call) \ | 90 V(Property) \ |
90 V(CallNew) \ | 91 V(Call) \ |
91 V(CallRuntime) \ | 92 V(CallNew) \ |
92 V(UnaryOperation) \ | 93 V(CallRuntime) \ |
93 V(CountOperation) \ | 94 V(UnaryOperation) \ |
94 V(BinaryOperation) \ | 95 V(CountOperation) \ |
95 V(CompareOperation) \ | 96 V(BinaryOperation) \ |
96 V(ThisFunction) \ | 97 V(CompareOperation) \ |
97 V(SuperReference) \ | 98 V(ThisFunction) \ |
| 99 V(SuperReference) \ |
98 V(CaseClause) | 100 V(CaseClause) |
99 | 101 |
100 #define AST_NODE_LIST(V) \ | 102 #define AST_NODE_LIST(V) \ |
101 DECLARATION_NODE_LIST(V) \ | 103 DECLARATION_NODE_LIST(V) \ |
102 MODULE_NODE_LIST(V) \ | 104 MODULE_NODE_LIST(V) \ |
103 STATEMENT_NODE_LIST(V) \ | 105 STATEMENT_NODE_LIST(V) \ |
104 EXPRESSION_NODE_LIST(V) | 106 EXPRESSION_NODE_LIST(V) |
105 | 107 |
106 // Forward declarations | 108 // Forward declarations |
107 class AstConstructionVisitor; | 109 class AstConstructionVisitor; |
(...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
553 // At the moment there are no "const functions" in JavaScript... | 555 // At the moment there are no "const functions" in JavaScript... |
554 DCHECK(mode == VAR || mode == LET); | 556 DCHECK(mode == VAR || mode == LET); |
555 DCHECK(fun != NULL); | 557 DCHECK(fun != NULL); |
556 } | 558 } |
557 | 559 |
558 private: | 560 private: |
559 FunctionLiteral* fun_; | 561 FunctionLiteral* fun_; |
560 }; | 562 }; |
561 | 563 |
562 | 564 |
| 565 class ClassDeclaration FINAL : public Declaration { |
| 566 public: |
| 567 DECLARE_NODE_TYPE(ClassDeclaration) |
| 568 |
| 569 ClassLiteral* classLiteral() const { return classLiteral_; } |
| 570 virtual InitializationFlag initialization() const OVERRIDE { |
| 571 return kCreatedInitialized; |
| 572 } |
| 573 |
| 574 protected: |
| 575 ClassDeclaration(Zone* zone, VariableProxy* proxy, ClassLiteral* classLiteral, |
| 576 Scope* scope, int pos) |
| 577 : Declaration(zone, proxy, LET, scope, pos), classLiteral_(classLiteral) { |
| 578 DCHECK(classLiteral != NULL); |
| 579 } |
| 580 |
| 581 private: |
| 582 ClassLiteral* classLiteral_; |
| 583 }; |
| 584 |
| 585 |
563 class ModuleDeclaration FINAL : public Declaration { | 586 class ModuleDeclaration FINAL : public Declaration { |
564 public: | 587 public: |
565 DECLARE_NODE_TYPE(ModuleDeclaration) | 588 DECLARE_NODE_TYPE(ModuleDeclaration) |
566 | 589 |
567 Module* module() const { return module_; } | 590 Module* module() const { return module_; } |
568 virtual InitializationFlag initialization() const OVERRIDE { | 591 virtual InitializationFlag initialization() const OVERRIDE { |
569 return kCreatedInitialized; | 592 return kCreatedInitialized; |
570 } | 593 } |
571 | 594 |
572 protected: | 595 protected: |
(...skipping 879 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1452 public: | 1475 public: |
1453 enum Kind { | 1476 enum Kind { |
1454 CONSTANT, // Property with constant value (compile time). | 1477 CONSTANT, // Property with constant value (compile time). |
1455 COMPUTED, // Property with computed value (execution time). | 1478 COMPUTED, // Property with computed value (execution time). |
1456 MATERIALIZED_LITERAL, // Property value is a materialized literal. | 1479 MATERIALIZED_LITERAL, // Property value is a materialized literal. |
1457 GETTER, SETTER, // Property is an accessor function. | 1480 GETTER, SETTER, // Property is an accessor function. |
1458 PROTOTYPE // Property is __proto__. | 1481 PROTOTYPE // Property is __proto__. |
1459 }; | 1482 }; |
1460 | 1483 |
1461 ObjectLiteralProperty(Zone* zone, AstValueFactory* ast_value_factory, | 1484 ObjectLiteralProperty(Zone* zone, AstValueFactory* ast_value_factory, |
1462 Literal* key, Expression* value); | 1485 Literal* key, Expression* value, |
| 1486 bool is_static = false); |
1463 | 1487 |
1464 Literal* key() { return key_; } | 1488 Literal* key() { return key_; } |
1465 Expression* value() { return value_; } | 1489 Expression* value() { return value_; } |
1466 Kind kind() { return kind_; } | 1490 Kind kind() { return kind_; } |
1467 | 1491 |
1468 // Type feedback information. | 1492 // Type feedback information. |
1469 void RecordTypeFeedback(TypeFeedbackOracle* oracle); | 1493 void RecordTypeFeedback(TypeFeedbackOracle* oracle); |
1470 bool IsMonomorphic() { return !receiver_type_.is_null(); } | 1494 bool IsMonomorphic() { return !receiver_type_.is_null(); } |
1471 Handle<Map> GetReceiverType() { return receiver_type_; } | 1495 Handle<Map> GetReceiverType() { return receiver_type_; } |
1472 | 1496 |
1473 bool IsCompileTimeValue(); | 1497 bool IsCompileTimeValue(); |
1474 | 1498 |
1475 void set_emit_store(bool emit_store); | 1499 void set_emit_store(bool emit_store); |
1476 bool emit_store(); | 1500 bool emit_store(); |
1477 | 1501 |
1478 protected: | 1502 protected: |
1479 template<class> friend class AstNodeFactory; | 1503 template<class> friend class AstNodeFactory; |
1480 | 1504 |
1481 ObjectLiteralProperty(Zone* zone, bool is_getter, FunctionLiteral* value); | 1505 ObjectLiteralProperty(Zone* zone, bool is_getter, FunctionLiteral* value, |
| 1506 bool is_static = false); |
1482 void set_key(Literal* key) { key_ = key; } | 1507 void set_key(Literal* key) { key_ = key; } |
1483 | 1508 |
1484 private: | 1509 private: |
1485 Literal* key_; | 1510 Literal* key_; |
1486 Expression* value_; | 1511 Expression* value_; |
1487 Kind kind_; | 1512 Kind kind_; |
1488 bool emit_store_; | 1513 bool emit_store_; |
1489 Handle<Map> receiver_type_; | 1514 Handle<Map> receiver_type_; |
| 1515 bool is_static_; |
1490 }; | 1516 }; |
1491 | 1517 |
1492 | 1518 |
1493 // An object literal has a boilerplate object that is used | 1519 // An object literal has a boilerplate object that is used |
1494 // for minimizing the work when constructing it at runtime. | 1520 // for minimizing the work when constructing it at runtime. |
1495 class ObjectLiteral FINAL : public MaterializedLiteral { | 1521 class ObjectLiteral FINAL : public MaterializedLiteral { |
1496 public: | 1522 public: |
1497 typedef ObjectLiteralProperty Property; | 1523 typedef ObjectLiteralProperty Property; |
1498 | 1524 |
1499 DECLARE_NODE_TYPE(ObjectLiteral) | 1525 DECLARE_NODE_TYPE(ObjectLiteral) |
(...skipping 991 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2491 class IsExpression : public BitField<bool, 0, 1> {}; | 2517 class IsExpression : public BitField<bool, 0, 1> {}; |
2492 class IsAnonymous : public BitField<bool, 1, 1> {}; | 2518 class IsAnonymous : public BitField<bool, 1, 1> {}; |
2493 class Pretenure : public BitField<bool, 2, 1> {}; | 2519 class Pretenure : public BitField<bool, 2, 1> {}; |
2494 class HasDuplicateParameters : public BitField<ParameterFlag, 3, 1> {}; | 2520 class HasDuplicateParameters : public BitField<ParameterFlag, 3, 1> {}; |
2495 class IsFunction : public BitField<IsFunctionFlag, 4, 1> {}; | 2521 class IsFunction : public BitField<IsFunctionFlag, 4, 1> {}; |
2496 class IsParenthesized : public BitField<IsParenthesizedFlag, 5, 1> {}; | 2522 class IsParenthesized : public BitField<IsParenthesizedFlag, 5, 1> {}; |
2497 class FunctionKindBits : public BitField<FunctionKind, 6, 3> {}; | 2523 class FunctionKindBits : public BitField<FunctionKind, 6, 3> {}; |
2498 }; | 2524 }; |
2499 | 2525 |
2500 | 2526 |
| 2527 class ClassLiteral FINAL : public Expression { |
| 2528 public: |
| 2529 typedef ObjectLiteralProperty Property; |
| 2530 |
| 2531 DECLARE_NODE_TYPE(ClassLiteral) |
| 2532 |
| 2533 Handle<String> name() const { return raw_name_->string(); } |
| 2534 const AstRawString* raw_name() const { return raw_name_; } |
| 2535 Expression* extends() const { return extends_; } |
| 2536 ZoneList<Property*>* properties() const { return properties_; } |
| 2537 |
| 2538 protected: |
| 2539 ClassLiteral(Zone* zone, const AstRawString* name, Expression* extends, |
| 2540 ZoneList<Property*>* properties, |
| 2541 AstValueFactory* ast_value_factory, int position, IdGen* id_gen) |
| 2542 : Expression(zone, position, id_gen), |
| 2543 raw_name_(name), |
| 2544 raw_inferred_name_(ast_value_factory->empty_string()), |
| 2545 extends_(extends), |
| 2546 properties_(properties) {} |
| 2547 |
| 2548 private: |
| 2549 const AstRawString* raw_name_; |
| 2550 Handle<String> name_; |
| 2551 const AstString* raw_inferred_name_; |
| 2552 Handle<String> inferred_name_; |
| 2553 Expression* extends_; |
| 2554 ZoneList<Property*>* properties_; |
| 2555 }; |
| 2556 |
| 2557 |
2501 class NativeFunctionLiteral FINAL : public Expression { | 2558 class NativeFunctionLiteral FINAL : public Expression { |
2502 public: | 2559 public: |
2503 DECLARE_NODE_TYPE(NativeFunctionLiteral) | 2560 DECLARE_NODE_TYPE(NativeFunctionLiteral) |
2504 | 2561 |
2505 Handle<String> name() const { return name_->string(); } | 2562 Handle<String> name() const { return name_->string(); } |
2506 v8::Extension* extension() const { return extension_; } | 2563 v8::Extension* extension() const { return extension_; } |
2507 | 2564 |
2508 protected: | 2565 protected: |
2509 NativeFunctionLiteral(Zone* zone, const AstRawString* name, | 2566 NativeFunctionLiteral(Zone* zone, const AstRawString* name, |
2510 v8::Extension* extension, int pos, IdGen* id_gen) | 2567 v8::Extension* extension, int pos, IdGen* id_gen) |
(...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3045 FunctionDeclaration* NewFunctionDeclaration(VariableProxy* proxy, | 3102 FunctionDeclaration* NewFunctionDeclaration(VariableProxy* proxy, |
3046 VariableMode mode, | 3103 VariableMode mode, |
3047 FunctionLiteral* fun, | 3104 FunctionLiteral* fun, |
3048 Scope* scope, | 3105 Scope* scope, |
3049 int pos) { | 3106 int pos) { |
3050 FunctionDeclaration* decl = | 3107 FunctionDeclaration* decl = |
3051 new(zone_) FunctionDeclaration(zone_, proxy, mode, fun, scope, pos); | 3108 new(zone_) FunctionDeclaration(zone_, proxy, mode, fun, scope, pos); |
3052 VISIT_AND_RETURN(FunctionDeclaration, decl) | 3109 VISIT_AND_RETURN(FunctionDeclaration, decl) |
3053 } | 3110 } |
3054 | 3111 |
| 3112 ClassDeclaration* NewClassDeclaration(VariableProxy* proxy, ClassLiteral* lit, |
| 3113 Scope* scope, int pos) { |
| 3114 ClassDeclaration* decl = |
| 3115 new (zone_) ClassDeclaration(zone_, proxy, lit, scope, pos); |
| 3116 VISIT_AND_RETURN(ClassDeclaration, decl) |
| 3117 } |
| 3118 |
3055 ModuleDeclaration* NewModuleDeclaration(VariableProxy* proxy, | 3119 ModuleDeclaration* NewModuleDeclaration(VariableProxy* proxy, |
3056 Module* module, | 3120 Module* module, |
3057 Scope* scope, | 3121 Scope* scope, |
3058 int pos) { | 3122 int pos) { |
3059 ModuleDeclaration* decl = | 3123 ModuleDeclaration* decl = |
3060 new(zone_) ModuleDeclaration(zone_, proxy, module, scope, pos); | 3124 new(zone_) ModuleDeclaration(zone_, proxy, module, scope, pos); |
3061 VISIT_AND_RETURN(ModuleDeclaration, decl) | 3125 VISIT_AND_RETURN(ModuleDeclaration, decl) |
3062 } | 3126 } |
3063 | 3127 |
3064 ImportDeclaration* NewImportDeclaration(VariableProxy* proxy, | 3128 ImportDeclaration* NewImportDeclaration(VariableProxy* proxy, |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3282 int boilerplate_properties, | 3346 int boilerplate_properties, |
3283 bool has_function, | 3347 bool has_function, |
3284 int pos) { | 3348 int pos) { |
3285 ObjectLiteral* lit = new (zone_) | 3349 ObjectLiteral* lit = new (zone_) |
3286 ObjectLiteral(zone_, properties, literal_index, boilerplate_properties, | 3350 ObjectLiteral(zone_, properties, literal_index, boilerplate_properties, |
3287 has_function, pos, id_gen_); | 3351 has_function, pos, id_gen_); |
3288 VISIT_AND_RETURN(ObjectLiteral, lit) | 3352 VISIT_AND_RETURN(ObjectLiteral, lit) |
3289 } | 3353 } |
3290 | 3354 |
3291 ObjectLiteral::Property* NewObjectLiteralProperty(Literal* key, | 3355 ObjectLiteral::Property* NewObjectLiteralProperty(Literal* key, |
3292 Expression* value) { | 3356 Expression* value, |
3293 return new (zone_) | 3357 bool is_static) { |
3294 ObjectLiteral::Property(zone_, ast_value_factory_, key, value); | 3358 return new (zone_) ObjectLiteral::Property(zone_, ast_value_factory_, key, |
| 3359 value, is_static); |
3295 } | 3360 } |
3296 | 3361 |
3297 ObjectLiteral::Property* NewObjectLiteralProperty(bool is_getter, | 3362 ObjectLiteral::Property* NewObjectLiteralProperty(bool is_getter, |
3298 FunctionLiteral* value, | 3363 FunctionLiteral* value, |
3299 int pos) { | 3364 int pos, bool is_static) { |
3300 ObjectLiteral::Property* prop = | 3365 ObjectLiteral::Property* prop = |
3301 new(zone_) ObjectLiteral::Property(zone_, is_getter, value); | 3366 new (zone_) ObjectLiteral::Property(zone_, is_getter, value, is_static); |
3302 prop->set_key(NewStringLiteral(value->raw_name(), pos)); | 3367 prop->set_key(NewStringLiteral(value->raw_name(), pos)); |
3303 return prop; // Not an AST node, will not be visited. | 3368 return prop; // Not an AST node, will not be visited. |
3304 } | 3369 } |
3305 | 3370 |
3306 RegExpLiteral* NewRegExpLiteral(const AstRawString* pattern, | 3371 RegExpLiteral* NewRegExpLiteral(const AstRawString* pattern, |
3307 const AstRawString* flags, | 3372 const AstRawString* flags, |
3308 int literal_index, | 3373 int literal_index, |
3309 int pos) { | 3374 int pos) { |
3310 RegExpLiteral* lit = new (zone_) | 3375 RegExpLiteral* lit = new (zone_) |
3311 RegExpLiteral(zone_, pattern, flags, literal_index, pos, id_gen_); | 3376 RegExpLiteral(zone_, pattern, flags, literal_index, pos, id_gen_); |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3447 expected_property_count, handler_count, parameter_count, function_type, | 3512 expected_property_count, handler_count, parameter_count, function_type, |
3448 has_duplicate_parameters, is_function, is_parenthesized, kind, position, | 3513 has_duplicate_parameters, is_function, is_parenthesized, kind, position, |
3449 id_gen_); | 3514 id_gen_); |
3450 // Top-level literal doesn't count for the AST's properties. | 3515 // Top-level literal doesn't count for the AST's properties. |
3451 if (is_function == FunctionLiteral::kIsFunction) { | 3516 if (is_function == FunctionLiteral::kIsFunction) { |
3452 visitor_.VisitFunctionLiteral(lit); | 3517 visitor_.VisitFunctionLiteral(lit); |
3453 } | 3518 } |
3454 return lit; | 3519 return lit; |
3455 } | 3520 } |
3456 | 3521 |
| 3522 ClassLiteral* NewClassLiteral(const AstRawString* name, Expression* extends, |
| 3523 ZoneList<ObjectLiteral::Property*>* properties, |
| 3524 AstValueFactory* ast_value_factory, |
| 3525 int position) { |
| 3526 ClassLiteral* lit = new (zone_) ClassLiteral( |
| 3527 zone_, name, extends, properties, ast_value_factory, position, id_gen_); |
| 3528 VISIT_AND_RETURN(ClassLiteral, lit) |
| 3529 } |
| 3530 |
3457 NativeFunctionLiteral* NewNativeFunctionLiteral(const AstRawString* name, | 3531 NativeFunctionLiteral* NewNativeFunctionLiteral(const AstRawString* name, |
3458 v8::Extension* extension, | 3532 v8::Extension* extension, |
3459 int pos) { | 3533 int pos) { |
3460 NativeFunctionLiteral* lit = | 3534 NativeFunctionLiteral* lit = |
3461 new (zone_) NativeFunctionLiteral(zone_, name, extension, pos, id_gen_); | 3535 new (zone_) NativeFunctionLiteral(zone_, name, extension, pos, id_gen_); |
3462 VISIT_AND_RETURN(NativeFunctionLiteral, lit) | 3536 VISIT_AND_RETURN(NativeFunctionLiteral, lit) |
3463 } | 3537 } |
3464 | 3538 |
3465 ThisFunction* NewThisFunction(int pos) { | 3539 ThisFunction* NewThisFunction(int pos) { |
3466 ThisFunction* fun = new (zone_) ThisFunction(zone_, pos, id_gen_); | 3540 ThisFunction* fun = new (zone_) ThisFunction(zone_, pos, id_gen_); |
(...skipping 12 matching lines...) Expand all Loading... |
3479 Zone* zone_; | 3553 Zone* zone_; |
3480 Visitor visitor_; | 3554 Visitor visitor_; |
3481 AstValueFactory* ast_value_factory_; | 3555 AstValueFactory* ast_value_factory_; |
3482 AstNode::IdGen* id_gen_; | 3556 AstNode::IdGen* id_gen_; |
3483 }; | 3557 }; |
3484 | 3558 |
3485 | 3559 |
3486 } } // namespace v8::internal | 3560 } } // namespace v8::internal |
3487 | 3561 |
3488 #endif // V8_AST_H_ | 3562 #endif // V8_AST_H_ |
OLD | NEW |