OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
108 namespace internal { | 108 namespace internal { |
109 | 109 |
110 class Arguments; | 110 class Arguments; |
111 class Object; | 111 class Object; |
112 class Heap; | 112 class Heap; |
113 class HeapObject; | 113 class HeapObject; |
114 class Isolate; | 114 class Isolate; |
115 } | 115 } |
116 | 116 |
117 | 117 |
118 // --- W e a k H a n d l e s | 118 // --- Weak Handles --- |
119 | 119 |
120 | 120 |
121 /** | 121 /** |
122 * A weak reference callback function. | 122 * A weak reference callback function. |
123 * | 123 * |
124 * This callback should either explicitly invoke Dispose on |object| if | 124 * This callback should either explicitly invoke Dispose on |object| if |
125 * V8 wrapper is not needed anymore, or 'revive' it by invocation of MakeWeak. | 125 * V8 wrapper is not needed anymore, or 'revive' it by invocation of MakeWeak. |
126 * | 126 * |
127 * \param object the weak global object to be reclaimed by the garbage collector | 127 * \param object the weak global object to be reclaimed by the garbage collector |
128 * \param parameter the value passed in when making the weak global object | 128 * \param parameter the value passed in when making the weak global object |
129 */ | 129 */ |
130 typedef void (*WeakReferenceCallback)(Persistent<Value> object, | 130 typedef void (*WeakReferenceCallback)(Persistent<Value> object, |
131 void* parameter); | 131 void* parameter); |
132 | 132 |
133 | 133 |
134 // --- H a n d l e s --- | 134 // --- Handles --- |
135 | 135 |
136 #define TYPE_CHECK(T, S) \ | 136 #define TYPE_CHECK(T, S) \ |
137 while (false) { \ | 137 while (false) { \ |
138 *(static_cast<T* volatile*>(0)) = static_cast<S*>(0); \ | 138 *(static_cast<T* volatile*>(0)) = static_cast<S*>(0); \ |
139 } | 139 } |
140 | 140 |
141 /** | 141 /** |
142 * An object reference managed by the v8 garbage collector. | 142 * An object reference managed by the v8 garbage collector. |
143 * | 143 * |
144 * All objects returned from v8 have to be tracked by the garbage | 144 * All objects returned from v8 have to be tracked by the garbage |
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
476 | 476 |
477 // Allow for the active closing of HandleScopes which allows to pass a handle | 477 // Allow for the active closing of HandleScopes which allows to pass a handle |
478 // from the HandleScope being closed to the next top most HandleScope. | 478 // from the HandleScope being closed to the next top most HandleScope. |
479 bool is_closed_; | 479 bool is_closed_; |
480 internal::Object** RawClose(internal::Object** value); | 480 internal::Object** RawClose(internal::Object** value); |
481 | 481 |
482 friend class ImplementationUtilities; | 482 friend class ImplementationUtilities; |
483 }; | 483 }; |
484 | 484 |
485 | 485 |
486 // --- S p e c i a l o b j e c t s --- | 486 // --- Special objects --- |
487 | 487 |
488 | 488 |
489 /** | 489 /** |
490 * The superclass of values and API object templates. | 490 * The superclass of values and API object templates. |
491 */ | 491 */ |
492 class V8EXPORT Data { | 492 class V8EXPORT Data { |
493 private: | 493 private: |
494 Data(); | 494 Data(); |
495 }; | 495 }; |
496 | 496 |
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
834 bool IsEval() const; | 834 bool IsEval() const; |
835 | 835 |
836 /** | 836 /** |
837 * Returns whther or not the associated function is called as a | 837 * Returns whther or not the associated function is called as a |
838 * constructor via "new". | 838 * constructor via "new". |
839 */ | 839 */ |
840 bool IsConstructor() const; | 840 bool IsConstructor() const; |
841 }; | 841 }; |
842 | 842 |
843 | 843 |
844 // --- V a l u e --- | 844 // --- Value --- |
845 | 845 |
846 | 846 |
847 /** | 847 /** |
848 * The superclass of all JavaScript values and objects. | 848 * The superclass of all JavaScript values and objects. |
849 */ | 849 */ |
850 class Value : public Data { | 850 class Value : public Data { |
851 public: | 851 public: |
852 | 852 |
853 /** | 853 /** |
854 * Returns true if this value is the undefined value. See ECMA-262 | 854 * Returns true if this value is the undefined value. See ECMA-262 |
(...skipping 921 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1776 static inline External* Cast(Value* obj); | 1776 static inline External* Cast(Value* obj); |
1777 V8EXPORT void* Value() const; | 1777 V8EXPORT void* Value() const; |
1778 private: | 1778 private: |
1779 V8EXPORT External(); | 1779 V8EXPORT External(); |
1780 V8EXPORT static void CheckCast(v8::Value* obj); | 1780 V8EXPORT static void CheckCast(v8::Value* obj); |
1781 static inline void* QuickUnwrap(Handle<v8::Value> obj); | 1781 static inline void* QuickUnwrap(Handle<v8::Value> obj); |
1782 V8EXPORT static void* FullUnwrap(Handle<v8::Value> obj); | 1782 V8EXPORT static void* FullUnwrap(Handle<v8::Value> obj); |
1783 }; | 1783 }; |
1784 | 1784 |
1785 | 1785 |
1786 // --- T e m p l a t e s --- | 1786 // --- Templates --- |
1787 | 1787 |
1788 | 1788 |
1789 /** | 1789 /** |
1790 * The superclass of object and function templates. | 1790 * The superclass of object and function templates. |
1791 */ | 1791 */ |
1792 class V8EXPORT Template : public Data { | 1792 class V8EXPORT Template : public Data { |
1793 public: | 1793 public: |
1794 /** Adds a property to each instance created by this template.*/ | 1794 /** Adds a property to each instance created by this template.*/ |
1795 void Set(Handle<String> name, Handle<Data> value, | 1795 void Set(Handle<String> name, Handle<Data> value, |
1796 PropertyAttribute attributes = None); | 1796 PropertyAttribute attributes = None); |
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2310 class V8EXPORT TypeSwitch : public Data { | 2310 class V8EXPORT TypeSwitch : public Data { |
2311 public: | 2311 public: |
2312 static Local<TypeSwitch> New(Handle<FunctionTemplate> type); | 2312 static Local<TypeSwitch> New(Handle<FunctionTemplate> type); |
2313 static Local<TypeSwitch> New(int argc, Handle<FunctionTemplate> types[]); | 2313 static Local<TypeSwitch> New(int argc, Handle<FunctionTemplate> types[]); |
2314 int match(Handle<Value> value); | 2314 int match(Handle<Value> value); |
2315 private: | 2315 private: |
2316 TypeSwitch(); | 2316 TypeSwitch(); |
2317 }; | 2317 }; |
2318 | 2318 |
2319 | 2319 |
2320 // --- E x t e n s i o n s --- | 2320 // --- Extensions --- |
2321 | 2321 |
2322 | 2322 |
2323 /** | 2323 /** |
2324 * Ignore | 2324 * Ignore |
2325 */ | 2325 */ |
2326 class V8EXPORT Extension { // NOLINT | 2326 class V8EXPORT Extension { // NOLINT |
2327 public: | 2327 public: |
2328 Extension(const char* name, | 2328 Extension(const char* name, |
2329 const char* source = 0, | 2329 const char* source = 0, |
2330 int dep_count = 0, | 2330 int dep_count = 0, |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2362 * Ignore | 2362 * Ignore |
2363 */ | 2363 */ |
2364 class V8EXPORT DeclareExtension { | 2364 class V8EXPORT DeclareExtension { |
2365 public: | 2365 public: |
2366 inline DeclareExtension(Extension* extension) { | 2366 inline DeclareExtension(Extension* extension) { |
2367 RegisterExtension(extension); | 2367 RegisterExtension(extension); |
2368 } | 2368 } |
2369 }; | 2369 }; |
2370 | 2370 |
2371 | 2371 |
2372 // --- S t a t i c s --- | 2372 // --- Statics --- |
2373 | 2373 |
2374 | 2374 |
2375 Handle<Primitive> V8EXPORT Undefined(); | 2375 Handle<Primitive> V8EXPORT Undefined(); |
2376 Handle<Primitive> V8EXPORT Null(); | 2376 Handle<Primitive> V8EXPORT Null(); |
2377 Handle<Boolean> V8EXPORT True(); | 2377 Handle<Boolean> V8EXPORT True(); |
2378 Handle<Boolean> V8EXPORT False(); | 2378 Handle<Boolean> V8EXPORT False(); |
2379 | 2379 |
2380 | 2380 |
2381 /** | 2381 /** |
2382 * A set of constraints that specifies the limits of the runtime's memory use. | 2382 * A set of constraints that specifies the limits of the runtime's memory use. |
(...skipping 20 matching lines...) Expand all Loading... |
2403 int max_young_space_size_; | 2403 int max_young_space_size_; |
2404 int max_old_space_size_; | 2404 int max_old_space_size_; |
2405 int max_executable_size_; | 2405 int max_executable_size_; |
2406 uint32_t* stack_limit_; | 2406 uint32_t* stack_limit_; |
2407 }; | 2407 }; |
2408 | 2408 |
2409 | 2409 |
2410 bool V8EXPORT SetResourceConstraints(ResourceConstraints* constraints); | 2410 bool V8EXPORT SetResourceConstraints(ResourceConstraints* constraints); |
2411 | 2411 |
2412 | 2412 |
2413 // --- E x c e p t i o n s --- | 2413 // --- Exceptions --- |
2414 | 2414 |
2415 | 2415 |
2416 typedef void (*FatalErrorCallback)(const char* location, const char* message); | 2416 typedef void (*FatalErrorCallback)(const char* location, const char* message); |
2417 | 2417 |
2418 | 2418 |
2419 typedef void (*MessageCallback)(Handle<Message> message, Handle<Value> data); | 2419 typedef void (*MessageCallback)(Handle<Message> message, Handle<Value> data); |
2420 | 2420 |
2421 | 2421 |
2422 /** | 2422 /** |
2423 * Schedules an exception to be thrown when returning to JavaScript. When an | 2423 * Schedules an exception to be thrown when returning to JavaScript. When an |
(...skipping 10 matching lines...) Expand all Loading... |
2434 class V8EXPORT Exception { | 2434 class V8EXPORT Exception { |
2435 public: | 2435 public: |
2436 static Local<Value> RangeError(Handle<String> message); | 2436 static Local<Value> RangeError(Handle<String> message); |
2437 static Local<Value> ReferenceError(Handle<String> message); | 2437 static Local<Value> ReferenceError(Handle<String> message); |
2438 static Local<Value> SyntaxError(Handle<String> message); | 2438 static Local<Value> SyntaxError(Handle<String> message); |
2439 static Local<Value> TypeError(Handle<String> message); | 2439 static Local<Value> TypeError(Handle<String> message); |
2440 static Local<Value> Error(Handle<String> message); | 2440 static Local<Value> Error(Handle<String> message); |
2441 }; | 2441 }; |
2442 | 2442 |
2443 | 2443 |
2444 // --- C o u n t e r s C a l l b a c k s --- | 2444 // --- Counters Callbacks --- |
2445 | 2445 |
2446 typedef int* (*CounterLookupCallback)(const char* name); | 2446 typedef int* (*CounterLookupCallback)(const char* name); |
2447 | 2447 |
2448 typedef void* (*CreateHistogramCallback)(const char* name, | 2448 typedef void* (*CreateHistogramCallback)(const char* name, |
2449 int min, | 2449 int min, |
2450 int max, | 2450 int max, |
2451 size_t buckets); | 2451 size_t buckets); |
2452 | 2452 |
2453 typedef void (*AddHistogramSampleCallback)(void* histogram, int sample); | 2453 typedef void (*AddHistogramSampleCallback)(void* histogram, int sample); |
2454 | 2454 |
2455 // --- M e m o r y A l l o c a t i o n C a l l b a c k --- | 2455 // --- Memory Allocation Callback --- |
2456 enum ObjectSpace { | 2456 enum ObjectSpace { |
2457 kObjectSpaceNewSpace = 1 << 0, | 2457 kObjectSpaceNewSpace = 1 << 0, |
2458 kObjectSpaceOldPointerSpace = 1 << 1, | 2458 kObjectSpaceOldPointerSpace = 1 << 1, |
2459 kObjectSpaceOldDataSpace = 1 << 2, | 2459 kObjectSpaceOldDataSpace = 1 << 2, |
2460 kObjectSpaceCodeSpace = 1 << 3, | 2460 kObjectSpaceCodeSpace = 1 << 3, |
2461 kObjectSpaceMapSpace = 1 << 4, | 2461 kObjectSpaceMapSpace = 1 << 4, |
2462 kObjectSpaceLoSpace = 1 << 5, | 2462 kObjectSpaceLoSpace = 1 << 5, |
2463 | 2463 |
2464 kObjectSpaceAll = kObjectSpaceNewSpace | kObjectSpaceOldPointerSpace | | 2464 kObjectSpaceAll = kObjectSpaceNewSpace | kObjectSpaceOldPointerSpace | |
2465 kObjectSpaceOldDataSpace | kObjectSpaceCodeSpace | kObjectSpaceMapSpace | | 2465 kObjectSpaceOldDataSpace | kObjectSpaceCodeSpace | kObjectSpaceMapSpace | |
2466 kObjectSpaceLoSpace | 2466 kObjectSpaceLoSpace |
2467 }; | 2467 }; |
2468 | 2468 |
2469 enum AllocationAction { | 2469 enum AllocationAction { |
2470 kAllocationActionAllocate = 1 << 0, | 2470 kAllocationActionAllocate = 1 << 0, |
2471 kAllocationActionFree = 1 << 1, | 2471 kAllocationActionFree = 1 << 1, |
2472 kAllocationActionAll = kAllocationActionAllocate | kAllocationActionFree | 2472 kAllocationActionAll = kAllocationActionAllocate | kAllocationActionFree |
2473 }; | 2473 }; |
2474 | 2474 |
2475 typedef void (*MemoryAllocationCallback)(ObjectSpace space, | 2475 typedef void (*MemoryAllocationCallback)(ObjectSpace space, |
2476 AllocationAction action, | 2476 AllocationAction action, |
2477 int size); | 2477 int size); |
2478 | 2478 |
2479 // --- F a i l e d A c c e s s C h e c k C a l l b a c k --- | 2479 // --- Failed Access Check Callback --- |
2480 typedef void (*FailedAccessCheckCallback)(Local<Object> target, | 2480 typedef void (*FailedAccessCheckCallback)(Local<Object> target, |
2481 AccessType type, | 2481 AccessType type, |
2482 Local<Value> data); | 2482 Local<Value> data); |
2483 | 2483 |
2484 // --- G a r b a g e C o l l e c t i o n C a l l b a c k s | 2484 // --- AllowCodeGenerationFromStrings callbacks --- |
| 2485 |
| 2486 /** |
| 2487 * Callback to check if code generation from strings is allowed. See |
| 2488 * Context::AllowCodeGenerationFromStrings. |
| 2489 */ |
| 2490 typedef bool (*AllowCodeGenerationFromStringsCallback)(Local<Context> context); |
| 2491 |
| 2492 // --- Garbage Collection Callbacks --- |
2485 | 2493 |
2486 /** | 2494 /** |
2487 * Applications can register callback functions which will be called | 2495 * Applications can register callback functions which will be called |
2488 * before and after a garbage collection. Allocations are not | 2496 * before and after a garbage collection. Allocations are not |
2489 * allowed in the callback functions, you therefore cannot manipulate | 2497 * allowed in the callback functions, you therefore cannot manipulate |
2490 * objects (set or delete properties for example) since it is possible | 2498 * objects (set or delete properties for example) since it is possible |
2491 * such operations will result in the allocation of objects. | 2499 * such operations will result in the allocation of objects. |
2492 */ | 2500 */ |
2493 enum GCType { | 2501 enum GCType { |
2494 kGCTypeScavenge = 1 << 0, | 2502 kGCTypeScavenge = 1 << 0, |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2655 | 2663 |
2656 /** | 2664 /** |
2657 * Container class for static utility functions. | 2665 * Container class for static utility functions. |
2658 */ | 2666 */ |
2659 class V8EXPORT V8 { | 2667 class V8EXPORT V8 { |
2660 public: | 2668 public: |
2661 /** Set the callback to invoke in case of fatal errors. */ | 2669 /** Set the callback to invoke in case of fatal errors. */ |
2662 static void SetFatalErrorHandler(FatalErrorCallback that); | 2670 static void SetFatalErrorHandler(FatalErrorCallback that); |
2663 | 2671 |
2664 /** | 2672 /** |
| 2673 * Set the callback to invoke to check if code generation from |
| 2674 * strings should be allowed. |
| 2675 */ |
| 2676 static void SetAllowCodeGenerationFromStringsCallback( |
| 2677 AllowCodeGenerationFromStringsCallback that); |
| 2678 |
| 2679 /** |
2665 * Ignore out-of-memory exceptions. | 2680 * Ignore out-of-memory exceptions. |
2666 * | 2681 * |
2667 * V8 running out of memory is treated as a fatal error by default. | 2682 * V8 running out of memory is treated as a fatal error by default. |
2668 * This means that the fatal error handler is called and that V8 is | 2683 * This means that the fatal error handler is called and that V8 is |
2669 * terminated. | 2684 * terminated. |
2670 * | 2685 * |
2671 * IgnoreOutOfMemoryException can be used to not treat a | 2686 * IgnoreOutOfMemoryException can be used to not treat a |
2672 * out-of-memory situation as a fatal error. This way, the contexts | 2687 * out-of-memory situation as a fatal error. This way, the contexts |
2673 * that did not cause the out of memory problem might be able to | 2688 * that did not cause the out of memory problem might be able to |
2674 * continue execution. | 2689 * continue execution. |
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3182 void* message_; | 3197 void* message_; |
3183 bool is_verbose_ : 1; | 3198 bool is_verbose_ : 1; |
3184 bool can_continue_ : 1; | 3199 bool can_continue_ : 1; |
3185 bool capture_message_ : 1; | 3200 bool capture_message_ : 1; |
3186 bool rethrow_ : 1; | 3201 bool rethrow_ : 1; |
3187 | 3202 |
3188 friend class v8::internal::Isolate; | 3203 friend class v8::internal::Isolate; |
3189 }; | 3204 }; |
3190 | 3205 |
3191 | 3206 |
3192 // --- C o n t e x t --- | 3207 // --- Context --- |
3193 | 3208 |
3194 | 3209 |
3195 /** | 3210 /** |
3196 * Ignore | 3211 * Ignore |
3197 */ | 3212 */ |
3198 class V8EXPORT ExtensionConfiguration { | 3213 class V8EXPORT ExtensionConfiguration { |
3199 public: | 3214 public: |
3200 ExtensionConfiguration(int name_count, const char* names[]) | 3215 ExtensionConfiguration(int name_count, const char* names[]) |
3201 : name_count_(name_count), names_(names) { } | 3216 : name_count_(name_count), names_(names) { } |
3202 private: | 3217 private: |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3318 | 3333 |
3319 /** | 3334 /** |
3320 * Associate an additional data object with the context. This is mainly used | 3335 * Associate an additional data object with the context. This is mainly used |
3321 * with the debugger to provide additional information on the context through | 3336 * with the debugger to provide additional information on the context through |
3322 * the debugger API. | 3337 * the debugger API. |
3323 */ | 3338 */ |
3324 void SetData(Handle<String> data); | 3339 void SetData(Handle<String> data); |
3325 Local<Value> GetData(); | 3340 Local<Value> GetData(); |
3326 | 3341 |
3327 /** | 3342 /** |
| 3343 * Control whether code generation from strings is allowed. Calling |
| 3344 * this method with false will disable 'eval' and the 'Function' |
| 3345 * constructor for code running in this context. If 'eval' or the |
| 3346 * 'Function' constructor are used an exception will be thrown. |
| 3347 * |
| 3348 * If code generation from strings is not allowed the |
| 3349 * V8::AllowCodeGenerationFromStrings callback will be invoked if |
| 3350 * set before blocking the call to 'eval' or the 'Function' |
| 3351 * constructor. If that callback returns true, the call will be |
| 3352 * allowed, otherwise an exception will be thrown. If no callback is |
| 3353 * set an exception will be thrown. |
| 3354 */ |
| 3355 void AllowCodeGenerationFromStrings(bool allow); |
| 3356 |
| 3357 /** |
3328 * Stack-allocated class which sets the execution context for all | 3358 * Stack-allocated class which sets the execution context for all |
3329 * operations executed within a local scope. | 3359 * operations executed within a local scope. |
3330 */ | 3360 */ |
3331 class Scope { | 3361 class Scope { |
3332 public: | 3362 public: |
3333 explicit inline Scope(Handle<Context> context) : context_(context) { | 3363 explicit inline Scope(Handle<Context> context) : context_(context) { |
3334 context_->Enter(); | 3364 context_->Enter(); |
3335 } | 3365 } |
3336 inline ~Scope() { context_->Exit(); } | 3366 inline ~Scope() { context_->Exit(); } |
3337 private: | 3367 private: |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3513 }; | 3543 }; |
3514 virtual ~ActivityControl() {} | 3544 virtual ~ActivityControl() {} |
3515 /** | 3545 /** |
3516 * Notify about current progress. The activity can be stopped by | 3546 * Notify about current progress. The activity can be stopped by |
3517 * returning kAbort as the callback result. | 3547 * returning kAbort as the callback result. |
3518 */ | 3548 */ |
3519 virtual ControlOption ReportProgressValue(int done, int total) = 0; | 3549 virtual ControlOption ReportProgressValue(int done, int total) = 0; |
3520 }; | 3550 }; |
3521 | 3551 |
3522 | 3552 |
3523 // --- I m p l e m e n t a t i o n --- | 3553 // --- Implementation --- |
3524 | 3554 |
3525 | 3555 |
3526 namespace internal { | 3556 namespace internal { |
3527 | 3557 |
3528 static const int kApiPointerSize = sizeof(void*); // NOLINT | 3558 static const int kApiPointerSize = sizeof(void*); // NOLINT |
3529 static const int kApiIntSize = sizeof(int); // NOLINT | 3559 static const int kApiIntSize = sizeof(int); // NOLINT |
3530 | 3560 |
3531 // Tag information for HeapObject. | 3561 // Tag information for HeapObject. |
3532 const int kHeapObjectTag = 1; | 3562 const int kHeapObjectTag = 1; |
3533 const int kHeapObjectTagSize = 2; | 3563 const int kHeapObjectTagSize = 2; |
(...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4025 | 4055 |
4026 | 4056 |
4027 } // namespace v8 | 4057 } // namespace v8 |
4028 | 4058 |
4029 | 4059 |
4030 #undef V8EXPORT | 4060 #undef V8EXPORT |
4031 #undef TYPE_CHECK | 4061 #undef TYPE_CHECK |
4032 | 4062 |
4033 | 4063 |
4034 #endif // V8_H_ | 4064 #endif // V8_H_ |
OLD | NEW |