OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/arguments.h" | 8 #include "src/arguments.h" |
9 #include "src/frames-inl.h" | 9 #include "src/frames-inl.h" |
10 #include "src/messages.h" | 10 #include "src/messages.h" |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 | 200 |
201 return *value; | 201 return *value; |
202 } | 202 } |
203 | 203 |
204 | 204 |
205 namespace { | 205 namespace { |
206 | 206 |
207 Object* DeclareLookupSlot(Isolate* isolate, Handle<String> name, | 207 Object* DeclareLookupSlot(Isolate* isolate, Handle<String> name, |
208 Handle<Object> initial_value, | 208 Handle<Object> initial_value, |
209 PropertyAttributes attr) { | 209 PropertyAttributes attr) { |
210 // Declarations are always made in a function, eval or script context. In | 210 // Declarations are always made in a function, eval or script context, or |
211 // the case of eval code, the context passed is the context of the caller, | 211 // a declaration block scope. |
| 212 // In the case of eval code, the context passed is the context of the caller, |
212 // which may be some nested context and not the declaration context. | 213 // which may be some nested context and not the declaration context. |
213 Handle<Context> context_arg(isolate->context(), isolate); | 214 Handle<Context> context_arg(isolate->context(), isolate); |
214 Handle<Context> context(context_arg->declaration_context(), isolate); | 215 Handle<Context> context(context_arg->declaration_context(), isolate); |
215 | 216 |
216 // TODO(verwaest): Unify the encoding indicating "var" with DeclareGlobals. | 217 // TODO(verwaest): Unify the encoding indicating "var" with DeclareGlobals. |
217 bool is_var = *initial_value == NULL; | 218 bool is_var = *initial_value == NULL; |
218 bool is_const = initial_value->IsTheHole(); | 219 bool is_const = initial_value->IsTheHole(); |
219 bool is_function = initial_value->IsJSFunction(); | 220 bool is_function = initial_value->IsJSFunction(); |
220 DCHECK_EQ(1, | 221 DCHECK_EQ(1, |
221 BoolToInt(is_var) + BoolToInt(is_const) + BoolToInt(is_function)); | 222 BoolToInt(is_var) + BoolToInt(is_const) + BoolToInt(is_function)); |
(...skipping 13 matching lines...) Expand all Loading... |
235 Handle<Object> value = | 236 Handle<Object> value = |
236 is_function ? initial_value | 237 is_function ? initial_value |
237 : Handle<Object>::cast(isolate->factory()->undefined_value()); | 238 : Handle<Object>::cast(isolate->factory()->undefined_value()); |
238 | 239 |
239 // TODO(verwaest): This case should probably not be covered by this function, | 240 // TODO(verwaest): This case should probably not be covered by this function, |
240 // but by DeclareGlobals instead. | 241 // but by DeclareGlobals instead. |
241 if (attributes != ABSENT && holder->IsJSGlobalObject()) { | 242 if (attributes != ABSENT && holder->IsJSGlobalObject()) { |
242 return DeclareGlobals(isolate, Handle<JSGlobalObject>::cast(holder), name, | 243 return DeclareGlobals(isolate, Handle<JSGlobalObject>::cast(holder), name, |
243 value, attr, is_var, is_const, is_function); | 244 value, attr, is_var, is_const, is_function); |
244 } | 245 } |
245 if (context_arg->has_extension() && | 246 if (context_arg->extension()->IsJSGlobalObject()) { |
246 context_arg->extension()->IsJSGlobalObject()) { | |
247 Handle<JSGlobalObject> global( | 247 Handle<JSGlobalObject> global( |
248 JSGlobalObject::cast(context_arg->extension()), isolate); | 248 JSGlobalObject::cast(context_arg->extension()), isolate); |
249 return DeclareGlobals(isolate, global, name, value, attr, is_var, is_const, | 249 return DeclareGlobals(isolate, global, name, value, attr, is_var, is_const, |
250 is_function); | 250 is_function); |
251 } else if (context->IsScriptContext()) { | 251 } else if (context->IsScriptContext()) { |
252 DCHECK(context->global_object()->IsJSGlobalObject()); | 252 DCHECK(context->global_object()->IsJSGlobalObject()); |
253 Handle<JSGlobalObject> global( | 253 Handle<JSGlobalObject> global( |
254 JSGlobalObject::cast(context->global_object()), isolate); | 254 JSGlobalObject::cast(context->global_object()), isolate); |
255 return DeclareGlobals(isolate, global, name, value, attr, is_var, is_const, | 255 return DeclareGlobals(isolate, global, name, value, attr, is_var, is_const, |
256 is_function); | 256 is_function); |
(...skipping 11 matching lines...) Expand all Loading... |
268 DCHECK(is_function); | 268 DCHECK(is_function); |
269 if (index >= 0) { | 269 if (index >= 0) { |
270 DCHECK(holder.is_identical_to(context)); | 270 DCHECK(holder.is_identical_to(context)); |
271 context->set(index, *initial_value); | 271 context->set(index, *initial_value); |
272 return isolate->heap()->undefined_value(); | 272 return isolate->heap()->undefined_value(); |
273 } | 273 } |
274 | 274 |
275 object = Handle<JSObject>::cast(holder); | 275 object = Handle<JSObject>::cast(holder); |
276 | 276 |
277 } else if (context->has_extension()) { | 277 } else if (context->has_extension()) { |
278 object = handle(JSObject::cast(context->extension())); | 278 // Sloppy varblock contexts might not have an extension object yet, |
| 279 // in which case their extension is a ScopeInfo. |
| 280 if (context->extension()->IsScopeInfo()) { |
| 281 DCHECK(context->IsBlockContext()); |
| 282 object = isolate->factory()->NewJSObject( |
| 283 isolate->context_extension_function()); |
| 284 Handle<Object> extension = |
| 285 isolate->factory()->NewSloppyBlockWithEvalContextExtension( |
| 286 handle(context->scope_info()), object); |
| 287 context->set_extension(*extension); |
| 288 } else { |
| 289 object = handle(context->extension_object(), isolate); |
| 290 } |
279 DCHECK(object->IsJSContextExtensionObject() || object->IsJSGlobalObject()); | 291 DCHECK(object->IsJSContextExtensionObject() || object->IsJSGlobalObject()); |
280 } else { | 292 } else { |
281 DCHECK(context->IsFunctionContext()); | 293 DCHECK(context->IsFunctionContext()); |
282 object = | 294 object = |
283 isolate->factory()->NewJSObject(isolate->context_extension_function()); | 295 isolate->factory()->NewJSObject(isolate->context_extension_function()); |
284 context->set_extension(*object); | 296 context->set_extension(*object); |
285 } | 297 } |
286 | 298 |
287 RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes( | 299 RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes( |
288 object, name, value, attr)); | 300 object, name, value, attr)); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
351 // Strict mode handling not needed (legacy const is disallowed in strict | 363 // Strict mode handling not needed (legacy const is disallowed in strict |
352 // mode). | 364 // mode). |
353 | 365 |
354 // The declared const was configurable, and may have been deleted in the | 366 // The declared const was configurable, and may have been deleted in the |
355 // meanwhile. If so, re-introduce the variable in the context extension. | 367 // meanwhile. If so, re-introduce the variable in the context extension. |
356 if (attributes == ABSENT) { | 368 if (attributes == ABSENT) { |
357 Handle<Context> declaration_context(context_arg->declaration_context()); | 369 Handle<Context> declaration_context(context_arg->declaration_context()); |
358 if (declaration_context->IsScriptContext()) { | 370 if (declaration_context->IsScriptContext()) { |
359 holder = handle(declaration_context->global_object(), isolate); | 371 holder = handle(declaration_context->global_object(), isolate); |
360 } else { | 372 } else { |
361 DCHECK(declaration_context->has_extension()); | 373 holder = handle(declaration_context->extension_object(), isolate); |
362 holder = handle(declaration_context->extension(), isolate); | 374 DCHECK(!holder.is_null()); |
363 } | 375 } |
364 CHECK(holder->IsJSObject()); | 376 CHECK(holder->IsJSObject()); |
365 } else { | 377 } else { |
366 // For JSContextExtensionObjects, the initializer can be run multiple times | 378 // For JSContextExtensionObjects, the initializer can be run multiple times |
367 // if in a for loop: for (var i = 0; i < 2; i++) { const x = i; }. Only the | 379 // if in a for loop: for (var i = 0; i < 2; i++) { const x = i; }. Only the |
368 // first assignment should go through. For JSGlobalObjects, additionally any | 380 // first assignment should go through. For JSGlobalObjects, additionally any |
369 // code can run in between that modifies the declared property. | 381 // code can run in between that modifies the declared property. |
370 DCHECK(holder->IsJSGlobalObject() || holder->IsJSContextExtensionObject()); | 382 DCHECK(holder->IsJSGlobalObject() || holder->IsJSContextExtensionObject()); |
371 | 383 |
372 LookupIterator it(holder, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR); | 384 LookupIterator it(holder, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR); |
(...skipping 788 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1161 | 1173 |
1162 // Lookup in the initial Object.prototype object. | 1174 // Lookup in the initial Object.prototype object. |
1163 Handle<Object> result; | 1175 Handle<Object> result; |
1164 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 1176 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
1165 isolate, result, | 1177 isolate, result, |
1166 Object::GetProperty(isolate->initial_object_prototype(), key)); | 1178 Object::GetProperty(isolate->initial_object_prototype(), key)); |
1167 return *result; | 1179 return *result; |
1168 } | 1180 } |
1169 } // namespace internal | 1181 } // namespace internal |
1170 } // namespace v8 | 1182 } // namespace v8 |
OLD | NEW |