| 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 <stdlib.h> | 7 #include <stdlib.h> |
| 8 #include <limits> | 8 #include <limits> |
| 9 | 9 |
| 10 #include "src/arguments.h" | 10 #include "src/arguments.h" |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 180 CONVERT_ARG_HANDLE_CHECKED(Object, super_class, 0); | 180 CONVERT_ARG_HANDLE_CHECKED(Object, super_class, 0); |
| 181 CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 1); | 181 CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 1); |
| 182 CONVERT_SMI_ARG_CHECKED(start_position, 2); | 182 CONVERT_SMI_ARG_CHECKED(start_position, 2); |
| 183 CONVERT_SMI_ARG_CHECKED(end_position, 3); | 183 CONVERT_SMI_ARG_CHECKED(end_position, 3); |
| 184 | 184 |
| 185 RETURN_RESULT_OR_FAILURE( | 185 RETURN_RESULT_OR_FAILURE( |
| 186 isolate, DefineClass(isolate, super_class, constructor, start_position, | 186 isolate, DefineClass(isolate, super_class, constructor, start_position, |
| 187 end_position)); | 187 end_position)); |
| 188 } | 188 } |
| 189 | 189 |
| 190 namespace { |
| 190 | 191 |
| 191 static MaybeHandle<Object> LoadFromSuper(Isolate* isolate, | 192 enum class SuperMode { kLoad, kStore }; |
| 192 Handle<Object> receiver, | 193 |
| 193 Handle<JSObject> home_object, | 194 MaybeHandle<JSReceiver> GetSuperHolder( |
| 194 Handle<Name> name) { | 195 Isolate* isolate, Handle<Object> receiver, Handle<JSObject> home_object, |
| 196 SuperMode mode, MaybeHandle<Name> maybe_name, uint32_t index) { |
| 195 if (home_object->IsAccessCheckNeeded() && | 197 if (home_object->IsAccessCheckNeeded() && |
| 196 !isolate->MayAccess(handle(isolate->context()), home_object)) { | 198 !isolate->MayAccess(handle(isolate->context()), home_object)) { |
| 197 isolate->ReportFailedAccessCheck(home_object); | 199 isolate->ReportFailedAccessCheck(home_object); |
| 198 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 200 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, JSReceiver); |
| 199 } | 201 } |
| 200 | 202 |
| 201 PrototypeIterator iter(isolate, home_object); | 203 PrototypeIterator iter(isolate, home_object); |
| 202 Handle<Object> proto = PrototypeIterator::GetCurrent(iter); | 204 Handle<Object> proto = PrototypeIterator::GetCurrent(iter); |
| 203 if (!proto->IsJSReceiver()) { | 205 if (!proto->IsJSReceiver()) { |
| 204 return Object::ReadAbsentProperty(isolate, proto, name); | 206 MessageTemplate::Template message = |
| 207 mode == SuperMode::kLoad ? MessageTemplate::kNonObjectPropertyLoad |
| 208 : MessageTemplate::kNonObjectPropertyStore; |
| 209 Handle<Name> name; |
| 210 if (!maybe_name.ToHandle(&name)) { |
| 211 name = isolate->factory()->Uint32ToString(index); |
| 212 } |
| 213 THROW_NEW_ERROR(isolate, NewTypeError(message, name, proto), JSReceiver); |
| 205 } | 214 } |
| 215 return Handle<JSReceiver>::cast(proto); |
| 216 } |
| 206 | 217 |
| 207 LookupIterator it(receiver, name, Handle<JSReceiver>::cast(proto)); | 218 MaybeHandle<Object> LoadFromSuper(Isolate* isolate, Handle<Object> receiver, |
| 219 Handle<JSObject> home_object, |
| 220 Handle<Name> name) { |
| 221 Handle<JSReceiver> holder; |
| 222 ASSIGN_RETURN_ON_EXCEPTION( |
| 223 isolate, holder, |
| 224 GetSuperHolder(isolate, receiver, home_object, SuperMode::kLoad, name, 0), |
| 225 Object); |
| 226 LookupIterator it(receiver, name, holder); |
| 208 Handle<Object> result; | 227 Handle<Object> result; |
| 209 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, Object::GetProperty(&it), Object); | 228 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, Object::GetProperty(&it), Object); |
| 210 return result; | 229 return result; |
| 211 } | 230 } |
| 212 | 231 |
| 213 static MaybeHandle<Object> LoadElementFromSuper(Isolate* isolate, | 232 MaybeHandle<Object> LoadElementFromSuper(Isolate* isolate, |
| 214 Handle<Object> receiver, | 233 Handle<Object> receiver, |
| 215 Handle<JSObject> home_object, | 234 Handle<JSObject> home_object, |
| 216 uint32_t index) { | 235 uint32_t index) { |
| 217 if (home_object->IsAccessCheckNeeded() && | 236 Handle<JSReceiver> holder; |
| 218 !isolate->MayAccess(handle(isolate->context()), home_object)) { | 237 ASSIGN_RETURN_ON_EXCEPTION( |
| 219 isolate->ReportFailedAccessCheck(home_object); | 238 isolate, holder, |
| 220 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 239 GetSuperHolder(isolate, receiver, home_object, SuperMode::kLoad, |
| 221 } | 240 MaybeHandle<Name>(), index), |
| 222 | 241 Object); |
| 223 PrototypeIterator iter(isolate, home_object); | 242 LookupIterator it(isolate, receiver, index, holder); |
| 224 Handle<Object> proto = PrototypeIterator::GetCurrent(iter); | |
| 225 if (!proto->IsJSReceiver()) { | |
| 226 Handle<Object> name = isolate->factory()->NewNumberFromUint(index); | |
| 227 return Object::ReadAbsentProperty(isolate, proto, name); | |
| 228 } | |
| 229 | |
| 230 LookupIterator it(isolate, receiver, index, Handle<JSReceiver>::cast(proto)); | |
| 231 Handle<Object> result; | 243 Handle<Object> result; |
| 232 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, Object::GetProperty(&it), Object); | 244 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, Object::GetProperty(&it), Object); |
| 233 return result; | 245 return result; |
| 234 } | 246 } |
| 235 | 247 |
| 248 } // anonymous namespace |
| 236 | 249 |
| 237 RUNTIME_FUNCTION(Runtime_LoadFromSuper) { | 250 RUNTIME_FUNCTION(Runtime_LoadFromSuper) { |
| 238 HandleScope scope(isolate); | 251 HandleScope scope(isolate); |
| 239 DCHECK_EQ(3, args.length()); | 252 DCHECK_EQ(3, args.length()); |
| 240 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0); | 253 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0); |
| 241 CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1); | 254 CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1); |
| 242 CONVERT_ARG_HANDLE_CHECKED(Name, name, 2); | 255 CONVERT_ARG_HANDLE_CHECKED(Name, name, 2); |
| 243 | 256 |
| 244 RETURN_RESULT_OR_FAILURE(isolate, | 257 RETURN_RESULT_OR_FAILURE(isolate, |
| 245 LoadFromSuper(isolate, receiver, home_object, name)); | 258 LoadFromSuper(isolate, receiver, home_object, name)); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 265 Object::ToName(isolate, key)); | 278 Object::ToName(isolate, key)); |
| 266 // TODO(verwaest): Unify using LookupIterator. | 279 // TODO(verwaest): Unify using LookupIterator. |
| 267 if (name->AsArrayIndex(&index)) { | 280 if (name->AsArrayIndex(&index)) { |
| 268 RETURN_RESULT_OR_FAILURE( | 281 RETURN_RESULT_OR_FAILURE( |
| 269 isolate, LoadElementFromSuper(isolate, receiver, home_object, index)); | 282 isolate, LoadElementFromSuper(isolate, receiver, home_object, index)); |
| 270 } | 283 } |
| 271 RETURN_RESULT_OR_FAILURE(isolate, | 284 RETURN_RESULT_OR_FAILURE(isolate, |
| 272 LoadFromSuper(isolate, receiver, home_object, name)); | 285 LoadFromSuper(isolate, receiver, home_object, name)); |
| 273 } | 286 } |
| 274 | 287 |
| 288 namespace { |
| 275 | 289 |
| 276 static Object* StoreToSuper(Isolate* isolate, Handle<JSObject> home_object, | 290 MaybeHandle<Object> StoreToSuper(Isolate* isolate, Handle<JSObject> home_object, |
| 277 Handle<Object> receiver, Handle<Name> name, | 291 Handle<Object> receiver, Handle<Name> name, |
| 278 Handle<Object> value, LanguageMode language_mode) { | 292 Handle<Object> value, |
| 279 if (home_object->IsAccessCheckNeeded() && | 293 LanguageMode language_mode) { |
| 280 !isolate->MayAccess(handle(isolate->context()), home_object)) { | 294 Handle<JSReceiver> holder; |
| 281 isolate->ReportFailedAccessCheck(home_object); | 295 ASSIGN_RETURN_ON_EXCEPTION(isolate, holder, |
| 282 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); | 296 GetSuperHolder(isolate, receiver, home_object, |
| 283 } | 297 SuperMode::kStore, name, 0), |
| 284 | 298 Object); |
| 285 PrototypeIterator iter(isolate, home_object); | 299 LookupIterator it(receiver, name, holder); |
| 286 Handle<Object> proto = PrototypeIterator::GetCurrent(iter); | |
| 287 if (!proto->IsJSReceiver()) return isolate->heap()->undefined_value(); | |
| 288 | |
| 289 LookupIterator it(receiver, name, Handle<JSReceiver>::cast(proto)); | |
| 290 MAYBE_RETURN(Object::SetSuperProperty(&it, value, language_mode, | 300 MAYBE_RETURN(Object::SetSuperProperty(&it, value, language_mode, |
| 291 Object::CERTAINLY_NOT_STORE_FROM_KEYED), | 301 Object::CERTAINLY_NOT_STORE_FROM_KEYED), |
| 292 isolate->heap()->exception()); | 302 MaybeHandle<Object>()); |
| 293 return *value; | 303 return value; |
| 294 } | 304 } |
| 295 | 305 |
| 296 | 306 MaybeHandle<Object> StoreElementToSuper(Isolate* isolate, |
| 297 static Object* StoreElementToSuper(Isolate* isolate, | 307 Handle<JSObject> home_object, |
| 298 Handle<JSObject> home_object, | 308 Handle<Object> receiver, uint32_t index, |
| 299 Handle<Object> receiver, uint32_t index, | 309 Handle<Object> value, |
| 300 Handle<Object> value, | 310 LanguageMode language_mode) { |
| 301 LanguageMode language_mode) { | 311 Handle<JSReceiver> holder; |
| 302 if (home_object->IsAccessCheckNeeded() && | 312 ASSIGN_RETURN_ON_EXCEPTION( |
| 303 !isolate->MayAccess(handle(isolate->context()), home_object)) { | 313 isolate, holder, |
| 304 isolate->ReportFailedAccessCheck(home_object); | 314 GetSuperHolder(isolate, receiver, home_object, SuperMode::kStore, |
| 305 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); | 315 MaybeHandle<Name>(), index), |
| 306 } | 316 Object); |
| 307 | 317 LookupIterator it(isolate, receiver, index, holder); |
| 308 PrototypeIterator iter(isolate, home_object); | |
| 309 Handle<Object> proto = PrototypeIterator::GetCurrent(iter); | |
| 310 if (!proto->IsJSReceiver()) return isolate->heap()->undefined_value(); | |
| 311 | |
| 312 LookupIterator it(isolate, receiver, index, Handle<JSReceiver>::cast(proto)); | |
| 313 MAYBE_RETURN(Object::SetSuperProperty(&it, value, language_mode, | 318 MAYBE_RETURN(Object::SetSuperProperty(&it, value, language_mode, |
| 314 Object::MAY_BE_STORE_FROM_KEYED), | 319 Object::MAY_BE_STORE_FROM_KEYED), |
| 315 isolate->heap()->exception()); | 320 MaybeHandle<Object>()); |
| 316 return *value; | 321 return value; |
| 317 } | 322 } |
| 318 | 323 |
| 324 } // anonymous namespace |
| 319 | 325 |
| 320 RUNTIME_FUNCTION(Runtime_StoreToSuper_Strict) { | 326 RUNTIME_FUNCTION(Runtime_StoreToSuper_Strict) { |
| 321 HandleScope scope(isolate); | 327 HandleScope scope(isolate); |
| 322 DCHECK(args.length() == 4); | 328 DCHECK(args.length() == 4); |
| 323 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0); | 329 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0); |
| 324 CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1); | 330 CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1); |
| 325 CONVERT_ARG_HANDLE_CHECKED(Name, name, 2); | 331 CONVERT_ARG_HANDLE_CHECKED(Name, name, 2); |
| 326 CONVERT_ARG_HANDLE_CHECKED(Object, value, 3); | 332 CONVERT_ARG_HANDLE_CHECKED(Object, value, 3); |
| 327 | 333 |
| 328 return StoreToSuper(isolate, home_object, receiver, name, value, STRICT); | 334 RETURN_RESULT_OR_FAILURE(isolate, StoreToSuper(isolate, home_object, receiver, |
| 335 name, value, STRICT)); |
| 329 } | 336 } |
| 330 | 337 |
| 331 | 338 |
| 332 RUNTIME_FUNCTION(Runtime_StoreToSuper_Sloppy) { | 339 RUNTIME_FUNCTION(Runtime_StoreToSuper_Sloppy) { |
| 333 HandleScope scope(isolate); | 340 HandleScope scope(isolate); |
| 334 DCHECK(args.length() == 4); | 341 DCHECK(args.length() == 4); |
| 335 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0); | 342 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0); |
| 336 CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1); | 343 CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1); |
| 337 CONVERT_ARG_HANDLE_CHECKED(Name, name, 2); | 344 CONVERT_ARG_HANDLE_CHECKED(Name, name, 2); |
| 338 CONVERT_ARG_HANDLE_CHECKED(Object, value, 3); | 345 CONVERT_ARG_HANDLE_CHECKED(Object, value, 3); |
| 339 | 346 |
| 340 return StoreToSuper(isolate, home_object, receiver, name, value, SLOPPY); | 347 RETURN_RESULT_OR_FAILURE(isolate, StoreToSuper(isolate, home_object, receiver, |
| 348 name, value, SLOPPY)); |
| 341 } | 349 } |
| 342 | 350 |
| 343 | 351 static MaybeHandle<Object> StoreKeyedToSuper( |
| 344 static Object* StoreKeyedToSuper(Isolate* isolate, Handle<JSObject> home_object, | 352 Isolate* isolate, Handle<JSObject> home_object, Handle<Object> receiver, |
| 345 Handle<Object> receiver, Handle<Object> key, | 353 Handle<Object> key, Handle<Object> value, LanguageMode language_mode) { |
| 346 Handle<Object> value, | |
| 347 LanguageMode language_mode) { | |
| 348 uint32_t index = 0; | 354 uint32_t index = 0; |
| 349 | 355 |
| 350 if (key->ToArrayIndex(&index)) { | 356 if (key->ToArrayIndex(&index)) { |
| 351 return StoreElementToSuper(isolate, home_object, receiver, index, value, | 357 return StoreElementToSuper(isolate, home_object, receiver, index, value, |
| 352 language_mode); | 358 language_mode); |
| 353 } | 359 } |
| 354 Handle<Name> name; | 360 Handle<Name> name; |
| 355 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name, | 361 ASSIGN_RETURN_ON_EXCEPTION(isolate, name, Object::ToName(isolate, key), |
| 356 Object::ToName(isolate, key)); | 362 Object); |
| 357 // TODO(verwaest): Unify using LookupIterator. | 363 // TODO(verwaest): Unify using LookupIterator. |
| 358 if (name->AsArrayIndex(&index)) { | 364 if (name->AsArrayIndex(&index)) { |
| 359 return StoreElementToSuper(isolate, home_object, receiver, index, value, | 365 return StoreElementToSuper(isolate, home_object, receiver, index, value, |
| 360 language_mode); | 366 language_mode); |
| 361 } | 367 } |
| 362 return StoreToSuper(isolate, home_object, receiver, name, value, | 368 return StoreToSuper(isolate, home_object, receiver, name, value, |
| 363 language_mode); | 369 language_mode); |
| 364 } | 370 } |
| 365 | 371 |
| 366 | 372 |
| 367 RUNTIME_FUNCTION(Runtime_StoreKeyedToSuper_Strict) { | 373 RUNTIME_FUNCTION(Runtime_StoreKeyedToSuper_Strict) { |
| 368 HandleScope scope(isolate); | 374 HandleScope scope(isolate); |
| 369 DCHECK(args.length() == 4); | 375 DCHECK(args.length() == 4); |
| 370 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0); | 376 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0); |
| 371 CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1); | 377 CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1); |
| 372 CONVERT_ARG_HANDLE_CHECKED(Object, key, 2); | 378 CONVERT_ARG_HANDLE_CHECKED(Object, key, 2); |
| 373 CONVERT_ARG_HANDLE_CHECKED(Object, value, 3); | 379 CONVERT_ARG_HANDLE_CHECKED(Object, value, 3); |
| 374 | 380 |
| 375 return StoreKeyedToSuper(isolate, home_object, receiver, key, value, STRICT); | 381 RETURN_RESULT_OR_FAILURE( |
| 382 isolate, |
| 383 StoreKeyedToSuper(isolate, home_object, receiver, key, value, STRICT)); |
| 376 } | 384 } |
| 377 | 385 |
| 378 | 386 |
| 379 RUNTIME_FUNCTION(Runtime_StoreKeyedToSuper_Sloppy) { | 387 RUNTIME_FUNCTION(Runtime_StoreKeyedToSuper_Sloppy) { |
| 380 HandleScope scope(isolate); | 388 HandleScope scope(isolate); |
| 381 DCHECK(args.length() == 4); | 389 DCHECK(args.length() == 4); |
| 382 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0); | 390 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0); |
| 383 CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1); | 391 CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1); |
| 384 CONVERT_ARG_HANDLE_CHECKED(Object, key, 2); | 392 CONVERT_ARG_HANDLE_CHECKED(Object, key, 2); |
| 385 CONVERT_ARG_HANDLE_CHECKED(Object, value, 3); | 393 CONVERT_ARG_HANDLE_CHECKED(Object, value, 3); |
| 386 | 394 |
| 387 return StoreKeyedToSuper(isolate, home_object, receiver, key, value, SLOPPY); | 395 RETURN_RESULT_OR_FAILURE( |
| 396 isolate, |
| 397 StoreKeyedToSuper(isolate, home_object, receiver, key, value, SLOPPY)); |
| 388 } | 398 } |
| 389 | 399 |
| 390 | 400 |
| 391 RUNTIME_FUNCTION(Runtime_GetSuperConstructor) { | 401 RUNTIME_FUNCTION(Runtime_GetSuperConstructor) { |
| 392 SealHandleScope shs(isolate); | 402 SealHandleScope shs(isolate); |
| 393 DCHECK_EQ(1, args.length()); | 403 DCHECK_EQ(1, args.length()); |
| 394 CONVERT_ARG_CHECKED(JSFunction, active_function, 0); | 404 CONVERT_ARG_CHECKED(JSFunction, active_function, 0); |
| 395 return active_function->map()->prototype(); | 405 return active_function->map()->prototype(); |
| 396 } | 406 } |
| 397 | 407 |
| 398 } // namespace internal | 408 } // namespace internal |
| 399 } // namespace v8 | 409 } // namespace v8 |
| OLD | NEW |