Home | History | Annotate | Download | only in src
      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
      3 // found in the LICENSE file.
      4 
      5 #ifndef V8_CONTEXTS_H_
      6 #define V8_CONTEXTS_H_
      7 
      8 #include "src/heap/heap.h"
      9 #include "src/objects.h"
     10 
     11 namespace v8 {
     12 namespace internal {
     13 
     14 
     15 enum ContextLookupFlags {
     16   FOLLOW_CONTEXT_CHAIN = 1,
     17   FOLLOW_PROTOTYPE_CHAIN = 2,
     18 
     19   DONT_FOLLOW_CHAINS = 0,
     20   FOLLOW_CHAINS = FOLLOW_CONTEXT_CHAIN | FOLLOW_PROTOTYPE_CHAIN
     21 };
     22 
     23 
     24 // ES5 10.2 defines lexical environments with mutable and immutable bindings.
     25 // Immutable bindings have two states, initialized and uninitialized, and
     26 // their state is changed by the InitializeImmutableBinding method. The
     27 // BindingFlags enum represents information if a binding has definitely been
     28 // initialized. A mutable binding does not need to be checked and thus has
     29 // the BindingFlag MUTABLE_IS_INITIALIZED.
     30 //
     31 // There are two possibilities for immutable bindings
     32 //  * 'const' declared variables. They are initialized when evaluating the
     33 //    corresponding declaration statement. They need to be checked for being
     34 //    initialized and thus get the flag IMMUTABLE_CHECK_INITIALIZED.
     35 //  * The function name of a named function literal. The binding is immediately
     36 //    initialized when entering the function and thus does not need to be
     37 //    checked. it gets the BindingFlag IMMUTABLE_IS_INITIALIZED.
     38 // Accessing an uninitialized binding produces the undefined value.
     39 //
     40 // The harmony proposal for block scoped bindings also introduces the
     41 // uninitialized state for mutable bindings.
     42 //  * A 'let' declared variable. They are initialized when evaluating the
     43 //    corresponding declaration statement. They need to be checked for being
     44 //    initialized and thus get the flag MUTABLE_CHECK_INITIALIZED.
     45 //  * A 'var' declared variable. It is initialized immediately upon creation
     46 //    and thus doesn't need to be checked. It gets the flag
     47 //    MUTABLE_IS_INITIALIZED.
     48 //  * Catch bound variables, function parameters and variables introduced by
     49 //    function declarations are initialized immediately and do not need to be
     50 //    checked. Thus they get the flag MUTABLE_IS_INITIALIZED.
     51 // Immutable bindings in harmony mode get the _HARMONY flag variants. Accessing
     52 // an uninitialized binding produces a reference error.
     53 //
     54 // In V8 uninitialized bindings are set to the hole value upon creation and set
     55 // to a different value upon initialization.
     56 enum BindingFlags {
     57   MUTABLE_IS_INITIALIZED,
     58   MUTABLE_CHECK_INITIALIZED,
     59   IMMUTABLE_IS_INITIALIZED,
     60   IMMUTABLE_CHECK_INITIALIZED,
     61   IMMUTABLE_IS_INITIALIZED_HARMONY,
     62   IMMUTABLE_CHECK_INITIALIZED_HARMONY,
     63   MISSING_BINDING
     64 };
     65 
     66 
     67 // Heap-allocated activation contexts.
     68 //
     69 // Contexts are implemented as FixedArray objects; the Context
     70 // class is a convenience interface casted on a FixedArray object.
     71 //
     72 // Note: Context must have no virtual functions and Context objects
     73 // must always be allocated via Heap::AllocateContext() or
     74 // Factory::NewContext.
     75 
     76 #define NATIVE_CONTEXT_FIELDS(V)                                               \
     77   V(GLOBAL_PROXY_INDEX, JSObject, global_proxy_object)                         \
     78   V(SECURITY_TOKEN_INDEX, Object, security_token)                              \
     79   V(BOOLEAN_FUNCTION_INDEX, JSFunction, boolean_function)                      \
     80   V(NUMBER_FUNCTION_INDEX, JSFunction, number_function)                        \
     81   V(STRING_FUNCTION_INDEX, JSFunction, string_function)                        \
     82   V(STRING_FUNCTION_PROTOTYPE_MAP_INDEX, Map, string_function_prototype_map)   \
     83   V(SYMBOL_FUNCTION_INDEX, JSFunction, symbol_function)                        \
     84   V(OBJECT_FUNCTION_INDEX, JSFunction, object_function)                        \
     85   V(INTERNAL_ARRAY_FUNCTION_INDEX, JSFunction, internal_array_function)        \
     86   V(ARRAY_FUNCTION_INDEX, JSFunction, array_function)                          \
     87   V(JS_ARRAY_MAPS_INDEX, Object, js_array_maps)                                \
     88   V(DATE_FUNCTION_INDEX, JSFunction, date_function)                            \
     89   V(JSON_OBJECT_INDEX, JSObject, json_object)                                  \
     90   V(REGEXP_FUNCTION_INDEX, JSFunction, regexp_function)                        \
     91   V(INITIAL_OBJECT_PROTOTYPE_INDEX, JSObject, initial_object_prototype)        \
     92   V(INITIAL_ARRAY_PROTOTYPE_INDEX, JSObject, initial_array_prototype)          \
     93   V(CREATE_DATE_FUN_INDEX, JSFunction, create_date_fun)                        \
     94   V(TO_NUMBER_FUN_INDEX, JSFunction, to_number_fun)                            \
     95   V(TO_STRING_FUN_INDEX, JSFunction, to_string_fun)                            \
     96   V(TO_DETAIL_STRING_FUN_INDEX, JSFunction, to_detail_string_fun)              \
     97   V(TO_OBJECT_FUN_INDEX, JSFunction, to_object_fun)                            \
     98   V(TO_INTEGER_FUN_INDEX, JSFunction, to_integer_fun)                          \
     99   V(TO_UINT32_FUN_INDEX, JSFunction, to_uint32_fun)                            \
    100   V(TO_INT32_FUN_INDEX, JSFunction, to_int32_fun)                              \
    101   V(GLOBAL_EVAL_FUN_INDEX, JSFunction, global_eval_fun)                        \
    102   V(INSTANTIATE_FUN_INDEX, JSFunction, instantiate_fun)                        \
    103   V(CONFIGURE_INSTANCE_FUN_INDEX, JSFunction, configure_instance_fun)          \
    104   V(MATH_ABS_FUN_INDEX, JSFunction, math_abs_fun)                              \
    105   V(MATH_ACOS_FUN_INDEX, JSFunction, math_acos_fun)                            \
    106   V(MATH_ASIN_FUN_INDEX, JSFunction, math_asin_fun)                            \
    107   V(MATH_ATAN_FUN_INDEX, JSFunction, math_atan_fun)                            \
    108   V(MATH_ATAN2_FUN_INDEX, JSFunction, math_atan2_fun)                          \
    109   V(MATH_CEIL_FUN_INDEX, JSFunction, math_ceil_fun)                            \
    110   V(MATH_COS_FUN_INDEX, JSFunction, math_cos_fun)                              \
    111   V(MATH_EXP_FUN_INDEX, JSFunction, math_exp_fun)                              \
    112   V(MATH_FLOOR_FUN_INDEX, JSFunction, math_floor_fun)                          \
    113   V(MATH_IMUL_FUN_INDEX, JSFunction, math_imul_fun)                            \
    114   V(MATH_LOG_FUN_INDEX, JSFunction, math_log_fun)                              \
    115   V(MATH_MAX_FUN_INDEX, JSFunction, math_max_fun)                              \
    116   V(MATH_MIN_FUN_INDEX, JSFunction, math_min_fun)                              \
    117   V(MATH_POW_FUN_INDEX, JSFunction, math_pow_fun)                              \
    118   V(MATH_RANDOM_FUN_INDEX, JSFunction, math_random_fun)                        \
    119   V(MATH_ROUND_FUN_INDEX, JSFunction, math_round_fun)                          \
    120   V(MATH_SIN_FUN_INDEX, JSFunction, math_sin_fun)                              \
    121   V(MATH_SQRT_FUN_INDEX, JSFunction, math_sqrt_fun)                            \
    122   V(MATH_TAN_FUN_INDEX, JSFunction, math_tan_fun)                              \
    123   V(ARRAY_BUFFER_FUN_INDEX, JSFunction, array_buffer_fun)                      \
    124   V(UINT8_ARRAY_FUN_INDEX, JSFunction, uint8_array_fun)                        \
    125   V(INT8_ARRAY_FUN_INDEX, JSFunction, int8_array_fun)                          \
    126   V(UINT16_ARRAY_FUN_INDEX, JSFunction, uint16_array_fun)                      \
    127   V(INT16_ARRAY_FUN_INDEX, JSFunction, int16_array_fun)                        \
    128   V(UINT32_ARRAY_FUN_INDEX, JSFunction, uint32_array_fun)                      \
    129   V(INT32_ARRAY_FUN_INDEX, JSFunction, int32_array_fun)                        \
    130   V(FLOAT32_ARRAY_FUN_INDEX, JSFunction, float32_array_fun)                    \
    131   V(FLOAT64_ARRAY_FUN_INDEX, JSFunction, float64_array_fun)                    \
    132   V(UINT8_CLAMPED_ARRAY_FUN_INDEX, JSFunction, uint8_clamped_array_fun)        \
    133   V(INT8_ARRAY_EXTERNAL_MAP_INDEX, Map, int8_array_external_map)               \
    134   V(UINT8_ARRAY_EXTERNAL_MAP_INDEX, Map, uint8_array_external_map)             \
    135   V(INT16_ARRAY_EXTERNAL_MAP_INDEX, Map, int16_array_external_map)             \
    136   V(UINT16_ARRAY_EXTERNAL_MAP_INDEX, Map, uint16_array_external_map)           \
    137   V(INT32_ARRAY_EXTERNAL_MAP_INDEX, Map, int32_array_external_map)             \
    138   V(UINT32_ARRAY_EXTERNAL_MAP_INDEX, Map, uint32_array_external_map)           \
    139   V(FLOAT32_ARRAY_EXTERNAL_MAP_INDEX, Map, float32_array_external_map)         \
    140   V(FLOAT64_ARRAY_EXTERNAL_MAP_INDEX, Map, float64_array_external_map)         \
    141   V(UINT8_CLAMPED_ARRAY_EXTERNAL_MAP_INDEX, Map,                               \
    142     uint8_clamped_array_external_map)                                          \
    143   V(DATA_VIEW_FUN_INDEX, JSFunction, data_view_fun)                            \
    144   V(SLOPPY_FUNCTION_MAP_INDEX, Map, sloppy_function_map)                       \
    145   V(SLOPPY_FUNCTION_WITH_READONLY_PROTOTYPE_MAP_INDEX, Map,                    \
    146     sloppy_function_with_readonly_prototype_map)                               \
    147   V(STRICT_FUNCTION_MAP_INDEX, Map, strict_function_map)                       \
    148   V(SLOPPY_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX, Map,                          \
    149     sloppy_function_without_prototype_map)                                     \
    150   V(STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX, Map,                          \
    151     strict_function_without_prototype_map)                                     \
    152   V(BOUND_FUNCTION_MAP_INDEX, Map, bound_function_map)                         \
    153   V(REGEXP_RESULT_MAP_INDEX, Map, regexp_result_map)                           \
    154   V(SLOPPY_ARGUMENTS_MAP_INDEX, Map, sloppy_arguments_map)                     \
    155   V(ALIASED_ARGUMENTS_MAP_INDEX, Map, aliased_arguments_map)                   \
    156   V(STRICT_ARGUMENTS_MAP_INDEX, Map, strict_arguments_map)                     \
    157   V(MESSAGE_LISTENERS_INDEX, JSObject, message_listeners)                      \
    158   V(MAKE_MESSAGE_FUN_INDEX, JSFunction, make_message_fun)                      \
    159   V(GET_STACK_TRACE_LINE_INDEX, JSFunction, get_stack_trace_line_fun)          \
    160   V(CONFIGURE_GLOBAL_INDEX, JSFunction, configure_global_fun)                  \
    161   V(FUNCTION_CACHE_INDEX, JSObject, function_cache)                            \
    162   V(JSFUNCTION_RESULT_CACHES_INDEX, FixedArray, jsfunction_result_caches)      \
    163   V(NORMALIZED_MAP_CACHE_INDEX, Object, normalized_map_cache)                  \
    164   V(RUNTIME_CONTEXT_INDEX, Context, runtime_context)                           \
    165   V(CALL_AS_FUNCTION_DELEGATE_INDEX, JSFunction, call_as_function_delegate)    \
    166   V(CALL_AS_CONSTRUCTOR_DELEGATE_INDEX, JSFunction,                            \
    167     call_as_constructor_delegate)                                              \
    168   V(SCRIPT_FUNCTION_INDEX, JSFunction, script_function)                        \
    169   V(OPAQUE_REFERENCE_FUNCTION_INDEX, JSFunction, opaque_reference_function)    \
    170   V(CONTEXT_EXTENSION_FUNCTION_INDEX, JSFunction, context_extension_function)  \
    171   V(MAP_CACHE_INDEX, Object, map_cache)                                        \
    172   V(EMBEDDER_DATA_INDEX, FixedArray, embedder_data)                            \
    173   V(ALLOW_CODE_GEN_FROM_STRINGS_INDEX, Object, allow_code_gen_from_strings)    \
    174   V(ERROR_MESSAGE_FOR_CODE_GEN_FROM_STRINGS_INDEX, Object,                     \
    175     error_message_for_code_gen_from_strings)                                   \
    176   V(IS_PROMISE_INDEX, JSFunction, is_promise)                                  \
    177   V(PROMISE_CREATE_INDEX, JSFunction, promise_create)                          \
    178   V(PROMISE_RESOLVE_INDEX, JSFunction, promise_resolve)                        \
    179   V(PROMISE_REJECT_INDEX, JSFunction, promise_reject)                          \
    180   V(PROMISE_CHAIN_INDEX, JSFunction, promise_chain)                            \
    181   V(PROMISE_CATCH_INDEX, JSFunction, promise_catch)                            \
    182   V(PROMISE_THEN_INDEX, JSFunction, promise_then)                              \
    183   V(TO_COMPLETE_PROPERTY_DESCRIPTOR_INDEX, JSFunction,                         \
    184     to_complete_property_descriptor)                                           \
    185   V(DERIVED_HAS_TRAP_INDEX, JSFunction, derived_has_trap)                      \
    186   V(DERIVED_GET_TRAP_INDEX, JSFunction, derived_get_trap)                      \
    187   V(DERIVED_SET_TRAP_INDEX, JSFunction, derived_set_trap)                      \
    188   V(PROXY_ENUMERATE_INDEX, JSFunction, proxy_enumerate)                        \
    189   V(OBSERVERS_NOTIFY_CHANGE_INDEX, JSFunction, observers_notify_change)        \
    190   V(OBSERVERS_ENQUEUE_SPLICE_INDEX, JSFunction, observers_enqueue_splice)      \
    191   V(OBSERVERS_BEGIN_SPLICE_INDEX, JSFunction, observers_begin_perform_splice)  \
    192   V(OBSERVERS_END_SPLICE_INDEX, JSFunction, observers_end_perform_splice)      \
    193   V(NATIVE_OBJECT_OBSERVE_INDEX, JSFunction, native_object_observe)            \
    194   V(NATIVE_OBJECT_GET_NOTIFIER_INDEX, JSFunction, native_object_get_notifier)  \
    195   V(NATIVE_OBJECT_NOTIFIER_PERFORM_CHANGE, JSFunction,                         \
    196     native_object_notifier_perform_change)                                     \
    197   V(SLOPPY_GENERATOR_FUNCTION_MAP_INDEX, Map, sloppy_generator_function_map)   \
    198   V(STRICT_GENERATOR_FUNCTION_MAP_INDEX, Map, strict_generator_function_map)   \
    199   V(GENERATOR_OBJECT_PROTOTYPE_MAP_INDEX, Map, generator_object_prototype_map) \
    200   V(ITERATOR_RESULT_MAP_INDEX, Map, iterator_result_map)                       \
    201   V(MAP_ITERATOR_MAP_INDEX, Map, map_iterator_map)                             \
    202   V(SET_ITERATOR_MAP_INDEX, Map, set_iterator_map)                             \
    203   V(ITERATOR_SYMBOL_INDEX, Symbol, iterator_symbol)                            \
    204   V(UNSCOPABLES_SYMBOL_INDEX, Symbol, unscopables_symbol)                      \
    205   V(ARRAY_VALUES_ITERATOR_INDEX, JSFunction, array_values_iterator)
    206 
    207 // JSFunctions are pairs (context, function code), sometimes also called
    208 // closures. A Context object is used to represent function contexts and
    209 // dynamically pushed 'with' contexts (or 'scopes' in ECMA-262 speak).
    210 //
    211 // At runtime, the contexts build a stack in parallel to the execution
    212 // stack, with the top-most context being the current context. All contexts
    213 // have the following slots:
    214 //
    215 // [ closure   ]  This is the current function. It is the same for all
    216 //                contexts inside a function. It provides access to the
    217 //                incoming context (i.e., the outer context, which may
    218 //                or may not become the current function's context), and
    219 //                it provides access to the functions code and thus it's
    220 //                scope information, which in turn contains the names of
    221 //                statically allocated context slots. The names are needed
    222 //                for dynamic lookups in the presence of 'with' or 'eval'.
    223 //
    224 // [ previous  ]  A pointer to the previous context. It is NULL for
    225 //                function contexts, and non-NULL for 'with' contexts.
    226 //                Used to implement the 'with' statement.
    227 //
    228 // [ extension ]  A pointer to an extension JSObject, or NULL. Used to
    229 //                implement 'with' statements and dynamic declarations
    230 //                (through 'eval'). The object in a 'with' statement is
    231 //                stored in the extension slot of a 'with' context.
    232 //                Dynamically declared variables/functions are also added
    233 //                to lazily allocated extension object. Context::Lookup
    234 //                searches the extension object for properties.
    235 //                For global and block contexts, contains the respective
    236 //                ScopeInfo.
    237 //                For module contexts, points back to the respective JSModule.
    238 //
    239 // [ global_object ]  A pointer to the global object. Provided for quick
    240 //                access to the global object from inside the code (since
    241 //                we always have a context pointer).
    242 //
    243 // In addition, function contexts may have statically allocated context slots
    244 // to store local variables/functions that are accessed from inner functions
    245 // (via static context addresses) or through 'eval' (dynamic context lookups).
    246 // The native context contains additional slots for fast access to native
    247 // properties.
    248 //
    249 // Finally, with Harmony scoping, the JSFunction representing a top level
    250 // script will have the GlobalContext rather than a FunctionContext.
    251 
    252 class Context: public FixedArray {
    253  public:
    254   // Conversions.
    255   static Context* cast(Object* context) {
    256     DCHECK(context->IsContext());
    257     return reinterpret_cast<Context*>(context);
    258   }
    259 
    260   // The default context slot layout; indices are FixedArray slot indices.
    261   enum {
    262     // These slots are in all contexts.
    263     CLOSURE_INDEX,
    264     PREVIOUS_INDEX,
    265     // The extension slot is used for either the global object (in global
    266     // contexts), eval extension object (function contexts), subject of with
    267     // (with contexts), or the variable name (catch contexts), the serialized
    268     // scope info (block contexts), or the module instance (module contexts).
    269     EXTENSION_INDEX,
    270     GLOBAL_OBJECT_INDEX,
    271     MIN_CONTEXT_SLOTS,
    272 
    273     // This slot holds the thrown value in catch contexts.
    274     THROWN_OBJECT_INDEX = MIN_CONTEXT_SLOTS,
    275 
    276     // These slots are only in native contexts.
    277     GLOBAL_PROXY_INDEX = MIN_CONTEXT_SLOTS,
    278     SECURITY_TOKEN_INDEX,
    279     SLOPPY_ARGUMENTS_MAP_INDEX,
    280     ALIASED_ARGUMENTS_MAP_INDEX,
    281     STRICT_ARGUMENTS_MAP_INDEX,
    282     REGEXP_RESULT_MAP_INDEX,
    283     SLOPPY_FUNCTION_MAP_INDEX,
    284     SLOPPY_FUNCTION_WITH_READONLY_PROTOTYPE_MAP_INDEX,
    285     STRICT_FUNCTION_MAP_INDEX,
    286     SLOPPY_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX,
    287     STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX,
    288     BOUND_FUNCTION_MAP_INDEX,
    289     INITIAL_OBJECT_PROTOTYPE_INDEX,
    290     INITIAL_ARRAY_PROTOTYPE_INDEX,
    291     BOOLEAN_FUNCTION_INDEX,
    292     NUMBER_FUNCTION_INDEX,
    293     STRING_FUNCTION_INDEX,
    294     STRING_FUNCTION_PROTOTYPE_MAP_INDEX,
    295     SYMBOL_FUNCTION_INDEX,
    296     OBJECT_FUNCTION_INDEX,
    297     INTERNAL_ARRAY_FUNCTION_INDEX,
    298     ARRAY_FUNCTION_INDEX,
    299     JS_ARRAY_MAPS_INDEX,
    300     DATE_FUNCTION_INDEX,
    301     JSON_OBJECT_INDEX,
    302     REGEXP_FUNCTION_INDEX,
    303     CREATE_DATE_FUN_INDEX,
    304     TO_NUMBER_FUN_INDEX,
    305     TO_STRING_FUN_INDEX,
    306     TO_DETAIL_STRING_FUN_INDEX,
    307     TO_OBJECT_FUN_INDEX,
    308     TO_INTEGER_FUN_INDEX,
    309     TO_UINT32_FUN_INDEX,
    310     TO_INT32_FUN_INDEX,
    311     TO_BOOLEAN_FUN_INDEX,
    312     GLOBAL_EVAL_FUN_INDEX,
    313     INSTANTIATE_FUN_INDEX,
    314     CONFIGURE_INSTANCE_FUN_INDEX,
    315     MATH_ABS_FUN_INDEX,
    316     MATH_ACOS_FUN_INDEX,
    317     MATH_ASIN_FUN_INDEX,
    318     MATH_ATAN_FUN_INDEX,
    319     MATH_ATAN2_FUN_INDEX,
    320     MATH_CEIL_FUN_INDEX,
    321     MATH_COS_FUN_INDEX,
    322     MATH_EXP_FUN_INDEX,
    323     MATH_FLOOR_FUN_INDEX,
    324     MATH_IMUL_FUN_INDEX,
    325     MATH_LOG_FUN_INDEX,
    326     MATH_MAX_FUN_INDEX,
    327     MATH_MIN_FUN_INDEX,
    328     MATH_POW_FUN_INDEX,
    329     MATH_RANDOM_FUN_INDEX,
    330     MATH_ROUND_FUN_INDEX,
    331     MATH_SIN_FUN_INDEX,
    332     MATH_SQRT_FUN_INDEX,
    333     MATH_TAN_FUN_INDEX,
    334     ARRAY_BUFFER_FUN_INDEX,
    335     UINT8_ARRAY_FUN_INDEX,
    336     INT8_ARRAY_FUN_INDEX,
    337     UINT16_ARRAY_FUN_INDEX,
    338     INT16_ARRAY_FUN_INDEX,
    339     UINT32_ARRAY_FUN_INDEX,
    340     INT32_ARRAY_FUN_INDEX,
    341     FLOAT32_ARRAY_FUN_INDEX,
    342     FLOAT64_ARRAY_FUN_INDEX,
    343     UINT8_CLAMPED_ARRAY_FUN_INDEX,
    344     INT8_ARRAY_EXTERNAL_MAP_INDEX,
    345     UINT8_ARRAY_EXTERNAL_MAP_INDEX,
    346     INT16_ARRAY_EXTERNAL_MAP_INDEX,
    347     UINT16_ARRAY_EXTERNAL_MAP_INDEX,
    348     INT32_ARRAY_EXTERNAL_MAP_INDEX,
    349     UINT32_ARRAY_EXTERNAL_MAP_INDEX,
    350     FLOAT32_ARRAY_EXTERNAL_MAP_INDEX,
    351     FLOAT64_ARRAY_EXTERNAL_MAP_INDEX,
    352     UINT8_CLAMPED_ARRAY_EXTERNAL_MAP_INDEX,
    353     DATA_VIEW_FUN_INDEX,
    354     MESSAGE_LISTENERS_INDEX,
    355     MAKE_MESSAGE_FUN_INDEX,
    356     GET_STACK_TRACE_LINE_INDEX,
    357     CONFIGURE_GLOBAL_INDEX,
    358     FUNCTION_CACHE_INDEX,
    359     JSFUNCTION_RESULT_CACHES_INDEX,
    360     NORMALIZED_MAP_CACHE_INDEX,
    361     RUNTIME_CONTEXT_INDEX,
    362     CALL_AS_FUNCTION_DELEGATE_INDEX,
    363     CALL_AS_CONSTRUCTOR_DELEGATE_INDEX,
    364     SCRIPT_FUNCTION_INDEX,
    365     OPAQUE_REFERENCE_FUNCTION_INDEX,
    366     CONTEXT_EXTENSION_FUNCTION_INDEX,
    367     OUT_OF_MEMORY_INDEX,
    368     EMBEDDER_DATA_INDEX,
    369     ALLOW_CODE_GEN_FROM_STRINGS_INDEX,
    370     ERROR_MESSAGE_FOR_CODE_GEN_FROM_STRINGS_INDEX,
    371     RUN_MICROTASKS_INDEX,
    372     ENQUEUE_MICROTASK_INDEX,
    373     IS_PROMISE_INDEX,
    374     PROMISE_CREATE_INDEX,
    375     PROMISE_RESOLVE_INDEX,
    376     PROMISE_REJECT_INDEX,
    377     PROMISE_CHAIN_INDEX,
    378     PROMISE_CATCH_INDEX,
    379     PROMISE_THEN_INDEX,
    380     TO_COMPLETE_PROPERTY_DESCRIPTOR_INDEX,
    381     DERIVED_HAS_TRAP_INDEX,
    382     DERIVED_GET_TRAP_INDEX,
    383     DERIVED_SET_TRAP_INDEX,
    384     PROXY_ENUMERATE_INDEX,
    385     OBSERVERS_NOTIFY_CHANGE_INDEX,
    386     OBSERVERS_ENQUEUE_SPLICE_INDEX,
    387     OBSERVERS_BEGIN_SPLICE_INDEX,
    388     OBSERVERS_END_SPLICE_INDEX,
    389     NATIVE_OBJECT_OBSERVE_INDEX,
    390     NATIVE_OBJECT_GET_NOTIFIER_INDEX,
    391     NATIVE_OBJECT_NOTIFIER_PERFORM_CHANGE,
    392     SLOPPY_GENERATOR_FUNCTION_MAP_INDEX,
    393     STRICT_GENERATOR_FUNCTION_MAP_INDEX,
    394     GENERATOR_OBJECT_PROTOTYPE_MAP_INDEX,
    395     ITERATOR_RESULT_MAP_INDEX,
    396     MAP_ITERATOR_MAP_INDEX,
    397     SET_ITERATOR_MAP_INDEX,
    398     ITERATOR_SYMBOL_INDEX,
    399     UNSCOPABLES_SYMBOL_INDEX,
    400     ARRAY_VALUES_ITERATOR_INDEX,
    401 
    402     // Properties from here are treated as weak references by the full GC.
    403     // Scavenge treats them as strong references.
    404     OPTIMIZED_FUNCTIONS_LIST,  // Weak.
    405     OPTIMIZED_CODE_LIST,       // Weak.
    406     DEOPTIMIZED_CODE_LIST,     // Weak.
    407     MAP_CACHE_INDEX,           // Weak.
    408     NEXT_CONTEXT_LINK,         // Weak.
    409 
    410     // Total number of slots.
    411     NATIVE_CONTEXT_SLOTS,
    412     FIRST_WEAK_SLOT = OPTIMIZED_FUNCTIONS_LIST
    413   };
    414 
    415   // Direct slot access.
    416   JSFunction* closure() { return JSFunction::cast(get(CLOSURE_INDEX)); }
    417   void set_closure(JSFunction* closure) { set(CLOSURE_INDEX, closure); }
    418 
    419   Context* previous() {
    420     Object* result = unchecked_previous();
    421     DCHECK(IsBootstrappingOrValidParentContext(result, this));
    422     return reinterpret_cast<Context*>(result);
    423   }
    424   void set_previous(Context* context) { set(PREVIOUS_INDEX, context); }
    425 
    426   bool has_extension() { return extension() != NULL; }
    427   Object* extension() { return get(EXTENSION_INDEX); }
    428   void set_extension(Object* object) { set(EXTENSION_INDEX, object); }
    429 
    430   JSModule* module() { return JSModule::cast(get(EXTENSION_INDEX)); }
    431   void set_module(JSModule* module) { set(EXTENSION_INDEX, module); }
    432 
    433   // Get the context where var declarations will be hoisted to, which
    434   // may be the context itself.
    435   Context* declaration_context();
    436 
    437   GlobalObject* global_object() {
    438     Object* result = get(GLOBAL_OBJECT_INDEX);
    439     DCHECK(IsBootstrappingOrGlobalObject(this->GetIsolate(), result));
    440     return reinterpret_cast<GlobalObject*>(result);
    441   }
    442   void set_global_object(GlobalObject* object) {
    443     set(GLOBAL_OBJECT_INDEX, object);
    444   }
    445 
    446   // Returns a JSGlobalProxy object or null.
    447   JSObject* global_proxy();
    448   void set_global_proxy(JSObject* global);
    449 
    450   // The builtins object.
    451   JSBuiltinsObject* builtins();
    452 
    453   // Get the innermost global context by traversing the context chain.
    454   Context* global_context();
    455 
    456   // Compute the native context by traversing the context chain.
    457   Context* native_context();
    458 
    459   // Predicates for context types.  IsNativeContext is also defined on Object
    460   // because we frequently have to know if arbitrary objects are natives
    461   // contexts.
    462   bool IsNativeContext() {
    463     Map* map = this->map();
    464     return map == map->GetHeap()->native_context_map();
    465   }
    466   bool IsFunctionContext() {
    467     Map* map = this->map();
    468     return map == map->GetHeap()->function_context_map();
    469   }
    470   bool IsCatchContext() {
    471     Map* map = this->map();
    472     return map == map->GetHeap()->catch_context_map();
    473   }
    474   bool IsWithContext() {
    475     Map* map = this->map();
    476     return map == map->GetHeap()->with_context_map();
    477   }
    478   bool IsBlockContext() {
    479     Map* map = this->map();
    480     return map == map->GetHeap()->block_context_map();
    481   }
    482   bool IsModuleContext() {
    483     Map* map = this->map();
    484     return map == map->GetHeap()->module_context_map();
    485   }
    486   bool IsGlobalContext() {
    487     Map* map = this->map();
    488     return map == map->GetHeap()->global_context_map();
    489   }
    490 
    491   bool HasSameSecurityTokenAs(Context* that) {
    492     return this->global_object()->native_context()->security_token() ==
    493         that->global_object()->native_context()->security_token();
    494   }
    495 
    496   // A native context holds a list of all functions with optimized code.
    497   void AddOptimizedFunction(JSFunction* function);
    498   void RemoveOptimizedFunction(JSFunction* function);
    499   void SetOptimizedFunctionsListHead(Object* head);
    500   Object* OptimizedFunctionsListHead();
    501 
    502   // The native context also stores a list of all optimized code and a
    503   // list of all deoptimized code, which are needed by the deoptimizer.
    504   void AddOptimizedCode(Code* code);
    505   void SetOptimizedCodeListHead(Object* head);
    506   Object* OptimizedCodeListHead();
    507   void SetDeoptimizedCodeListHead(Object* head);
    508   Object* DeoptimizedCodeListHead();
    509 
    510   Handle<Object> ErrorMessageForCodeGenerationFromStrings();
    511 
    512 #define NATIVE_CONTEXT_FIELD_ACCESSORS(index, type, name) \
    513   void  set_##name(type* value) {                         \
    514     DCHECK(IsNativeContext());                            \
    515     set(index, value);                                    \
    516   }                                                       \
    517   bool is_##name(type* value) {                           \
    518     DCHECK(IsNativeContext());                            \
    519     return type::cast(get(index)) == value;               \
    520   }                                                       \
    521   type* name() {                                          \
    522     DCHECK(IsNativeContext());                            \
    523     return type::cast(get(index));                        \
    524   }
    525   NATIVE_CONTEXT_FIELDS(NATIVE_CONTEXT_FIELD_ACCESSORS)
    526 #undef NATIVE_CONTEXT_FIELD_ACCESSORS
    527 
    528   // Lookup the slot called name, starting with the current context.
    529   // There are three possibilities:
    530   //
    531   // 1) result->IsContext():
    532   //    The binding was found in a context.  *index is always the
    533   //    non-negative slot index.  *attributes is NONE for var and let
    534   //    declarations, READ_ONLY for const declarations (never ABSENT).
    535   //
    536   // 2) result->IsJSObject():
    537   //    The binding was found as a named property in a context extension
    538   //    object (i.e., was introduced via eval), as a property on the subject
    539   //    of with, or as a property of the global object.  *index is -1 and
    540   //    *attributes is not ABSENT.
    541   //
    542   // 3) result.is_null():
    543   //    There was no binding found, *index is always -1 and *attributes is
    544   //    always ABSENT.
    545   Handle<Object> Lookup(Handle<String> name,
    546                         ContextLookupFlags flags,
    547                         int* index,
    548                         PropertyAttributes* attributes,
    549                         BindingFlags* binding_flags);
    550 
    551   // Code generation support.
    552   static int SlotOffset(int index) {
    553     return kHeaderSize + index * kPointerSize - kHeapObjectTag;
    554   }
    555 
    556   static int FunctionMapIndex(StrictMode strict_mode, FunctionKind kind) {
    557     if (IsGeneratorFunction(kind)) {
    558       return strict_mode == SLOPPY ? SLOPPY_GENERATOR_FUNCTION_MAP_INDEX
    559                                    : STRICT_GENERATOR_FUNCTION_MAP_INDEX;
    560     }
    561 
    562     if (IsArrowFunction(kind) || IsConciseMethod(kind)) {
    563       return strict_mode == SLOPPY
    564                  ? SLOPPY_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX
    565                  : STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX;
    566     }
    567 
    568     return strict_mode == SLOPPY ? SLOPPY_FUNCTION_MAP_INDEX
    569                                  : STRICT_FUNCTION_MAP_INDEX;
    570   }
    571 
    572   static const int kSize = kHeaderSize + NATIVE_CONTEXT_SLOTS * kPointerSize;
    573 
    574   // GC support.
    575   typedef FixedBodyDescriptor<
    576       kHeaderSize, kSize, kSize> ScavengeBodyDescriptor;
    577 
    578   typedef FixedBodyDescriptor<
    579       kHeaderSize,
    580       kHeaderSize + FIRST_WEAK_SLOT * kPointerSize,
    581       kSize> MarkCompactBodyDescriptor;
    582 
    583  private:
    584   // Unchecked access to the slots.
    585   Object* unchecked_previous() { return get(PREVIOUS_INDEX); }
    586 
    587 #ifdef DEBUG
    588   // Bootstrapping-aware type checks.
    589   static bool IsBootstrappingOrValidParentContext(Object* object, Context* kid);
    590   static bool IsBootstrappingOrGlobalObject(Isolate* isolate, Object* object);
    591 #endif
    592 
    593   STATIC_ASSERT(kHeaderSize == Internals::kContextHeaderSize);
    594   STATIC_ASSERT(EMBEDDER_DATA_INDEX == Internals::kContextEmbedderDataIndex);
    595 };
    596 
    597 } }  // namespace v8::internal
    598 
    599 #endif  // V8_CONTEXTS_H_
    600