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 1027 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1038 return heap->null_value(); | 1038 return heap->null_value(); |
1039 } | 1039 } |
1040 | 1040 |
1041 | 1041 |
1042 // Returns the holder JSObject if the function can legally be called | 1042 // Returns the holder JSObject if the function can legally be called |
1043 // with this receiver. Returns Heap::null_value() if the call is | 1043 // with this receiver. Returns Heap::null_value() if the call is |
1044 // illegal. Any arguments that don't fit the expected type is | 1044 // illegal. Any arguments that don't fit the expected type is |
1045 // overwritten with undefined. Note that holder and the arguments are | 1045 // overwritten with undefined. Note that holder and the arguments are |
1046 // implicitly rewritten with the first object in the hidden prototype | 1046 // implicitly rewritten with the first object in the hidden prototype |
1047 // chain that actually has the expected type. | 1047 // chain that actually has the expected type. |
1048 static inline Object* TypeCheck(Heap* heap, | 1048 static inline Object* TypeCheck(Heap* heap, Object* recv, |
1049 int argc, | |
1050 Object** argv, | |
1051 FunctionTemplateInfo* info) { | 1049 FunctionTemplateInfo* info) { |
1052 Object* recv = argv[0]; | |
1053 // API calls are only supported with JSObject receivers. | 1050 // API calls are only supported with JSObject receivers. |
1054 if (!recv->IsJSObject()) return heap->null_value(); | 1051 if (!recv->IsJSObject()) return heap->null_value(); |
1055 Object* sig_obj = info->signature(); | 1052 Object* recv_type = info->signature(); |
1056 if (sig_obj->IsUndefined()) return recv; | 1053 if (recv_type->IsUndefined()) return recv; |
1057 SignatureInfo* sig = SignatureInfo::cast(sig_obj); | |
1058 // If necessary, check the receiver | 1054 // If necessary, check the receiver |
1059 Object* recv_type = sig->receiver(); | |
1060 Object* holder = recv; | 1055 Object* holder = recv; |
1061 if (!recv_type->IsUndefined()) { | 1056 if (!recv_type->IsUndefined()) { |
1062 holder = FindHidden(heap, holder, FunctionTemplateInfo::cast(recv_type)); | 1057 holder = FindHidden(heap, holder, FunctionTemplateInfo::cast(recv_type)); |
1063 if (holder == heap->null_value()) return heap->null_value(); | 1058 if (holder == heap->null_value()) return heap->null_value(); |
1064 } | 1059 } |
1065 Object* args_obj = sig->args(); | |
1066 // If there is no argument signature we're done | |
1067 if (args_obj->IsUndefined()) return holder; | |
1068 FixedArray* args = FixedArray::cast(args_obj); | |
1069 int length = args->length(); | |
1070 if (argc <= length) length = argc - 1; | |
1071 for (int i = 0; i < length; i++) { | |
1072 Object* argtype = args->get(i); | |
1073 if (argtype->IsUndefined()) continue; | |
1074 Object** arg = &argv[-1 - i]; | |
1075 Object* current = *arg; | |
1076 current = FindHidden(heap, current, FunctionTemplateInfo::cast(argtype)); | |
1077 if (current == heap->null_value()) current = heap->undefined_value(); | |
1078 *arg = current; | |
1079 } | |
1080 return holder; | 1060 return holder; |
1081 } | 1061 } |
1082 | 1062 |
1083 | 1063 |
1084 template <bool is_construct> | 1064 template <bool is_construct> |
1085 MUST_USE_RESULT static Object* HandleApiCallHelper( | 1065 MUST_USE_RESULT static Object* HandleApiCallHelper( |
1086 BuiltinArguments<NEEDS_CALLED_FUNCTION> args, Isolate* isolate) { | 1066 BuiltinArguments<NEEDS_CALLED_FUNCTION> args, Isolate* isolate) { |
1087 DCHECK(is_construct == CalledAsConstructor(isolate)); | 1067 DCHECK(is_construct == CalledAsConstructor(isolate)); |
1088 Heap* heap = isolate->heap(); | 1068 Heap* heap = isolate->heap(); |
1089 | 1069 |
1090 HandleScope scope(isolate); | 1070 HandleScope scope(isolate); |
1091 Handle<JSFunction> function = args.called_function(); | 1071 Handle<JSFunction> function = args.called_function(); |
1092 // TODO(ishell): turn this back to a DCHECK. | 1072 // TODO(ishell): turn this back to a DCHECK. |
1093 CHECK(function->shared()->IsApiFunction()); | 1073 CHECK(function->shared()->IsApiFunction()); |
1094 | 1074 |
1095 Handle<FunctionTemplateInfo> fun_data( | 1075 Handle<FunctionTemplateInfo> fun_data( |
1096 function->shared()->get_api_func_data(), isolate); | 1076 function->shared()->get_api_func_data(), isolate); |
1097 if (is_construct) { | 1077 if (is_construct) { |
1098 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 1078 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
1099 isolate, fun_data, | 1079 isolate, fun_data, |
1100 isolate->factory()->ConfigureInstance( | 1080 isolate->factory()->ConfigureInstance( |
1101 fun_data, Handle<JSObject>::cast(args.receiver()))); | 1081 fun_data, Handle<JSObject>::cast(args.receiver()))); |
1102 } | 1082 } |
1103 | 1083 |
1104 SharedFunctionInfo* shared = function->shared(); | 1084 DCHECK(!args[0]->IsNull()); |
1105 if (shared->strict_mode() == SLOPPY && !shared->native()) { | 1085 if (args[0]->IsUndefined()) args[0] = function->global_proxy(); |
1106 Object* recv = args[0]; | |
1107 DCHECK(!recv->IsNull()); | |
1108 if (recv->IsUndefined()) args[0] = function->global_proxy(); | |
1109 } | |
1110 | 1086 |
1111 Object* raw_holder = TypeCheck(heap, args.length(), &args[0], *fun_data); | 1087 Object* raw_holder = TypeCheck(heap, args[0], *fun_data); |
1112 | 1088 |
1113 if (raw_holder->IsNull()) { | 1089 if (raw_holder->IsNull()) { |
1114 // This function cannot be called with the given receiver. Abort! | 1090 // This function cannot be called with the given receiver. Abort! |
1115 THROW_NEW_ERROR_RETURN_FAILURE( | 1091 THROW_NEW_ERROR_RETURN_FAILURE( |
1116 isolate, | 1092 isolate, |
1117 NewTypeError("illegal_invocation", HandleVector(&function, 1))); | 1093 NewTypeError("illegal_invocation", HandleVector(&function, 1))); |
1118 } | 1094 } |
1119 | 1095 |
1120 Object* raw_call_data = fun_data->call_code(); | 1096 Object* raw_call_data = fun_data->call_code(); |
1121 if (!raw_call_data->IsUndefined()) { | 1097 if (!raw_call_data->IsUndefined()) { |
(...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1650 } | 1626 } |
1651 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) | 1627 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) |
1652 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) | 1628 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) |
1653 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) | 1629 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) |
1654 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) | 1630 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) |
1655 #undef DEFINE_BUILTIN_ACCESSOR_C | 1631 #undef DEFINE_BUILTIN_ACCESSOR_C |
1656 #undef DEFINE_BUILTIN_ACCESSOR_A | 1632 #undef DEFINE_BUILTIN_ACCESSOR_A |
1657 | 1633 |
1658 | 1634 |
1659 } } // namespace v8::internal | 1635 } } // namespace v8::internal |
OLD | NEW |