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 5130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5141 JSObject* current = iter.GetCurrent<JSObject>(); | 5141 JSObject* current = iter.GetCurrent<JSObject>(); |
5142 if (signature->IsTemplateFor(current)) return current; | 5142 if (signature->IsTemplateFor(current)) return current; |
5143 } | 5143 } |
5144 return nullptr; | 5144 return nullptr; |
5145 } | 5145 } |
5146 | 5146 |
5147 template <bool is_construct> | 5147 template <bool is_construct> |
5148 MUST_USE_RESULT MaybeHandle<Object> HandleApiCallHelper( | 5148 MUST_USE_RESULT MaybeHandle<Object> HandleApiCallHelper( |
5149 Isolate* isolate, Handle<HeapObject> function, | 5149 Isolate* isolate, Handle<HeapObject> function, |
5150 Handle<HeapObject> new_target, Handle<FunctionTemplateInfo> fun_data, | 5150 Handle<HeapObject> new_target, Handle<FunctionTemplateInfo> fun_data, |
5151 BuiltinArguments args) { | 5151 Handle<Object> receiver, BuiltinArguments args) { |
5152 Handle<JSObject> receiver; | 5152 Handle<JSObject> js_receiver; |
5153 JSObject* raw_holder; | 5153 JSObject* raw_holder; |
5154 if (is_construct) { | 5154 if (is_construct) { |
5155 DCHECK(args.receiver()->IsTheHole(isolate)); | 5155 DCHECK(args.receiver()->IsTheHole(isolate)); |
5156 if (fun_data->instance_template()->IsUndefined(isolate)) { | 5156 if (fun_data->instance_template()->IsUndefined(isolate)) { |
5157 v8::Local<ObjectTemplate> templ = | 5157 v8::Local<ObjectTemplate> templ = |
5158 ObjectTemplate::New(reinterpret_cast<v8::Isolate*>(isolate), | 5158 ObjectTemplate::New(reinterpret_cast<v8::Isolate*>(isolate), |
5159 ToApiHandle<v8::FunctionTemplate>(fun_data)); | 5159 ToApiHandle<v8::FunctionTemplate>(fun_data)); |
5160 fun_data->set_instance_template(*Utils::OpenHandle(*templ)); | 5160 fun_data->set_instance_template(*Utils::OpenHandle(*templ)); |
5161 } | 5161 } |
5162 Handle<ObjectTemplateInfo> instance_template( | 5162 Handle<ObjectTemplateInfo> instance_template( |
5163 ObjectTemplateInfo::cast(fun_data->instance_template()), isolate); | 5163 ObjectTemplateInfo::cast(fun_data->instance_template()), isolate); |
5164 ASSIGN_RETURN_ON_EXCEPTION( | 5164 ASSIGN_RETURN_ON_EXCEPTION( |
5165 isolate, receiver, | 5165 isolate, js_receiver, |
5166 ApiNatives::InstantiateObject(instance_template, | 5166 ApiNatives::InstantiateObject(instance_template, |
5167 Handle<JSReceiver>::cast(new_target)), | 5167 Handle<JSReceiver>::cast(new_target)), |
5168 Object); | 5168 Object); |
5169 args[0] = *receiver; | 5169 args[0] = *js_receiver; |
5170 DCHECK_EQ(*receiver, *args.receiver()); | 5170 DCHECK_EQ(*js_receiver, *args.receiver()); |
5171 | 5171 |
5172 raw_holder = *receiver; | 5172 raw_holder = *js_receiver; |
5173 } else { | 5173 } else { |
5174 DCHECK(args.receiver()->IsJSReceiver()); | 5174 DCHECK(receiver->IsJSReceiver()); |
5175 | 5175 |
5176 Handle<JSReceiver> object = args.at<JSReceiver>(0); | 5176 if (!receiver->IsJSObject()) { |
5177 if (!object->IsJSObject()) { | |
5178 // This function cannot be called with the given receiver. Abort! | 5177 // This function cannot be called with the given receiver. Abort! |
5179 THROW_NEW_ERROR( | 5178 THROW_NEW_ERROR( |
5180 isolate, NewTypeError(MessageTemplate::kIllegalInvocation), Object); | 5179 isolate, NewTypeError(MessageTemplate::kIllegalInvocation), Object); |
5181 } | 5180 } |
5182 | 5181 |
5183 receiver = Handle<JSObject>::cast(object); | 5182 js_receiver = Handle<JSObject>::cast(receiver); |
5184 | 5183 |
5185 if (!fun_data->accept_any_receiver() && receiver->IsAccessCheckNeeded() && | 5184 if (!fun_data->accept_any_receiver() && |
5186 !isolate->MayAccess(handle(isolate->context()), receiver)) { | 5185 js_receiver->IsAccessCheckNeeded() && |
5187 isolate->ReportFailedAccessCheck(receiver); | 5186 !isolate->MayAccess(handle(isolate->context()), js_receiver)) { |
| 5187 isolate->ReportFailedAccessCheck(js_receiver); |
5188 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 5188 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
5189 } | 5189 } |
5190 | 5190 |
5191 raw_holder = GetCompatibleReceiver(isolate, *fun_data, *receiver); | 5191 raw_holder = GetCompatibleReceiver(isolate, *fun_data, *js_receiver); |
5192 | 5192 |
5193 if (raw_holder == nullptr) { | 5193 if (raw_holder == nullptr) { |
5194 // This function cannot be called with the given receiver. Abort! | 5194 // This function cannot be called with the given receiver. Abort! |
5195 THROW_NEW_ERROR( | 5195 THROW_NEW_ERROR( |
5196 isolate, NewTypeError(MessageTemplate::kIllegalInvocation), Object); | 5196 isolate, NewTypeError(MessageTemplate::kIllegalInvocation), Object); |
5197 } | 5197 } |
5198 } | 5198 } |
5199 | 5199 |
5200 Object* raw_call_data = fun_data->call_code(); | 5200 Object* raw_call_data = fun_data->call_code(); |
5201 if (!raw_call_data->IsUndefined(isolate)) { | 5201 if (!raw_call_data->IsUndefined(isolate)) { |
5202 DCHECK(raw_call_data->IsCallHandlerInfo()); | 5202 DCHECK(raw_call_data->IsCallHandlerInfo()); |
5203 CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data); | 5203 CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data); |
5204 Object* callback_obj = call_data->callback(); | 5204 Object* callback_obj = call_data->callback(); |
5205 v8::FunctionCallback callback = | 5205 v8::FunctionCallback callback = |
5206 v8::ToCData<v8::FunctionCallback>(callback_obj); | 5206 v8::ToCData<v8::FunctionCallback>(callback_obj); |
5207 Object* data_obj = call_data->data(); | 5207 Object* data_obj = call_data->data(); |
5208 | 5208 |
5209 LOG(isolate, ApiObjectAccess("call", JSObject::cast(*args.receiver()))); | 5209 LOG(isolate, ApiObjectAccess("call", JSObject::cast(*js_receiver))); |
5210 | 5210 |
5211 FunctionCallbackArguments custom(isolate, data_obj, *function, raw_holder, | 5211 FunctionCallbackArguments custom(isolate, data_obj, *function, raw_holder, |
5212 *new_target, &args[0] - 1, | 5212 *new_target, &args[0] - 1, |
5213 args.length() - 1); | 5213 args.length() - 1); |
5214 | 5214 |
5215 Handle<Object> result = custom.Call(callback); | 5215 Handle<Object> result = custom.Call(callback); |
5216 | 5216 |
5217 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 5217 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
5218 if (result.is_null()) { | 5218 if (result.is_null()) { |
5219 if (is_construct) return receiver; | 5219 if (is_construct) return js_receiver; |
5220 return isolate->factory()->undefined_value(); | 5220 return isolate->factory()->undefined_value(); |
5221 } | 5221 } |
5222 // Rebox the result. | 5222 // Rebox the result. |
5223 result->VerifyApiCallResultType(); | 5223 result->VerifyApiCallResultType(); |
5224 if (!is_construct || result->IsJSObject()) return handle(*result, isolate); | 5224 if (!is_construct || result->IsJSObject()) return handle(*result, isolate); |
5225 } | 5225 } |
5226 | 5226 |
5227 return receiver; | 5227 return js_receiver; |
5228 } | 5228 } |
5229 | 5229 |
5230 } // namespace | 5230 } // namespace |
5231 | 5231 |
5232 | 5232 |
5233 BUILTIN(HandleApiCall) { | 5233 BUILTIN(HandleApiCall) { |
5234 HandleScope scope(isolate); | 5234 HandleScope scope(isolate); |
5235 Handle<JSFunction> function = args.target<JSFunction>(); | 5235 Handle<JSFunction> function = args.target<JSFunction>(); |
| 5236 Handle<Object> receiver = args.receiver(); |
5236 Handle<HeapObject> new_target = args.new_target(); | 5237 Handle<HeapObject> new_target = args.new_target(); |
5237 Handle<FunctionTemplateInfo> fun_data(function->shared()->get_api_func_data(), | 5238 Handle<FunctionTemplateInfo> fun_data(function->shared()->get_api_func_data(), |
5238 isolate); | 5239 isolate); |
5239 if (new_target->IsJSReceiver()) { | 5240 if (new_target->IsJSReceiver()) { |
5240 RETURN_RESULT_OR_FAILURE( | 5241 RETURN_RESULT_OR_FAILURE( |
5241 isolate, HandleApiCallHelper<true>(isolate, function, new_target, | 5242 isolate, HandleApiCallHelper<true>(isolate, function, new_target, |
5242 fun_data, args)); | 5243 fun_data, receiver, args)); |
5243 } else { | 5244 } else { |
5244 RETURN_RESULT_OR_FAILURE( | 5245 RETURN_RESULT_OR_FAILURE( |
5245 isolate, HandleApiCallHelper<false>(isolate, function, new_target, | 5246 isolate, HandleApiCallHelper<false>(isolate, function, new_target, |
5246 fun_data, args)); | 5247 fun_data, receiver, args)); |
5247 } | 5248 } |
5248 } | 5249 } |
5249 | 5250 |
5250 | 5251 |
5251 Handle<Code> Builtins::CallFunction(ConvertReceiverMode mode, | 5252 Handle<Code> Builtins::CallFunction(ConvertReceiverMode mode, |
5252 TailCallMode tail_call_mode) { | 5253 TailCallMode tail_call_mode) { |
5253 switch (tail_call_mode) { | 5254 switch (tail_call_mode) { |
5254 case TailCallMode::kDisallow: | 5255 case TailCallMode::kDisallow: |
5255 switch (mode) { | 5256 switch (mode) { |
5256 case ConvertReceiverMode::kNullOrUndefined: | 5257 case ConvertReceiverMode::kNullOrUndefined: |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5382 argv[argc + 2] = *receiver; | 5383 argv[argc + 2] = *receiver; |
5383 for (int i = 0; i < argc; ++i) { | 5384 for (int i = 0; i < argc; ++i) { |
5384 argv[argc - i + 1] = *args[i]; | 5385 argv[argc - i + 1] = *args[i]; |
5385 } | 5386 } |
5386 argv[1] = *function; | 5387 argv[1] = *function; |
5387 argv[0] = *new_target; | 5388 argv[0] = *new_target; |
5388 MaybeHandle<Object> result; | 5389 MaybeHandle<Object> result; |
5389 { | 5390 { |
5390 RelocatableArguments arguments(isolate, argc + 3, &argv[argc] + 2); | 5391 RelocatableArguments arguments(isolate, argc + 3, &argv[argc] + 2); |
5391 result = HandleApiCallHelper<false>(isolate, function, new_target, fun_data, | 5392 result = HandleApiCallHelper<false>(isolate, function, new_target, fun_data, |
5392 arguments); | 5393 receiver, arguments); |
5393 } | 5394 } |
5394 if (argv != small_argv) delete[] argv; | 5395 if (argv != small_argv) delete[] argv; |
5395 return result; | 5396 return result; |
5396 } | 5397 } |
5397 | 5398 |
5398 | 5399 |
5399 // Helper function to handle calls to non-function objects created through the | 5400 // Helper function to handle calls to non-function objects created through the |
5400 // API. The object can be called as either a constructor (using new) or just as | 5401 // API. The object can be called as either a constructor (using new) or just as |
5401 // a function (without new). | 5402 // a function (without new). |
5402 MUST_USE_RESULT static Object* HandleApiCallAsFunctionOrConstructor( | 5403 MUST_USE_RESULT static Object* HandleApiCallAsFunctionOrConstructor( |
(...skipping 737 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6140 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) | 6141 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) |
6141 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) | 6142 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) |
6142 #undef DEFINE_BUILTIN_ACCESSOR_C | 6143 #undef DEFINE_BUILTIN_ACCESSOR_C |
6143 #undef DEFINE_BUILTIN_ACCESSOR_A | 6144 #undef DEFINE_BUILTIN_ACCESSOR_A |
6144 #undef DEFINE_BUILTIN_ACCESSOR_T | 6145 #undef DEFINE_BUILTIN_ACCESSOR_T |
6145 #undef DEFINE_BUILTIN_ACCESSOR_S | 6146 #undef DEFINE_BUILTIN_ACCESSOR_S |
6146 #undef DEFINE_BUILTIN_ACCESSOR_H | 6147 #undef DEFINE_BUILTIN_ACCESSOR_H |
6147 | 6148 |
6148 } // namespace internal | 6149 } // namespace internal |
6149 } // namespace v8 | 6150 } // namespace v8 |
OLD | NEW |