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/once.h" | 10 #include "src/base/once.h" |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 NewTypeError(MessageTemplate::kIncompatibleMethodReceiver, \ | 177 NewTypeError(MessageTemplate::kIncompatibleMethodReceiver, \ |
178 isolate->factory()->NewStringFromAsciiChecked(method), \ | 178 isolate->factory()->NewStringFromAsciiChecked(method), \ |
179 args.receiver())); \ | 179 args.receiver())); \ |
180 } \ | 180 } \ |
181 Handle<Type> name = Handle<Type>::cast(args.receiver()) | 181 Handle<Type> name = Handle<Type>::cast(args.receiver()) |
182 | 182 |
183 // Throws a TypeError for {method} if the receiver is not coercible to Object, | 183 // Throws a TypeError for {method} if the receiver is not coercible to Object, |
184 // or converts the receiver to a String otherwise and assigns it to a new var | 184 // or converts the receiver to a String otherwise and assigns it to a new var |
185 // with the given {name}. | 185 // with the given {name}. |
186 #define TO_THIS_STRING(name, method) \ | 186 #define TO_THIS_STRING(name, method) \ |
187 if (args.receiver()->IsNull() || args.receiver()->IsUndefined(isolate)) { \ | 187 if (args.receiver()->IsNull(isolate) || \ |
| 188 args.receiver()->IsUndefined(isolate)) { \ |
188 THROW_NEW_ERROR_RETURN_FAILURE( \ | 189 THROW_NEW_ERROR_RETURN_FAILURE( \ |
189 isolate, \ | 190 isolate, \ |
190 NewTypeError(MessageTemplate::kCalledOnNullOrUndefined, \ | 191 NewTypeError(MessageTemplate::kCalledOnNullOrUndefined, \ |
191 isolate->factory()->NewStringFromAsciiChecked(method))); \ | 192 isolate->factory()->NewStringFromAsciiChecked(method))); \ |
192 } \ | 193 } \ |
193 Handle<String> name; \ | 194 Handle<String> name; \ |
194 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( \ | 195 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( \ |
195 isolate, name, Object::ToString(isolate, args.receiver())) | 196 isolate, name, Object::ToString(isolate, args.receiver())) |
196 | 197 |
197 inline bool ClampedToInteger(Isolate* isolate, Object* object, int* out) { | 198 inline bool ClampedToInteger(Isolate* isolate, Object* object, int* out) { |
198 // This is an extended version of ECMA-262 7.1.11 handling signed values | 199 // This is an extended version of ECMA-262 7.1.11 handling signed values |
199 // Try to convert object to a number and clamp values to [kMinInt, kMaxInt] | 200 // Try to convert object to a number and clamp values to [kMinInt, kMaxInt] |
200 if (object->IsSmi()) { | 201 if (object->IsSmi()) { |
201 *out = Smi::cast(object)->value(); | 202 *out = Smi::cast(object)->value(); |
202 return true; | 203 return true; |
203 } else if (object->IsHeapNumber()) { | 204 } else if (object->IsHeapNumber()) { |
204 double value = HeapNumber::cast(object)->value(); | 205 double value = HeapNumber::cast(object)->value(); |
205 if (std::isnan(value)) { | 206 if (std::isnan(value)) { |
206 *out = 0; | 207 *out = 0; |
207 } else if (value > kMaxInt) { | 208 } else if (value > kMaxInt) { |
208 *out = kMaxInt; | 209 *out = kMaxInt; |
209 } else if (value < kMinInt) { | 210 } else if (value < kMinInt) { |
210 *out = kMinInt; | 211 *out = kMinInt; |
211 } else { | 212 } else { |
212 *out = static_cast<int>(value); | 213 *out = static_cast<int>(value); |
213 } | 214 } |
214 return true; | 215 return true; |
215 } else if (object->IsUndefined(isolate) || object->IsNull()) { | 216 } else if (object->IsUndefined(isolate) || object->IsNull(isolate)) { |
216 *out = 0; | 217 *out = 0; |
217 return true; | 218 return true; |
218 } else if (object->IsBoolean()) { | 219 } else if (object->IsBoolean()) { |
219 *out = object->IsTrue(); | 220 *out = object->IsTrue(isolate); |
220 return true; | 221 return true; |
221 } | 222 } |
222 return false; | 223 return false; |
223 } | 224 } |
224 | 225 |
225 | 226 |
226 inline bool GetSloppyArgumentsLength(Isolate* isolate, Handle<JSObject> object, | 227 inline bool GetSloppyArgumentsLength(Isolate* isolate, Handle<JSObject> object, |
227 int* out) { | 228 int* out) { |
228 Context* context = *isolate->native_context(); | 229 Context* context = *isolate->native_context(); |
229 Map* map = object->map(); | 230 Map* map = object->map(); |
(...skipping 1258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1488 | 1489 |
1489 } // namespace | 1490 } // namespace |
1490 | 1491 |
1491 | 1492 |
1492 // ES6 22.1.3.1 Array.prototype.concat | 1493 // ES6 22.1.3.1 Array.prototype.concat |
1493 BUILTIN(ArrayConcat) { | 1494 BUILTIN(ArrayConcat) { |
1494 HandleScope scope(isolate); | 1495 HandleScope scope(isolate); |
1495 | 1496 |
1496 Handle<Object> receiver = args.receiver(); | 1497 Handle<Object> receiver = args.receiver(); |
1497 // TODO(bmeurer): Do we really care about the exact exception message here? | 1498 // TODO(bmeurer): Do we really care about the exact exception message here? |
1498 if (receiver->IsNull() || receiver->IsUndefined(isolate)) { | 1499 if (receiver->IsNull(isolate) || receiver->IsUndefined(isolate)) { |
1499 THROW_NEW_ERROR_RETURN_FAILURE( | 1500 THROW_NEW_ERROR_RETURN_FAILURE( |
1500 isolate, NewTypeError(MessageTemplate::kCalledOnNullOrUndefined, | 1501 isolate, NewTypeError(MessageTemplate::kCalledOnNullOrUndefined, |
1501 isolate->factory()->NewStringFromAsciiChecked( | 1502 isolate->factory()->NewStringFromAsciiChecked( |
1502 "Array.prototype.concat"))); | 1503 "Array.prototype.concat"))); |
1503 } | 1504 } |
1504 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 1505 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
1505 isolate, receiver, Object::ToObject(isolate, args.receiver())); | 1506 isolate, receiver, Object::ToObject(isolate, args.receiver())); |
1506 args[0] = *receiver; | 1507 args[0] = *receiver; |
1507 | 1508 |
1508 Handle<JSArray> result_array; | 1509 Handle<JSArray> result_array; |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1668 } | 1669 } |
1669 // 5. Return to. | 1670 // 5. Return to. |
1670 return *to; | 1671 return *to; |
1671 } | 1672 } |
1672 | 1673 |
1673 | 1674 |
1674 // ES6 section 19.1.2.2 Object.create ( O [ , Properties ] ) | 1675 // ES6 section 19.1.2.2 Object.create ( O [ , Properties ] ) |
1675 BUILTIN(ObjectCreate) { | 1676 BUILTIN(ObjectCreate) { |
1676 HandleScope scope(isolate); | 1677 HandleScope scope(isolate); |
1677 Handle<Object> prototype = args.atOrUndefined(isolate, 1); | 1678 Handle<Object> prototype = args.atOrUndefined(isolate, 1); |
1678 if (!prototype->IsNull() && !prototype->IsJSReceiver()) { | 1679 if (!prototype->IsNull(isolate) && !prototype->IsJSReceiver()) { |
1679 THROW_NEW_ERROR_RETURN_FAILURE( | 1680 THROW_NEW_ERROR_RETURN_FAILURE( |
1680 isolate, NewTypeError(MessageTemplate::kProtoObjectOrNull, prototype)); | 1681 isolate, NewTypeError(MessageTemplate::kProtoObjectOrNull, prototype)); |
1681 } | 1682 } |
1682 | 1683 |
1683 // Generate the map with the specified {prototype} based on the Object | 1684 // Generate the map with the specified {prototype} based on the Object |
1684 // function's initial map from the current native context. | 1685 // function's initial map from the current native context. |
1685 // TODO(bmeurer): Use a dedicated cache for Object.create; think about | 1686 // TODO(bmeurer): Use a dedicated cache for Object.create; think about |
1686 // slack tracking for Object.create. | 1687 // slack tracking for Object.create. |
1687 Handle<Map> map(isolate->native_context()->object_function()->initial_map(), | 1688 Handle<Map> map(isolate->native_context()->object_function()->initial_map(), |
1688 isolate); | 1689 isolate); |
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2173 isolate, string, | 2174 isolate, string, |
2174 Object::ToString(isolate, args.atOrUndefined(isolate, 1))); | 2175 Object::ToString(isolate, args.atOrUndefined(isolate, 1))); |
2175 | 2176 |
2176 RETURN_RESULT_OR_FAILURE(isolate, Uri::Unescape(isolate, string)); | 2177 RETURN_RESULT_OR_FAILURE(isolate, Uri::Unescape(isolate, string)); |
2177 } | 2178 } |
2178 | 2179 |
2179 namespace { | 2180 namespace { |
2180 | 2181 |
2181 bool CodeGenerationFromStringsAllowed(Isolate* isolate, | 2182 bool CodeGenerationFromStringsAllowed(Isolate* isolate, |
2182 Handle<Context> context) { | 2183 Handle<Context> context) { |
2183 DCHECK(context->allow_code_gen_from_strings()->IsFalse()); | 2184 DCHECK(context->allow_code_gen_from_strings()->IsFalse(isolate)); |
2184 // Check with callback if set. | 2185 // Check with callback if set. |
2185 AllowCodeGenerationFromStringsCallback callback = | 2186 AllowCodeGenerationFromStringsCallback callback = |
2186 isolate->allow_code_gen_callback(); | 2187 isolate->allow_code_gen_callback(); |
2187 if (callback == NULL) { | 2188 if (callback == NULL) { |
2188 // No callback set and code generation disallowed. | 2189 // No callback set and code generation disallowed. |
2189 return false; | 2190 return false; |
2190 } else { | 2191 } else { |
2191 // Callback set. Let it decide if code generation is allowed. | 2192 // Callback set. Let it decide if code generation is allowed. |
2192 VMState<EXTERNAL> state(isolate); | 2193 VMState<EXTERNAL> state(isolate); |
2193 return callback(v8::Utils::ToLocal(context)); | 2194 return callback(v8::Utils::ToLocal(context)); |
2194 } | 2195 } |
2195 } | 2196 } |
2196 | 2197 |
2197 | 2198 |
2198 MaybeHandle<JSFunction> CompileString(Handle<Context> context, | 2199 MaybeHandle<JSFunction> CompileString(Handle<Context> context, |
2199 Handle<String> source, | 2200 Handle<String> source, |
2200 ParseRestriction restriction) { | 2201 ParseRestriction restriction) { |
2201 Isolate* const isolate = context->GetIsolate(); | 2202 Isolate* const isolate = context->GetIsolate(); |
2202 Handle<Context> native_context(context->native_context(), isolate); | 2203 Handle<Context> native_context(context->native_context(), isolate); |
2203 | 2204 |
2204 // Check if native context allows code generation from | 2205 // Check if native context allows code generation from |
2205 // strings. Throw an exception if it doesn't. | 2206 // strings. Throw an exception if it doesn't. |
2206 if (native_context->allow_code_gen_from_strings()->IsFalse() && | 2207 if (native_context->allow_code_gen_from_strings()->IsFalse(isolate) && |
2207 !CodeGenerationFromStringsAllowed(isolate, native_context)) { | 2208 !CodeGenerationFromStringsAllowed(isolate, native_context)) { |
2208 Handle<Object> error_message = | 2209 Handle<Object> error_message = |
2209 native_context->ErrorMessageForCodeGenerationFromStrings(); | 2210 native_context->ErrorMessageForCodeGenerationFromStrings(); |
2210 THROW_NEW_ERROR(isolate, NewEvalError(MessageTemplate::kCodeGenFromStrings, | 2211 THROW_NEW_ERROR(isolate, NewEvalError(MessageTemplate::kCodeGenFromStrings, |
2211 error_message), | 2212 error_message), |
2212 JSFunction); | 2213 JSFunction); |
2213 } | 2214 } |
2214 | 2215 |
2215 // Compile source string in the native context. | 2216 // Compile source string in the native context. |
2216 int eval_scope_position = 0; | 2217 int eval_scope_position = 0; |
(...skipping 652 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2869 Handle<Object> target = args.at<Object>(1); | 2870 Handle<Object> target = args.at<Object>(1); |
2870 Handle<Object> proto = args.at<Object>(2); | 2871 Handle<Object> proto = args.at<Object>(2); |
2871 | 2872 |
2872 if (!target->IsJSReceiver()) { | 2873 if (!target->IsJSReceiver()) { |
2873 THROW_NEW_ERROR_RETURN_FAILURE( | 2874 THROW_NEW_ERROR_RETURN_FAILURE( |
2874 isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, | 2875 isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, |
2875 isolate->factory()->NewStringFromAsciiChecked( | 2876 isolate->factory()->NewStringFromAsciiChecked( |
2876 "Reflect.setPrototypeOf"))); | 2877 "Reflect.setPrototypeOf"))); |
2877 } | 2878 } |
2878 | 2879 |
2879 if (!proto->IsJSReceiver() && !proto->IsNull()) { | 2880 if (!proto->IsJSReceiver() && !proto->IsNull(isolate)) { |
2880 THROW_NEW_ERROR_RETURN_FAILURE( | 2881 THROW_NEW_ERROR_RETURN_FAILURE( |
2881 isolate, NewTypeError(MessageTemplate::kProtoObjectOrNull, proto)); | 2882 isolate, NewTypeError(MessageTemplate::kProtoObjectOrNull, proto)); |
2882 } | 2883 } |
2883 | 2884 |
2884 Maybe<bool> result = JSReceiver::SetPrototype( | 2885 Maybe<bool> result = JSReceiver::SetPrototype( |
2885 Handle<JSReceiver>::cast(target), proto, true, Object::DONT_THROW); | 2886 Handle<JSReceiver>::cast(target), proto, true, Object::DONT_THROW); |
2886 MAYBE_RETURN(result, isolate->heap()->exception()); | 2887 MAYBE_RETURN(result, isolate->heap()->exception()); |
2887 return *isolate->factory()->ToBoolean(result.FromJust()); | 2888 return *isolate->factory()->ToBoolean(result.FromJust()); |
2888 } | 2889 } |
2889 | 2890 |
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3297 } else { | 3298 } else { |
3298 result = DateParser::Parse(str_content.ToUC16Vector(), *tmp, | 3299 result = DateParser::Parse(str_content.ToUC16Vector(), *tmp, |
3299 isolate->unicode_cache()); | 3300 isolate->unicode_cache()); |
3300 } | 3301 } |
3301 if (!result) return std::numeric_limits<double>::quiet_NaN(); | 3302 if (!result) return std::numeric_limits<double>::quiet_NaN(); |
3302 double const day = MakeDay(tmp->get(0)->Number(), tmp->get(1)->Number(), | 3303 double const day = MakeDay(tmp->get(0)->Number(), tmp->get(1)->Number(), |
3303 tmp->get(2)->Number()); | 3304 tmp->get(2)->Number()); |
3304 double const time = MakeTime(tmp->get(3)->Number(), tmp->get(4)->Number(), | 3305 double const time = MakeTime(tmp->get(3)->Number(), tmp->get(4)->Number(), |
3305 tmp->get(5)->Number(), tmp->get(6)->Number()); | 3306 tmp->get(5)->Number(), tmp->get(6)->Number()); |
3306 double date = MakeDate(day, time); | 3307 double date = MakeDate(day, time); |
3307 if (tmp->get(7)->IsNull()) { | 3308 if (tmp->get(7)->IsNull(isolate)) { |
3308 if (!std::isnan(date)) { | 3309 if (!std::isnan(date)) { |
3309 date = isolate->date_cache()->ToUTC(static_cast<int64_t>(date)); | 3310 date = isolate->date_cache()->ToUTC(static_cast<int64_t>(date)); |
3310 } | 3311 } |
3311 } else { | 3312 } else { |
3312 date -= tmp->get(7)->Number() * 1000.0; | 3313 date -= tmp->get(7)->Number() * 1000.0; |
3313 } | 3314 } |
3314 return date; | 3315 return date; |
3315 } | 3316 } |
3316 | 3317 |
3317 | 3318 |
(...skipping 1723 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5041 Handle<JSObject> js_receiver = Handle<JSObject>::cast(receiver); | 5042 Handle<JSObject> js_receiver = Handle<JSObject>::cast(receiver); |
5042 if (!isolate->MayAccess(handle(isolate->context()), js_receiver)) { | 5043 if (!isolate->MayAccess(handle(isolate->context()), js_receiver)) { |
5043 isolate->ReportFailedAccessCheck(js_receiver); | 5044 isolate->ReportFailedAccessCheck(js_receiver); |
5044 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 5045 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
5045 } | 5046 } |
5046 } | 5047 } |
5047 } | 5048 } |
5048 | 5049 |
5049 Object* raw_holder = fun_data->GetCompatibleReceiver(isolate, *receiver); | 5050 Object* raw_holder = fun_data->GetCompatibleReceiver(isolate, *receiver); |
5050 | 5051 |
5051 if (raw_holder->IsNull()) { | 5052 if (raw_holder->IsNull(isolate)) { |
5052 // This function cannot be called with the given receiver. Abort! | 5053 // This function cannot be called with the given receiver. Abort! |
5053 THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kIllegalInvocation), | 5054 THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kIllegalInvocation), |
5054 Object); | 5055 Object); |
5055 } | 5056 } |
5056 | 5057 |
5057 Object* raw_call_data = fun_data->call_code(); | 5058 Object* raw_call_data = fun_data->call_code(); |
5058 if (!raw_call_data->IsUndefined(isolate)) { | 5059 if (!raw_call_data->IsUndefined(isolate)) { |
5059 DCHECK(raw_call_data->IsCallHandlerInfo()); | 5060 DCHECK(raw_call_data->IsCallHandlerInfo()); |
5060 CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data); | 5061 CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data); |
5061 Object* callback_obj = call_data->callback(); | 5062 Object* callback_obj = call_data->callback(); |
(...skipping 855 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5917 BUILTIN_LIST_T(DEFINE_BUILTIN_ACCESSOR_T) | 5918 BUILTIN_LIST_T(DEFINE_BUILTIN_ACCESSOR_T) |
5918 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) | 5919 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) |
5919 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) | 5920 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) |
5920 #undef DEFINE_BUILTIN_ACCESSOR_C | 5921 #undef DEFINE_BUILTIN_ACCESSOR_C |
5921 #undef DEFINE_BUILTIN_ACCESSOR_A | 5922 #undef DEFINE_BUILTIN_ACCESSOR_A |
5922 #undef DEFINE_BUILTIN_ACCESSOR_T | 5923 #undef DEFINE_BUILTIN_ACCESSOR_T |
5923 #undef DEFINE_BUILTIN_ACCESSOR_H | 5924 #undef DEFINE_BUILTIN_ACCESSOR_H |
5924 | 5925 |
5925 } // namespace internal | 5926 } // namespace internal |
5926 } // namespace v8 | 5927 } // namespace v8 |
OLD | NEW |