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

Side by Side Diff: src/builtins.cc

Issue 2089703004: Further streamline HandleApiCall (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 6 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/builtins.h ('k') | src/execution.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-arguments.h" 7 #include "src/api-arguments.h"
8 #include "src/api-natives.h" 8 #include "src/api-natives.h"
9 #include "src/api.h" 9 #include "src/api.h"
10 #include "src/base/ieee754.h" 10 #include "src/base/ieee754.h"
(...skipping 5105 matching lines...) Expand 10 before | Expand all | Expand 10 after
5116 if (!receiver->map()->has_hidden_prototype()) return nullptr; 5116 if (!receiver->map()->has_hidden_prototype()) return nullptr;
5117 for (PrototypeIterator iter(isolate, receiver, kStartAtPrototype, 5117 for (PrototypeIterator iter(isolate, receiver, kStartAtPrototype,
5118 PrototypeIterator::END_AT_NON_HIDDEN); 5118 PrototypeIterator::END_AT_NON_HIDDEN);
5119 !iter.IsAtEnd(); iter.Advance()) { 5119 !iter.IsAtEnd(); iter.Advance()) {
5120 JSObject* current = iter.GetCurrent<JSObject>(); 5120 JSObject* current = iter.GetCurrent<JSObject>();
5121 if (signature->IsTemplateFor(current)) return current; 5121 if (signature->IsTemplateFor(current)) return current;
5122 } 5122 }
5123 return nullptr; 5123 return nullptr;
5124 } 5124 }
5125 5125
5126 MUST_USE_RESULT MaybeHandle<Object> HandleApiCallHelper(Isolate* isolate, 5126 template <bool is_construct>
5127 BuiltinArguments args) { 5127 MUST_USE_RESULT MaybeHandle<Object> HandleApiCallHelper(
5128 HandleScope scope(isolate); 5128 Isolate* isolate, Handle<HeapObject> function,
5129 Handle<HeapObject> function = args.target<HeapObject>(); 5129 Handle<HeapObject> new_target, Handle<FunctionTemplateInfo> fun_data,
5130 Handle<HeapObject> new_target = args.new_target(); 5130 BuiltinArguments args) {
5131 bool is_construct = !new_target->IsUndefined(isolate);
5132 Handle<JSObject> receiver; 5131 Handle<JSObject> receiver;
5133
5134 DCHECK(function->IsFunctionTemplateInfo() ||
5135 Handle<JSFunction>::cast(function)->shared()->IsApiFunction());
5136
5137 Handle<FunctionTemplateInfo> fun_data =
5138 function->IsFunctionTemplateInfo()
5139 ? Handle<FunctionTemplateInfo>::cast(function)
5140 : handle(JSFunction::cast(*function)->shared()->get_api_func_data());
5141 JSObject* raw_holder; 5132 JSObject* raw_holder;
5142 if (is_construct) { 5133 if (is_construct) {
5143 DCHECK(args.receiver()->IsTheHole(isolate)); 5134 DCHECK(args.receiver()->IsTheHole(isolate));
5144 if (fun_data->instance_template()->IsUndefined(isolate)) { 5135 if (fun_data->instance_template()->IsUndefined(isolate)) {
5145 v8::Local<ObjectTemplate> templ = 5136 v8::Local<ObjectTemplate> templ =
5146 ObjectTemplate::New(reinterpret_cast<v8::Isolate*>(isolate), 5137 ObjectTemplate::New(reinterpret_cast<v8::Isolate*>(isolate),
5147 ToApiHandle<v8::FunctionTemplate>(fun_data)); 5138 ToApiHandle<v8::FunctionTemplate>(fun_data));
5148 fun_data->set_instance_template(*Utils::OpenHandle(*templ)); 5139 fun_data->set_instance_template(*Utils::OpenHandle(*templ));
5149 } 5140 }
5150 Handle<ObjectTemplateInfo> instance_template( 5141 Handle<ObjectTemplateInfo> instance_template(
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
5194 v8::ToCData<v8::FunctionCallback>(callback_obj); 5185 v8::ToCData<v8::FunctionCallback>(callback_obj);
5195 Object* data_obj = call_data->data(); 5186 Object* data_obj = call_data->data();
5196 5187
5197 LOG(isolate, ApiObjectAccess("call", JSObject::cast(*args.receiver()))); 5188 LOG(isolate, ApiObjectAccess("call", JSObject::cast(*args.receiver())));
5198 5189
5199 FunctionCallbackArguments custom(isolate, data_obj, *function, raw_holder, 5190 FunctionCallbackArguments custom(isolate, data_obj, *function, raw_holder,
5200 *new_target, &args[0] - 1, 5191 *new_target, &args[0] - 1,
5201 args.length() - 1); 5192 args.length() - 1);
5202 5193
5203 Handle<Object> result = custom.Call(callback); 5194 Handle<Object> result = custom.Call(callback);
5204 if (result.is_null()) result = isolate->factory()->undefined_value();
5205 5195
5206 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); 5196 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
5207 if (!is_construct || result->IsJSObject()) { 5197 if (result.is_null()) {
5208 return scope.CloseAndEscape(result); 5198 if (is_construct) return receiver;
5199 return isolate->factory()->undefined_value();
5209 } 5200 }
5201 // Rebox the result.
5202 result->VerifyApiCallResultType();
5203 if (!is_construct || result->IsJSObject()) return handle(*result, isolate);
5210 } 5204 }
5211 5205
5212 return scope.CloseAndEscape(receiver); 5206 return receiver;
5213 } 5207 }
5214 5208
5215 } // namespace 5209 } // namespace
5216 5210
5217 5211
5218 BUILTIN(HandleApiCall) { 5212 BUILTIN(HandleApiCall) {
5219 HandleScope scope(isolate); 5213 HandleScope scope(isolate);
5220 RETURN_RESULT_OR_FAILURE(isolate, HandleApiCallHelper(isolate, args)); 5214 Handle<JSFunction> function = args.target<JSFunction>();
5215 Handle<HeapObject> new_target = args.new_target();
5216 Handle<FunctionTemplateInfo> fun_data(function->shared()->get_api_func_data(),
5217 isolate);
5218 if (new_target->IsJSReceiver()) {
5219 RETURN_RESULT_OR_FAILURE(
5220 isolate, HandleApiCallHelper<true>(isolate, function, new_target,
5221 fun_data, args));
5222 } else {
5223 RETURN_RESULT_OR_FAILURE(
5224 isolate, HandleApiCallHelper<false>(isolate, function, new_target,
5225 fun_data, args));
5226 }
5221 } 5227 }
5222 5228
5223 5229
5224 Handle<Code> Builtins::CallFunction(ConvertReceiverMode mode, 5230 Handle<Code> Builtins::CallFunction(ConvertReceiverMode mode,
5225 TailCallMode tail_call_mode) { 5231 TailCallMode tail_call_mode) {
5226 switch (tail_call_mode) { 5232 switch (tail_call_mode) {
5227 case TailCallMode::kDisallow: 5233 case TailCallMode::kDisallow:
5228 switch (mode) { 5234 switch (mode) {
5229 case ConvertReceiverMode::kNullOrUndefined: 5235 case ConvertReceiverMode::kNullOrUndefined:
5230 return CallFunction_ReceiverIsNullOrUndefined(); 5236 return CallFunction_ReceiverIsNullOrUndefined();
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
5310 if (length() == 0) return; 5316 if (length() == 0) return;
5311 v->VisitPointers(lowest_address(), highest_address() + 1); 5317 v->VisitPointers(lowest_address(), highest_address() + 1);
5312 } 5318 }
5313 5319
5314 private: 5320 private:
5315 DISALLOW_COPY_AND_ASSIGN(RelocatableArguments); 5321 DISALLOW_COPY_AND_ASSIGN(RelocatableArguments);
5316 }; 5322 };
5317 5323
5318 } // namespace 5324 } // namespace
5319 5325
5320 MaybeHandle<Object> Builtins::InvokeApiFunction(Handle<HeapObject> function, 5326 MaybeHandle<Object> Builtins::InvokeApiFunction(Isolate* isolate,
5327 Handle<HeapObject> function,
5321 Handle<Object> receiver, 5328 Handle<Object> receiver,
5322 int argc, 5329 int argc,
5323 Handle<Object> args[]) { 5330 Handle<Object> args[]) {
5324 Isolate* isolate = function->GetIsolate(); 5331 DCHECK(function->IsFunctionTemplateInfo() ||
5332 (function->IsJSFunction() &&
5333 JSFunction::cast(*function)->shared()->IsApiFunction()));
5334
5325 // Do proper receiver conversion for non-strict mode api functions. 5335 // Do proper receiver conversion for non-strict mode api functions.
5326 if (!receiver->IsJSReceiver()) { 5336 if (!receiver->IsJSReceiver()) {
5327 DCHECK(function->IsFunctionTemplateInfo() || function->IsJSFunction());
5328 if (function->IsFunctionTemplateInfo() || 5337 if (function->IsFunctionTemplateInfo() ||
5329 is_sloppy(JSFunction::cast(*function)->shared()->language_mode())) { 5338 is_sloppy(JSFunction::cast(*function)->shared()->language_mode())) {
5330 ASSIGN_RETURN_ON_EXCEPTION(isolate, receiver, 5339 ASSIGN_RETURN_ON_EXCEPTION(isolate, receiver,
5331 Object::ConvertReceiver(isolate, receiver), 5340 Object::ConvertReceiver(isolate, receiver),
5332 Object); 5341 Object);
5333 } 5342 }
5334 } 5343 }
5344
5345 Handle<FunctionTemplateInfo> fun_data =
5346 function->IsFunctionTemplateInfo()
5347 ? Handle<FunctionTemplateInfo>::cast(function)
5348 : handle(JSFunction::cast(*function)->shared()->get_api_func_data(),
5349 isolate);
5350 Handle<HeapObject> new_target = isolate->factory()->undefined_value();
5335 // Construct BuiltinArguments object: 5351 // Construct BuiltinArguments object:
5336 // new target, function, arguments reversed, receiver. 5352 // new target, function, arguments reversed, receiver.
5337 const int kBufferSize = 32; 5353 const int kBufferSize = 32;
5338 Object* small_argv[kBufferSize]; 5354 Object* small_argv[kBufferSize];
5339 Object** argv; 5355 Object** argv;
5340 if (argc + 3 <= kBufferSize) { 5356 if (argc + 3 <= kBufferSize) {
5341 argv = small_argv; 5357 argv = small_argv;
5342 } else { 5358 } else {
5343 argv = new Object*[argc + 3]; 5359 argv = new Object*[argc + 3];
5344 } 5360 }
5345 argv[argc + 2] = *receiver; 5361 argv[argc + 2] = *receiver;
5346 for (int i = 0; i < argc; ++i) { 5362 for (int i = 0; i < argc; ++i) {
5347 argv[argc - i + 1] = *args[i]; 5363 argv[argc - i + 1] = *args[i];
5348 } 5364 }
5349 argv[1] = *function; 5365 argv[1] = *function;
5350 argv[0] = isolate->heap()->undefined_value(); // new target 5366 argv[0] = *new_target;
5351 MaybeHandle<Object> result; 5367 MaybeHandle<Object> result;
5352 { 5368 {
5353 RelocatableArguments arguments(isolate, argc + 3, &argv[argc] + 2); 5369 RelocatableArguments arguments(isolate, argc + 3, &argv[argc] + 2);
5354 result = HandleApiCallHelper(isolate, arguments); 5370 result = HandleApiCallHelper<false>(isolate, function, new_target, fun_data,
5371 arguments);
5355 } 5372 }
5356 if (argv != small_argv) { 5373 if (argv != small_argv) delete[] argv;
5357 delete[] argv;
5358 }
5359 return result; 5374 return result;
5360 } 5375 }
5361 5376
5362 5377
5363 // Helper function to handle calls to non-function objects created through the 5378 // Helper function to handle calls to non-function objects created through the
5364 // API. The object can be called as either a constructor (using new) or just as 5379 // API. The object can be called as either a constructor (using new) or just as
5365 // a function (without new). 5380 // a function (without new).
5366 MUST_USE_RESULT static Object* HandleApiCallAsFunctionOrConstructor( 5381 MUST_USE_RESULT static Object* HandleApiCallAsFunctionOrConstructor(
5367 Isolate* isolate, bool is_construct_call, BuiltinArguments args) { 5382 Isolate* isolate, bool is_construct_call, BuiltinArguments args) {
5368 Handle<Object> receiver = args.receiver(); 5383 Handle<Object> receiver = args.receiver();
(...skipping 724 matching lines...) Expand 10 before | Expand all | Expand 10 after
6093 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) 6108 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H)
6094 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) 6109 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A)
6095 #undef DEFINE_BUILTIN_ACCESSOR_C 6110 #undef DEFINE_BUILTIN_ACCESSOR_C
6096 #undef DEFINE_BUILTIN_ACCESSOR_A 6111 #undef DEFINE_BUILTIN_ACCESSOR_A
6097 #undef DEFINE_BUILTIN_ACCESSOR_T 6112 #undef DEFINE_BUILTIN_ACCESSOR_T
6098 #undef DEFINE_BUILTIN_ACCESSOR_S 6113 #undef DEFINE_BUILTIN_ACCESSOR_S
6099 #undef DEFINE_BUILTIN_ACCESSOR_H 6114 #undef DEFINE_BUILTIN_ACCESSOR_H
6100 6115
6101 } // namespace internal 6116 } // namespace internal
6102 } // namespace v8 6117 } // namespace v8
OLDNEW
« no previous file with comments | « src/builtins.h ('k') | src/execution.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698