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