Home | History | Annotate | Download | only in src
      1 // Copyright 2012 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 
     28 #ifndef V8_CONTEXTS_H_
     29 #define V8_CONTEXTS_H_
     30 
     31 #include "heap.h"
     32 #include "objects.h"
     33 
     34 namespace v8 {
     35 namespace internal {
     36 
     37 
     38 enum ContextLookupFlags {
     39   FOLLOW_CONTEXT_CHAIN = 1,
     40   FOLLOW_PROTOTYPE_CHAIN = 2,
     41 
     42   DONT_FOLLOW_CHAINS = 0,
     43   FOLLOW_CHAINS = FOLLOW_CONTEXT_CHAIN | FOLLOW_PROTOTYPE_CHAIN
     44 };
     45 
     46 
     47 // ES5 10.2 defines lexical environments with mutable and immutable bindings.
     48 // Immutable bindings have two states, initialized and uninitialized, and
     49 // their state is changed by the InitializeImmutableBinding method. The
     50 // BindingFlags enum represents information if a binding has definitely been
     51 // initialized. A mutable binding does not need to be checked and thus has
     52 // the BindingFlag MUTABLE_IS_INITIALIZED.
     53 //
     54 // There are two possibilities for immutable bindings
     55 //  * 'const' declared variables. They are initialized when evaluating the
     56 //    corresponding declaration statement. They need to be checked for being
     57 //    initialized and thus get the flag IMMUTABLE_CHECK_INITIALIZED.
     58 //  * The function name of a named function literal. The binding is immediately
     59 //    initialized when entering the function and thus does not need to be
     60 //    checked. it gets the BindingFlag IMMUTABLE_IS_INITIALIZED.
     61 // Accessing an uninitialized binding produces the undefined value.
     62 //
     63 // The harmony proposal for block scoped bindings also introduces the
     64 // uninitialized state for mutable bindings.
     65 //  * A 'let' declared variable. They are initialized when evaluating the
     66 //    corresponding declaration statement. They need to be checked for being
     67 //    initialized and thus get the flag MUTABLE_CHECK_INITIALIZED.
     68 //  * A 'var' declared variable. It is initialized immediately upon creation
     69 //    and thus doesn't need to be checked. It gets the flag
     70 //    MUTABLE_IS_INITIALIZED.
     71 //  * Catch bound variables, function parameters and variables introduced by
     72 //    function declarations are initialized immediately and do not need to be
     73 //    checked. Thus they get the flag MUTABLE_IS_INITIALIZED.
     74 // Immutable bindings in harmony mode get the _HARMONY flag variants. Accessing
     75 // an uninitialized binding produces a reference error.
     76 //
     77 // In V8 uninitialized bindings are set to the hole value upon creation and set
     78 // to a different value upon initialization.
     79 enum BindingFlags {
     80   MUTABLE_IS_INITIALIZED,
     81   MUTABLE_CHECK_INITIALIZED,
     82   IMMUTABLE_IS_INITIALIZED,
     83   IMMUTABLE_CHECK_INITIALIZED,
     84   IMMUTABLE_IS_INITIALIZED_HARMONY,
     85   IMMUTABLE_CHECK_INITIALIZED_HARMONY,
     86   MISSING_BINDING
     87 };
     88 
     89 
     90 // Heap-allocated activation contexts.
     91 //
     92 // Contexts are implemented as FixedArray objects; the Context
     93 // class is a convenience interface casted on a FixedArray object.
     94 //
     95 // Note: Context must have no virtual functions and Context objects
     96 // must always be allocated via Heap::AllocateContext() or
     97 // Factory::NewContext.
     98 
     99 #define NATIVE_CONTEXT_FIELDS(V) \
    100   V(GLOBAL_PROXY_INDEX, JSObject, global_proxy_object) \
    101   V(SECURITY_TOKEN_INDEX, Object, security_token) \
    102   V(BOOLEAN_FUNCTION_INDEX, JSFunction, boolean_function) \
    103   V(NUMBER_FUNCTION_INDEX, JSFunction, number_function) \
    104   V(STRING_FUNCTION_INDEX, JSFunction, string_function) \
    105   V(STRING_FUNCTION_PROTOTYPE_MAP_INDEX, Map, string_function_prototype_map) \
    106   V(SYMBOL_FUNCTION_INDEX, JSFunction, symbol_function) \
    107   V(OBJECT_FUNCTION_INDEX, JSFunction, object_function) \
    108   V(INTERNAL_ARRAY_FUNCTION_INDEX, JSFunction, internal_array_function) \
    109   V(ARRAY_FUNCTION_INDEX, JSFunction, array_function) \
    110   V(JS_ARRAY_MAPS_INDEX, Object, js_array_maps) \
    111   V(DATE_FUNCTION_INDEX, JSFunction, date_function) \
    112   V(JSON_OBJECT_INDEX, JSObject, json_object) \
    113   V(REGEXP_FUNCTION_INDEX, JSFunction, regexp_function) \
    114   V(INITIAL_OBJECT_PROTOTYPE_INDEX, JSObject, initial_object_prototype) \
    115   V(INITIAL_ARRAY_PROTOTYPE_INDEX, JSObject, initial_array_prototype) \
    116   V(CREATE_DATE_FUN_INDEX, JSFunction,  create_date_fun) \
    117   V(TO_NUMBER_FUN_INDEX, JSFunction, to_number_fun) \
    118   V(TO_STRING_FUN_INDEX, JSFunction, to_string_fun) \
    119   V(TO_DETAIL_STRING_FUN_INDEX, JSFunction, to_detail_string_fun) \
    120   V(TO_OBJECT_FUN_INDEX, JSFunction, to_object_fun) \
    121   V(TO_INTEGER_FUN_INDEX, JSFunction, to_integer_fun) \
    122   V(TO_UINT32_FUN_INDEX, JSFunction, to_uint32_fun) \
    123   V(TO_INT32_FUN_INDEX, JSFunction, to_int32_fun) \
    124   V(GLOBAL_EVAL_FUN_INDEX, JSFunction, global_eval_fun) \
    125   V(INSTANTIATE_FUN_INDEX, JSFunction, instantiate_fun) \
    126   V(CONFIGURE_INSTANCE_FUN_INDEX, JSFunction, configure_instance_fun) \
    127   V(ARRAY_BUFFER_FUN_INDEX, JSFunction, array_buffer_fun) \
    128   V(UINT8_ARRAY_FUN_INDEX, JSFunction, uint8_array_fun) \
    129   V(INT8_ARRAY_FUN_INDEX, JSFunction, int8_array_fun) \
    130   V(UINT16_ARRAY_FUN_INDEX, JSFunction, uint16_array_fun) \
    131   V(INT16_ARRAY_FUN_INDEX, JSFunction, int16_array_fun) \
    132   V(UINT32_ARRAY_FUN_INDEX, JSFunction, uint32_array_fun) \
    133   V(INT32_ARRAY_FUN_INDEX, JSFunction, int32_array_fun) \
    134   V(FLOAT_ARRAY_FUN_INDEX, JSFunction, float_array_fun) \
    135   V(DOUBLE_ARRAY_FUN_INDEX, JSFunction, double_array_fun) \
    136   V(UINT8C_ARRAY_FUN_INDEX, JSFunction, uint8c_array_fun) \
    137   V(DATA_VIEW_FUN_INDEX, JSFunction, data_view_fun) \
    138   V(FUNCTION_MAP_INDEX, Map, function_map) \
    139   V(STRICT_MODE_FUNCTION_MAP_INDEX, Map, strict_mode_function_map) \
    140   V(FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX, Map, function_without_prototype_map) \
    141   V(STRICT_MODE_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX, Map, \
    142     strict_mode_function_without_prototype_map) \
    143   V(REGEXP_RESULT_MAP_INDEX, Map, regexp_result_map)\
    144   V(ARGUMENTS_BOILERPLATE_INDEX, JSObject, arguments_boilerplate) \
    145   V(ALIASED_ARGUMENTS_BOILERPLATE_INDEX, JSObject, \
    146     aliased_arguments_boilerplate) \
    147   V(STRICT_MODE_ARGUMENTS_BOILERPLATE_INDEX, JSObject, \
    148     strict_mode_arguments_boilerplate) \
    149   V(MESSAGE_LISTENERS_INDEX, JSObject, message_listeners) \
    150   V(MAKE_MESSAGE_FUN_INDEX, JSFunction, make_message_fun) \
    151   V(GET_STACK_TRACE_LINE_INDEX, JSFunction, get_stack_trace_line_fun) \
    152   V(CONFIGURE_GLOBAL_INDEX, JSFunction, configure_global_fun) \
    153   V(FUNCTION_CACHE_INDEX, JSObject, function_cache) \
    154   V(JSFUNCTION_RESULT_CACHES_INDEX, FixedArray, jsfunction_result_caches) \
    155   V(NORMALIZED_MAP_CACHE_INDEX, NormalizedMapCache, normalized_map_cache) \
    156   V(RUNTIME_CONTEXT_INDEX, Context, runtime_context) \
    157   V(CALL_AS_FUNCTION_DELEGATE_INDEX, JSFunction, call_as_function_delegate) \
    158   V(CALL_AS_CONSTRUCTOR_DELEGATE_INDEX, JSFunction, \
    159     call_as_constructor_delegate) \
    160   V(SCRIPT_FUNCTION_INDEX, JSFunction, script_function) \
    161   V(OPAQUE_REFERENCE_FUNCTION_INDEX, JSFunction, opaque_reference_function) \
    162   V(CONTEXT_EXTENSION_FUNCTION_INDEX, JSFunction, context_extension_function) \
    163   V(OUT_OF_MEMORY_INDEX, Object, out_of_memory) \
    164   V(MAP_CACHE_INDEX, Object, map_cache) \
    165   V(EMBEDDER_DATA_INDEX, FixedArray, embedder_data) \
    166   V(ALLOW_CODE_GEN_FROM_STRINGS_INDEX, Object, allow_code_gen_from_strings) \
    167   V(ERROR_MESSAGE_FOR_CODE_GEN_FROM_STRINGS_INDEX, Object, \
    168     error_message_for_code_gen_from_strings) \
    169   V(TO_COMPLETE_PROPERTY_DESCRIPTOR_INDEX, JSFunction, \
    170     to_complete_property_descriptor) \
    171   V(DERIVED_HAS_TRAP_INDEX, JSFunction, derived_has_trap) \
    172   V(DERIVED_GET_TRAP_INDEX, JSFunction, derived_get_trap) \
    173   V(DERIVED_SET_TRAP_INDEX, JSFunction, derived_set_trap) \
    174   V(PROXY_ENUMERATE_INDEX, JSFunction, proxy_enumerate) \
    175   V(OBSERVERS_NOTIFY_CHANGE_INDEX, JSFunction, observers_notify_change) \
    176   V(OBSERVERS_ENQUEUE_SPLICE_INDEX, JSFunction, observers_enqueue_splice) \
    177   V(OBSERVERS_BEGIN_SPLICE_INDEX, JSFunction, \
    178     observers_begin_perform_splice) \
    179   V(OBSERVERS_END_SPLICE_INDEX, JSFunction, \
    180     observers_end_perform_splice) \
    181   V(OBSERVERS_DELIVER_CHANGES_INDEX, JSFunction, observers_deliver_changes) \
    182   V(GENERATOR_FUNCTION_MAP_INDEX, Map, generator_function_map) \
    183   V(STRICT_MODE_GENERATOR_FUNCTION_MAP_INDEX, Map, \
    184     strict_mode_generator_function_map) \
    185   V(GENERATOR_OBJECT_PROTOTYPE_MAP_INDEX, Map, \
    186     generator_object_prototype_map) \
    187   V(GENERATOR_RESULT_MAP_INDEX, Map, generator_result_map) \
    188   V(RANDOM_SEED_INDEX, ByteArray, random_seed)
    189 
    190 // JSFunctions are pairs (context, function code), sometimes also called
    191 // closures. A Context object is used to represent function contexts and
    192 // dynamically pushed 'with' contexts (or 'scopes' in ECMA-262 speak).
    193 //
    194 // At runtime, the contexts build a stack in parallel to the execution
    195 // stack, with the top-most context being the current context. All contexts
    196 // have the following slots:
    197 //
    198 // [ closure   ]  This is the current function. It is the same for all
    199 //                contexts inside a function. It provides access to the
    200 //                incoming context (i.e., the outer context, which may
    201 //                or may not become the current function's context), and
    202 //                it provides access to the functions code and thus it's
    203 //                scope information, which in turn contains the names of
    204 //                statically allocated context slots. The names are needed
    205 //                for dynamic lookups in the presence of 'with' or 'eval'.
    206 //
    207 // [ previous  ]  A pointer to the previous context. It is NULL for
    208 //                function contexts, and non-NULL for 'with' contexts.
    209 //                Used to implement the 'with' statement.
    210 //
    211 // [ extension ]  A pointer to an extension JSObject, or NULL. Used to
    212 //                implement 'with' statements and dynamic declarations
    213 //                (through 'eval'). The object in a 'with' statement is
    214 //                stored in the extension slot of a 'with' context.
    215 //                Dynamically declared variables/functions are also added
    216 //                to lazily allocated extension object. Context::Lookup
    217 //                searches the extension object for properties.
    218 //                For global and block contexts, contains the respective
    219 //                ScopeInfo.
    220 //                For module contexts, points back to the respective JSModule.
    221 //
    222 // [ global_object ]  A pointer to the global object. Provided for quick
    223 //                access to the global object from inside the code (since
    224 //                we always have a context pointer).
    225 //
    226 // In addition, function contexts may have statically allocated context slots
    227 // to store local variables/functions that are accessed from inner functions
    228 // (via static context addresses) or through 'eval' (dynamic context lookups).
    229 // Finally, the native context contains additional slots for fast access to
    230 // native properties.
    231 
    232 class Context: public FixedArray {
    233  public:
    234   // Conversions.
    235   static Context* cast(Object* context) {
    236     ASSERT(context->IsContext());
    237     return reinterpret_cast<Context*>(context);
    238   }
    239 
    240   // The default context slot layout; indices are FixedArray slot indices.
    241   enum {
    242     // These slots are in all contexts.
    243     CLOSURE_INDEX,
    244     PREVIOUS_INDEX,
    245     // The extension slot is used for either the global object (in global
    246     // contexts), eval extension object (function contexts), subject of with
    247     // (with contexts), or the variable name (catch contexts), the serialized
    248     // scope info (block contexts), or the module instance (module contexts).
    249     EXTENSION_INDEX,
    250     GLOBAL_OBJECT_INDEX,
    251     MIN_CONTEXT_SLOTS,
    252 
    253     // This slot holds the thrown value in catch contexts.
    254     THROWN_OBJECT_INDEX = MIN_CONTEXT_SLOTS,
    255 
    256     // These slots are only in native contexts.
    257     GLOBAL_PROXY_INDEX = MIN_CONTEXT_SLOTS,
    258     SECURITY_TOKEN_INDEX,
    259     ARGUMENTS_BOILERPLATE_INDEX,
    260     ALIASED_ARGUMENTS_BOILERPLATE_INDEX,
    261     STRICT_MODE_ARGUMENTS_BOILERPLATE_INDEX,
    262     REGEXP_RESULT_MAP_INDEX,
    263     FUNCTION_MAP_INDEX,
    264     STRICT_MODE_FUNCTION_MAP_INDEX,
    265     FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX,
    266     STRICT_MODE_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX,
    267     INITIAL_OBJECT_PROTOTYPE_INDEX,
    268     INITIAL_ARRAY_PROTOTYPE_INDEX,
    269     BOOLEAN_FUNCTION_INDEX,
    270     NUMBER_FUNCTION_INDEX,
    271     STRING_FUNCTION_INDEX,
    272     STRING_FUNCTION_PROTOTYPE_MAP_INDEX,
    273     SYMBOL_FUNCTION_INDEX,
    274     OBJECT_FUNCTION_INDEX,
    275     INTERNAL_ARRAY_FUNCTION_INDEX,
    276     ARRAY_FUNCTION_INDEX,
    277     JS_ARRAY_MAPS_INDEX,
    278     DATE_FUNCTION_INDEX,
    279     JSON_OBJECT_INDEX,
    280     REGEXP_FUNCTION_INDEX,
    281     CREATE_DATE_FUN_INDEX,
    282     TO_NUMBER_FUN_INDEX,
    283     TO_STRING_FUN_INDEX,
    284     TO_DETAIL_STRING_FUN_INDEX,
    285     TO_OBJECT_FUN_INDEX,
    286     TO_INTEGER_FUN_INDEX,
    287     TO_UINT32_FUN_INDEX,
    288     TO_INT32_FUN_INDEX,
    289     TO_BOOLEAN_FUN_INDEX,
    290     GLOBAL_EVAL_FUN_INDEX,
    291     INSTANTIATE_FUN_INDEX,
    292     CONFIGURE_INSTANCE_FUN_INDEX,
    293     ARRAY_BUFFER_FUN_INDEX,
    294     UINT8_ARRAY_FUN_INDEX,
    295     INT8_ARRAY_FUN_INDEX,
    296     UINT16_ARRAY_FUN_INDEX,
    297     INT16_ARRAY_FUN_INDEX,
    298     UINT32_ARRAY_FUN_INDEX,
    299     INT32_ARRAY_FUN_INDEX,
    300     FLOAT_ARRAY_FUN_INDEX,
    301     DOUBLE_ARRAY_FUN_INDEX,
    302     UINT8C_ARRAY_FUN_INDEX,
    303     DATA_VIEW_FUN_INDEX,
    304     MESSAGE_LISTENERS_INDEX,
    305     MAKE_MESSAGE_FUN_INDEX,
    306     GET_STACK_TRACE_LINE_INDEX,
    307     CONFIGURE_GLOBAL_INDEX,
    308     FUNCTION_CACHE_INDEX,
    309     JSFUNCTION_RESULT_CACHES_INDEX,
    310     NORMALIZED_MAP_CACHE_INDEX,
    311     RUNTIME_CONTEXT_INDEX,
    312     CALL_AS_FUNCTION_DELEGATE_INDEX,
    313     CALL_AS_CONSTRUCTOR_DELEGATE_INDEX,
    314     SCRIPT_FUNCTION_INDEX,
    315     OPAQUE_REFERENCE_FUNCTION_INDEX,
    316     CONTEXT_EXTENSION_FUNCTION_INDEX,
    317     OUT_OF_MEMORY_INDEX,
    318     EMBEDDER_DATA_INDEX,
    319     ALLOW_CODE_GEN_FROM_STRINGS_INDEX,
    320     ERROR_MESSAGE_FOR_CODE_GEN_FROM_STRINGS_INDEX,
    321     TO_COMPLETE_PROPERTY_DESCRIPTOR_INDEX,
    322     DERIVED_HAS_TRAP_INDEX,
    323     DERIVED_GET_TRAP_INDEX,
    324     DERIVED_SET_TRAP_INDEX,
    325     PROXY_ENUMERATE_INDEX,
    326     OBSERVERS_NOTIFY_CHANGE_INDEX,
    327     OBSERVERS_ENQUEUE_SPLICE_INDEX,
    328     OBSERVERS_BEGIN_SPLICE_INDEX,
    329     OBSERVERS_END_SPLICE_INDEX,
    330     OBSERVERS_DELIVER_CHANGES_INDEX,
    331     GENERATOR_FUNCTION_MAP_INDEX,
    332     STRICT_MODE_GENERATOR_FUNCTION_MAP_INDEX,
    333     GENERATOR_OBJECT_PROTOTYPE_MAP_INDEX,
    334     GENERATOR_RESULT_MAP_INDEX,
    335     RANDOM_SEED_INDEX,
    336 
    337     // Properties from here are treated as weak references by the full GC.
    338     // Scavenge treats them as strong references.
    339     OPTIMIZED_FUNCTIONS_LIST,  // Weak.
    340     MAP_CACHE_INDEX,  // Weak.
    341     NEXT_CONTEXT_LINK,  // Weak.
    342 
    343     // Total number of slots.
    344     NATIVE_CONTEXT_SLOTS,
    345 
    346     FIRST_WEAK_SLOT = OPTIMIZED_FUNCTIONS_LIST
    347   };
    348 
    349   // Direct slot access.
    350   JSFunction* closure() { return JSFunction::cast(get(CLOSURE_INDEX)); }
    351   void set_closure(JSFunction* closure) { set(CLOSURE_INDEX, closure); }
    352 
    353   Context* previous() {
    354     Object* result = unchecked_previous();
    355     ASSERT(IsBootstrappingOrValidParentContext(result, this));
    356     return reinterpret_cast<Context*>(result);
    357   }
    358   void set_previous(Context* context) { set(PREVIOUS_INDEX, context); }
    359 
    360   bool has_extension() { return extension() != NULL; }
    361   Object* extension() { return get(EXTENSION_INDEX); }
    362   void set_extension(Object* object) { set(EXTENSION_INDEX, object); }
    363 
    364   JSModule* module() { return JSModule::cast(get(EXTENSION_INDEX)); }
    365   void set_module(JSModule* module) { set(EXTENSION_INDEX, module); }
    366 
    367   // Get the context where var declarations will be hoisted to, which
    368   // may be the context itself.
    369   Context* declaration_context();
    370 
    371   GlobalObject* global_object() {
    372     Object* result = get(GLOBAL_OBJECT_INDEX);
    373     ASSERT(IsBootstrappingOrGlobalObject(result));
    374     return reinterpret_cast<GlobalObject*>(result);
    375   }
    376   void set_global_object(GlobalObject* object) {
    377     set(GLOBAL_OBJECT_INDEX, object);
    378   }
    379 
    380   // Returns a JSGlobalProxy object or null.
    381   JSObject* global_proxy();
    382   void set_global_proxy(JSObject* global);
    383 
    384   // The builtins object.
    385   JSBuiltinsObject* builtins();
    386 
    387   // Get the innermost global context by traversing the context chain.
    388   Context* global_context();
    389 
    390   // Compute the native context by traversing the context chain.
    391   Context* native_context();
    392 
    393   // Predicates for context types.  IsNativeContext is also defined on Object
    394   // because we frequently have to know if arbitrary objects are natives
    395   // contexts.
    396   bool IsNativeContext() {
    397     Map* map = this->map();
    398     return map == map->GetHeap()->native_context_map();
    399   }
    400   bool IsFunctionContext() {
    401     Map* map = this->map();
    402     return map == map->GetHeap()->function_context_map();
    403   }
    404   bool IsCatchContext() {
    405     Map* map = this->map();
    406     return map == map->GetHeap()->catch_context_map();
    407   }
    408   bool IsWithContext() {
    409     Map* map = this->map();
    410     return map == map->GetHeap()->with_context_map();
    411   }
    412   bool IsBlockContext() {
    413     Map* map = this->map();
    414     return map == map->GetHeap()->block_context_map();
    415   }
    416   bool IsModuleContext() {
    417     Map* map = this->map();
    418     return map == map->GetHeap()->module_context_map();
    419   }
    420   bool IsGlobalContext() {
    421     Map* map = this->map();
    422     return map == map->GetHeap()->global_context_map();
    423   }
    424 
    425   // Tells whether the native context is marked with out of memory.
    426   inline bool has_out_of_memory();
    427 
    428   // Mark the native context with out of memory.
    429   inline void mark_out_of_memory();
    430 
    431   // A native context hold a list of all functions which have been optimized.
    432   void AddOptimizedFunction(JSFunction* function);
    433   void RemoveOptimizedFunction(JSFunction* function);
    434   Object* OptimizedFunctionsListHead();
    435   void ClearOptimizedFunctions();
    436 
    437   Handle<Object> ErrorMessageForCodeGenerationFromStrings();
    438 
    439 #define NATIVE_CONTEXT_FIELD_ACCESSORS(index, type, name) \
    440   void  set_##name(type* value) {                         \
    441     ASSERT(IsNativeContext());                            \
    442     set(index, value);                                    \
    443   }                                                       \
    444   bool is_##name(type* value) {                           \
    445     ASSERT(IsNativeContext());                            \
    446     return type::cast(get(index)) == value;               \
    447   }                                                       \
    448   type* name() {                                          \
    449     ASSERT(IsNativeContext());                            \
    450     return type::cast(get(index));                        \
    451   }
    452   NATIVE_CONTEXT_FIELDS(NATIVE_CONTEXT_FIELD_ACCESSORS)
    453 #undef NATIVE_CONTEXT_FIELD_ACCESSORS
    454 
    455   // Lookup the slot called name, starting with the current context.
    456   // There are three possibilities:
    457   //
    458   // 1) result->IsContext():
    459   //    The binding was found in a context.  *index is always the
    460   //    non-negative slot index.  *attributes is NONE for var and let
    461   //    declarations, READ_ONLY for const declarations (never ABSENT).
    462   //
    463   // 2) result->IsJSObject():
    464   //    The binding was found as a named property in a context extension
    465   //    object (i.e., was introduced via eval), as a property on the subject
    466   //    of with, or as a property of the global object.  *index is -1 and
    467   //    *attributes is not ABSENT.
    468   //
    469   // 3) result.is_null():
    470   //    There was no binding found, *index is always -1 and *attributes is
    471   //    always ABSENT.
    472   Handle<Object> Lookup(Handle<String> name,
    473                         ContextLookupFlags flags,
    474                         int* index,
    475                         PropertyAttributes* attributes,
    476                         BindingFlags* binding_flags);
    477 
    478   // Code generation support.
    479   static int SlotOffset(int index) {
    480     return kHeaderSize + index * kPointerSize - kHeapObjectTag;
    481   }
    482 
    483   static int FunctionMapIndex(LanguageMode language_mode, bool is_generator) {
    484     return is_generator
    485       ? (language_mode == CLASSIC_MODE
    486          ? GENERATOR_FUNCTION_MAP_INDEX
    487          : STRICT_MODE_GENERATOR_FUNCTION_MAP_INDEX)
    488       : (language_mode == CLASSIC_MODE
    489          ? FUNCTION_MAP_INDEX
    490          : STRICT_MODE_FUNCTION_MAP_INDEX);
    491   }
    492 
    493   static const int kSize = kHeaderSize + NATIVE_CONTEXT_SLOTS * kPointerSize;
    494 
    495   // GC support.
    496   typedef FixedBodyDescriptor<
    497       kHeaderSize, kSize, kSize> ScavengeBodyDescriptor;
    498 
    499   typedef FixedBodyDescriptor<
    500       kHeaderSize,
    501       kHeaderSize + FIRST_WEAK_SLOT * kPointerSize,
    502       kSize> MarkCompactBodyDescriptor;
    503 
    504  private:
    505   // Unchecked access to the slots.
    506   Object* unchecked_previous() { return get(PREVIOUS_INDEX); }
    507 
    508 #ifdef DEBUG
    509   // Bootstrapping-aware type checks.
    510   static bool IsBootstrappingOrValidParentContext(Object* object, Context* kid);
    511   static bool IsBootstrappingOrGlobalObject(Object* object);
    512 #endif
    513 
    514   STATIC_CHECK(kHeaderSize == Internals::kContextHeaderSize);
    515   STATIC_CHECK(EMBEDDER_DATA_INDEX == Internals::kContextEmbedderDataIndex);
    516 };
    517 
    518 } }  // namespace v8::internal
    519 
    520 #endif  // V8_CONTEXTS_H_
    521