| 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 519 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 530 info->set_property_accessors(*list); | 530 info->set_property_accessors(*list); |
| 531 } | 531 } |
| 532 NeanderArray array(list); | 532 NeanderArray array(list); |
| 533 array.add(isolate, property); | 533 array.add(isolate, property); |
| 534 } | 534 } |
| 535 | 535 |
| 536 | 536 |
| 537 Handle<JSFunction> ApiNatives::CreateApiFunction( | 537 Handle<JSFunction> ApiNatives::CreateApiFunction( |
| 538 Isolate* isolate, Handle<FunctionTemplateInfo> obj, | 538 Isolate* isolate, Handle<FunctionTemplateInfo> obj, |
| 539 Handle<Object> prototype, ApiInstanceType instance_type) { | 539 Handle<Object> prototype, ApiInstanceType instance_type) { |
| 540 Handle<Code> code; | 540 Handle<SharedFunctionInfo> shared = |
| 541 if (obj->call_code()->IsCallHandlerInfo() && | 541 FunctionTemplateInfo::GetOrCreateSharedFunctionInfo(isolate, obj); |
| 542 CallHandlerInfo::cast(obj->call_code())->fast_handler()->IsCode()) { | 542 Handle<JSFunction> result = |
| 543 code = isolate->builtins()->HandleFastApiCall(); | 543 isolate->factory()->NewFunctionFromSharedFunctionInfo( |
| 544 } else { | 544 shared, isolate->native_context()); |
| 545 code = isolate->builtins()->HandleApiCall(); | |
| 546 } | |
| 547 Handle<Code> construct_stub = | |
| 548 prototype.is_null() ? isolate->builtins()->ConstructedNonConstructable() | |
| 549 : isolate->builtins()->JSConstructStubApi(); | |
| 550 | |
| 551 obj->set_instantiated(true); | |
| 552 Handle<JSFunction> result; | |
| 553 if (obj->remove_prototype()) { | |
| 554 result = isolate->factory()->NewFunctionWithoutPrototype( | |
| 555 isolate->factory()->empty_string(), code); | |
| 556 } else { | |
| 557 int internal_field_count = 0; | |
| 558 if (!obj->instance_template()->IsUndefined(isolate)) { | |
| 559 Handle<ObjectTemplateInfo> instance_template = Handle<ObjectTemplateInfo>( | |
| 560 ObjectTemplateInfo::cast(obj->instance_template())); | |
| 561 internal_field_count = | |
| 562 Smi::cast(instance_template->internal_field_count())->value(); | |
| 563 } | |
| 564 | |
| 565 // TODO(svenpanne) Kill ApiInstanceType and refactor things by generalizing | |
| 566 // JSObject::GetHeaderSize. | |
| 567 int instance_size = kPointerSize * internal_field_count; | |
| 568 InstanceType type; | |
| 569 switch (instance_type) { | |
| 570 case JavaScriptObjectType: | |
| 571 if (!obj->needs_access_check() && | |
| 572 obj->named_property_handler()->IsUndefined(isolate) && | |
| 573 obj->indexed_property_handler()->IsUndefined(isolate)) { | |
| 574 type = JS_API_OBJECT_TYPE; | |
| 575 } else { | |
| 576 type = JS_SPECIAL_API_OBJECT_TYPE; | |
| 577 } | |
| 578 instance_size += JSObject::kHeaderSize; | |
| 579 break; | |
| 580 case GlobalObjectType: | |
| 581 type = JS_GLOBAL_OBJECT_TYPE; | |
| 582 instance_size += JSGlobalObject::kSize; | |
| 583 break; | |
| 584 case GlobalProxyType: | |
| 585 type = JS_GLOBAL_PROXY_TYPE; | |
| 586 instance_size += JSGlobalProxy::kSize; | |
| 587 break; | |
| 588 default: | |
| 589 UNREACHABLE(); | |
| 590 type = JS_OBJECT_TYPE; // Keep the compiler happy. | |
| 591 break; | |
| 592 } | |
| 593 | |
| 594 result = isolate->factory()->NewFunction( | |
| 595 isolate->factory()->empty_string(), code, prototype, type, | |
| 596 instance_size, obj->read_only_prototype(), true); | |
| 597 } | |
| 598 | |
| 599 result->shared()->set_length(obj->length()); | |
| 600 Handle<Object> class_name(obj->class_name(), isolate); | |
| 601 if (class_name->IsString()) { | |
| 602 result->shared()->set_instance_class_name(*class_name); | |
| 603 result->shared()->set_name(*class_name); | |
| 604 } | |
| 605 result->shared()->set_api_func_data(*obj); | |
| 606 result->shared()->set_construct_stub(*construct_stub); | |
| 607 result->shared()->DontAdaptArguments(); | |
| 608 | 545 |
| 609 if (obj->remove_prototype()) { | 546 if (obj->remove_prototype()) { |
| 547 result->set_map(*isolate->sloppy_function_without_prototype_map()); |
| 548 DCHECK(prototype.is_null()); |
| 610 DCHECK(result->shared()->IsApiFunction()); | 549 DCHECK(result->shared()->IsApiFunction()); |
| 611 DCHECK(!result->has_initial_map()); | 550 DCHECK(!result->has_initial_map()); |
| 612 DCHECK(!result->has_prototype()); | 551 DCHECK(!result->has_prototype()); |
| 552 DCHECK(!result->IsConstructor()); |
| 613 return result; | 553 return result; |
| 614 } | 554 } |
| 615 | 555 |
| 616 #ifdef DEBUG | |
| 617 LookupIterator it(handle(JSObject::cast(result->prototype())), | |
| 618 isolate->factory()->constructor_string(), | |
| 619 LookupIterator::OWN_SKIP_INTERCEPTOR); | |
| 620 MaybeHandle<Object> maybe_prop = Object::GetProperty(&it); | |
| 621 DCHECK(it.IsFound()); | |
| 622 DCHECK(maybe_prop.ToHandleChecked().is_identical_to(result)); | |
| 623 #endif | |
| 624 | |
| 625 // Down from here is only valid for API functions that can be used as a | 556 // Down from here is only valid for API functions that can be used as a |
| 626 // constructor (don't set the "remove prototype" flag). | 557 // constructor (don't set the "remove prototype" flag). |
| 627 | 558 |
| 628 Handle<Map> map(result->initial_map()); | 559 if (obj->read_only_prototype()) { |
| 560 result->set_map(*isolate->sloppy_function_with_readonly_prototype_map()); |
| 561 } |
| 562 |
| 563 if (prototype->IsTheHole(isolate)) { |
| 564 prototype = isolate->factory()->NewFunctionPrototype(result); |
| 565 } else { |
| 566 JSObject::AddProperty(Handle<JSObject>::cast(prototype), |
| 567 isolate->factory()->constructor_string(), result, |
| 568 DONT_ENUM); |
| 569 } |
| 570 |
| 571 int internal_field_count = 0; |
| 572 if (!obj->instance_template()->IsUndefined(isolate)) { |
| 573 Handle<ObjectTemplateInfo> instance_template = Handle<ObjectTemplateInfo>( |
| 574 ObjectTemplateInfo::cast(obj->instance_template())); |
| 575 internal_field_count = |
| 576 Smi::cast(instance_template->internal_field_count())->value(); |
| 577 } |
| 578 |
| 579 // TODO(svenpanne) Kill ApiInstanceType and refactor things by generalizing |
| 580 // JSObject::GetHeaderSize. |
| 581 int instance_size = kPointerSize * internal_field_count; |
| 582 InstanceType type; |
| 583 switch (instance_type) { |
| 584 case JavaScriptObjectType: |
| 585 if (!obj->needs_access_check() && |
| 586 obj->named_property_handler()->IsUndefined(isolate) && |
| 587 obj->indexed_property_handler()->IsUndefined(isolate)) { |
| 588 type = JS_API_OBJECT_TYPE; |
| 589 } else { |
| 590 type = JS_SPECIAL_API_OBJECT_TYPE; |
| 591 } |
| 592 instance_size += JSObject::kHeaderSize; |
| 593 break; |
| 594 case GlobalObjectType: |
| 595 type = JS_GLOBAL_OBJECT_TYPE; |
| 596 instance_size += JSGlobalObject::kSize; |
| 597 break; |
| 598 case GlobalProxyType: |
| 599 type = JS_GLOBAL_PROXY_TYPE; |
| 600 instance_size += JSGlobalProxy::kSize; |
| 601 break; |
| 602 default: |
| 603 UNREACHABLE(); |
| 604 type = JS_OBJECT_TYPE; // Keep the compiler happy. |
| 605 break; |
| 606 } |
| 607 |
| 608 Handle<Map> map = |
| 609 isolate->factory()->NewMap(type, instance_size, FAST_HOLEY_SMI_ELEMENTS); |
| 610 JSFunction::SetInitialMap(result, map, Handle<JSObject>::cast(prototype)); |
| 629 | 611 |
| 630 // Mark as undetectable if needed. | 612 // Mark as undetectable if needed. |
| 631 if (obj->undetectable()) { | 613 if (obj->undetectable()) { |
| 632 map->set_is_undetectable(); | 614 map->set_is_undetectable(); |
| 633 } | 615 } |
| 634 | 616 |
| 635 // Mark as needs_access_check if needed. | 617 // Mark as needs_access_check if needed. |
| 636 if (obj->needs_access_check()) { | 618 if (obj->needs_access_check()) { |
| 637 map->set_is_access_check_needed(true); | 619 map->set_is_access_check_needed(true); |
| 638 } | 620 } |
| 639 | 621 |
| 640 // Set interceptor information in the map. | 622 // Set interceptor information in the map. |
| 641 if (!obj->named_property_handler()->IsUndefined(isolate)) { | 623 if (!obj->named_property_handler()->IsUndefined(isolate)) { |
| 642 map->set_has_named_interceptor(); | 624 map->set_has_named_interceptor(); |
| 643 } | 625 } |
| 644 if (!obj->indexed_property_handler()->IsUndefined(isolate)) { | 626 if (!obj->indexed_property_handler()->IsUndefined(isolate)) { |
| 645 map->set_has_indexed_interceptor(); | 627 map->set_has_indexed_interceptor(); |
| 646 } | 628 } |
| 647 | 629 |
| 648 // Mark instance as callable in the map. | 630 // Mark instance as callable in the map. |
| 649 if (!obj->instance_call_handler()->IsUndefined(isolate)) { | 631 if (!obj->instance_call_handler()->IsUndefined(isolate)) { |
| 650 map->set_is_callable(); | 632 map->set_is_callable(); |
| 651 map->set_is_constructor(true); | 633 map->set_is_constructor(true); |
| 652 } | 634 } |
| 653 | 635 |
| 654 DCHECK(result->shared()->IsApiFunction()); | |
| 655 return result; | 636 return result; |
| 656 } | 637 } |
| 657 | 638 |
| 658 } // namespace internal | 639 } // namespace internal |
| 659 } // namespace v8 | 640 } // namespace v8 |
| OLD | NEW |