OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/api-natives.h" | 5 #include "src/api-natives.h" |
6 | 6 |
7 #include "src/api.h" | 7 #include "src/api.h" |
8 #include "src/isolate-inl.h" | 8 #include "src/isolate-inl.h" |
9 #include "src/lookup.h" | 9 #include "src/lookup.h" |
10 #include "src/messages.h" | 10 #include "src/messages.h" |
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
388 // TODO(dcarney): is this necessary? | 388 // TODO(dcarney): is this necessary? |
389 JSObject::MigrateSlowToFast(result, 0, "ApiNatives::InstantiateObject"); | 389 JSObject::MigrateSlowToFast(result, 0, "ApiNatives::InstantiateObject"); |
390 | 390 |
391 if (serial_number) { | 391 if (serial_number) { |
392 CacheTemplateInstantiation(isolate, serial_number, result); | 392 CacheTemplateInstantiation(isolate, serial_number, result); |
393 result = isolate->factory()->CopyJSObject(result); | 393 result = isolate->factory()->CopyJSObject(result); |
394 } | 394 } |
395 return result; | 395 return result; |
396 } | 396 } |
397 | 397 |
| 398 namespace { |
| 399 MaybeHandle<Object> GetInstancePrototype(Isolate* isolate, |
| 400 Object* function_template) { |
| 401 // Enter a new scope. Recursion could otherwise create a lot of handles. |
| 402 HandleScope scope(isolate); |
| 403 Handle<JSFunction> parent_instance; |
| 404 ASSIGN_RETURN_ON_EXCEPTION( |
| 405 isolate, parent_instance, |
| 406 InstantiateFunction( |
| 407 isolate, |
| 408 handle(FunctionTemplateInfo::cast(function_template), isolate)), |
| 409 JSFunction); |
| 410 Handle<Object> instance_prototype; |
| 411 // TODO(cbruni): decide what to do here. |
| 412 ASSIGN_RETURN_ON_EXCEPTION( |
| 413 isolate, instance_prototype, |
| 414 JSObject::GetProperty(parent_instance, |
| 415 isolate->factory()->prototype_string()), |
| 416 JSFunction); |
| 417 return scope.CloseAndEscape(instance_prototype); |
| 418 } |
| 419 } // namespace |
398 | 420 |
399 MaybeHandle<JSFunction> InstantiateFunction(Isolate* isolate, | 421 MaybeHandle<JSFunction> InstantiateFunction(Isolate* isolate, |
400 Handle<FunctionTemplateInfo> data, | 422 Handle<FunctionTemplateInfo> data, |
401 Handle<Name> name) { | 423 Handle<Name> name) { |
402 int serial_number = Smi::cast(data->serial_number())->value(); | 424 int serial_number = Smi::cast(data->serial_number())->value(); |
403 if (serial_number) { | 425 if (serial_number) { |
404 Handle<JSObject> result; | 426 Handle<JSObject> result; |
405 if (ProbeInstantiationsCache(isolate, serial_number).ToHandle(&result)) { | 427 if (ProbeInstantiationsCache(isolate, serial_number).ToHandle(&result)) { |
406 return Handle<JSFunction>::cast(result); | 428 return Handle<JSFunction>::cast(result); |
407 } | 429 } |
408 } | 430 } |
409 Handle<JSObject> prototype; | 431 Handle<Object> prototype; |
410 if (!data->remove_prototype()) { | 432 if (!data->remove_prototype()) { |
411 Object* prototype_templ = data->prototype_template(); | 433 Object* prototype_templ = data->prototype_template(); |
412 if (prototype_templ->IsUndefined(isolate)) { | 434 if (prototype_templ->IsUndefined(isolate)) { |
413 prototype = isolate->factory()->NewJSObject(isolate->object_function()); | 435 Object* protoype_provider_templ = data->prototype_provider_template(); |
| 436 if (protoype_provider_templ->IsUndefined(isolate)) { |
| 437 prototype = isolate->factory()->NewJSObject(isolate->object_function()); |
| 438 } else { |
| 439 ASSIGN_RETURN_ON_EXCEPTION( |
| 440 isolate, prototype, |
| 441 GetInstancePrototype(isolate, protoype_provider_templ), JSFunction); |
| 442 } |
414 } else { | 443 } else { |
415 ASSIGN_RETURN_ON_EXCEPTION( | 444 ASSIGN_RETURN_ON_EXCEPTION( |
416 isolate, prototype, | 445 isolate, prototype, |
417 InstantiateObject( | 446 InstantiateObject( |
418 isolate, | 447 isolate, |
419 handle(ObjectTemplateInfo::cast(prototype_templ), isolate), | 448 handle(ObjectTemplateInfo::cast(prototype_templ), isolate), |
420 Handle<JSReceiver>(), data->hidden_prototype()), | 449 Handle<JSReceiver>(), data->hidden_prototype()), |
421 JSFunction); | 450 JSFunction); |
422 } | 451 } |
423 Object* parent = data->parent_template(); | 452 Object* parent = data->parent_template(); |
424 if (!parent->IsUndefined(isolate)) { | 453 if (!parent->IsUndefined(isolate)) { |
425 // Enter a new scope. Recursion could otherwise create a lot of handles. | |
426 HandleScope scope(isolate); | |
427 Handle<JSFunction> parent_instance; | |
428 ASSIGN_RETURN_ON_EXCEPTION( | |
429 isolate, parent_instance, | |
430 InstantiateFunction( | |
431 isolate, handle(FunctionTemplateInfo::cast(parent), isolate)), | |
432 JSFunction); | |
433 // TODO(dcarney): decide what to do here. | |
434 Handle<Object> parent_prototype; | 454 Handle<Object> parent_prototype; |
435 ASSIGN_RETURN_ON_EXCEPTION( | 455 ASSIGN_RETURN_ON_EXCEPTION(isolate, parent_prototype, |
436 isolate, parent_prototype, | 456 GetInstancePrototype(isolate, parent), |
437 JSObject::GetProperty(parent_instance, | 457 JSFunction); |
438 isolate->factory()->prototype_string()), | 458 JSObject::ForceSetPrototype(Handle<JSObject>::cast(prototype), |
439 JSFunction); | 459 parent_prototype); |
440 JSObject::ForceSetPrototype(prototype, parent_prototype); | |
441 } | 460 } |
442 } | 461 } |
443 Handle<JSFunction> function = ApiNatives::CreateApiFunction( | 462 Handle<JSFunction> function = ApiNatives::CreateApiFunction( |
444 isolate, data, prototype, ApiNatives::JavaScriptObjectType); | 463 isolate, data, prototype, ApiNatives::JavaScriptObjectType); |
445 if (!name.is_null() && name->IsString()) { | 464 if (!name.is_null() && name->IsString()) { |
446 function->shared()->set_name(*name); | 465 function->shared()->set_name(*name); |
447 } | 466 } |
448 if (serial_number) { | 467 if (serial_number) { |
449 // Cache the function. | 468 // Cache the function. |
450 CacheTemplateInstantiation(isolate, serial_number, function); | 469 CacheTemplateInstantiation(isolate, serial_number, function); |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
599 | 618 |
600 // Down from here is only valid for API functions that can be used as a | 619 // Down from here is only valid for API functions that can be used as a |
601 // constructor (don't set the "remove prototype" flag). | 620 // constructor (don't set the "remove prototype" flag). |
602 | 621 |
603 if (obj->read_only_prototype()) { | 622 if (obj->read_only_prototype()) { |
604 result->set_map(*isolate->sloppy_function_with_readonly_prototype_map()); | 623 result->set_map(*isolate->sloppy_function_with_readonly_prototype_map()); |
605 } | 624 } |
606 | 625 |
607 if (prototype->IsTheHole(isolate)) { | 626 if (prototype->IsTheHole(isolate)) { |
608 prototype = isolate->factory()->NewFunctionPrototype(result); | 627 prototype = isolate->factory()->NewFunctionPrototype(result); |
609 } else { | 628 } else if (obj->prototype_provider_template()->IsUndefined(isolate)) { |
610 JSObject::AddProperty(Handle<JSObject>::cast(prototype), | 629 JSObject::AddProperty(Handle<JSObject>::cast(prototype), |
611 isolate->factory()->constructor_string(), result, | 630 isolate->factory()->constructor_string(), result, |
612 DONT_ENUM); | 631 DONT_ENUM); |
613 } | 632 } |
614 | 633 |
615 int internal_field_count = 0; | 634 int internal_field_count = 0; |
616 bool immutable_proto = false; | 635 bool immutable_proto = false; |
617 if (!obj->instance_template()->IsUndefined(isolate)) { | 636 if (!obj->instance_template()->IsUndefined(isolate)) { |
618 Handle<ObjectTemplateInfo> instance_template = Handle<ObjectTemplateInfo>( | 637 Handle<ObjectTemplateInfo> instance_template = Handle<ObjectTemplateInfo>( |
619 ObjectTemplateInfo::cast(obj->instance_template())); | 638 ObjectTemplateInfo::cast(obj->instance_template())); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
678 map->set_is_constructor(true); | 697 map->set_is_constructor(true); |
679 } | 698 } |
680 | 699 |
681 if (immutable_proto) map->set_immutable_proto(true); | 700 if (immutable_proto) map->set_immutable_proto(true); |
682 | 701 |
683 return result; | 702 return result; |
684 } | 703 } |
685 | 704 |
686 } // namespace internal | 705 } // namespace internal |
687 } // namespace v8 | 706 } // namespace v8 |
OLD | NEW |