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 |