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 |