OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/parsing/rewriter.h" | 5 #include "src/parsing/rewriter.h" |
6 | 6 |
7 #include "src/ast/ast.h" | 7 #include "src/ast/ast.h" |
8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
9 #include "src/objects-inl.h" | 9 #include "src/objects-inl.h" |
10 #include "src/parsing/parse-info.h" | 10 #include "src/parsing/parse-info.h" |
11 #include "src/parsing/parser.h" | 11 #include "src/parsing/parser.h" |
12 | 12 |
13 namespace v8 { | 13 namespace v8 { |
14 namespace internal { | 14 namespace internal { |
15 | 15 |
16 class Processor final : public AstVisitor<Processor> { | 16 class Processor final : public AstVisitor<Processor> { |
17 public: | 17 public: |
18 Processor(Isolate* isolate, DeclarationScope* closure_scope, Variable* result, | 18 Processor(uintptr_t stack_limit, DeclarationScope* closure_scope, |
19 AstValueFactory* ast_value_factory) | 19 Variable* result, AstValueFactory* ast_value_factory) |
20 : result_(result), | 20 : result_(result), |
21 result_assigned_(false), | 21 result_assigned_(false), |
22 replacement_(nullptr), | 22 replacement_(nullptr), |
23 is_set_(false), | 23 is_set_(false), |
24 breakable_(false), | 24 breakable_(false), |
25 zone_(ast_value_factory->zone()), | 25 zone_(ast_value_factory->zone()), |
26 closure_scope_(closure_scope), | 26 closure_scope_(closure_scope), |
27 factory_(ast_value_factory) { | 27 factory_(ast_value_factory) { |
28 DCHECK_EQ(closure_scope, closure_scope->GetClosureScope()); | 28 DCHECK_EQ(closure_scope, closure_scope->GetClosureScope()); |
29 InitializeAstVisitor(isolate); | 29 InitializeAstVisitor(stack_limit); |
30 } | 30 } |
31 | 31 |
32 Processor(Parser* parser, DeclarationScope* closure_scope, Variable* result, | 32 Processor(Parser* parser, DeclarationScope* closure_scope, Variable* result, |
33 AstValueFactory* ast_value_factory) | 33 AstValueFactory* ast_value_factory) |
34 : result_(result), | 34 : result_(result), |
35 result_assigned_(false), | 35 result_assigned_(false), |
36 replacement_(nullptr), | 36 replacement_(nullptr), |
37 is_set_(false), | 37 is_set_(false), |
38 breakable_(false), | 38 breakable_(false), |
39 zone_(ast_value_factory->zone()), | 39 zone_(ast_value_factory->zone()), |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
348 // Declarations are never visited. | 348 // Declarations are never visited. |
349 #define DEF_VISIT(type) \ | 349 #define DEF_VISIT(type) \ |
350 void Processor::Visit##type(type* expr) { UNREACHABLE(); } | 350 void Processor::Visit##type(type* expr) { UNREACHABLE(); } |
351 DECLARATION_NODE_LIST(DEF_VISIT) | 351 DECLARATION_NODE_LIST(DEF_VISIT) |
352 #undef DEF_VISIT | 352 #undef DEF_VISIT |
353 | 353 |
354 | 354 |
355 // Assumes code has been parsed. Mutates the AST, so the AST should not | 355 // Assumes code has been parsed. Mutates the AST, so the AST should not |
356 // continue to be used in the case of failure. | 356 // continue to be used in the case of failure. |
357 bool Rewriter::Rewrite(ParseInfo* info) { | 357 bool Rewriter::Rewrite(ParseInfo* info) { |
358 { | 358 DisallowHeapAllocation no_allocation; |
359 DisallowHeapAllocation no_allocation; | 359 DisallowHandleAllocation no_handles; |
360 DisallowHandleAllocation no_handles; | 360 DisallowHandleDereference no_deref; |
361 DisallowHandleDereference no_deref; | |
362 | |
363 FunctionLiteral* function = info->literal(); | |
364 DCHECK_NOT_NULL(function); | |
365 Scope* scope = function->scope(); | |
366 DCHECK_NOT_NULL(scope); | |
367 if (!scope->is_script_scope() && !scope->is_eval_scope()) return true; | |
368 } | |
369 | 361 |
370 RuntimeCallTimerScope runtimeTimer( | 362 RuntimeCallTimerScope runtimeTimer( |
371 info->isolate(), &RuntimeCallStats::CompileRewriteReturnResult); | 363 info->isolate(), &RuntimeCallStats::CompileRewriteReturnResult); |
| 364 |
372 FunctionLiteral* function = info->literal(); | 365 FunctionLiteral* function = info->literal(); |
373 DCHECK_NOT_NULL(function); | 366 DCHECK_NOT_NULL(function); |
374 Scope* scope = function->scope(); | 367 Scope* scope = function->scope(); |
375 DCHECK_NOT_NULL(scope); | 368 DCHECK_NOT_NULL(scope); |
376 DCHECK(ThreadId::Current().Equals(info->isolate()->thread_id())); | 369 if (!scope->is_script_scope() && !scope->is_eval_scope()) return true; |
377 | 370 |
378 DeclarationScope* closure_scope = scope->GetClosureScope(); | 371 DeclarationScope* closure_scope = scope->GetClosureScope(); |
379 | 372 |
380 ZoneList<Statement*>* body = function->body(); | 373 ZoneList<Statement*>* body = function->body(); |
381 if (!body->is_empty()) { | 374 if (!body->is_empty()) { |
382 Variable* result = closure_scope->NewTemporary( | 375 Variable* result = closure_scope->NewTemporary( |
383 info->ast_value_factory()->dot_result_string()); | 376 info->ast_value_factory()->dot_result_string()); |
384 // The name string must be internalized at this point. | 377 Processor processor(info->isolate()->stack_guard()->real_climit(), |
385 info->ast_value_factory()->Internalize(info->isolate()); | 378 closure_scope, result, info->ast_value_factory()); |
386 DCHECK(!result->name().is_null()); | |
387 Processor processor(info->isolate(), closure_scope, result, | |
388 info->ast_value_factory()); | |
389 processor.Process(body); | 379 processor.Process(body); |
| 380 |
| 381 // TODO(leszeks): Remove this check and releases once internalization is |
| 382 // moved out of parsing/analysis. |
| 383 DCHECK(ThreadId::Current().Equals(info->isolate()->thread_id())); |
| 384 no_deref.Release(); |
| 385 no_handles.Release(); |
| 386 no_allocation.Release(); |
| 387 |
390 // Internalize any values created during rewriting. | 388 // Internalize any values created during rewriting. |
391 info->ast_value_factory()->Internalize(info->isolate()); | 389 info->ast_value_factory()->Internalize(info->isolate()); |
392 if (processor.HasStackOverflow()) return false; | 390 if (processor.HasStackOverflow()) return false; |
393 | 391 |
394 if (processor.result_assigned()) { | 392 if (processor.result_assigned()) { |
395 int pos = kNoSourcePosition; | 393 int pos = kNoSourcePosition; |
396 VariableProxy* result_proxy = | 394 VariableProxy* result_proxy = |
397 processor.factory()->NewVariableProxy(result, pos); | 395 processor.factory()->NewVariableProxy(result, pos); |
398 Statement* result_statement = | 396 Statement* result_statement = |
399 processor.factory()->NewReturnStatement(result_proxy, pos); | 397 processor.factory()->NewReturnStatement(result_proxy, pos); |
(...skipping 30 matching lines...) Expand all Loading... |
430 processor.SetResult(undef), expr->position()); | 428 processor.SetResult(undef), expr->position()); |
431 body->Add(completion, factory->zone()); | 429 body->Add(completion, factory->zone()); |
432 } | 430 } |
433 } | 431 } |
434 return true; | 432 return true; |
435 } | 433 } |
436 | 434 |
437 | 435 |
438 } // namespace internal | 436 } // namespace internal |
439 } // namespace v8 | 437 } // namespace v8 |
OLD | NEW |