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