Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(265)

Side by Side Diff: src/builtins.cc

Issue 1871503002: Lazily compute boundfunction .name and .length if possible (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Addressed Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/bootstrapper.cc ('k') | src/factory.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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/builtins.h" 5 #include "src/builtins.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/api-arguments.h" 8 #include "src/api-arguments.h"
9 #include "src/api-natives.h" 9 #include "src/api-natives.h"
10 #include "src/base/once.h" 10 #include "src/base/once.h"
(...skipping 4048 matching lines...) Expand 10 before | Expand all | Expand 10 after
4059 this_arg = args.at<Object>(1); 4059 this_arg = args.at<Object>(1);
4060 for (int i = 2; i < args.length(); ++i) { 4060 for (int i = 2; i < args.length(); ++i) {
4061 argv[i - 2] = args.at<Object>(i); 4061 argv[i - 2] = args.at<Object>(i);
4062 } 4062 }
4063 } 4063 }
4064 Handle<JSBoundFunction> function; 4064 Handle<JSBoundFunction> function;
4065 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 4065 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
4066 isolate, function, 4066 isolate, function,
4067 isolate->factory()->NewJSBoundFunction(target, this_arg, argv)); 4067 isolate->factory()->NewJSBoundFunction(target, this_arg, argv));
4068 4068
4069 // TODO(bmeurer): Optimize the rest for the common cases where {target} is 4069 LookupIterator length_lookup(target, isolate->factory()->length_string(),
4070 // a function with some initial map or even a bound function. 4070 target, LookupIterator::HIDDEN);
4071 // Setup the "length" property based on the "length" of the {target}. 4071 // Setup the "length" property based on the "length" of the {target}.
4072 Handle<Object> length(Smi::FromInt(0), isolate); 4072 // If the targets length is the default JSFunction accessor, we can keep the
4073 Maybe<bool> target_has_length = 4073 // accessor that's installed by default on the JSBoundFunction. It lazily
4074 JSReceiver::HasOwnProperty(target, isolate->factory()->length_string()); 4074 // computes the value from the underlying internal length.
4075 if (!target_has_length.IsJust()) { 4075 if (!target->IsJSFunction() ||
4076 return isolate->heap()->exception(); 4076 length_lookup.state() != LookupIterator::ACCESSOR ||
4077 } else if (target_has_length.FromJust()) { 4077 !length_lookup.GetAccessors()->IsAccessorInfo()) {
4078 Handle<Object> target_length; 4078 Handle<Object> length(Smi::FromInt(0), isolate);
4079 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 4079 Maybe<PropertyAttributes> attributes =
4080 isolate, target_length, 4080 JSReceiver::GetPropertyAttributes(&length_lookup);
4081 JSReceiver::GetProperty(target, isolate->factory()->length_string())); 4081 if (!attributes.IsJust()) return isolate->heap()->exception();
4082 if (target_length->IsNumber()) { 4082 if (attributes.FromJust() != ABSENT) {
4083 length = isolate->factory()->NewNumber(std::max( 4083 Handle<Object> target_length;
4084 0.0, DoubleToInteger(target_length->Number()) - argv.length())); 4084 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, target_length,
4085 Object::GetProperty(&length_lookup));
4086 if (target_length->IsNumber()) {
4087 length = isolate->factory()->NewNumber(std::max(
4088 0.0, DoubleToInteger(target_length->Number()) - argv.length()));
4089 }
4085 } 4090 }
4091 LookupIterator it(function, isolate->factory()->length_string(), function);
4092 DCHECK_EQ(LookupIterator::ACCESSOR, it.state());
4093 RETURN_FAILURE_ON_EXCEPTION(isolate,
4094 JSObject::DefineOwnPropertyIgnoreAttributes(
4095 &it, length, it.property_attributes()));
4086 } 4096 }
4087 function->set_length(*length);
4088 4097
4089 // Setup the "name" property based on the "name" of the {target}. 4098 // Setup the "name" property based on the "name" of the {target}.
4090 Handle<Object> target_name; 4099 // If the targets name is the default JSFunction accessor, we can keep the
4091 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 4100 // accessor that's installed by default on the JSBoundFunction. It lazily
4092 isolate, target_name, 4101 // computes the value from the underlying internal name.
4093 JSReceiver::GetProperty(target, isolate->factory()->name_string())); 4102 LookupIterator name_lookup(target, isolate->factory()->name_string(), target,
4094 Handle<String> name; 4103 LookupIterator::HIDDEN);
4095 if (!target_name->IsString()) { 4104 if (!target->IsJSFunction() ||
4096 name = isolate->factory()->bound__string(); 4105 name_lookup.state() != LookupIterator::ACCESSOR ||
4097 } else { 4106 !name_lookup.GetAccessors()->IsAccessorInfo()) {
4098 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 4107 Handle<Object> target_name;
4099 isolate, name, Name::ToFunctionName(Handle<String>::cast(target_name))); 4108 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, target_name,
4100 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 4109 Object::GetProperty(&name_lookup));
4101 isolate, name, isolate->factory()->NewConsString( 4110 Handle<String> name;
4102 isolate->factory()->bound__string(), name)); 4111 if (target_name->IsString()) {
4112 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
4113 isolate, name,
4114 Name::ToFunctionName(Handle<String>::cast(target_name)));
4115 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
4116 isolate, name, isolate->factory()->NewConsString(
4117 isolate->factory()->bound__string(), name));
4118 } else {
4119 name = isolate->factory()->bound__string();
4120 }
4121 LookupIterator it(function, isolate->factory()->name_string());
4122 DCHECK_EQ(LookupIterator::ACCESSOR, it.state());
4123 RETURN_FAILURE_ON_EXCEPTION(isolate,
4124 JSObject::DefineOwnPropertyIgnoreAttributes(
4125 &it, name, it.property_attributes()));
4103 } 4126 }
4104 function->set_name(*name);
4105 return *function; 4127 return *function;
4106 } 4128 }
4107 4129
4108 4130
4109 // ES6 section 19.2.3.5 Function.prototype.toString ( ) 4131 // ES6 section 19.2.3.5 Function.prototype.toString ( )
4110 BUILTIN(FunctionPrototypeToString) { 4132 BUILTIN(FunctionPrototypeToString) {
4111 HandleScope scope(isolate); 4133 HandleScope scope(isolate);
4112 Handle<Object> receiver = args.receiver(); 4134 Handle<Object> receiver = args.receiver();
4113 if (receiver->IsJSBoundFunction()) { 4135 if (receiver->IsJSBoundFunction()) {
4114 return *JSBoundFunction::ToString(Handle<JSBoundFunction>::cast(receiver)); 4136 return *JSBoundFunction::ToString(Handle<JSBoundFunction>::cast(receiver));
(...skipping 836 matching lines...) Expand 10 before | Expand all | Expand 10 after
4951 BUILTIN_LIST_T(DEFINE_BUILTIN_ACCESSOR_T) 4973 BUILTIN_LIST_T(DEFINE_BUILTIN_ACCESSOR_T)
4952 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) 4974 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H)
4953 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) 4975 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A)
4954 #undef DEFINE_BUILTIN_ACCESSOR_C 4976 #undef DEFINE_BUILTIN_ACCESSOR_C
4955 #undef DEFINE_BUILTIN_ACCESSOR_A 4977 #undef DEFINE_BUILTIN_ACCESSOR_A
4956 #undef DEFINE_BUILTIN_ACCESSOR_T 4978 #undef DEFINE_BUILTIN_ACCESSOR_T
4957 #undef DEFINE_BUILTIN_ACCESSOR_H 4979 #undef DEFINE_BUILTIN_ACCESSOR_H
4958 4980
4959 } // namespace internal 4981 } // namespace internal
4960 } // namespace v8 4982 } // namespace v8
OLDNEW
« no previous file with comments | « src/bootstrapper.cc ('k') | src/factory.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698