OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/ast.h" | 5 #include "src/ast.h" |
6 #include "src/messages.h" | 6 #include "src/messages.h" |
7 #include "src/parser.h" | 7 #include "src/parser.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 | 10 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 // If we have a legacy const declaration, in an inner scope, the proxy | 44 // If we have a legacy const declaration, in an inner scope, the proxy |
45 // is always bound to the declared variable (independent of possibly | 45 // is always bound to the declared variable (independent of possibly |
46 // surrounding 'with' statements). | 46 // surrounding 'with' statements). |
47 // For let/const declarations in harmony mode, we can also immediately | 47 // For let/const declarations in harmony mode, we can also immediately |
48 // pre-resolve the proxy because it resides in the same scope as the | 48 // pre-resolve the proxy because it resides in the same scope as the |
49 // declaration. | 49 // declaration. |
50 Parser* parser = descriptor_->parser; | 50 Parser* parser = descriptor_->parser; |
51 const AstRawString* name = pattern->raw_name(); | 51 const AstRawString* name = pattern->raw_name(); |
52 VariableProxy* proxy = parser->NewUnresolved(name, descriptor_->mode); | 52 VariableProxy* proxy = parser->NewUnresolved(name, descriptor_->mode); |
53 Declaration* declaration = factory()->NewVariableDeclaration( | 53 Declaration* declaration = factory()->NewVariableDeclaration( |
54 proxy, descriptor_->mode, descriptor_->scope, descriptor_->pos); | 54 proxy, descriptor_->mode, descriptor_->scope, |
| 55 descriptor_->declaration_pos); |
55 Variable* var = parser->Declare(declaration, descriptor_->mode != VAR, ok_); | 56 Variable* var = parser->Declare(declaration, descriptor_->mode != VAR, ok_); |
56 if (!*ok_) return; | 57 if (!*ok_) return; |
57 DCHECK_NOT_NULL(var); | 58 DCHECK_NOT_NULL(var); |
58 DCHECK(!proxy->is_resolved() || proxy->var() == var); | 59 DCHECK(!proxy->is_resolved() || proxy->var() == var); |
59 var->set_initializer_position(initializer_position_); | 60 var->set_initializer_position(initializer_position_); |
60 | 61 |
61 DCHECK(initializer_position_ != RelocInfo::kNoPosition); | 62 DCHECK(initializer_position_ != RelocInfo::kNoPosition); |
62 | 63 |
63 if (descriptor_->declaration_scope->num_var_or_const() > | 64 if (descriptor_->declaration_scope->num_var_or_const() > |
64 kMaxNumFunctionLocals) { | 65 kMaxNumFunctionLocals) { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 // declaration statement has been executed. This is important in | 120 // declaration statement has been executed. This is important in |
120 // browsers where the global object (window) has lots of | 121 // browsers where the global object (window) has lots of |
121 // properties defined in prototype objects. | 122 // properties defined in prototype objects. |
122 if (initialization_scope->is_script_scope() && | 123 if (initialization_scope->is_script_scope() && |
123 !IsLexicalVariableMode(descriptor_->mode)) { | 124 !IsLexicalVariableMode(descriptor_->mode)) { |
124 // Compute the arguments for the runtime | 125 // Compute the arguments for the runtime |
125 // call.test-parsing/InitializedDeclarationsInStrictForOfError | 126 // call.test-parsing/InitializedDeclarationsInStrictForOfError |
126 ZoneList<Expression*>* arguments = | 127 ZoneList<Expression*>* arguments = |
127 new (zone()) ZoneList<Expression*>(3, zone()); | 128 new (zone()) ZoneList<Expression*>(3, zone()); |
128 // We have at least 1 parameter. | 129 // We have at least 1 parameter. |
129 arguments->Add(factory()->NewStringLiteral(name, descriptor_->pos), zone()); | 130 arguments->Add( |
| 131 factory()->NewStringLiteral(name, descriptor_->declaration_pos), |
| 132 zone()); |
130 CallRuntime* initialize; | 133 CallRuntime* initialize; |
131 | 134 |
132 if (descriptor_->is_const) { | 135 if (descriptor_->is_const) { |
133 arguments->Add(value, zone()); | 136 arguments->Add(value, zone()); |
134 value = NULL; // zap the value to avoid the unnecessary assignment | 137 value = NULL; // zap the value to avoid the unnecessary assignment |
135 | 138 |
136 // Construct the call to Runtime_InitializeConstGlobal | 139 // Construct the call to Runtime_InitializeConstGlobal |
137 // and add it to the initialization statement block. | 140 // and add it to the initialization statement block. |
138 // Note that the function does different things depending on | 141 // Note that the function does different things depending on |
139 // the number of arguments (1 or 2). | 142 // the number of arguments (1 or 2). |
140 initialize = factory()->NewCallRuntime( | 143 initialize = factory()->NewCallRuntime( |
141 ast_value_factory()->initialize_const_global_string(), | 144 ast_value_factory()->initialize_const_global_string(), |
142 Runtime::FunctionForId(Runtime::kInitializeConstGlobal), arguments, | 145 Runtime::FunctionForId(Runtime::kInitializeConstGlobal), arguments, |
143 descriptor_->pos); | 146 descriptor_->initialization_pos); |
144 } else { | 147 } else { |
145 // Add language mode. | 148 // Add language mode. |
146 // We may want to pass singleton to avoid Literal allocations. | 149 // We may want to pass singleton to avoid Literal allocations. |
147 LanguageMode language_mode = initialization_scope->language_mode(); | 150 LanguageMode language_mode = initialization_scope->language_mode(); |
148 arguments->Add( | 151 arguments->Add(factory()->NewNumberLiteral(language_mode, |
149 factory()->NewNumberLiteral(language_mode, descriptor_->pos), zone()); | 152 descriptor_->declaration_pos), |
| 153 zone()); |
150 | 154 |
151 // Be careful not to assign a value to the global variable if | 155 // Be careful not to assign a value to the global variable if |
152 // we're in a with. The initialization value should not | 156 // we're in a with. The initialization value should not |
153 // necessarily be stored in the global object in that case, | 157 // necessarily be stored in the global object in that case, |
154 // which is why we need to generate a separate assignment node. | 158 // which is why we need to generate a separate assignment node. |
155 if (value != NULL && !inside_with()) { | 159 if (value != NULL && !inside_with()) { |
156 arguments->Add(value, zone()); | 160 arguments->Add(value, zone()); |
157 value = NULL; // zap the value to avoid the unnecessary assignment | 161 value = NULL; // zap the value to avoid the unnecessary assignment |
158 // Construct the call to Runtime_InitializeVarGlobal | 162 // Construct the call to Runtime_InitializeVarGlobal |
159 // and add it to the initialization statement block. | 163 // and add it to the initialization statement block. |
160 initialize = factory()->NewCallRuntime( | 164 initialize = factory()->NewCallRuntime( |
161 ast_value_factory()->initialize_var_global_string(), | 165 ast_value_factory()->initialize_var_global_string(), |
162 Runtime::FunctionForId(Runtime::kInitializeVarGlobal), arguments, | 166 Runtime::FunctionForId(Runtime::kInitializeVarGlobal), arguments, |
163 descriptor_->pos); | 167 descriptor_->declaration_pos); |
164 } else { | 168 } else { |
165 initialize = NULL; | 169 initialize = NULL; |
166 } | 170 } |
167 } | 171 } |
168 | 172 |
169 if (initialize != NULL) { | 173 if (initialize != NULL) { |
170 block_->AddStatement( | 174 block_->AddStatement( |
171 factory()->NewExpressionStatement(initialize, RelocInfo::kNoPosition), | 175 factory()->NewExpressionStatement(initialize, RelocInfo::kNoPosition), |
172 zone()); | 176 zone()); |
173 } | 177 } |
174 } else if (value != nullptr && (descriptor_->needs_init || | 178 } else if (value != nullptr && (descriptor_->needs_init || |
175 IsLexicalVariableMode(descriptor_->mode))) { | 179 IsLexicalVariableMode(descriptor_->mode))) { |
176 // Constant initializations always assign to the declared constant which | 180 // Constant initializations always assign to the declared constant which |
177 // is always at the function scope level. This is only relevant for | 181 // is always at the function scope level. This is only relevant for |
178 // dynamically looked-up variables and constants (the | 182 // dynamically looked-up variables and constants (the |
179 // start context for constant lookups is always the function context, | 183 // start context for constant lookups is always the function context, |
180 // while it is the top context for var declared variables). Sigh... | 184 // while it is the top context for var declared variables). Sigh... |
181 // For 'let' and 'const' declared variables in harmony mode the | 185 // For 'let' and 'const' declared variables in harmony mode the |
182 // initialization also always assigns to the declared variable. | 186 // initialization also always assigns to the declared variable. |
183 DCHECK_NOT_NULL(proxy); | 187 DCHECK_NOT_NULL(proxy); |
184 DCHECK_NOT_NULL(proxy->var()); | 188 DCHECK_NOT_NULL(proxy->var()); |
185 DCHECK_NOT_NULL(value); | 189 DCHECK_NOT_NULL(value); |
186 Assignment* assignment = factory()->NewAssignment( | 190 Assignment* assignment = factory()->NewAssignment( |
187 descriptor_->init_op, proxy, value, descriptor_->pos); | 191 descriptor_->init_op, proxy, value, descriptor_->initialization_pos); |
188 block_->AddStatement( | 192 block_->AddStatement( |
189 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition), | 193 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition), |
190 zone()); | 194 zone()); |
191 value = NULL; | 195 value = NULL; |
192 } | 196 } |
193 | 197 |
194 // Add an assignment node to the initialization statement block if we still | 198 // Add an assignment node to the initialization statement block if we still |
195 // have a pending initialization value. | 199 // have a pending initialization value. |
196 if (value != NULL) { | 200 if (value != NULL) { |
197 DCHECK(descriptor_->mode == VAR); | 201 DCHECK(descriptor_->mode == VAR); |
198 // 'var' initializations are simply assignments (with all the consequences | 202 // 'var' initializations are simply assignments (with all the consequences |
199 // if they are inside a 'with' statement - they may change a 'with' object | 203 // if they are inside a 'with' statement - they may change a 'with' object |
200 // property). | 204 // property). |
201 VariableProxy* proxy = initialization_scope->NewUnresolved(factory(), name); | 205 VariableProxy* proxy = initialization_scope->NewUnresolved(factory(), name); |
202 Assignment* assignment = factory()->NewAssignment( | 206 Assignment* assignment = factory()->NewAssignment( |
203 descriptor_->init_op, proxy, value, descriptor_->pos); | 207 descriptor_->init_op, proxy, value, descriptor_->initialization_pos); |
204 block_->AddStatement( | 208 block_->AddStatement( |
205 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition), | 209 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition), |
206 zone()); | 210 zone()); |
207 } | 211 } |
208 } | 212 } |
209 | 213 |
210 | 214 |
211 Variable* Parser::PatternRewriter::CreateTempVar(Expression* value) { | 215 Variable* Parser::PatternRewriter::CreateTempVar(Expression* value) { |
212 auto temp_scope = descriptor_->parser->scope_->DeclarationScope(); | 216 auto temp_scope = descriptor_->parser->scope_->DeclarationScope(); |
213 auto temp = temp_scope->NewTemporary(ast_value_factory()->empty_string()); | 217 auto temp = temp_scope->NewTemporary(ast_value_factory()->empty_string()); |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 NOT_A_PATTERN(TryFinallyStatement) | 412 NOT_A_PATTERN(TryFinallyStatement) |
409 NOT_A_PATTERN(UnaryOperation) | 413 NOT_A_PATTERN(UnaryOperation) |
410 NOT_A_PATTERN(VariableDeclaration) | 414 NOT_A_PATTERN(VariableDeclaration) |
411 NOT_A_PATTERN(WhileStatement) | 415 NOT_A_PATTERN(WhileStatement) |
412 NOT_A_PATTERN(WithStatement) | 416 NOT_A_PATTERN(WithStatement) |
413 NOT_A_PATTERN(Yield) | 417 NOT_A_PATTERN(Yield) |
414 | 418 |
415 #undef NOT_A_PATTERN | 419 #undef NOT_A_PATTERN |
416 } | 420 } |
417 } // namespace v8::internal | 421 } // namespace v8::internal |
OLD | NEW |