| 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/ieee754.h" | 10 #include "src/base/ieee754.h" |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 178 NewTypeError(MessageTemplate::kIncompatibleMethodReceiver, \ | 178 NewTypeError(MessageTemplate::kIncompatibleMethodReceiver, \ |
| 179 isolate->factory()->NewStringFromAsciiChecked(method), \ | 179 isolate->factory()->NewStringFromAsciiChecked(method), \ |
| 180 args.receiver())); \ | 180 args.receiver())); \ |
| 181 } \ | 181 } \ |
| 182 Handle<Type> name = Handle<Type>::cast(args.receiver()) | 182 Handle<Type> name = Handle<Type>::cast(args.receiver()) |
| 183 | 183 |
| 184 // Throws a TypeError for {method} if the receiver is not coercible to Object, | 184 // Throws a TypeError for {method} if the receiver is not coercible to Object, |
| 185 // or converts the receiver to a String otherwise and assigns it to a new var | 185 // or converts the receiver to a String otherwise and assigns it to a new var |
| 186 // with the given {name}. | 186 // with the given {name}. |
| 187 #define TO_THIS_STRING(name, method) \ | 187 #define TO_THIS_STRING(name, method) \ |
| 188 if (args.receiver()->IsNull(isolate) || \ | 188 if (args.receiver()->IsNull() || args.receiver()->IsUndefined(isolate)) { \ |
| 189 args.receiver()->IsUndefined(isolate)) { \ | |
| 190 THROW_NEW_ERROR_RETURN_FAILURE( \ | 189 THROW_NEW_ERROR_RETURN_FAILURE( \ |
| 191 isolate, \ | 190 isolate, \ |
| 192 NewTypeError(MessageTemplate::kCalledOnNullOrUndefined, \ | 191 NewTypeError(MessageTemplate::kCalledOnNullOrUndefined, \ |
| 193 isolate->factory()->NewStringFromAsciiChecked(method))); \ | 192 isolate->factory()->NewStringFromAsciiChecked(method))); \ |
| 194 } \ | 193 } \ |
| 195 Handle<String> name; \ | 194 Handle<String> name; \ |
| 196 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( \ | 195 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( \ |
| 197 isolate, name, Object::ToString(isolate, args.receiver())) | 196 isolate, name, Object::ToString(isolate, args.receiver())) |
| 198 | 197 |
| 199 inline bool ClampedToInteger(Isolate* isolate, Object* object, int* out) { | 198 inline bool ClampedToInteger(Isolate* isolate, Object* object, int* out) { |
| 200 // 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 |
| 201 // 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] |
| 202 if (object->IsSmi()) { | 201 if (object->IsSmi()) { |
| 203 *out = Smi::cast(object)->value(); | 202 *out = Smi::cast(object)->value(); |
| 204 return true; | 203 return true; |
| 205 } else if (object->IsHeapNumber()) { | 204 } else if (object->IsHeapNumber()) { |
| 206 double value = HeapNumber::cast(object)->value(); | 205 double value = HeapNumber::cast(object)->value(); |
| 207 if (std::isnan(value)) { | 206 if (std::isnan(value)) { |
| 208 *out = 0; | 207 *out = 0; |
| 209 } else if (value > kMaxInt) { | 208 } else if (value > kMaxInt) { |
| 210 *out = kMaxInt; | 209 *out = kMaxInt; |
| 211 } else if (value < kMinInt) { | 210 } else if (value < kMinInt) { |
| 212 *out = kMinInt; | 211 *out = kMinInt; |
| 213 } else { | 212 } else { |
| 214 *out = static_cast<int>(value); | 213 *out = static_cast<int>(value); |
| 215 } | 214 } |
| 216 return true; | 215 return true; |
| 217 } else if (object->IsUndefined(isolate) || object->IsNull(isolate)) { | 216 } else if (object->IsUndefined(isolate) || object->IsNull()) { |
| 218 *out = 0; | 217 *out = 0; |
| 219 return true; | 218 return true; |
| 220 } else if (object->IsBoolean()) { | 219 } else if (object->IsBoolean()) { |
| 221 *out = object->IsTrue(isolate); | 220 *out = object->IsTrue(); |
| 222 return true; | 221 return true; |
| 223 } | 222 } |
| 224 return false; | 223 return false; |
| 225 } | 224 } |
| 226 | 225 |
| 227 | 226 |
| 228 inline bool GetSloppyArgumentsLength(Isolate* isolate, Handle<JSObject> object, | 227 inline bool GetSloppyArgumentsLength(Isolate* isolate, Handle<JSObject> object, |
| 229 int* out) { | 228 int* out) { |
| 230 Context* context = *isolate->native_context(); | 229 Context* context = *isolate->native_context(); |
| 231 Map* map = object->map(); | 230 Map* map = object->map(); |
| (...skipping 1257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1489 | 1488 |
| 1490 } // namespace | 1489 } // namespace |
| 1491 | 1490 |
| 1492 | 1491 |
| 1493 // ES6 22.1.3.1 Array.prototype.concat | 1492 // ES6 22.1.3.1 Array.prototype.concat |
| 1494 BUILTIN(ArrayConcat) { | 1493 BUILTIN(ArrayConcat) { |
| 1495 HandleScope scope(isolate); | 1494 HandleScope scope(isolate); |
| 1496 | 1495 |
| 1497 Handle<Object> receiver = args.receiver(); | 1496 Handle<Object> receiver = args.receiver(); |
| 1498 // TODO(bmeurer): Do we really care about the exact exception message here? | 1497 // TODO(bmeurer): Do we really care about the exact exception message here? |
| 1499 if (receiver->IsNull(isolate) || receiver->IsUndefined(isolate)) { | 1498 if (receiver->IsNull() || receiver->IsUndefined(isolate)) { |
| 1500 THROW_NEW_ERROR_RETURN_FAILURE( | 1499 THROW_NEW_ERROR_RETURN_FAILURE( |
| 1501 isolate, NewTypeError(MessageTemplate::kCalledOnNullOrUndefined, | 1500 isolate, NewTypeError(MessageTemplate::kCalledOnNullOrUndefined, |
| 1502 isolate->factory()->NewStringFromAsciiChecked( | 1501 isolate->factory()->NewStringFromAsciiChecked( |
| 1503 "Array.prototype.concat"))); | 1502 "Array.prototype.concat"))); |
| 1504 } | 1503 } |
| 1505 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 1504 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| 1506 isolate, receiver, Object::ToObject(isolate, args.receiver())); | 1505 isolate, receiver, Object::ToObject(isolate, args.receiver())); |
| 1507 args[0] = *receiver; | 1506 args[0] = *receiver; |
| 1508 | 1507 |
| 1509 Handle<JSArray> result_array; | 1508 Handle<JSArray> result_array; |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1669 } | 1668 } |
| 1670 // 5. Return to. | 1669 // 5. Return to. |
| 1671 return *to; | 1670 return *to; |
| 1672 } | 1671 } |
| 1673 | 1672 |
| 1674 | 1673 |
| 1675 // ES6 section 19.1.2.2 Object.create ( O [ , Properties ] ) | 1674 // ES6 section 19.1.2.2 Object.create ( O [ , Properties ] ) |
| 1676 BUILTIN(ObjectCreate) { | 1675 BUILTIN(ObjectCreate) { |
| 1677 HandleScope scope(isolate); | 1676 HandleScope scope(isolate); |
| 1678 Handle<Object> prototype = args.atOrUndefined(isolate, 1); | 1677 Handle<Object> prototype = args.atOrUndefined(isolate, 1); |
| 1679 if (!prototype->IsNull(isolate) && !prototype->IsJSReceiver()) { | 1678 if (!prototype->IsNull() && !prototype->IsJSReceiver()) { |
| 1680 THROW_NEW_ERROR_RETURN_FAILURE( | 1679 THROW_NEW_ERROR_RETURN_FAILURE( |
| 1681 isolate, NewTypeError(MessageTemplate::kProtoObjectOrNull, prototype)); | 1680 isolate, NewTypeError(MessageTemplate::kProtoObjectOrNull, prototype)); |
| 1682 } | 1681 } |
| 1683 | 1682 |
| 1684 // Generate the map with the specified {prototype} based on the Object | 1683 // Generate the map with the specified {prototype} based on the Object |
| 1685 // function's initial map from the current native context. | 1684 // function's initial map from the current native context. |
| 1686 // TODO(bmeurer): Use a dedicated cache for Object.create; think about | 1685 // TODO(bmeurer): Use a dedicated cache for Object.create; think about |
| 1687 // slack tracking for Object.create. | 1686 // slack tracking for Object.create. |
| 1688 Handle<Map> map(isolate->native_context()->object_function()->initial_map(), | 1687 Handle<Map> map(isolate->native_context()->object_function()->initial_map(), |
| 1689 isolate); | 1688 isolate); |
| (...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2174 isolate, string, | 2173 isolate, string, |
| 2175 Object::ToString(isolate, args.atOrUndefined(isolate, 1))); | 2174 Object::ToString(isolate, args.atOrUndefined(isolate, 1))); |
| 2176 | 2175 |
| 2177 RETURN_RESULT_OR_FAILURE(isolate, Uri::Unescape(isolate, string)); | 2176 RETURN_RESULT_OR_FAILURE(isolate, Uri::Unescape(isolate, string)); |
| 2178 } | 2177 } |
| 2179 | 2178 |
| 2180 namespace { | 2179 namespace { |
| 2181 | 2180 |
| 2182 bool CodeGenerationFromStringsAllowed(Isolate* isolate, | 2181 bool CodeGenerationFromStringsAllowed(Isolate* isolate, |
| 2183 Handle<Context> context) { | 2182 Handle<Context> context) { |
| 2184 DCHECK(context->allow_code_gen_from_strings()->IsFalse(isolate)); | 2183 DCHECK(context->allow_code_gen_from_strings()->IsFalse()); |
| 2185 // Check with callback if set. | 2184 // Check with callback if set. |
| 2186 AllowCodeGenerationFromStringsCallback callback = | 2185 AllowCodeGenerationFromStringsCallback callback = |
| 2187 isolate->allow_code_gen_callback(); | 2186 isolate->allow_code_gen_callback(); |
| 2188 if (callback == NULL) { | 2187 if (callback == NULL) { |
| 2189 // No callback set and code generation disallowed. | 2188 // No callback set and code generation disallowed. |
| 2190 return false; | 2189 return false; |
| 2191 } else { | 2190 } else { |
| 2192 // Callback set. Let it decide if code generation is allowed. | 2191 // Callback set. Let it decide if code generation is allowed. |
| 2193 VMState<EXTERNAL> state(isolate); | 2192 VMState<EXTERNAL> state(isolate); |
| 2194 return callback(v8::Utils::ToLocal(context)); | 2193 return callback(v8::Utils::ToLocal(context)); |
| 2195 } | 2194 } |
| 2196 } | 2195 } |
| 2197 | 2196 |
| 2198 | 2197 |
| 2199 MaybeHandle<JSFunction> CompileString(Handle<Context> context, | 2198 MaybeHandle<JSFunction> CompileString(Handle<Context> context, |
| 2200 Handle<String> source, | 2199 Handle<String> source, |
| 2201 ParseRestriction restriction) { | 2200 ParseRestriction restriction) { |
| 2202 Isolate* const isolate = context->GetIsolate(); | 2201 Isolate* const isolate = context->GetIsolate(); |
| 2203 Handle<Context> native_context(context->native_context(), isolate); | 2202 Handle<Context> native_context(context->native_context(), isolate); |
| 2204 | 2203 |
| 2205 // Check if native context allows code generation from | 2204 // Check if native context allows code generation from |
| 2206 // strings. Throw an exception if it doesn't. | 2205 // strings. Throw an exception if it doesn't. |
| 2207 if (native_context->allow_code_gen_from_strings()->IsFalse(isolate) && | 2206 if (native_context->allow_code_gen_from_strings()->IsFalse() && |
| 2208 !CodeGenerationFromStringsAllowed(isolate, native_context)) { | 2207 !CodeGenerationFromStringsAllowed(isolate, native_context)) { |
| 2209 Handle<Object> error_message = | 2208 Handle<Object> error_message = |
| 2210 native_context->ErrorMessageForCodeGenerationFromStrings(); | 2209 native_context->ErrorMessageForCodeGenerationFromStrings(); |
| 2211 THROW_NEW_ERROR(isolate, NewEvalError(MessageTemplate::kCodeGenFromStrings, | 2210 THROW_NEW_ERROR(isolate, NewEvalError(MessageTemplate::kCodeGenFromStrings, |
| 2212 error_message), | 2211 error_message), |
| 2213 JSFunction); | 2212 JSFunction); |
| 2214 } | 2213 } |
| 2215 | 2214 |
| 2216 // Compile source string in the native context. | 2215 // Compile source string in the native context. |
| 2217 int eval_scope_position = 0; | 2216 int eval_scope_position = 0; |
| (...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2898 Handle<Object> target = args.at<Object>(1); | 2897 Handle<Object> target = args.at<Object>(1); |
| 2899 Handle<Object> proto = args.at<Object>(2); | 2898 Handle<Object> proto = args.at<Object>(2); |
| 2900 | 2899 |
| 2901 if (!target->IsJSReceiver()) { | 2900 if (!target->IsJSReceiver()) { |
| 2902 THROW_NEW_ERROR_RETURN_FAILURE( | 2901 THROW_NEW_ERROR_RETURN_FAILURE( |
| 2903 isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, | 2902 isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, |
| 2904 isolate->factory()->NewStringFromAsciiChecked( | 2903 isolate->factory()->NewStringFromAsciiChecked( |
| 2905 "Reflect.setPrototypeOf"))); | 2904 "Reflect.setPrototypeOf"))); |
| 2906 } | 2905 } |
| 2907 | 2906 |
| 2908 if (!proto->IsJSReceiver() && !proto->IsNull(isolate)) { | 2907 if (!proto->IsJSReceiver() && !proto->IsNull()) { |
| 2909 THROW_NEW_ERROR_RETURN_FAILURE( | 2908 THROW_NEW_ERROR_RETURN_FAILURE( |
| 2910 isolate, NewTypeError(MessageTemplate::kProtoObjectOrNull, proto)); | 2909 isolate, NewTypeError(MessageTemplate::kProtoObjectOrNull, proto)); |
| 2911 } | 2910 } |
| 2912 | 2911 |
| 2913 Maybe<bool> result = JSReceiver::SetPrototype( | 2912 Maybe<bool> result = JSReceiver::SetPrototype( |
| 2914 Handle<JSReceiver>::cast(target), proto, true, Object::DONT_THROW); | 2913 Handle<JSReceiver>::cast(target), proto, true, Object::DONT_THROW); |
| 2915 MAYBE_RETURN(result, isolate->heap()->exception()); | 2914 MAYBE_RETURN(result, isolate->heap()->exception()); |
| 2916 return *isolate->factory()->ToBoolean(result.FromJust()); | 2915 return *isolate->factory()->ToBoolean(result.FromJust()); |
| 2917 } | 2916 } |
| 2918 | 2917 |
| (...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3324 result = DateParser::Parse(isolate, str_content.ToOneByteVector(), *tmp); | 3323 result = DateParser::Parse(isolate, str_content.ToOneByteVector(), *tmp); |
| 3325 } else { | 3324 } else { |
| 3326 result = DateParser::Parse(isolate, str_content.ToUC16Vector(), *tmp); | 3325 result = DateParser::Parse(isolate, str_content.ToUC16Vector(), *tmp); |
| 3327 } | 3326 } |
| 3328 if (!result) return std::numeric_limits<double>::quiet_NaN(); | 3327 if (!result) return std::numeric_limits<double>::quiet_NaN(); |
| 3329 double const day = MakeDay(tmp->get(0)->Number(), tmp->get(1)->Number(), | 3328 double const day = MakeDay(tmp->get(0)->Number(), tmp->get(1)->Number(), |
| 3330 tmp->get(2)->Number()); | 3329 tmp->get(2)->Number()); |
| 3331 double const time = MakeTime(tmp->get(3)->Number(), tmp->get(4)->Number(), | 3330 double const time = MakeTime(tmp->get(3)->Number(), tmp->get(4)->Number(), |
| 3332 tmp->get(5)->Number(), tmp->get(6)->Number()); | 3331 tmp->get(5)->Number(), tmp->get(6)->Number()); |
| 3333 double date = MakeDate(day, time); | 3332 double date = MakeDate(day, time); |
| 3334 if (tmp->get(7)->IsNull(isolate)) { | 3333 if (tmp->get(7)->IsNull()) { |
| 3335 if (!std::isnan(date)) { | 3334 if (!std::isnan(date)) { |
| 3336 date = isolate->date_cache()->ToUTC(static_cast<int64_t>(date)); | 3335 date = isolate->date_cache()->ToUTC(static_cast<int64_t>(date)); |
| 3337 } | 3336 } |
| 3338 } else { | 3337 } else { |
| 3339 date -= tmp->get(7)->Number() * 1000.0; | 3338 date -= tmp->get(7)->Number() * 1000.0; |
| 3340 } | 3339 } |
| 3341 return date; | 3340 return date; |
| 3342 } | 3341 } |
| 3343 | 3342 |
| 3344 | 3343 |
| (...skipping 1740 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5085 Handle<JSObject> js_receiver = Handle<JSObject>::cast(receiver); | 5084 Handle<JSObject> js_receiver = Handle<JSObject>::cast(receiver); |
| 5086 if (!isolate->MayAccess(handle(isolate->context()), js_receiver)) { | 5085 if (!isolate->MayAccess(handle(isolate->context()), js_receiver)) { |
| 5087 isolate->ReportFailedAccessCheck(js_receiver); | 5086 isolate->ReportFailedAccessCheck(js_receiver); |
| 5088 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 5087 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
| 5089 } | 5088 } |
| 5090 } | 5089 } |
| 5091 } | 5090 } |
| 5092 | 5091 |
| 5093 Object* raw_holder = fun_data->GetCompatibleReceiver(isolate, *receiver); | 5092 Object* raw_holder = fun_data->GetCompatibleReceiver(isolate, *receiver); |
| 5094 | 5093 |
| 5095 if (raw_holder->IsNull(isolate)) { | 5094 if (raw_holder->IsNull()) { |
| 5096 // This function cannot be called with the given receiver. Abort! | 5095 // This function cannot be called with the given receiver. Abort! |
| 5097 THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kIllegalInvocation), | 5096 THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kIllegalInvocation), |
| 5098 Object); | 5097 Object); |
| 5099 } | 5098 } |
| 5100 | 5099 |
| 5101 Object* raw_call_data = fun_data->call_code(); | 5100 Object* raw_call_data = fun_data->call_code(); |
| 5102 if (!raw_call_data->IsUndefined(isolate)) { | 5101 if (!raw_call_data->IsUndefined(isolate)) { |
| 5103 DCHECK(raw_call_data->IsCallHandlerInfo()); | 5102 DCHECK(raw_call_data->IsCallHandlerInfo()); |
| 5104 CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data); | 5103 CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data); |
| 5105 Object* callback_obj = call_data->callback(); | 5104 Object* callback_obj = call_data->callback(); |
| (...skipping 900 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6006 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) | 6005 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) |
| 6007 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) | 6006 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) |
| 6008 #undef DEFINE_BUILTIN_ACCESSOR_C | 6007 #undef DEFINE_BUILTIN_ACCESSOR_C |
| 6009 #undef DEFINE_BUILTIN_ACCESSOR_A | 6008 #undef DEFINE_BUILTIN_ACCESSOR_A |
| 6010 #undef DEFINE_BUILTIN_ACCESSOR_T | 6009 #undef DEFINE_BUILTIN_ACCESSOR_T |
| 6011 #undef DEFINE_BUILTIN_ACCESSOR_S | 6010 #undef DEFINE_BUILTIN_ACCESSOR_S |
| 6012 #undef DEFINE_BUILTIN_ACCESSOR_H | 6011 #undef DEFINE_BUILTIN_ACCESSOR_H |
| 6013 | 6012 |
| 6014 } // namespace internal | 6013 } // namespace internal |
| 6015 } // namespace v8 | 6014 } // namespace v8 |
| OLD | NEW |