| 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/ast/scopeinfo.h" | 9 #include "src/ast/scopeinfo.h" |
| 10 #include "src/ast/scopes.h" | 10 #include "src/ast/scopes.h" |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 181 attr = static_cast<PropertyAttributes>(old_attributes | READ_ONLY); | 181 attr = static_cast<PropertyAttributes>(old_attributes | READ_ONLY); |
| 182 } | 182 } |
| 183 } | 183 } |
| 184 | 184 |
| 185 RETURN_FAILURE_ON_EXCEPTION( | 185 RETURN_FAILURE_ON_EXCEPTION( |
| 186 isolate, JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, attr)); | 186 isolate, JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, attr)); |
| 187 | 187 |
| 188 return *value; | 188 return *value; |
| 189 } | 189 } |
| 190 | 190 |
| 191 RUNTIME_FUNCTION(Runtime_DeclareLookupSlot) { |
| 192 HandleScope scope(isolate); |
| 193 DCHECK_EQ(2, args.length()); |
| 194 CONVERT_ARG_HANDLE_CHECKED(String, name, 0); |
| 195 CONVERT_ARG_HANDLE_CHECKED(Object, initial_value, 1); |
| 191 | 196 |
| 192 namespace { | |
| 193 | |
| 194 Object* DeclareLookupSlot(Isolate* isolate, Handle<String> name, | |
| 195 Handle<Object> initial_value, | |
| 196 PropertyAttributes attr) { | |
| 197 // Declarations are always made in a function, eval or script context, or | 197 // Declarations are always made in a function, eval or script context, or |
| 198 // a declaration block scope. | 198 // a declaration block scope. |
| 199 // In the case of eval code, the context passed is the context of the caller, | 199 // In the case of eval code, the context passed is the context of the caller, |
| 200 // which may be some nested context and not the declaration context. | 200 // which may be some nested context and not the declaration context. |
| 201 Handle<Context> context_arg(isolate->context(), isolate); | 201 Handle<Context> context_arg(isolate->context(), isolate); |
| 202 Handle<Context> context(context_arg->declaration_context(), isolate); | 202 Handle<Context> context(context_arg->declaration_context(), isolate); |
| 203 | 203 |
| 204 DCHECK(context->IsFunctionContext() || context->IsNativeContext() || |
| 205 context->IsScriptContext() || |
| 206 (context->IsBlockContext() && context->has_extension())); |
| 207 |
| 204 // TODO(verwaest): Unify the encoding indicating "var" with DeclareGlobals. | 208 // TODO(verwaest): Unify the encoding indicating "var" with DeclareGlobals. |
| 205 bool is_var = *initial_value == NULL; | 209 bool is_var = *initial_value == NULL; |
| 206 bool is_function = initial_value->IsJSFunction(); | 210 bool is_function = initial_value->IsJSFunction(); |
| 207 DCHECK_EQ(1, BoolToInt(is_var) + BoolToInt(is_function)); | 211 DCHECK_EQ(1, BoolToInt(is_var) + BoolToInt(is_function)); |
| 208 | 212 |
| 209 int index; | 213 int index; |
| 210 PropertyAttributes attributes; | 214 PropertyAttributes attributes; |
| 211 BindingFlags binding_flags; | 215 BindingFlags binding_flags; |
| 212 | 216 |
| 213 if ((attr & EVAL_DECLARED) != 0) { | 217 // Check for a conflict with a lexically scoped variable |
| 214 // Check for a conflict with a lexically scoped variable | 218 context_arg->Lookup(name, LEXICAL_TEST, &index, &attributes, &binding_flags); |
| 215 context_arg->Lookup(name, LEXICAL_TEST, &index, &attributes, | 219 if (attributes != ABSENT && binding_flags == BINDING_CHECK_INITIALIZED) { |
| 216 &binding_flags); | 220 return ThrowRedeclarationError(isolate, name); |
| 217 if (attributes != ABSENT && binding_flags == BINDING_CHECK_INITIALIZED) { | |
| 218 return ThrowRedeclarationError(isolate, name); | |
| 219 } | |
| 220 attr = static_cast<PropertyAttributes>(attr & ~EVAL_DECLARED); | |
| 221 } | 221 } |
| 222 | 222 |
| 223 Handle<Object> holder = context->Lookup(name, DONT_FOLLOW_CHAINS, &index, | 223 Handle<Object> holder = context->Lookup(name, DONT_FOLLOW_CHAINS, &index, |
| 224 &attributes, &binding_flags); | 224 &attributes, &binding_flags); |
| 225 if (holder.is_null()) { | 225 DCHECK(!isolate->has_pending_exception()); |
| 226 // In case of JSProxy, an exception might have been thrown. | |
| 227 if (isolate->has_pending_exception()) return isolate->heap()->exception(); | |
| 228 } | |
| 229 | 226 |
| 230 Handle<JSObject> object; | 227 Handle<JSObject> object; |
| 231 Handle<Object> value = | 228 Handle<Object> value = |
| 232 is_function ? initial_value | 229 is_function ? initial_value |
| 233 : Handle<Object>::cast(isolate->factory()->undefined_value()); | 230 : Handle<Object>::cast(isolate->factory()->undefined_value()); |
| 234 | 231 |
| 235 // TODO(verwaest): This case should probably not be covered by this function, | |
| 236 // but by DeclareGlobals instead. | |
| 237 if (attributes != ABSENT && holder->IsJSGlobalObject()) { | 232 if (attributes != ABSENT && holder->IsJSGlobalObject()) { |
| 238 return DeclareGlobals(isolate, Handle<JSGlobalObject>::cast(holder), name, | 233 return DeclareGlobals(isolate, Handle<JSGlobalObject>::cast(holder), name, |
| 239 value, attr, is_var, is_function); | 234 value, NONE, is_var, is_function); |
| 240 } | 235 } |
| 241 if (context_arg->extension()->IsJSGlobalObject()) { | 236 if (context_arg->extension()->IsJSGlobalObject()) { |
| 242 Handle<JSGlobalObject> global( | 237 Handle<JSGlobalObject> global( |
| 243 JSGlobalObject::cast(context_arg->extension()), isolate); | 238 JSGlobalObject::cast(context_arg->extension()), isolate); |
| 244 return DeclareGlobals(isolate, global, name, value, attr, is_var, | 239 return DeclareGlobals(isolate, global, name, value, NONE, is_var, |
| 245 is_function); | 240 is_function); |
| 246 } else if (context->IsScriptContext()) { | 241 } else if (context->IsScriptContext()) { |
| 247 DCHECK(context->global_object()->IsJSGlobalObject()); | 242 DCHECK(context->global_object()->IsJSGlobalObject()); |
| 248 Handle<JSGlobalObject> global( | 243 Handle<JSGlobalObject> global( |
| 249 JSGlobalObject::cast(context->global_object()), isolate); | 244 JSGlobalObject::cast(context->global_object()), isolate); |
| 250 return DeclareGlobals(isolate, global, name, value, attr, is_var, | 245 return DeclareGlobals(isolate, global, name, value, NONE, is_var, |
| 251 is_function); | 246 is_function); |
| 252 } | 247 } |
| 253 | 248 |
| 254 if (attributes != ABSENT) { | 249 if (attributes != ABSENT) { |
| 255 // The name was declared before; check for conflicting re-declarations. | 250 DCHECK_EQ(NONE, attributes); |
| 256 if ((attributes & READ_ONLY) != 0) { | |
| 257 return ThrowRedeclarationError(isolate, name); | |
| 258 } | |
| 259 | 251 |
| 260 // Skip var re-declarations. | 252 // Skip var re-declarations. |
| 261 if (is_var) return isolate->heap()->undefined_value(); | 253 if (is_var) return isolate->heap()->undefined_value(); |
| 262 | 254 |
| 263 DCHECK(is_function); | 255 DCHECK(is_function); |
| 264 if (index != Context::kNotFound) { | 256 if (index != Context::kNotFound) { |
| 265 DCHECK(holder.is_identical_to(context)); | 257 DCHECK(holder.is_identical_to(context)); |
| 266 context->set(index, *initial_value); | 258 context->set(index, *initial_value); |
| 267 return isolate->heap()->undefined_value(); | 259 return isolate->heap()->undefined_value(); |
| 268 } | 260 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 285 } | 277 } |
| 286 DCHECK(object->IsJSContextExtensionObject() || object->IsJSGlobalObject()); | 278 DCHECK(object->IsJSContextExtensionObject() || object->IsJSGlobalObject()); |
| 287 } else { | 279 } else { |
| 288 DCHECK(context->IsFunctionContext()); | 280 DCHECK(context->IsFunctionContext()); |
| 289 object = | 281 object = |
| 290 isolate->factory()->NewJSObject(isolate->context_extension_function()); | 282 isolate->factory()->NewJSObject(isolate->context_extension_function()); |
| 291 context->set_extension(*object); | 283 context->set_extension(*object); |
| 292 } | 284 } |
| 293 | 285 |
| 294 RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes( | 286 RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes( |
| 295 object, name, value, attr)); | 287 object, name, value, NONE)); |
| 296 | 288 |
| 297 return isolate->heap()->undefined_value(); | 289 return isolate->heap()->undefined_value(); |
| 298 } | 290 } |
| 299 | 291 |
| 300 } // namespace | |
| 301 | |
| 302 | |
| 303 RUNTIME_FUNCTION(Runtime_DeclareLookupSlot) { | |
| 304 HandleScope scope(isolate); | |
| 305 DCHECK_EQ(3, args.length()); | |
| 306 CONVERT_ARG_HANDLE_CHECKED(String, name, 0); | |
| 307 CONVERT_ARG_HANDLE_CHECKED(Object, initial_value, 1); | |
| 308 CONVERT_ARG_HANDLE_CHECKED(Smi, property_attributes, 2); | |
| 309 | |
| 310 PropertyAttributes attributes = | |
| 311 static_cast<PropertyAttributes>(property_attributes->value()); | |
| 312 return DeclareLookupSlot(isolate, name, initial_value, attributes); | |
| 313 } | |
| 314 | |
| 315 | |
| 316 namespace { | 292 namespace { |
| 317 | 293 |
| 318 // Find the arguments of the JavaScript function invocation that called | 294 // Find the arguments of the JavaScript function invocation that called |
| 319 // into C++ code. Collect these in a newly allocated array of handles. | 295 // into C++ code. Collect these in a newly allocated array of handles. |
| 320 base::SmartArrayPointer<Handle<Object>> GetCallerArguments(Isolate* isolate, | 296 base::SmartArrayPointer<Handle<Object>> GetCallerArguments(Isolate* isolate, |
| 321 int* total_argc) { | 297 int* total_argc) { |
| 322 // Find frame containing arguments passed to the caller. | 298 // Find frame containing arguments passed to the caller. |
| 323 JavaScriptFrameIterator it(isolate); | 299 JavaScriptFrameIterator it(isolate); |
| 324 JavaScriptFrame* frame = it.frame(); | 300 JavaScriptFrame* frame = it.frame(); |
| 325 List<JSFunction*> functions(2); | 301 List<JSFunction*> functions(2); |
| (...skipping 676 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1002 RUNTIME_FUNCTION(Runtime_StoreLookupSlot_Strict) { | 978 RUNTIME_FUNCTION(Runtime_StoreLookupSlot_Strict) { |
| 1003 HandleScope scope(isolate); | 979 HandleScope scope(isolate); |
| 1004 DCHECK_EQ(2, args.length()); | 980 DCHECK_EQ(2, args.length()); |
| 1005 CONVERT_ARG_HANDLE_CHECKED(String, name, 0); | 981 CONVERT_ARG_HANDLE_CHECKED(String, name, 0); |
| 1006 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); | 982 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); |
| 1007 RETURN_RESULT_OR_FAILURE(isolate, StoreLookupSlot(name, value, STRICT)); | 983 RETURN_RESULT_OR_FAILURE(isolate, StoreLookupSlot(name, value, STRICT)); |
| 1008 } | 984 } |
| 1009 | 985 |
| 1010 } // namespace internal | 986 } // namespace internal |
| 1011 } // namespace v8 | 987 } // namespace v8 |
| OLD | NEW |