| 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 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 123 // | 123 // |
| 124 // [ closure ] This is the current function. It is the same for all | 124 // [ closure ] This is the current function. It is the same for all |
| 125 // contexts inside a function. It provides access to the | 125 // contexts inside a function. It provides access to the |
| 126 // incoming context (i.e., the outer context, which may | 126 // incoming context (i.e., the outer context, which may |
| 127 // or may not become the current function's context), and | 127 // or may not become the current function's context), and |
| 128 // it provides access to the functions code and thus it's | 128 // it provides access to the functions code and thus it's |
| 129 // scope information, which in turn contains the names of | 129 // scope information, which in turn contains the names of |
| 130 // statically allocated context slots. The names are needed | 130 // statically allocated context slots. The names are needed |
| 131 // for dynamic lookups in the presence of 'with' or 'eval'. | 131 // for dynamic lookups in the presence of 'with' or 'eval'. |
| 132 // | 132 // |
| 133 // [ fcontext ] A pointer to the innermost enclosing function context. | |
| 134 // It is the same for all contexts *allocated* inside a | |
| 135 // function, and the function context's fcontext points | |
| 136 // to itself. It is only needed for fast access of the | |
| 137 // function context (used for declarations, and static | |
| 138 // context slot access). | |
| 139 // | |
| 140 // [ previous ] A pointer to the previous context. It is NULL for | 133 // [ previous ] A pointer to the previous context. It is NULL for |
| 141 // function contexts, and non-NULL for 'with' contexts. | 134 // function contexts, and non-NULL for 'with' contexts. |
| 142 // Used to implement the 'with' statement. | 135 // Used to implement the 'with' statement. |
| 143 // | 136 // |
| 144 // [ extension ] A pointer to an extension JSObject, or NULL. Used to | 137 // [ extension ] A pointer to an extension JSObject, or NULL. Used to |
| 145 // implement 'with' statements and dynamic declarations | 138 // implement 'with' statements and dynamic declarations |
| 146 // (through 'eval'). The object in a 'with' statement is | 139 // (through 'eval'). The object in a 'with' statement is |
| 147 // stored in the extension slot of a 'with' context. | 140 // stored in the extension slot of a 'with' context. |
| 148 // Dynamically declared variables/functions are also added | 141 // Dynamically declared variables/functions are also added |
| 149 // to lazily allocated extension object. Context::Lookup | 142 // to lazily allocated extension object. Context::Lookup |
| 150 // searches the extension object for properties. | 143 // searches the extension object for properties. |
| 151 // | 144 // |
| 152 // [ global ] A pointer to the global object. Provided for quick | 145 // [ global ] A pointer to the global object. Provided for quick |
| 153 // access to the global object from inside the code (since | 146 // access to the global object from inside the code (since |
| 154 // we always have a context pointer). | 147 // we always have a context pointer). |
| 155 // | 148 // |
| 156 // In addition, function contexts may have statically allocated context slots | 149 // In addition, function contexts may have statically allocated context slots |
| 157 // to store local variables/functions that are accessed from inner functions | 150 // to store local variables/functions that are accessed from inner functions |
| 158 // (via static context addresses) or through 'eval' (dynamic context lookups). | 151 // (via static context addresses) or through 'eval' (dynamic context lookups). |
| 159 // Finally, the global context contains additional slots for fast access to | 152 // Finally, the global context contains additional slots for fast access to |
| 160 // global properties. | 153 // global properties. |
| 161 // | |
| 162 // We may be able to simplify the implementation: | |
| 163 // | |
| 164 // - We may be able to get rid of 'fcontext': We can always use the fact that | |
| 165 // previous == NULL for function contexts and so we can search for them. They | |
| 166 // are only needed when doing dynamic declarations, and the context chains | |
| 167 // tend to be very very short (depth of nesting of 'with' statements). At | |
| 168 // the moment we also use it in generated code for context slot accesses - | |
| 169 // and there we don't want a loop because of code bloat - but we may not | |
| 170 // need it there after all (see comment in codegen_*.cc). | |
| 171 | 154 |
| 172 class Context: public FixedArray { | 155 class Context: public FixedArray { |
| 173 public: | 156 public: |
| 174 // Conversions. | 157 // Conversions. |
| 175 static Context* cast(Object* context) { | 158 static Context* cast(Object* context) { |
| 176 ASSERT(context->IsContext()); | 159 ASSERT(context->IsContext()); |
| 177 return reinterpret_cast<Context*>(context); | 160 return reinterpret_cast<Context*>(context); |
| 178 } | 161 } |
| 179 | 162 |
| 180 // The default context slot layout; indices are FixedArray slot indices. | 163 // The default context slot layout; indices are FixedArray slot indices. |
| 181 enum { | 164 enum { |
| 182 // These slots are in all contexts. | 165 // These slots are in all contexts. |
| 183 CLOSURE_INDEX, | 166 CLOSURE_INDEX, |
| 184 FCONTEXT_INDEX, | |
| 185 PREVIOUS_INDEX, | 167 PREVIOUS_INDEX, |
| 186 // The extension slot is used for either the global object (in global | 168 // The extension slot is used for either the global object (in global |
| 187 // contexts), eval extension object (function contexts), subject of with | 169 // contexts), eval extension object (function contexts), subject of with |
| 188 // (with contexts), or the variable name (catch contexts). | 170 // (with contexts), or the variable name (catch contexts). |
| 189 EXTENSION_INDEX, | 171 EXTENSION_INDEX, |
| 190 GLOBAL_INDEX, | 172 GLOBAL_INDEX, |
| 191 MIN_CONTEXT_SLOTS, | 173 MIN_CONTEXT_SLOTS, |
| 192 | 174 |
| 193 // This slot holds the thrown value in catch contexts. | 175 // This slot holds the thrown value in catch contexts. |
| 194 THROWN_OBJECT_INDEX = MIN_CONTEXT_SLOTS, | 176 THROWN_OBJECT_INDEX = MIN_CONTEXT_SLOTS, |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 257 // Total number of slots. | 239 // Total number of slots. |
| 258 GLOBAL_CONTEXT_SLOTS, | 240 GLOBAL_CONTEXT_SLOTS, |
| 259 | 241 |
| 260 FIRST_WEAK_SLOT = OPTIMIZED_FUNCTIONS_LIST | 242 FIRST_WEAK_SLOT = OPTIMIZED_FUNCTIONS_LIST |
| 261 }; | 243 }; |
| 262 | 244 |
| 263 // Direct slot access. | 245 // Direct slot access. |
| 264 JSFunction* closure() { return JSFunction::cast(get(CLOSURE_INDEX)); } | 246 JSFunction* closure() { return JSFunction::cast(get(CLOSURE_INDEX)); } |
| 265 void set_closure(JSFunction* closure) { set(CLOSURE_INDEX, closure); } | 247 void set_closure(JSFunction* closure) { set(CLOSURE_INDEX, closure); } |
| 266 | 248 |
| 267 Context* fcontext() { return Context::cast(get(FCONTEXT_INDEX)); } | |
| 268 void set_fcontext(Context* context) { set(FCONTEXT_INDEX, context); } | |
| 269 | |
| 270 Context* previous() { | 249 Context* previous() { |
| 271 Object* result = unchecked_previous(); | 250 Object* result = unchecked_previous(); |
| 272 ASSERT(IsBootstrappingOrContext(result)); | 251 ASSERT(IsBootstrappingOrContext(result)); |
| 273 return reinterpret_cast<Context*>(result); | 252 return reinterpret_cast<Context*>(result); |
| 274 } | 253 } |
| 275 void set_previous(Context* context) { set(PREVIOUS_INDEX, context); } | 254 void set_previous(Context* context) { set(PREVIOUS_INDEX, context); } |
| 276 | 255 |
| 277 bool has_extension() { return extension() != NULL; } | 256 bool has_extension() { return extension() != NULL; } |
| 278 Object* extension() { return get(EXTENSION_INDEX); } | 257 Object* extension() { return get(EXTENSION_INDEX); } |
| 279 void set_extension(Object* object) { set(EXTENSION_INDEX, object); } | 258 void set_extension(Object* object) { set(EXTENSION_INDEX, object); } |
| 280 | 259 |
| 260 // Get the context where var declarations will be hoisted to, which |
| 261 // may be the context itself. |
| 262 Context* declaration_context(); |
| 263 |
| 281 GlobalObject* global() { | 264 GlobalObject* global() { |
| 282 Object* result = get(GLOBAL_INDEX); | 265 Object* result = get(GLOBAL_INDEX); |
| 283 ASSERT(IsBootstrappingOrGlobalObject(result)); | 266 ASSERT(IsBootstrappingOrGlobalObject(result)); |
| 284 return reinterpret_cast<GlobalObject*>(result); | 267 return reinterpret_cast<GlobalObject*>(result); |
| 285 } | 268 } |
| 286 void set_global(GlobalObject* global) { set(GLOBAL_INDEX, global); } | 269 void set_global(GlobalObject* global) { set(GLOBAL_INDEX, global); } |
| 287 | 270 |
| 288 // Returns a JSGlobalProxy object or null. | 271 // Returns a JSGlobalProxy object or null. |
| 289 JSObject* global_proxy(); | 272 JSObject* global_proxy(); |
| 290 void set_global_proxy(JSObject* global); | 273 void set_global_proxy(JSObject* global); |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 402 #ifdef DEBUG | 385 #ifdef DEBUG |
| 403 // Bootstrapping-aware type checks. | 386 // Bootstrapping-aware type checks. |
| 404 static bool IsBootstrappingOrContext(Object* object); | 387 static bool IsBootstrappingOrContext(Object* object); |
| 405 static bool IsBootstrappingOrGlobalObject(Object* object); | 388 static bool IsBootstrappingOrGlobalObject(Object* object); |
| 406 #endif | 389 #endif |
| 407 }; | 390 }; |
| 408 | 391 |
| 409 } } // namespace v8::internal | 392 } } // namespace v8::internal |
| 410 | 393 |
| 411 #endif // V8_CONTEXTS_H_ | 394 #endif // V8_CONTEXTS_H_ |
| OLD | NEW |