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 |