| 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 |