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 1005 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1016 isolate, | 1016 isolate, |
1017 NewTypeError("generator_poison_pill", HandleVector<Object>(NULL, 0))); | 1017 NewTypeError("generator_poison_pill", HandleVector<Object>(NULL, 0))); |
1018 } | 1018 } |
1019 | 1019 |
1020 | 1020 |
1021 // ----------------------------------------------------------------------------- | 1021 // ----------------------------------------------------------------------------- |
1022 // | 1022 // |
1023 | 1023 |
1024 | 1024 |
1025 template <bool is_construct> | 1025 template <bool is_construct> |
1026 MUST_USE_RESULT static Object* HandleApiCallHelper( | 1026 MUST_USE_RESULT static MaybeHandle<Object> HandleApiCallHelper( |
1027 BuiltinArguments<NEEDS_CALLED_FUNCTION> args, Isolate* isolate) { | 1027 Isolate* isolate, BuiltinArguments<NEEDS_CALLED_FUNCTION>& args) { |
1028 DCHECK(is_construct == CalledAsConstructor(isolate)); | |
1029 Heap* heap = isolate->heap(); | |
1030 | |
1031 HandleScope scope(isolate); | 1028 HandleScope scope(isolate); |
1032 Handle<JSFunction> function = args.called_function(); | 1029 Handle<JSFunction> function = args.called_function(); |
1033 // TODO(ishell): turn this back to a DCHECK. | 1030 // TODO(ishell): turn this back to a DCHECK. |
1034 CHECK(function->shared()->IsApiFunction()); | 1031 CHECK(function->shared()->IsApiFunction()); |
1035 | 1032 |
1036 Handle<FunctionTemplateInfo> fun_data( | 1033 Handle<FunctionTemplateInfo> fun_data( |
1037 function->shared()->get_api_func_data(), isolate); | 1034 function->shared()->get_api_func_data(), isolate); |
1038 if (is_construct) { | 1035 if (is_construct) { |
1039 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 1036 ASSIGN_RETURN_ON_EXCEPTION( |
1040 isolate, fun_data, | 1037 isolate, fun_data, |
1041 isolate->factory()->ConfigureInstance( | 1038 isolate->factory()->ConfigureInstance( |
1042 fun_data, Handle<JSObject>::cast(args.receiver()))); | 1039 fun_data, Handle<JSObject>::cast(args.receiver())), |
| 1040 Object); |
1043 } | 1041 } |
1044 | 1042 |
1045 DCHECK(!args[0]->IsNull()); | 1043 DCHECK(!args[0]->IsNull()); |
1046 if (args[0]->IsUndefined()) args[0] = function->global_proxy(); | 1044 if (args[0]->IsUndefined()) args[0] = function->global_proxy(); |
1047 | 1045 |
1048 Object* raw_holder = fun_data->GetCompatibleReceiver(isolate, args[0]); | 1046 Object* raw_holder = fun_data->GetCompatibleReceiver(isolate, args[0]); |
1049 | 1047 |
1050 if (raw_holder->IsNull()) { | 1048 if (raw_holder->IsNull()) { |
1051 // This function cannot be called with the given receiver. Abort! | 1049 // This function cannot be called with the given receiver. Abort! |
1052 THROW_NEW_ERROR_RETURN_FAILURE( | 1050 THROW_NEW_ERROR( |
1053 isolate, | 1051 isolate, NewTypeError("illegal_invocation", HandleVector(&function, 1)), |
1054 NewTypeError("illegal_invocation", HandleVector(&function, 1))); | 1052 Object); |
1055 } | 1053 } |
1056 | 1054 |
1057 Object* raw_call_data = fun_data->call_code(); | 1055 Object* raw_call_data = fun_data->call_code(); |
1058 if (!raw_call_data->IsUndefined()) { | 1056 if (!raw_call_data->IsUndefined()) { |
1059 // TODO(ishell): remove this debugging code. | 1057 // TODO(ishell): remove this debugging code. |
1060 CHECK(raw_call_data->IsCallHandlerInfo()); | 1058 CHECK(raw_call_data->IsCallHandlerInfo()); |
1061 CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data); | 1059 CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data); |
1062 Object* callback_obj = call_data->callback(); | 1060 Object* callback_obj = call_data->callback(); |
1063 v8::FunctionCallback callback = | 1061 v8::FunctionCallback callback = |
1064 v8::ToCData<v8::FunctionCallback>(callback_obj); | 1062 v8::ToCData<v8::FunctionCallback>(callback_obj); |
1065 Object* data_obj = call_data->data(); | 1063 Object* data_obj = call_data->data(); |
1066 Object* result; | |
1067 | 1064 |
1068 LOG(isolate, ApiObjectAccess("call", JSObject::cast(*args.receiver()))); | 1065 LOG(isolate, ApiObjectAccess("call", JSObject::cast(*args.receiver()))); |
1069 DCHECK(raw_holder->IsJSObject()); | 1066 DCHECK(raw_holder->IsJSObject()); |
1070 | 1067 |
1071 FunctionCallbackArguments custom(isolate, | 1068 FunctionCallbackArguments custom(isolate, |
1072 data_obj, | 1069 data_obj, |
1073 *function, | 1070 *function, |
1074 raw_holder, | 1071 raw_holder, |
1075 &args[0] - 1, | 1072 &args[0] - 1, |
1076 args.length() - 1, | 1073 args.length() - 1, |
1077 is_construct); | 1074 is_construct); |
1078 | 1075 |
1079 v8::Handle<v8::Value> value = custom.Call(callback); | 1076 v8::Handle<v8::Value> value = custom.Call(callback); |
| 1077 Handle<Object> result; |
1080 if (value.IsEmpty()) { | 1078 if (value.IsEmpty()) { |
1081 result = heap->undefined_value(); | 1079 result = isolate->factory()->undefined_value(); |
1082 } else { | 1080 } else { |
1083 result = *reinterpret_cast<Object**>(*value); | 1081 result = v8::Utils::OpenHandle(*value); |
1084 result->VerifyApiCallResultType(); | 1082 result->VerifyApiCallResultType(); |
1085 } | 1083 } |
1086 | 1084 |
1087 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); | 1085 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
1088 if (!is_construct || result->IsJSObject()) return result; | 1086 if (!is_construct || result->IsJSObject()) { |
| 1087 return scope.CloseAndEscape(result); |
| 1088 } |
1089 } | 1089 } |
1090 | 1090 |
1091 return *args.receiver(); | 1091 return scope.CloseAndEscape(args.receiver()); |
1092 } | 1092 } |
1093 | 1093 |
1094 | 1094 |
1095 BUILTIN(HandleApiCall) { | 1095 BUILTIN(HandleApiCall) { |
1096 return HandleApiCallHelper<false>(args, isolate); | 1096 HandleScope scope(isolate); |
| 1097 DCHECK(!CalledAsConstructor(isolate)); |
| 1098 Handle<Object> result; |
| 1099 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, |
| 1100 HandleApiCallHelper<false>(isolate, args)); |
| 1101 return *result; |
1097 } | 1102 } |
1098 | 1103 |
1099 | 1104 |
1100 BUILTIN(HandleApiCallConstruct) { | 1105 BUILTIN(HandleApiCallConstruct) { |
1101 return HandleApiCallHelper<true>(args, isolate); | 1106 HandleScope scope(isolate); |
| 1107 DCHECK(CalledAsConstructor(isolate)); |
| 1108 Handle<Object> result; |
| 1109 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, |
| 1110 HandleApiCallHelper<true>(isolate, args)); |
| 1111 return *result; |
1102 } | 1112 } |
1103 | 1113 |
1104 | 1114 |
| 1115 namespace { |
| 1116 |
| 1117 class RelocatableArguments : public BuiltinArguments<NEEDS_CALLED_FUNCTION>, |
| 1118 public Relocatable { |
| 1119 public: |
| 1120 RelocatableArguments(Isolate* isolate, int length, Object** arguments) |
| 1121 : BuiltinArguments<NEEDS_CALLED_FUNCTION>(length, arguments), |
| 1122 Relocatable(isolate) {} |
| 1123 |
| 1124 virtual inline void IterateInstance(ObjectVisitor* v) { |
| 1125 if (length() == 0) return; |
| 1126 v->VisitPointers(lowest_address(), highest_address() + 1); |
| 1127 } |
| 1128 |
| 1129 private: |
| 1130 DISALLOW_COPY_AND_ASSIGN(RelocatableArguments); |
| 1131 }; |
| 1132 |
| 1133 } // namespace |
| 1134 |
| 1135 |
| 1136 MaybeHandle<Object> Builtins::InvokeApiFunction(Handle<JSFunction> function, |
| 1137 Handle<Object> receiver, |
| 1138 int argc, |
| 1139 Handle<Object> args[]) { |
| 1140 // Construct BuiltinArguments object: function, arguments reversed, receiver. |
| 1141 const int kBufferSize = 32; |
| 1142 Object* small_argv[kBufferSize]; |
| 1143 Object** argv; |
| 1144 if (argc + 2 <= kBufferSize) { |
| 1145 argv = small_argv; |
| 1146 } else { |
| 1147 argv = new Object* [argc + 2]; |
| 1148 } |
| 1149 argv[argc + 1] = *receiver; |
| 1150 for (int i = 0; i < argc; ++i) { |
| 1151 argv[argc - i] = *args[i]; |
| 1152 } |
| 1153 argv[0] = *function; |
| 1154 MaybeHandle<Object> result; |
| 1155 { |
| 1156 auto isolate = function->GetIsolate(); |
| 1157 RelocatableArguments arguments(isolate, argc + 2, &argv[argc + 1]); |
| 1158 result = HandleApiCallHelper<false>(isolate, arguments); |
| 1159 } |
| 1160 if (argv != small_argv) { |
| 1161 delete[] argv; |
| 1162 } |
| 1163 return result; |
| 1164 } |
| 1165 |
| 1166 |
1105 // Helper function to handle calls to non-function objects created through the | 1167 // Helper function to handle calls to non-function objects created through the |
1106 // API. The object can be called as either a constructor (using new) or just as | 1168 // API. The object can be called as either a constructor (using new) or just as |
1107 // a function (without new). | 1169 // a function (without new). |
1108 MUST_USE_RESULT static Object* HandleApiCallAsFunctionOrConstructor( | 1170 MUST_USE_RESULT static Object* HandleApiCallAsFunctionOrConstructor( |
1109 Isolate* isolate, | 1171 Isolate* isolate, |
1110 bool is_construct_call, | 1172 bool is_construct_call, |
1111 BuiltinArguments<NO_EXTRA_ARGUMENTS> args) { | 1173 BuiltinArguments<NO_EXTRA_ARGUMENTS> args) { |
1112 // Non-functions are never called as constructors. Even if this is an object | 1174 // Non-functions are never called as constructors. Even if this is an object |
1113 // called as a constructor the delegate call is not a construct call. | 1175 // called as a constructor the delegate call is not a construct call. |
1114 DCHECK(!CalledAsConstructor(isolate)); | 1176 DCHECK(!CalledAsConstructor(isolate)); |
(...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1577 } | 1639 } |
1578 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) | 1640 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) |
1579 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) | 1641 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) |
1580 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) | 1642 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) |
1581 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) | 1643 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) |
1582 #undef DEFINE_BUILTIN_ACCESSOR_C | 1644 #undef DEFINE_BUILTIN_ACCESSOR_C |
1583 #undef DEFINE_BUILTIN_ACCESSOR_A | 1645 #undef DEFINE_BUILTIN_ACCESSOR_A |
1584 | 1646 |
1585 | 1647 |
1586 } } // namespace v8::internal | 1648 } } // namespace v8::internal |
OLD | NEW |