| 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 |