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 Scope(Scope* outer_scope, ScopeType type); | 92 enum 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 WITH_SCOPE // The scope introduced by with. |
| 99 }; |
| 100 |
| 101 Scope(Scope* outer_scope, Type type); |
93 | 102 |
94 // Compute top scope and allocate variables. For lazy compilation the top | 103 // Compute top scope and allocate variables. For lazy compilation the top |
95 // scope only contains the single lazily compiled function, so this | 104 // scope only contains the single lazily compiled function, so this |
96 // doesn't re-allocate variables repeatedly. | 105 // doesn't re-allocate variables repeatedly. |
97 static bool Analyze(CompilationInfo* info); | 106 static bool Analyze(CompilationInfo* info); |
98 | 107 |
99 static Scope* DeserializeScopeChain(CompilationInfo* info, | 108 static Scope* DeserializeScopeChain(CompilationInfo* info, |
100 Scope* innermost_scope); | 109 Scope* innermost_scope); |
101 | 110 |
102 // The scope name is only used for printing/debugging. | 111 // The scope name is only used for printing/debugging. |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
190 void RecordWithStatement() { scope_contains_with_ = true; } | 199 void RecordWithStatement() { scope_contains_with_ = true; } |
191 | 200 |
192 // Inform the scope that the corresponding code contains an eval call. | 201 // Inform the scope that the corresponding code contains an eval call. |
193 void RecordEvalCall() { if (!is_global_scope()) scope_calls_eval_ = true; } | 202 void RecordEvalCall() { if (!is_global_scope()) scope_calls_eval_ = true; } |
194 | 203 |
195 // Enable strict mode for the scope (unless disabled by a global flag). | 204 // Enable strict mode for the scope (unless disabled by a global flag). |
196 void EnableStrictMode() { | 205 void EnableStrictMode() { |
197 strict_mode_ = FLAG_strict_mode; | 206 strict_mode_ = FLAG_strict_mode; |
198 } | 207 } |
199 | 208 |
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; | |
229 } | |
230 | |
231 // --------------------------------------------------------------------------- | 209 // --------------------------------------------------------------------------- |
232 // Predicates. | 210 // Predicates. |
233 | 211 |
234 // Specific scope types. | 212 // Specific scope types. |
235 bool is_eval_scope() const { return type_ == EVAL_SCOPE; } | 213 bool is_eval_scope() const { return type_ == EVAL_SCOPE; } |
236 bool is_function_scope() const { return type_ == FUNCTION_SCOPE; } | 214 bool is_function_scope() const { return type_ == FUNCTION_SCOPE; } |
237 bool is_global_scope() const { return type_ == GLOBAL_SCOPE; } | 215 bool is_global_scope() const { return type_ == GLOBAL_SCOPE; } |
238 bool is_catch_scope() const { return type_ == CATCH_SCOPE; } | 216 bool is_catch_scope() const { return type_ == CATCH_SCOPE; } |
239 bool is_block_scope() const { return type_ == BLOCK_SCOPE; } | 217 bool is_block_scope() const { return type_ == BLOCK_SCOPE; } |
240 bool is_with_scope() const { return type_ == WITH_SCOPE; } | 218 bool is_with_scope() const { return type_ == WITH_SCOPE; } |
(...skipping 18 matching lines...) Expand all Loading... |
259 bool inside_with() const { return scope_inside_with_; } | 237 bool inside_with() const { return scope_inside_with_; } |
260 // Does this scope contain a with statement. | 238 // Does this scope contain a with statement. |
261 bool contains_with() const { return scope_contains_with_; } | 239 bool contains_with() const { return scope_contains_with_; } |
262 | 240 |
263 // The scope immediately surrounding this scope, or NULL. | 241 // The scope immediately surrounding this scope, or NULL. |
264 Scope* outer_scope() const { return outer_scope_; } | 242 Scope* outer_scope() const { return outer_scope_; } |
265 | 243 |
266 // --------------------------------------------------------------------------- | 244 // --------------------------------------------------------------------------- |
267 // Accessors. | 245 // Accessors. |
268 | 246 |
269 // The type of this scope. | |
270 ScopeType type() const { return type_; } | |
271 | |
272 // The variable corresponding the 'this' value. | 247 // The variable corresponding the 'this' value. |
273 Variable* receiver() { return receiver_; } | 248 Variable* receiver() { return receiver_; } |
274 | 249 |
275 // The variable holding the function literal for named function | 250 // The variable holding the function literal for named function |
276 // literals, or NULL. | 251 // literals, or NULL. |
277 // Only valid for function scopes. | 252 // Only valid for function scopes. |
278 VariableProxy* function() const { | 253 VariableProxy* function() const { |
279 ASSERT(is_function_scope()); | 254 ASSERT(is_function_scope()); |
280 return function_; | 255 return function_; |
281 } | 256 } |
282 | 257 |
283 // Parameters. The left-most parameter has index 0. | 258 // Parameters. The left-most parameter has index 0. |
284 // Only valid for function scopes. | 259 // Only valid for function scopes. |
285 Variable* parameter(int index) const { | 260 Variable* parameter(int index) const { |
286 ASSERT(is_function_scope()); | 261 ASSERT(is_function_scope()); |
287 return params_[index]; | 262 return params_[index]; |
288 } | 263 } |
289 | 264 |
290 int num_parameters() const { return params_.length(); } | 265 int num_parameters() const { return params_.length(); } |
291 | 266 |
292 // The local variable 'arguments' if we need to allocate it; NULL otherwise. | 267 // The local variable 'arguments' if we need to allocate it; NULL otherwise. |
293 Variable* arguments() const { return arguments_; } | 268 Variable* arguments() const { return arguments_; } |
294 | 269 |
295 // Declarations list. | 270 // Declarations list. |
296 ZoneList<Declaration*>* declarations() { return &decls_; } | 271 ZoneList<Declaration*>* declarations() { return &decls_; } |
297 | 272 |
298 // Inner scope list. | |
299 ZoneList<Scope*>* inner_scopes() { return &inner_scopes_; } | |
300 | 273 |
301 // --------------------------------------------------------------------------- | 274 // --------------------------------------------------------------------------- |
302 // Variable allocation. | 275 // Variable allocation. |
303 | 276 |
304 // Collect all used locals in this scope. | 277 // Collect all used locals in this scope. |
305 template<class Allocator> | 278 template<class Allocator> |
306 void CollectUsedVariables(List<Variable*, Allocator>* locals); | 279 void CollectUsedVariables(List<Variable*, Allocator>* locals); |
307 | 280 |
308 // Resolve and fill in the allocation information for all variables | 281 // Resolve and fill in the allocation information for all variables |
309 // in this scopes. Must be called *after* all scopes have been | 282 // in this scopes. Must be called *after* all scopes have been |
(...skipping 23 matching lines...) Expand all Loading... |
333 | 306 |
334 // The number of contexts between this and scope; zero if this == scope. | 307 // The number of contexts between this and scope; zero if this == scope. |
335 int ContextChainLength(Scope* scope); | 308 int ContextChainLength(Scope* scope); |
336 | 309 |
337 // Find the first function, global, or eval scope. This is the scope | 310 // Find the first function, global, or eval scope. This is the scope |
338 // where var declarations will be hoisted to in the implementation. | 311 // where var declarations will be hoisted to in the implementation. |
339 Scope* DeclarationScope(); | 312 Scope* DeclarationScope(); |
340 | 313 |
341 Handle<SerializedScopeInfo> GetSerializedScopeInfo(); | 314 Handle<SerializedScopeInfo> GetSerializedScopeInfo(); |
342 | 315 |
343 // Get the chain of nested scopes within this scope for the source statement | |
344 // position. The scopes will be added to the list from the outermost scope to | |
345 // the innermost scope. Only nested block, catch or with scopes are tracked | |
346 // and will be returned, but no inner function scopes. | |
347 void GetNestedScopeChain(List<Handle<SerializedScopeInfo> >* chain, | |
348 int statement_position); | |
349 | |
350 // --------------------------------------------------------------------------- | 316 // --------------------------------------------------------------------------- |
351 // Strict mode support. | 317 // Strict mode support. |
352 bool IsDeclared(Handle<String> name) { | 318 bool IsDeclared(Handle<String> name) { |
353 // During formal parameter list parsing the scope only contains | 319 // During formal parameter list parsing the scope only contains |
354 // two variables inserted at initialization: "this" and "arguments". | 320 // two variables inserted at initialization: "this" and "arguments". |
355 // "this" is an invalid parameter name and "arguments" is invalid parameter | 321 // "this" is an invalid parameter name and "arguments" is invalid parameter |
356 // name in strict mode. Therefore looking up with the map which includes | 322 // name in strict mode. Therefore looking up with the map which includes |
357 // "this" and "arguments" in addition to all formal parameters is safe. | 323 // "this" and "arguments" in addition to all formal parameters is safe. |
358 return variables_.Lookup(name) != NULL; | 324 return variables_.Lookup(name) != NULL; |
359 } | 325 } |
360 | 326 |
361 // --------------------------------------------------------------------------- | 327 // --------------------------------------------------------------------------- |
362 // Debugging. | 328 // Debugging. |
363 | 329 |
364 #ifdef DEBUG | 330 #ifdef DEBUG |
365 void Print(int n = 0); // n = indentation; n < 0 => don't print recursively | 331 void Print(int n = 0); // n = indentation; n < 0 => don't print recursively |
366 #endif | 332 #endif |
367 | 333 |
368 // --------------------------------------------------------------------------- | 334 // --------------------------------------------------------------------------- |
369 // Implementation. | 335 // Implementation. |
370 protected: | 336 protected: |
371 friend class ParserFactory; | 337 friend class ParserFactory; |
372 | 338 |
373 explicit Scope(ScopeType type); | 339 explicit Scope(Type type); |
374 | 340 |
375 Isolate* const isolate_; | 341 Isolate* const isolate_; |
376 | 342 |
377 // Scope tree. | 343 // Scope tree. |
378 Scope* outer_scope_; // the immediately enclosing outer scope, or NULL | 344 Scope* outer_scope_; // the immediately enclosing outer scope, or NULL |
379 ZoneList<Scope*> inner_scopes_; // the immediately enclosed inner scopes | 345 ZoneList<Scope*> inner_scopes_; // the immediately enclosed inner scopes |
380 | 346 |
381 // The scope type. | 347 // The scope type. |
382 ScopeType type_; | 348 Type type_; |
383 | 349 |
384 // Debugging support. | 350 // Debugging support. |
385 Handle<String> scope_name_; | 351 Handle<String> scope_name_; |
386 | 352 |
387 // The variables declared in this scope: | 353 // The variables declared in this scope: |
388 // | 354 // |
389 // All user-declared variables (incl. parameters). For global scopes | 355 // All user-declared variables (incl. parameters). For global scopes |
390 // variables may be implicitly 'declared' by being used (possibly in | 356 // variables may be implicitly 'declared' by being used (possibly in |
391 // an inner scope) with no intervening with statements or eval calls. | 357 // an inner scope) with no intervening with statements or eval calls. |
392 VariableMap variables_; | 358 VariableMap variables_; |
(...skipping 21 matching lines...) Expand all Loading... |
414 // | 380 // |
415 // This scope is inside a 'with' of some outer scope. | 381 // This scope is inside a 'with' of some outer scope. |
416 bool scope_inside_with_; | 382 bool scope_inside_with_; |
417 // This scope contains a 'with' statement. | 383 // This scope contains a 'with' statement. |
418 bool scope_contains_with_; | 384 bool scope_contains_with_; |
419 // This scope or a nested catch scope or with scope contain an 'eval' call. At | 385 // This scope or a nested catch scope or with scope contain an 'eval' call. At |
420 // the 'eval' call site this scope is the declaration scope. | 386 // the 'eval' call site this scope is the declaration scope. |
421 bool scope_calls_eval_; | 387 bool scope_calls_eval_; |
422 // This scope is a strict mode scope. | 388 // This scope is a strict mode scope. |
423 bool strict_mode_; | 389 bool strict_mode_; |
424 // Source positions. | |
425 int start_position_; | |
426 int end_position_; | |
427 | 390 |
428 // Computed via PropagateScopeInfo. | 391 // Computed via PropagateScopeInfo. |
429 bool outer_scope_calls_non_strict_eval_; | 392 bool outer_scope_calls_non_strict_eval_; |
430 bool inner_scope_calls_eval_; | 393 bool inner_scope_calls_eval_; |
431 bool force_eager_compilation_; | 394 bool force_eager_compilation_; |
432 | 395 |
433 // True if it doesn't need scope resolution (e.g., if the scope was | 396 // True if it doesn't need scope resolution (e.g., if the scope was |
434 // constructed based on a serialized scope info or a catch context). | 397 // constructed based on a serialized scope info or a catch context). |
435 bool already_resolved_; | 398 bool already_resolved_; |
436 | 399 |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
519 // Variable allocation. | 482 // Variable allocation. |
520 void AllocateStackSlot(Variable* var); | 483 void AllocateStackSlot(Variable* var); |
521 void AllocateHeapSlot(Variable* var); | 484 void AllocateHeapSlot(Variable* var); |
522 void AllocateParameterLocals(); | 485 void AllocateParameterLocals(); |
523 void AllocateNonParameterLocal(Variable* var); | 486 void AllocateNonParameterLocal(Variable* var); |
524 void AllocateNonParameterLocals(); | 487 void AllocateNonParameterLocals(); |
525 void AllocateVariablesRecursively(); | 488 void AllocateVariablesRecursively(); |
526 | 489 |
527 private: | 490 private: |
528 // Construct a scope based on the scope info. | 491 // Construct a scope based on the scope info. |
529 Scope(Scope* inner_scope, | 492 Scope(Scope* inner_scope, Type type, Handle<SerializedScopeInfo> scope_info); |
530 ScopeType type, | |
531 Handle<SerializedScopeInfo> scope_info); | |
532 | 493 |
533 // Construct a catch scope with a binding for the name. | 494 // Construct a catch scope with a binding for the name. |
534 Scope(Scope* inner_scope, Handle<String> catch_variable_name); | 495 Scope(Scope* inner_scope, Handle<String> catch_variable_name); |
535 | 496 |
536 void AddInnerScope(Scope* inner_scope) { | 497 void AddInnerScope(Scope* inner_scope) { |
537 if (inner_scope != NULL) { | 498 if (inner_scope != NULL) { |
538 inner_scopes_.Add(inner_scope); | 499 inner_scopes_.Add(inner_scope); |
539 inner_scope->outer_scope_ = this; | 500 inner_scope->outer_scope_ = this; |
540 } | 501 } |
541 } | 502 } |
542 | 503 |
543 void SetDefaults(ScopeType type, | 504 void SetDefaults(Type type, |
544 Scope* outer_scope, | 505 Scope* outer_scope, |
545 Handle<SerializedScopeInfo> scope_info); | 506 Handle<SerializedScopeInfo> scope_info); |
546 }; | 507 }; |
547 | 508 |
548 } } // namespace v8::internal | 509 } } // namespace v8::internal |
549 | 510 |
550 #endif // V8_SCOPES_H_ | 511 #endif // V8_SCOPES_H_ |
OLD | NEW |