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 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 // corresponding variable (though some are bound during parse time). Variable | 82 // corresponding variable (though some are bound during parse time). Variable |
83 // allocation binds each unresolved VariableProxy to one Variable and assigns | 83 // allocation binds each unresolved VariableProxy to one Variable and assigns |
84 // a location. Note that many VariableProxy nodes may refer to the same Java- | 84 // a location. Note that many VariableProxy nodes may refer to the same Java- |
85 // Script variable. | 85 // Script variable. |
86 | 86 |
87 class Scope: public ZoneObject { | 87 class Scope: public ZoneObject { |
88 public: | 88 public: |
89 // --------------------------------------------------------------------------- | 89 // --------------------------------------------------------------------------- |
90 // Construction | 90 // Construction |
91 | 91 |
92 enum Type { | 92 Scope(Scope* outer_scope, ScopeType type); |
93 EVAL_SCOPE, // The top-level scope for an eval source. | |
94 FUNCTION_SCOPE, // The top-level scope for a function. | |
95 GLOBAL_SCOPE, // The top-level scope for a program or a top-level eval. | |
96 CATCH_SCOPE, // The scope introduced by catch. | |
97 BLOCK_SCOPE // The scope introduced by a new block. | |
98 }; | |
99 | |
100 Scope(Scope* outer_scope, Type type); | |
101 | 93 |
102 // Compute top scope and allocate variables. For lazy compilation the top | 94 // Compute top scope and allocate variables. For lazy compilation the top |
103 // scope only contains the single lazily compiled function, so this | 95 // scope only contains the single lazily compiled function, so this |
104 // doesn't re-allocate variables repeatedly. | 96 // doesn't re-allocate variables repeatedly. |
105 static bool Analyze(CompilationInfo* info); | 97 static bool Analyze(CompilationInfo* info); |
106 | 98 |
107 static Scope* DeserializeScopeChain(CompilationInfo* info, | 99 static Scope* DeserializeScopeChain(CompilationInfo* info, |
108 Scope* innermost_scope); | 100 Scope* innermost_scope); |
109 | 101 |
110 // The scope name is only used for printing/debugging. | 102 // The scope name is only used for printing/debugging. |
111 void SetScopeName(Handle<String> scope_name) { scope_name_ = scope_name; } | 103 void SetScopeName(Handle<String> scope_name) { scope_name_ = scope_name; } |
112 | 104 |
113 void Initialize(bool inside_with); | 105 void Initialize(); |
114 | 106 |
115 // Checks if the block scope is redundant, i.e. it does not contain any | 107 // Checks if the block scope is redundant, i.e. it does not contain any |
116 // block scoped declarations. In that case it is removed from the scope | 108 // block scoped declarations. In that case it is removed from the scope |
117 // tree and its children are reparented. | 109 // tree and its children are reparented. |
118 Scope* FinalizeBlockScope(); | 110 Scope* FinalizeBlockScope(); |
119 | 111 |
120 // --------------------------------------------------------------------------- | 112 // --------------------------------------------------------------------------- |
121 // Declarations | 113 // Declarations |
122 | 114 |
123 // Lookup a variable in this scope. Returns the variable or NULL if not found. | 115 // Lookup a variable in this scope. Returns the variable or NULL if not found. |
124 Variable* LocalLookup(Handle<String> name); | 116 Variable* LocalLookup(Handle<String> name); |
125 | 117 |
126 // Lookup a variable in this scope or outer scopes. | 118 // Lookup a variable in this scope or outer scopes. |
127 // Returns the variable or NULL if not found. | 119 // Returns the variable or NULL if not found. |
128 Variable* Lookup(Handle<String> name); | 120 Variable* Lookup(Handle<String> name); |
129 | 121 |
130 // Declare the function variable for a function literal. This variable | 122 // Declare the function variable for a function literal. This variable |
131 // is in an intermediate scope between this function scope and the the | 123 // is in an intermediate scope between this function scope and the the |
132 // outer scope. Only possible for function scopes; at most one variable. | 124 // outer scope. Only possible for function scopes; at most one variable. |
133 Variable* DeclareFunctionVar(Handle<String> name); | 125 Variable* DeclareFunctionVar(Handle<String> name, VariableMode mode); |
134 | 126 |
135 // Declare a parameter in this scope. When there are duplicated | 127 // Declare a parameter in this scope. When there are duplicated |
136 // parameters the rightmost one 'wins'. However, the implementation | 128 // parameters the rightmost one 'wins'. However, the implementation |
137 // expects all parameters to be declared and from left to right. | 129 // expects all parameters to be declared and from left to right. |
138 void DeclareParameter(Handle<String> name, VariableMode mode); | 130 void DeclareParameter(Handle<String> name, VariableMode mode); |
139 | 131 |
140 // Declare a local variable in this scope. If the variable has been | 132 // Declare a local variable in this scope. If the variable has been |
141 // declared before, the previously declared variable is returned. | 133 // declared before, the previously declared variable is returned. |
142 Variable* DeclareLocal(Handle<String> name, VariableMode mode); | 134 Variable* DeclareLocal(Handle<String> name, VariableMode mode); |
143 | 135 |
144 // Declare an implicit global variable in this scope which must be a | 136 // Declare an implicit global variable in this scope which must be a |
145 // global scope. The variable was introduced (possibly from an inner | 137 // global scope. The variable was introduced (possibly from an inner |
146 // scope) by a reference to an unresolved variable with no intervening | 138 // scope) by a reference to an unresolved variable with no intervening |
147 // with statements or eval calls. | 139 // with statements or eval calls. |
148 Variable* DeclareGlobal(Handle<String> name); | 140 Variable* DeclareGlobal(Handle<String> name); |
149 | 141 |
150 // Create a new unresolved variable. | 142 // Create a new unresolved variable. |
151 VariableProxy* NewUnresolved(Handle<String> name, | 143 VariableProxy* NewUnresolved(Handle<String> name, |
152 bool inside_with, | |
153 int position = RelocInfo::kNoPosition); | 144 int position = RelocInfo::kNoPosition); |
154 | 145 |
155 // Remove a unresolved variable. During parsing, an unresolved variable | 146 // Remove a unresolved variable. During parsing, an unresolved variable |
156 // may have been added optimistically, but then only the variable name | 147 // may have been added optimistically, but then only the variable name |
157 // was used (typically for labels). If the variable was not declared, the | 148 // was used (typically for labels). If the variable was not declared, the |
158 // addition introduced a new unresolved variable which may end up being | 149 // addition introduced a new unresolved variable which may end up being |
159 // allocated globally as a "ghost" variable. RemoveUnresolved removes | 150 // allocated globally as a "ghost" variable. RemoveUnresolved removes |
160 // such a variable again if it was added; otherwise this is a no-op. | 151 // such a variable again if it was added; otherwise this is a no-op. |
161 void RemoveUnresolved(VariableProxy* var); | 152 void RemoveUnresolved(VariableProxy* var); |
162 | 153 |
(...skipping 29 matching lines...) Expand all Loading... |
192 // scope over a let binding of the same name. | 183 // scope over a let binding of the same name. |
193 Declaration* CheckConflictingVarDeclarations(); | 184 Declaration* CheckConflictingVarDeclarations(); |
194 | 185 |
195 // --------------------------------------------------------------------------- | 186 // --------------------------------------------------------------------------- |
196 // Scope-specific info. | 187 // Scope-specific info. |
197 | 188 |
198 // Inform the scope that the corresponding code contains a with statement. | 189 // Inform the scope that the corresponding code contains a with statement. |
199 void RecordWithStatement() { scope_contains_with_ = true; } | 190 void RecordWithStatement() { scope_contains_with_ = true; } |
200 | 191 |
201 // Inform the scope that the corresponding code contains an eval call. | 192 // Inform the scope that the corresponding code contains an eval call. |
202 void RecordEvalCall() { scope_calls_eval_ = true; } | 193 void RecordEvalCall() { if (!is_global_scope()) scope_calls_eval_ = true; } |
203 | 194 |
204 // Enable strict mode for the scope (unless disabled by a global flag). | 195 // Set the strict mode flag (unless disabled by a global flag). |
205 void EnableStrictMode() { | 196 void SetStrictModeFlag(StrictModeFlag strict_mode_flag) { |
206 strict_mode_ = FLAG_strict_mode; | 197 strict_mode_flag_ = FLAG_strict_mode ? strict_mode_flag : kNonStrictMode; |
| 198 } |
| 199 |
| 200 // Position in the source where this scope begins and ends. |
| 201 // |
| 202 // * For the scope of a with statement |
| 203 // with (obj) stmt |
| 204 // start position: start position of first token of 'stmt' |
| 205 // end position: end position of last token of 'stmt' |
| 206 // * For the scope of a block |
| 207 // { stmts } |
| 208 // start position: start position of '{' |
| 209 // end position: end position of '}' |
| 210 // * For the scope of a function literal or decalaration |
| 211 // function fun(a,b) { stmts } |
| 212 // start position: start position of '(' |
| 213 // end position: end position of '}' |
| 214 // * For the scope of a catch block |
| 215 // try { stms } catch(e) { stmts } |
| 216 // start position: start position of '(' |
| 217 // end position: end position of ')' |
| 218 // * For the scope of a for-statement |
| 219 // for (let x ...) stmt |
| 220 // start position: start position of '(' |
| 221 // end position: end position of last token of 'stmt' |
| 222 int start_position() const { return start_position_; } |
| 223 void set_start_position(int statement_pos) { |
| 224 start_position_ = statement_pos; |
| 225 } |
| 226 int end_position() const { return end_position_; } |
| 227 void set_end_position(int statement_pos) { |
| 228 end_position_ = statement_pos; |
207 } | 229 } |
208 | 230 |
209 // --------------------------------------------------------------------------- | 231 // --------------------------------------------------------------------------- |
210 // Predicates. | 232 // Predicates. |
211 | 233 |
212 // Specific scope types. | 234 // Specific scope types. |
213 bool is_eval_scope() const { return type_ == EVAL_SCOPE; } | 235 bool is_eval_scope() const { return type_ == EVAL_SCOPE; } |
214 bool is_function_scope() const { return type_ == FUNCTION_SCOPE; } | 236 bool is_function_scope() const { return type_ == FUNCTION_SCOPE; } |
215 bool is_global_scope() const { return type_ == GLOBAL_SCOPE; } | 237 bool is_global_scope() const { return type_ == GLOBAL_SCOPE; } |
216 bool is_catch_scope() const { return type_ == CATCH_SCOPE; } | 238 bool is_catch_scope() const { return type_ == CATCH_SCOPE; } |
217 bool is_block_scope() const { return type_ == BLOCK_SCOPE; } | 239 bool is_block_scope() const { return type_ == BLOCK_SCOPE; } |
218 bool is_strict_mode() const { return strict_mode_; } | 240 bool is_with_scope() const { return type_ == WITH_SCOPE; } |
| 241 bool is_declaration_scope() const { |
| 242 return is_eval_scope() || is_function_scope() || is_global_scope(); |
| 243 } |
| 244 bool is_strict_mode() const { return strict_mode_flag() == kStrictMode; } |
219 bool is_strict_mode_eval_scope() const { | 245 bool is_strict_mode_eval_scope() const { |
220 return is_eval_scope() && is_strict_mode(); | 246 return is_eval_scope() && is_strict_mode(); |
221 } | 247 } |
222 | 248 |
223 // Information about which scopes calls eval. | 249 // Information about which scopes calls eval. |
224 bool calls_eval() const { return scope_calls_eval_; } | 250 bool calls_eval() const { return scope_calls_eval_; } |
225 bool outer_scope_calls_eval() const { return outer_scope_calls_eval_; } | 251 bool calls_non_strict_eval() { |
| 252 return scope_calls_eval_ && !is_strict_mode(); |
| 253 } |
226 bool outer_scope_calls_non_strict_eval() const { | 254 bool outer_scope_calls_non_strict_eval() const { |
227 return outer_scope_calls_non_strict_eval_; | 255 return outer_scope_calls_non_strict_eval_; |
228 } | 256 } |
229 | 257 |
230 // Is this scope inside a with statement. | 258 // Is this scope inside a with statement. |
231 bool inside_with() const { return scope_inside_with_; } | 259 bool inside_with() const { return scope_inside_with_; } |
232 // Does this scope contain a with statement. | 260 // Does this scope contain a with statement. |
233 bool contains_with() const { return scope_contains_with_; } | 261 bool contains_with() const { return scope_contains_with_; } |
234 | 262 |
235 // The scope immediately surrounding this scope, or NULL. | 263 // The scope immediately surrounding this scope, or NULL. |
236 Scope* outer_scope() const { return outer_scope_; } | 264 Scope* outer_scope() const { return outer_scope_; } |
237 | 265 |
238 // --------------------------------------------------------------------------- | 266 // --------------------------------------------------------------------------- |
239 // Accessors. | 267 // Accessors. |
240 | 268 |
| 269 // The type of this scope. |
| 270 ScopeType type() const { return type_; } |
| 271 |
| 272 // The strict mode of this scope. |
| 273 StrictModeFlag strict_mode_flag() const { return strict_mode_flag_; } |
| 274 |
241 // The variable corresponding the 'this' value. | 275 // The variable corresponding the 'this' value. |
242 Variable* receiver() { return receiver_; } | 276 Variable* receiver() { return receiver_; } |
243 | 277 |
244 // The variable holding the function literal for named function | 278 // The variable holding the function literal for named function |
245 // literals, or NULL. | 279 // literals, or NULL. |
246 // Only valid for function scopes. | 280 // Only valid for function scopes. |
247 VariableProxy* function() const { | 281 VariableProxy* function() const { |
248 ASSERT(is_function_scope()); | 282 ASSERT(is_function_scope()); |
249 return function_; | 283 return function_; |
250 } | 284 } |
251 | 285 |
252 // Parameters. The left-most parameter has index 0. | 286 // Parameters. The left-most parameter has index 0. |
253 // Only valid for function scopes. | 287 // Only valid for function scopes. |
254 Variable* parameter(int index) const { | 288 Variable* parameter(int index) const { |
255 ASSERT(is_function_scope()); | 289 ASSERT(is_function_scope()); |
256 return params_[index]; | 290 return params_[index]; |
257 } | 291 } |
258 | 292 |
259 int num_parameters() const { return params_.length(); } | 293 int num_parameters() const { return params_.length(); } |
260 | 294 |
261 // The local variable 'arguments' if we need to allocate it; NULL otherwise. | 295 // The local variable 'arguments' if we need to allocate it; NULL otherwise. |
262 Variable* arguments() const { return arguments_; } | 296 Variable* arguments() const { return arguments_; } |
263 | 297 |
264 // Declarations list. | 298 // Declarations list. |
265 ZoneList<Declaration*>* declarations() { return &decls_; } | 299 ZoneList<Declaration*>* declarations() { return &decls_; } |
266 | 300 |
| 301 // Inner scope list. |
| 302 ZoneList<Scope*>* inner_scopes() { return &inner_scopes_; } |
267 | 303 |
268 // --------------------------------------------------------------------------- | 304 // --------------------------------------------------------------------------- |
269 // Variable allocation. | 305 // Variable allocation. |
270 | 306 |
271 // Collect all used locals in this scope. | 307 // Collect all used locals in this scope. |
272 template<class Allocator> | 308 template<class Allocator> |
273 void CollectUsedVariables(List<Variable*, Allocator>* locals); | 309 void CollectUsedVariables(List<Variable*, Allocator>* locals); |
274 | 310 |
275 // Resolve and fill in the allocation information for all variables | 311 // Resolve and fill in the allocation information for all variables |
276 // in this scopes. Must be called *after* all scopes have been | 312 // in this scopes. Must be called *after* all scopes have been |
(...skipping 23 matching lines...) Expand all Loading... |
300 | 336 |
301 // The number of contexts between this and scope; zero if this == scope. | 337 // The number of contexts between this and scope; zero if this == scope. |
302 int ContextChainLength(Scope* scope); | 338 int ContextChainLength(Scope* scope); |
303 | 339 |
304 // Find the first function, global, or eval scope. This is the scope | 340 // Find the first function, global, or eval scope. This is the scope |
305 // where var declarations will be hoisted to in the implementation. | 341 // where var declarations will be hoisted to in the implementation. |
306 Scope* DeclarationScope(); | 342 Scope* DeclarationScope(); |
307 | 343 |
308 Handle<SerializedScopeInfo> GetSerializedScopeInfo(); | 344 Handle<SerializedScopeInfo> GetSerializedScopeInfo(); |
309 | 345 |
| 346 // Get the chain of nested scopes within this scope for the source statement |
| 347 // position. The scopes will be added to the list from the outermost scope to |
| 348 // the innermost scope. Only nested block, catch or with scopes are tracked |
| 349 // and will be returned, but no inner function scopes. |
| 350 void GetNestedScopeChain(List<Handle<SerializedScopeInfo> >* chain, |
| 351 int statement_position); |
| 352 |
310 // --------------------------------------------------------------------------- | 353 // --------------------------------------------------------------------------- |
311 // Strict mode support. | 354 // Strict mode support. |
312 bool IsDeclared(Handle<String> name) { | 355 bool IsDeclared(Handle<String> name) { |
313 // During formal parameter list parsing the scope only contains | 356 // During formal parameter list parsing the scope only contains |
314 // two variables inserted at initialization: "this" and "arguments". | 357 // two variables inserted at initialization: "this" and "arguments". |
315 // "this" is an invalid parameter name and "arguments" is invalid parameter | 358 // "this" is an invalid parameter name and "arguments" is invalid parameter |
316 // name in strict mode. Therefore looking up with the map which includes | 359 // name in strict mode. Therefore looking up with the map which includes |
317 // "this" and "arguments" in addition to all formal parameters is safe. | 360 // "this" and "arguments" in addition to all formal parameters is safe. |
318 return variables_.Lookup(name) != NULL; | 361 return variables_.Lookup(name) != NULL; |
319 } | 362 } |
320 | 363 |
321 // --------------------------------------------------------------------------- | 364 // --------------------------------------------------------------------------- |
322 // Debugging. | 365 // Debugging. |
323 | 366 |
324 #ifdef DEBUG | 367 #ifdef DEBUG |
325 void Print(int n = 0); // n = indentation; n < 0 => don't print recursively | 368 void Print(int n = 0); // n = indentation; n < 0 => don't print recursively |
326 #endif | 369 #endif |
327 | 370 |
328 // --------------------------------------------------------------------------- | 371 // --------------------------------------------------------------------------- |
329 // Implementation. | 372 // Implementation. |
330 protected: | 373 protected: |
331 friend class ParserFactory; | 374 friend class ParserFactory; |
332 | 375 |
333 explicit Scope(Type type); | 376 explicit Scope(ScopeType type); |
334 | 377 |
335 Isolate* const isolate_; | 378 Isolate* const isolate_; |
336 | 379 |
337 // Scope tree. | 380 // Scope tree. |
338 Scope* outer_scope_; // the immediately enclosing outer scope, or NULL | 381 Scope* outer_scope_; // the immediately enclosing outer scope, or NULL |
339 ZoneList<Scope*> inner_scopes_; // the immediately enclosed inner scopes | 382 ZoneList<Scope*> inner_scopes_; // the immediately enclosed inner scopes |
340 | 383 |
341 // The scope type. | 384 // The scope type. |
342 Type type_; | 385 ScopeType type_; |
343 | 386 |
344 // Debugging support. | 387 // Debugging support. |
345 Handle<String> scope_name_; | 388 Handle<String> scope_name_; |
346 | 389 |
347 // The variables declared in this scope: | 390 // The variables declared in this scope: |
348 // | 391 // |
349 // All user-declared variables (incl. parameters). For global scopes | 392 // All user-declared variables (incl. parameters). For global scopes |
350 // variables may be implicitly 'declared' by being used (possibly in | 393 // variables may be implicitly 'declared' by being used (possibly in |
351 // an inner scope) with no intervening with statements or eval calls. | 394 // an inner scope) with no intervening with statements or eval calls. |
352 VariableMap variables_; | 395 VariableMap variables_; |
(...skipping 20 matching lines...) Expand all Loading... |
373 // Scope-specific information computed during parsing. | 416 // Scope-specific information computed during parsing. |
374 // | 417 // |
375 // This scope is inside a 'with' of some outer scope. | 418 // This scope is inside a 'with' of some outer scope. |
376 bool scope_inside_with_; | 419 bool scope_inside_with_; |
377 // This scope contains a 'with' statement. | 420 // This scope contains a 'with' statement. |
378 bool scope_contains_with_; | 421 bool scope_contains_with_; |
379 // This scope or a nested catch scope or with scope contain an 'eval' call. At | 422 // This scope or a nested catch scope or with scope contain an 'eval' call. At |
380 // the 'eval' call site this scope is the declaration scope. | 423 // the 'eval' call site this scope is the declaration scope. |
381 bool scope_calls_eval_; | 424 bool scope_calls_eval_; |
382 // This scope is a strict mode scope. | 425 // This scope is a strict mode scope. |
383 bool strict_mode_; | 426 StrictModeFlag strict_mode_flag_; |
| 427 // Source positions. |
| 428 int start_position_; |
| 429 int end_position_; |
384 | 430 |
385 // Computed via PropagateScopeInfo. | 431 // Computed via PropagateScopeInfo. |
386 bool outer_scope_calls_eval_; | |
387 bool outer_scope_calls_non_strict_eval_; | 432 bool outer_scope_calls_non_strict_eval_; |
388 bool inner_scope_calls_eval_; | 433 bool inner_scope_calls_eval_; |
389 bool outer_scope_is_eval_scope_; | |
390 bool force_eager_compilation_; | 434 bool force_eager_compilation_; |
391 | 435 |
392 // True if it doesn't need scope resolution (e.g., if the scope was | 436 // True if it doesn't need scope resolution (e.g., if the scope was |
393 // constructed based on a serialized scope info or a catch context). | 437 // constructed based on a serialized scope info or a catch context). |
394 bool already_resolved_; | 438 bool already_resolved_; |
395 | 439 |
396 // Computed as variables are declared. | 440 // Computed as variables are declared. |
397 int num_var_or_const_; | 441 int num_var_or_const_; |
398 | 442 |
399 // Computed via AllocateVariables; function scopes only. | 443 // Computed via AllocateVariables; function, block and catch scopes only. |
400 int num_stack_slots_; | 444 int num_stack_slots_; |
401 int num_heap_slots_; | 445 int num_heap_slots_; |
402 | 446 |
403 // Serialized scopes support. | 447 // Serialized scopes support. |
404 Handle<SerializedScopeInfo> scope_info_; | 448 Handle<SerializedScopeInfo> scope_info_; |
405 bool already_resolved() { return already_resolved_; } | 449 bool already_resolved() { return already_resolved_; } |
406 | 450 |
407 // Create a non-local variable with a given name. | 451 // Create a non-local variable with a given name. |
408 // These variables are looked up dynamically at runtime. | 452 // These variables are looked up dynamically at runtime. |
409 Variable* NonLocal(Handle<String> name, VariableMode mode); | 453 Variable* NonLocal(Handle<String> name, VariableMode mode); |
410 | 454 |
411 // Variable resolution. | 455 // Variable resolution. |
| 456 // Possible results of a recursive variable lookup telling if and how a |
| 457 // variable is bound. These are returned in the output parameter *binding_kind |
| 458 // of the LookupRecursive function. |
| 459 enum BindingKind { |
| 460 // The variable reference could be statically resolved to a variable binding |
| 461 // which is returned. There is no 'with' statement between the reference and |
| 462 // the binding and no scope between the reference scope (inclusive) and |
| 463 // binding scope (exclusive) makes a non-strict 'eval' call. |
| 464 BOUND, |
| 465 |
| 466 // The variable reference could be statically resolved to a variable binding |
| 467 // which is returned. There is no 'with' statement between the reference and |
| 468 // the binding, but some scope between the reference scope (inclusive) and |
| 469 // binding scope (exclusive) makes a non-strict 'eval' call, that might |
| 470 // possibly introduce variable bindings shadowing the found one. Thus the |
| 471 // found variable binding is just a guess. |
| 472 BOUND_EVAL_SHADOWED, |
| 473 |
| 474 // The variable reference could not be statically resolved to any binding |
| 475 // and thus should be considered referencing a global variable. NULL is |
| 476 // returned. The variable reference is not inside any 'with' statement and |
| 477 // no scope between the reference scope (inclusive) and global scope |
| 478 // (exclusive) makes a non-strict 'eval' call. |
| 479 UNBOUND, |
| 480 |
| 481 // The variable reference could not be statically resolved to any binding |
| 482 // NULL is returned. The variable reference is not inside any 'with' |
| 483 // statement, but some scope between the reference scope (inclusive) and |
| 484 // global scope (exclusive) makes a non-strict 'eval' call, that might |
| 485 // possibly introduce a variable binding. Thus the reference should be |
| 486 // considered referencing a global variable unless it is shadowed by an |
| 487 // 'eval' introduced binding. |
| 488 UNBOUND_EVAL_SHADOWED, |
| 489 |
| 490 // The variable could not be statically resolved and needs to be looked up |
| 491 // dynamically. NULL is returned. There are two possible reasons: |
| 492 // * A 'with' statement has been encountered and there is no variable |
| 493 // binding for the name between the variable reference and the 'with'. |
| 494 // The variable potentially references a property of the 'with' object. |
| 495 // * The code is being executed as part of a call to 'eval' and the calling |
| 496 // context chain contains either a variable binding for the name or it |
| 497 // contains a 'with' context. |
| 498 DYNAMIC_LOOKUP |
| 499 }; |
| 500 |
| 501 // Lookup a variable reference given by name recursively starting with this |
| 502 // scope. If the code is executed because of a call to 'eval', the context |
| 503 // parameter should be set to the calling context of 'eval'. |
412 Variable* LookupRecursive(Handle<String> name, | 504 Variable* LookupRecursive(Handle<String> name, |
413 bool from_inner_function, | 505 Handle<Context> context, |
414 Variable** invalidated_local); | 506 BindingKind* binding_kind); |
415 void ResolveVariable(Scope* global_scope, | 507 void ResolveVariable(Scope* global_scope, |
416 Handle<Context> context, | 508 Handle<Context> context, |
417 VariableProxy* proxy); | 509 VariableProxy* proxy); |
418 void ResolveVariablesRecursively(Scope* global_scope, | 510 void ResolveVariablesRecursively(Scope* global_scope, |
419 Handle<Context> context); | 511 Handle<Context> context); |
420 | 512 |
421 // Scope analysis. | 513 // Scope analysis. |
422 bool PropagateScopeInfo(bool outer_scope_calls_eval, | 514 bool PropagateScopeInfo(bool outer_scope_calls_non_strict_eval); |
423 bool outer_scope_calls_non_strict_eval, | |
424 bool outer_scope_is_eval_scope); | |
425 bool HasTrivialContext() const; | 515 bool HasTrivialContext() const; |
426 | 516 |
427 // Predicates. | 517 // Predicates. |
428 bool MustAllocate(Variable* var); | 518 bool MustAllocate(Variable* var); |
429 bool MustAllocateInContext(Variable* var); | 519 bool MustAllocateInContext(Variable* var); |
430 bool HasArgumentsParameter(); | 520 bool HasArgumentsParameter(); |
431 | 521 |
432 // Variable allocation. | 522 // Variable allocation. |
433 void AllocateStackSlot(Variable* var); | 523 void AllocateStackSlot(Variable* var); |
434 void AllocateHeapSlot(Variable* var); | 524 void AllocateHeapSlot(Variable* var); |
435 void AllocateParameterLocals(); | 525 void AllocateParameterLocals(); |
436 void AllocateNonParameterLocal(Variable* var); | 526 void AllocateNonParameterLocal(Variable* var); |
437 void AllocateNonParameterLocals(); | 527 void AllocateNonParameterLocals(); |
438 void AllocateVariablesRecursively(); | 528 void AllocateVariablesRecursively(); |
439 | 529 |
440 private: | 530 private: |
441 // Construct a function or block scope based on the scope info. | 531 // Construct a scope based on the scope info. |
442 Scope(Scope* inner_scope, Type type, Handle<SerializedScopeInfo> scope_info); | 532 Scope(Scope* inner_scope, |
| 533 ScopeType type, |
| 534 Handle<SerializedScopeInfo> scope_info); |
443 | 535 |
444 // Construct a catch scope with a binding for the name. | 536 // Construct a catch scope with a binding for the name. |
445 Scope(Scope* inner_scope, Handle<String> catch_variable_name); | 537 Scope(Scope* inner_scope, Handle<String> catch_variable_name); |
446 | 538 |
447 void AddInnerScope(Scope* inner_scope) { | 539 void AddInnerScope(Scope* inner_scope) { |
448 if (inner_scope != NULL) { | 540 if (inner_scope != NULL) { |
449 inner_scopes_.Add(inner_scope); | 541 inner_scopes_.Add(inner_scope); |
450 inner_scope->outer_scope_ = this; | 542 inner_scope->outer_scope_ = this; |
451 } | 543 } |
452 } | 544 } |
453 | 545 |
454 void SetDefaults(Type type, | 546 void SetDefaults(ScopeType type, |
455 Scope* outer_scope, | 547 Scope* outer_scope, |
456 Handle<SerializedScopeInfo> scope_info); | 548 Handle<SerializedScopeInfo> scope_info); |
457 }; | 549 }; |
458 | 550 |
459 } } // namespace v8::internal | 551 } } // namespace v8::internal |
460 | 552 |
461 #endif // V8_SCOPES_H_ | 553 #endif // V8_SCOPES_H_ |
OLD | NEW |