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() || args.receiver()->IsUndefined(isolate)) { \ | 188 if (args.receiver()->IsNull(isolate) || \ |
| 189 args.receiver()->IsUndefined(isolate)) { \ |
189 THROW_NEW_ERROR_RETURN_FAILURE( \ | 190 THROW_NEW_ERROR_RETURN_FAILURE( \ |
190 isolate, \ | 191 isolate, \ |
191 NewTypeError(MessageTemplate::kCalledOnNullOrUndefined, \ | 192 NewTypeError(MessageTemplate::kCalledOnNullOrUndefined, \ |
192 isolate->factory()->NewStringFromAsciiChecked(method))); \ | 193 isolate->factory()->NewStringFromAsciiChecked(method))); \ |
193 } \ | 194 } \ |
194 Handle<String> name; \ | 195 Handle<String> name; \ |
195 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( \ | 196 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( \ |
196 isolate, name, Object::ToString(isolate, args.receiver())) | 197 isolate, name, Object::ToString(isolate, args.receiver())) |
197 | 198 |
198 inline bool ClampedToInteger(Isolate* isolate, Object* object, int* out) { | 199 inline bool ClampedToInteger(Isolate* isolate, Object* object, int* out) { |
199 // This is an extended version of ECMA-262 7.1.11 handling signed values | 200 // This is an extended version of ECMA-262 7.1.11 handling signed values |
200 // Try to convert object to a number and clamp values to [kMinInt, kMaxInt] | 201 // Try to convert object to a number and clamp values to [kMinInt, kMaxInt] |
201 if (object->IsSmi()) { | 202 if (object->IsSmi()) { |
202 *out = Smi::cast(object)->value(); | 203 *out = Smi::cast(object)->value(); |
203 return true; | 204 return true; |
204 } else if (object->IsHeapNumber()) { | 205 } else if (object->IsHeapNumber()) { |
205 double value = HeapNumber::cast(object)->value(); | 206 double value = HeapNumber::cast(object)->value(); |
206 if (std::isnan(value)) { | 207 if (std::isnan(value)) { |
207 *out = 0; | 208 *out = 0; |
208 } else if (value > kMaxInt) { | 209 } else if (value > kMaxInt) { |
209 *out = kMaxInt; | 210 *out = kMaxInt; |
210 } else if (value < kMinInt) { | 211 } else if (value < kMinInt) { |
211 *out = kMinInt; | 212 *out = kMinInt; |
212 } else { | 213 } else { |
213 *out = static_cast<int>(value); | 214 *out = static_cast<int>(value); |
214 } | 215 } |
215 return true; | 216 return true; |
216 } else if (object->IsUndefined(isolate) || object->IsNull()) { | 217 } else if (object->IsUndefined(isolate) || object->IsNull(isolate)) { |
217 *out = 0; | 218 *out = 0; |
218 return true; | 219 return true; |
219 } else if (object->IsBoolean()) { | 220 } else if (object->IsBoolean()) { |
220 *out = object->IsTrue(); | 221 *out = object->IsTrue(isolate); |
221 return true; | 222 return true; |
222 } | 223 } |
223 return false; | 224 return false; |
224 } | 225 } |
225 | 226 |
226 | 227 |
227 inline bool GetSloppyArgumentsLength(Isolate* isolate, Handle<JSObject> object, | 228 inline bool GetSloppyArgumentsLength(Isolate* isolate, Handle<JSObject> object, |
228 int* out) { | 229 int* out) { |
229 Context* context = *isolate->native_context(); | 230 Context* context = *isolate->native_context(); |
230 Map* map = object->map(); | 231 Map* map = object->map(); |
(...skipping 1257 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 680 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2897 Handle<Object> target = args.at<Object>(1); | 2898 Handle<Object> target = args.at<Object>(1); |
2898 Handle<Object> proto = args.at<Object>(2); | 2899 Handle<Object> proto = args.at<Object>(2); |
2899 | 2900 |
2900 if (!target->IsJSReceiver()) { | 2901 if (!target->IsJSReceiver()) { |
2901 THROW_NEW_ERROR_RETURN_FAILURE( | 2902 THROW_NEW_ERROR_RETURN_FAILURE( |
2902 isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, | 2903 isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, |
2903 isolate->factory()->NewStringFromAsciiChecked( | 2904 isolate->factory()->NewStringFromAsciiChecked( |
2904 "Reflect.setPrototypeOf"))); | 2905 "Reflect.setPrototypeOf"))); |
2905 } | 2906 } |
2906 | 2907 |
2907 if (!proto->IsJSReceiver() && !proto->IsNull()) { | 2908 if (!proto->IsJSReceiver() && !proto->IsNull(isolate)) { |
2908 THROW_NEW_ERROR_RETURN_FAILURE( | 2909 THROW_NEW_ERROR_RETURN_FAILURE( |
2909 isolate, NewTypeError(MessageTemplate::kProtoObjectOrNull, proto)); | 2910 isolate, NewTypeError(MessageTemplate::kProtoObjectOrNull, proto)); |
2910 } | 2911 } |
2911 | 2912 |
2912 Maybe<bool> result = JSReceiver::SetPrototype( | 2913 Maybe<bool> result = JSReceiver::SetPrototype( |
2913 Handle<JSReceiver>::cast(target), proto, true, Object::DONT_THROW); | 2914 Handle<JSReceiver>::cast(target), proto, true, Object::DONT_THROW); |
2914 MAYBE_RETURN(result, isolate->heap()->exception()); | 2915 MAYBE_RETURN(result, isolate->heap()->exception()); |
2915 return *isolate->factory()->ToBoolean(result.FromJust()); | 2916 return *isolate->factory()->ToBoolean(result.FromJust()); |
2916 } | 2917 } |
2917 | 2918 |
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3323 result = DateParser::Parse(isolate, str_content.ToOneByteVector(), *tmp); | 3324 result = DateParser::Parse(isolate, str_content.ToOneByteVector(), *tmp); |
3324 } else { | 3325 } else { |
3325 result = DateParser::Parse(isolate, str_content.ToUC16Vector(), *tmp); | 3326 result = DateParser::Parse(isolate, str_content.ToUC16Vector(), *tmp); |
3326 } | 3327 } |
3327 if (!result) return std::numeric_limits<double>::quiet_NaN(); | 3328 if (!result) return std::numeric_limits<double>::quiet_NaN(); |
3328 double const day = MakeDay(tmp->get(0)->Number(), tmp->get(1)->Number(), | 3329 double const day = MakeDay(tmp->get(0)->Number(), tmp->get(1)->Number(), |
3329 tmp->get(2)->Number()); | 3330 tmp->get(2)->Number()); |
3330 double const time = MakeTime(tmp->get(3)->Number(), tmp->get(4)->Number(), | 3331 double const time = MakeTime(tmp->get(3)->Number(), tmp->get(4)->Number(), |
3331 tmp->get(5)->Number(), tmp->get(6)->Number()); | 3332 tmp->get(5)->Number(), tmp->get(6)->Number()); |
3332 double date = MakeDate(day, time); | 3333 double date = MakeDate(day, time); |
3333 if (tmp->get(7)->IsNull()) { | 3334 if (tmp->get(7)->IsNull(isolate)) { |
3334 if (!std::isnan(date)) { | 3335 if (!std::isnan(date)) { |
3335 date = isolate->date_cache()->ToUTC(static_cast<int64_t>(date)); | 3336 date = isolate->date_cache()->ToUTC(static_cast<int64_t>(date)); |
3336 } | 3337 } |
3337 } else { | 3338 } else { |
3338 date -= tmp->get(7)->Number() * 1000.0; | 3339 date -= tmp->get(7)->Number() * 1000.0; |
3339 } | 3340 } |
3340 return date; | 3341 return date; |
3341 } | 3342 } |
3342 | 3343 |
3343 | 3344 |
(...skipping 1740 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5084 Handle<JSObject> js_receiver = Handle<JSObject>::cast(receiver); | 5085 Handle<JSObject> js_receiver = Handle<JSObject>::cast(receiver); |
5085 if (!isolate->MayAccess(handle(isolate->context()), js_receiver)) { | 5086 if (!isolate->MayAccess(handle(isolate->context()), js_receiver)) { |
5086 isolate->ReportFailedAccessCheck(js_receiver); | 5087 isolate->ReportFailedAccessCheck(js_receiver); |
5087 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 5088 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
5088 } | 5089 } |
5089 } | 5090 } |
5090 } | 5091 } |
5091 | 5092 |
5092 Object* raw_holder = fun_data->GetCompatibleReceiver(isolate, *receiver); | 5093 Object* raw_holder = fun_data->GetCompatibleReceiver(isolate, *receiver); |
5093 | 5094 |
5094 if (raw_holder->IsNull()) { | 5095 if (raw_holder->IsNull(isolate)) { |
5095 // This function cannot be called with the given receiver. Abort! | 5096 // This function cannot be called with the given receiver. Abort! |
5096 THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kIllegalInvocation), | 5097 THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kIllegalInvocation), |
5097 Object); | 5098 Object); |
5098 } | 5099 } |
5099 | 5100 |
5100 Object* raw_call_data = fun_data->call_code(); | 5101 Object* raw_call_data = fun_data->call_code(); |
5101 if (!raw_call_data->IsUndefined(isolate)) { | 5102 if (!raw_call_data->IsUndefined(isolate)) { |
5102 DCHECK(raw_call_data->IsCallHandlerInfo()); | 5103 DCHECK(raw_call_data->IsCallHandlerInfo()); |
5103 CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data); | 5104 CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data); |
5104 Object* callback_obj = call_data->callback(); | 5105 Object* callback_obj = call_data->callback(); |
(...skipping 900 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6005 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) | 6006 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) |
6006 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) | 6007 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) |
6007 #undef DEFINE_BUILTIN_ACCESSOR_C | 6008 #undef DEFINE_BUILTIN_ACCESSOR_C |
6008 #undef DEFINE_BUILTIN_ACCESSOR_A | 6009 #undef DEFINE_BUILTIN_ACCESSOR_A |
6009 #undef DEFINE_BUILTIN_ACCESSOR_T | 6010 #undef DEFINE_BUILTIN_ACCESSOR_T |
6010 #undef DEFINE_BUILTIN_ACCESSOR_S | 6011 #undef DEFINE_BUILTIN_ACCESSOR_S |
6011 #undef DEFINE_BUILTIN_ACCESSOR_H | 6012 #undef DEFINE_BUILTIN_ACCESSOR_H |
6012 | 6013 |
6013 } // namespace internal | 6014 } // namespace internal |
6014 } // namespace v8 | 6015 } // namespace v8 |
OLD | NEW |