| 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/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/api.h" | 7 #include "src/api.h" |
| 8 #include "src/arguments.h" | 8 #include "src/arguments.h" |
| 9 #include "src/base/once.h" | 9 #include "src/base/once.h" |
| 10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
| (...skipping 1044 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1055 Object* holder = recv; | 1055 Object* holder = recv; |
| 1056 if (!recv_type->IsUndefined()) { | 1056 if (!recv_type->IsUndefined()) { |
| 1057 holder = FindHidden(heap, holder, FunctionTemplateInfo::cast(recv_type)); | 1057 holder = FindHidden(heap, holder, FunctionTemplateInfo::cast(recv_type)); |
| 1058 if (holder == heap->null_value()) return heap->null_value(); | 1058 if (holder == heap->null_value()) return heap->null_value(); |
| 1059 } | 1059 } |
| 1060 return holder; | 1060 return holder; |
| 1061 } | 1061 } |
| 1062 | 1062 |
| 1063 | 1063 |
| 1064 template <bool is_construct> | 1064 template <bool is_construct> |
| 1065 MUST_USE_RESULT static MaybeHandle<Object> HandleApiCallHelper( | 1065 MUST_USE_RESULT static Object* HandleApiCallHelper( |
| 1066 Isolate* isolate, BuiltinArguments<NEEDS_CALLED_FUNCTION> args) { | 1066 BuiltinArguments<NEEDS_CALLED_FUNCTION> args, Isolate* isolate) { |
| 1067 DCHECK(is_construct == CalledAsConstructor(isolate)); |
| 1068 Heap* heap = isolate->heap(); |
| 1069 |
| 1067 HandleScope scope(isolate); | 1070 HandleScope scope(isolate); |
| 1068 Handle<JSFunction> function = args.called_function(); | 1071 Handle<JSFunction> function = args.called_function(); |
| 1069 // TODO(ishell): turn this back to a DCHECK. | 1072 // TODO(ishell): turn this back to a DCHECK. |
| 1070 CHECK(function->shared()->IsApiFunction()); | 1073 CHECK(function->shared()->IsApiFunction()); |
| 1071 | 1074 |
| 1072 Handle<FunctionTemplateInfo> fun_data( | 1075 Handle<FunctionTemplateInfo> fun_data( |
| 1073 function->shared()->get_api_func_data(), isolate); | 1076 function->shared()->get_api_func_data(), isolate); |
| 1074 if (is_construct) { | 1077 if (is_construct) { |
| 1075 ASSIGN_RETURN_ON_EXCEPTION( | 1078 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| 1076 isolate, fun_data, | 1079 isolate, fun_data, |
| 1077 isolate->factory()->ConfigureInstance( | 1080 isolate->factory()->ConfigureInstance( |
| 1078 fun_data, Handle<JSObject>::cast(args.receiver())), | 1081 fun_data, Handle<JSObject>::cast(args.receiver()))); |
| 1079 Object); | |
| 1080 } | 1082 } |
| 1081 | 1083 |
| 1082 DCHECK(!args[0]->IsNull()); | 1084 DCHECK(!args[0]->IsNull()); |
| 1083 if (args[0]->IsUndefined()) args[0] = function->global_proxy(); | 1085 if (args[0]->IsUndefined()) args[0] = function->global_proxy(); |
| 1084 | 1086 |
| 1085 Object* raw_holder = TypeCheck(isolate->heap(), args[0], *fun_data); | 1087 Object* raw_holder = TypeCheck(heap, args[0], *fun_data); |
| 1086 | 1088 |
| 1087 if (raw_holder->IsNull()) { | 1089 if (raw_holder->IsNull()) { |
| 1088 // This function cannot be called with the given receiver. Abort! | 1090 // This function cannot be called with the given receiver. Abort! |
| 1089 THROW_NEW_ERROR( | 1091 THROW_NEW_ERROR_RETURN_FAILURE( |
| 1090 isolate, NewTypeError("illegal_invocation", HandleVector(&function, 1)), | 1092 isolate, |
| 1091 Object); | 1093 NewTypeError("illegal_invocation", HandleVector(&function, 1))); |
| 1092 } | 1094 } |
| 1093 | 1095 |
| 1094 Object* raw_call_data = fun_data->call_code(); | 1096 Object* raw_call_data = fun_data->call_code(); |
| 1095 if (!raw_call_data->IsUndefined()) { | 1097 if (!raw_call_data->IsUndefined()) { |
| 1096 // TODO(ishell): remove this debugging code. | 1098 // TODO(ishell): remove this debugging code. |
| 1097 CHECK(raw_call_data->IsCallHandlerInfo()); | 1099 CHECK(raw_call_data->IsCallHandlerInfo()); |
| 1098 CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data); | 1100 CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data); |
| 1099 Object* callback_obj = call_data->callback(); | 1101 Object* callback_obj = call_data->callback(); |
| 1100 v8::FunctionCallback callback = | 1102 v8::FunctionCallback callback = |
| 1101 v8::ToCData<v8::FunctionCallback>(callback_obj); | 1103 v8::ToCData<v8::FunctionCallback>(callback_obj); |
| 1102 Object* data_obj = call_data->data(); | 1104 Object* data_obj = call_data->data(); |
| 1105 Object* result; |
| 1103 | 1106 |
| 1104 LOG(isolate, ApiObjectAccess("call", JSObject::cast(*args.receiver()))); | 1107 LOG(isolate, ApiObjectAccess("call", JSObject::cast(*args.receiver()))); |
| 1105 DCHECK(raw_holder->IsJSObject()); | 1108 DCHECK(raw_holder->IsJSObject()); |
| 1106 | 1109 |
| 1107 FunctionCallbackArguments custom(isolate, | 1110 FunctionCallbackArguments custom(isolate, |
| 1108 data_obj, | 1111 data_obj, |
| 1109 *function, | 1112 *function, |
| 1110 raw_holder, | 1113 raw_holder, |
| 1111 &args[0] - 1, | 1114 &args[0] - 1, |
| 1112 args.length() - 1, | 1115 args.length() - 1, |
| 1113 is_construct); | 1116 is_construct); |
| 1114 | 1117 |
| 1115 v8::Handle<v8::Value> value = custom.Call(callback); | 1118 v8::Handle<v8::Value> value = custom.Call(callback); |
| 1116 Handle<Object> result; | |
| 1117 if (value.IsEmpty()) { | 1119 if (value.IsEmpty()) { |
| 1118 result = isolate->factory()->undefined_value(); | 1120 result = heap->undefined_value(); |
| 1119 } else { | 1121 } else { |
| 1120 result = v8::Utils::OpenHandle(*value); | 1122 result = *reinterpret_cast<Object**>(*value); |
| 1121 result->VerifyApiCallResultType(); | 1123 result->VerifyApiCallResultType(); |
| 1122 } | 1124 } |
| 1123 | 1125 |
| 1124 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 1126 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); |
| 1125 if (!is_construct || result->IsJSObject()) { | 1127 if (!is_construct || result->IsJSObject()) return result; |
| 1126 return scope.CloseAndEscape(result); | |
| 1127 } | |
| 1128 } | 1128 } |
| 1129 | 1129 |
| 1130 return scope.CloseAndEscape(args.receiver()); | 1130 return *args.receiver(); |
| 1131 } | 1131 } |
| 1132 | 1132 |
| 1133 | 1133 |
| 1134 BUILTIN(HandleApiCall) { | 1134 BUILTIN(HandleApiCall) { |
| 1135 HandleScope scope(isolate); | 1135 return HandleApiCallHelper<false>(args, isolate); |
| 1136 DCHECK(!CalledAsConstructor(isolate)); | |
| 1137 Handle<Object> result; | |
| 1138 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, | |
| 1139 HandleApiCallHelper<false>(isolate, args)); | |
| 1140 return *result; | |
| 1141 } | 1136 } |
| 1142 | 1137 |
| 1143 | 1138 |
| 1144 BUILTIN(HandleApiCallConstruct) { | 1139 BUILTIN(HandleApiCallConstruct) { |
| 1145 HandleScope scope(isolate); | 1140 return HandleApiCallHelper<true>(args, isolate); |
| 1146 DCHECK(CalledAsConstructor(isolate)); | |
| 1147 Handle<Object> result; | |
| 1148 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, | |
| 1149 HandleApiCallHelper<true>(isolate, args)); | |
| 1150 return *result; | |
| 1151 } | 1141 } |
| 1152 | 1142 |
| 1153 | 1143 |
| 1154 MaybeHandle<Object> Builtins::InvokeApiFunction(Handle<JSFunction> function, | |
| 1155 Handle<Object> receiver, | |
| 1156 int argc, | |
| 1157 Handle<Object> args[]) { | |
| 1158 // Construct BuiltinArguments object: function, arguments reversed, receiver. | |
| 1159 const int kBufferSize = 32; | |
| 1160 Object* small_argv[kBufferSize]; | |
| 1161 Object** argv; | |
| 1162 if (argc + 2 <= kBufferSize) { | |
| 1163 argv = small_argv; | |
| 1164 } else { | |
| 1165 argv = new Object* [argc + 2]; | |
| 1166 } | |
| 1167 argv[argc + 1] = *receiver; | |
| 1168 for (int i = 0; i < argc; ++i) { | |
| 1169 argv[argc - i] = *args[i]; | |
| 1170 } | |
| 1171 argv[0] = *function; | |
| 1172 MaybeHandle<Object> result; | |
| 1173 { | |
| 1174 auto isolate = function->GetIsolate(); | |
| 1175 BuiltinArguments<NEEDS_CALLED_FUNCTION> arguments(argc + 2, | |
| 1176 &argv[argc + 1]); | |
| 1177 result = HandleApiCallHelper<false>(isolate, arguments); | |
| 1178 } | |
| 1179 if (argv != small_argv) { | |
| 1180 delete[] argv; | |
| 1181 } | |
| 1182 return result; | |
| 1183 } | |
| 1184 | |
| 1185 | |
| 1186 // Helper function to handle calls to non-function objects created through the | 1144 // Helper function to handle calls to non-function objects created through the |
| 1187 // API. The object can be called as either a constructor (using new) or just as | 1145 // API. The object can be called as either a constructor (using new) or just as |
| 1188 // a function (without new). | 1146 // a function (without new). |
| 1189 MUST_USE_RESULT static Object* HandleApiCallAsFunctionOrConstructor( | 1147 MUST_USE_RESULT static Object* HandleApiCallAsFunctionOrConstructor( |
| 1190 Isolate* isolate, | 1148 Isolate* isolate, |
| 1191 bool is_construct_call, | 1149 bool is_construct_call, |
| 1192 BuiltinArguments<NO_EXTRA_ARGUMENTS> args) { | 1150 BuiltinArguments<NO_EXTRA_ARGUMENTS> args) { |
| 1193 // Non-functions are never called as constructors. Even if this is an object | 1151 // Non-functions are never called as constructors. Even if this is an object |
| 1194 // called as a constructor the delegate call is not a construct call. | 1152 // called as a constructor the delegate call is not a construct call. |
| 1195 DCHECK(!CalledAsConstructor(isolate)); | 1153 DCHECK(!CalledAsConstructor(isolate)); |
| (...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1658 } | 1616 } |
| 1659 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) | 1617 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) |
| 1660 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) | 1618 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) |
| 1661 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) | 1619 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) |
| 1662 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) | 1620 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) |
| 1663 #undef DEFINE_BUILTIN_ACCESSOR_C | 1621 #undef DEFINE_BUILTIN_ACCESSOR_C |
| 1664 #undef DEFINE_BUILTIN_ACCESSOR_A | 1622 #undef DEFINE_BUILTIN_ACCESSOR_A |
| 1665 | 1623 |
| 1666 | 1624 |
| 1667 } } // namespace v8::internal | 1625 } } // namespace v8::internal |
| OLD | NEW |