OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |