uint32_t length = 0;
if (!FastAsArrayLength(isolate, length_obj, &length)) {
Handle<Object> uint32_v;
- if (!Execution::ToUint32(isolate, length_obj).ToHandle(&uint32_v)) {
+ if (!Object::ToUint32(isolate, length_obj).ToHandle(&uint32_v)) {
isolate->OptionalRescheduleException(false);
return;
}
PREPARE_FOR_EXECUTION(context, "ToInteger", Integer);
Local<Integer> result;
has_pending_exception =
- !ToLocal<Integer>(i::Execution::ToInteger(isolate, obj), &result);
+ !ToLocal<Integer>(i::Object::ToInteger(isolate, obj), &result);
RETURN_ON_FAILED_EXECUTION(Integer);
RETURN_ESCAPED(result);
}
Local<Int32> result;
PREPARE_FOR_EXECUTION(context, "ToInt32", Int32);
has_pending_exception =
- !ToLocal<Int32>(i::Execution::ToInt32(isolate, obj), &result);
+ !ToLocal<Int32>(i::Object::ToInt32(isolate, obj), &result);
RETURN_ON_FAILED_EXECUTION(Int32);
RETURN_ESCAPED(result);
}
auto obj = Utils::OpenHandle(this);
if (obj->IsSmi()) return ToApiHandle<Uint32>(obj);
Local<Uint32> result;
- PREPARE_FOR_EXECUTION(context, "ToUInt32", Uint32);
+ PREPARE_FOR_EXECUTION(context, "ToUint32", Uint32);
has_pending_exception =
- !ToLocal<Uint32>(i::Execution::ToUint32(isolate, obj), &result);
+ !ToLocal<Uint32>(i::Object::ToUint32(isolate, obj), &result);
RETURN_ON_FAILED_EXECUTION(Uint32);
RETURN_ESCAPED(result);
}
num = obj;
} else {
PREPARE_FOR_EXECUTION_PRIMITIVE(context, "IntegerValue", int64_t);
- has_pending_exception =
- !i::Execution::ToInteger(isolate, obj).ToHandle(&num);
+ has_pending_exception = !i::Object::ToInteger(isolate, obj).ToHandle(&num);
RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int64_t);
}
return Just(num->IsSmi() ? static_cast<int64_t>(i::Smi::cast(*num)->value())
if (obj->IsNumber()) return Just(NumberToInt32(*obj));
PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Int32Value", int32_t);
i::Handle<i::Object> num;
- has_pending_exception = !i::Execution::ToInt32(isolate, obj).ToHandle(&num);
+ has_pending_exception = !i::Object::ToInt32(isolate, obj).ToHandle(&num);
RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int32_t);
return Just(num->IsSmi() ? i::Smi::cast(*num)->value()
: static_cast<int32_t>(num->Number()));
if (obj->IsNumber()) return Just(NumberToUint32(*obj));
PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Uint32Value", uint32_t);
i::Handle<i::Object> num;
- has_pending_exception = !i::Execution::ToUint32(isolate, obj).ToHandle(&num);
+ has_pending_exception = !i::Object::ToUint32(isolate, obj).ToHandle(&num);
RETURN_ON_FAILED_EXECUTION_PRIMITIVE(uint32_t);
return Just(num->IsSmi() ? static_cast<uint32_t>(i::Smi::cast(*num)->value())
: static_cast<uint32_t>(num->Number()));
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
isolate, val, Runtime::GetObjectProperty(isolate, receiver, key),
false);
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, val,
+ Object::ToLength(isolate, val), false);
// TODO(caitp): Support larger element indexes (up to 2^53-1).
if (!val->ToUint32(&length)) {
- ASSIGN_RETURN_ON_EXCEPTION_VALUE(
- isolate, val, Execution::ToLength(isolate, val), false);
- val->ToUint32(&length);
+ length = 0;
}
}
case Runtime::kInlineGetPrototype:
case Runtime::kInlineRegExpExec:
case Runtime::kInlineSubString:
+ case Runtime::kInlineToInteger:
+ case Runtime::kInlineToLength:
case Runtime::kInlineToName:
case Runtime::kInlineToNumber:
case Runtime::kInlineToObject:
V(REFLECT_CONSTRUCT_INDEX, JSFunction, reflect_construct) \
V(SPREAD_ARGUMENTS_INDEX, JSFunction, spread_arguments) \
V(SPREAD_ITERABLE_INDEX, JSFunction, spread_iterable) \
- V(TO_LENGTH_FUN_INDEX, JSFunction, to_length_fun) \
V(TO_NUMBER_FUN_INDEX, JSFunction, to_number_fun)
V(TO_COMPLETE_PROPERTY_DESCRIPTOR_INDEX, JSFunction, \
to_complete_property_descriptor) \
V(TO_DETAIL_STRING_FUN_INDEX, JSFunction, to_detail_string_fun) \
- V(TO_INTEGER_FUN_INDEX, JSFunction, to_integer_fun) \
V(TYPE_ERROR_FUNCTION_INDEX, JSFunction, type_error_function) \
V(URI_ERROR_FUNCTION_INDEX, JSFunction, uri_error_function) \
NATIVE_CONTEXT_JS_BUILTINS(V)
}
-MaybeHandle<Object> Execution::ToInteger(
- Isolate* isolate, Handle<Object> obj) {
- RETURN_NATIVE_CALL(to_integer, { obj });
-}
-
-
-MaybeHandle<Object> Execution::ToLength(
- Isolate* isolate, Handle<Object> obj) {
- RETURN_NATIVE_CALL(to_length, { obj });
-}
-
-
MaybeHandle<Object> Execution::NewDate(Isolate* isolate, double time) {
Handle<Object> time_obj = isolate->factory()->NewNumber(time);
RETURN_NATIVE_CALL(create_date, { time_obj });
#undef RETURN_NATIVE_CALL
-MaybeHandle<Object> Execution::ToInt32(Isolate* isolate, Handle<Object> obj) {
- ASSIGN_RETURN_ON_EXCEPTION(isolate, obj, Object::ToNumber(obj), Object);
- return isolate->factory()->NewNumberFromInt(DoubleToInt32(obj->Number()));
-}
-
-
MaybeHandle<Object> Execution::ToObject(Isolate* isolate, Handle<Object> obj) {
Handle<JSReceiver> receiver;
if (JSReceiver::ToObject(isolate, obj).ToHandle(&receiver)) {
}
-MaybeHandle<Object> Execution::ToUint32(Isolate* isolate, Handle<Object> obj) {
- ASSIGN_RETURN_ON_EXCEPTION(isolate, obj, Object::ToNumber(obj), Object);
- return isolate->factory()->NewNumberFromUint(DoubleToUint32(obj->Number()));
-}
-
-
MaybeHandle<JSRegExp> Execution::NewJSRegExp(Handle<String> pattern,
Handle<String> flags) {
Isolate* isolate = pattern->GetIsolate();
Handle<Object> argv[],
MaybeHandle<Object>* exception_out = NULL);
- // ECMA-262 9.4
- MUST_USE_RESULT static MaybeHandle<Object> ToInteger(
- Isolate* isolate, Handle<Object> obj);
-
- // ECMA-262 9.5
- MUST_USE_RESULT static MaybeHandle<Object> ToInt32(
- Isolate* isolate, Handle<Object> obj);
-
- // ECMA-262 9.6
- MUST_USE_RESULT static MaybeHandle<Object> ToUint32(
- Isolate* isolate, Handle<Object> obj);
-
-
- // ES6, draft 10-14-14, section 7.1.15
- MUST_USE_RESULT static MaybeHandle<Object> ToLength(
- Isolate* isolate, Handle<Object> obj);
-
// ECMA-262 9.8
MUST_USE_RESULT static MaybeHandle<Object> ToDetailString(
Isolate* isolate, Handle<Object> obj);
}
+void FullCodeGenerator::EmitToInteger(CallRuntime* expr) {
+ ZoneList<Expression*>* args = expr->arguments();
+ DCHECK_EQ(1, args->length());
+
+ // Load the argument into r0 and convert it.
+ VisitForAccumulatorValue(args->at(0));
+
+ // Convert the object to an integer.
+ Label done_convert;
+ __ JumpIfSmi(r0, &done_convert);
+ __ Push(r0);
+ __ CallRuntime(Runtime::kToInteger, 1);
+ __ bind(&done_convert);
+ context()->Plug(r0);
+}
+
+
void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK_EQ(args->length(), 1);
}
+void FullCodeGenerator::EmitToInteger(CallRuntime* expr) {
+ ZoneList<Expression*>* args = expr->arguments();
+ DCHECK_EQ(1, args->length());
+
+ // Load the argument into x0 and convert it.
+ VisitForAccumulatorValue(args->at(0));
+
+ // Convert the object to an integer.
+ Label done_convert;
+ __ JumpIfSmi(x0, &done_convert);
+ __ Push(x0);
+ __ CallRuntime(Runtime::kToInteger, 1);
+ __ bind(&done_convert);
+ context()->Plug(x0);
+}
+
+
void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK_EQ(args->length(), 1);
void EmitKeyedCallWithLoadIC(Call* expr, Expression* key);
void EmitKeyedSuperCallWithLoadIC(Call* expr);
-#define FOR_EACH_FULL_CODE_INTRINSIC(F) \
- F(IsSmi) \
- F(IsArray) \
- F(IsTypedArray) \
- F(IsRegExp) \
- F(IsJSProxy) \
- F(IsConstructCall) \
- F(Call) \
- F(CallFunction) \
- F(DefaultConstructorCallSuper) \
- F(ArgumentsLength) \
- F(Arguments) \
- F(ValueOf) \
- F(SetValueOf) \
- F(IsDate) \
- F(DateField) \
- F(StringCharFromCode) \
- F(StringCharAt) \
- F(OneByteSeqStringSetChar) \
- F(TwoByteSeqStringSetChar) \
- F(ObjectEquals) \
- F(IsFunction) \
- F(IsSpecObject) \
- F(IsSimdValue) \
- F(MathPow) \
- F(IsMinusZero) \
- F(HasCachedArrayIndex) \
- F(GetCachedArrayIndex) \
- F(FastOneByteArrayJoin) \
- F(GeneratorNext) \
- F(GeneratorThrow) \
- F(DebugBreakInOptimizedCode) \
- F(ClassOf) \
- F(StringCharCodeAt) \
- F(StringAdd) \
- F(SubString) \
- F(RegExpExec) \
- F(RegExpConstructResult) \
- F(NumberToString) \
- F(ToString) \
- F(ToName) \
- F(ToObject) \
- F(DebugIsActive) \
+#define FOR_EACH_FULL_CODE_INTRINSIC(F) \
+ F(IsSmi) \
+ F(IsArray) \
+ F(IsTypedArray) \
+ F(IsRegExp) \
+ F(IsJSProxy) \
+ F(IsConstructCall) \
+ F(Call) \
+ F(CallFunction) \
+ F(DefaultConstructorCallSuper) \
+ F(ArgumentsLength) \
+ F(Arguments) \
+ F(ValueOf) \
+ F(SetValueOf) \
+ F(IsDate) \
+ F(DateField) \
+ F(StringCharFromCode) \
+ F(StringCharAt) \
+ F(OneByteSeqStringSetChar) \
+ F(TwoByteSeqStringSetChar) \
+ F(ObjectEquals) \
+ F(IsFunction) \
+ F(IsSpecObject) \
+ F(IsSimdValue) \
+ F(MathPow) \
+ F(IsMinusZero) \
+ F(HasCachedArrayIndex) \
+ F(GetCachedArrayIndex) \
+ F(FastOneByteArrayJoin) \
+ F(GeneratorNext) \
+ F(GeneratorThrow) \
+ F(DebugBreakInOptimizedCode) \
+ F(ClassOf) \
+ F(StringCharCodeAt) \
+ F(StringAdd) \
+ F(SubString) \
+ F(RegExpExec) \
+ F(RegExpConstructResult) \
+ F(ToInteger) \
+ F(NumberToString) \
+ F(ToString) \
+ F(ToName) \
+ F(ToObject) \
+ F(DebugIsActive) \
F(CreateIterResultObject)
#define GENERATOR_DECLARATION(Name) void Emit##Name(CallRuntime* call);
}
+void FullCodeGenerator::EmitToInteger(CallRuntime* expr) {
+ ZoneList<Expression*>* args = expr->arguments();
+ DCHECK_EQ(1, args->length());
+
+ // Load the argument into eax and convert it.
+ VisitForAccumulatorValue(args->at(0));
+
+ // Convert the object to an integer.
+ Label done_convert;
+ __ JumpIfSmi(eax, &done_convert, Label::kNear);
+ __ Push(eax);
+ __ CallRuntime(Runtime::kToInteger, 1);
+ __ bind(&done_convert);
+ context()->Plug(eax);
+}
+
+
void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK_EQ(args->length(), 1);
}
+void FullCodeGenerator::EmitToInteger(CallRuntime* expr) {
+ ZoneList<Expression*>* args = expr->arguments();
+ DCHECK_EQ(1, args->length());
+
+ // Load the argument into v0 and convert it.
+ VisitForAccumulatorValue(args->at(0));
+
+ // Convert the object to an integer.
+ Label done_convert;
+ __ JumpIfSmi(v0, &done_convert);
+ __ Push(v0);
+ __ CallRuntime(Runtime::kToInteger, 1);
+ __ bind(&done_convert);
+ context()->Plug(v0);
+}
+
+
void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK_EQ(args->length(), 1);
}
+void FullCodeGenerator::EmitToInteger(CallRuntime* expr) {
+ ZoneList<Expression*>* args = expr->arguments();
+ DCHECK_EQ(1, args->length());
+
+ // Load the argument into v0 and convert it.
+ VisitForAccumulatorValue(args->at(0));
+
+ // Convert the object to an integer.
+ Label done_convert;
+ __ JumpIfSmi(v0, &done_convert);
+ __ Push(v0);
+ __ CallRuntime(Runtime::kToInteger, 1);
+ __ bind(&done_convert);
+ context()->Plug(v0);
+}
+
+
void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK_EQ(args->length(), 1);
}
+void FullCodeGenerator::EmitToInteger(CallRuntime* expr) {
+ ZoneList<Expression*>* args = expr->arguments();
+ DCHECK_EQ(1, args->length());
+
+ // Load the argument into r3 and convert it.
+ VisitForAccumulatorValue(args->at(0));
+
+ // Convert the object to an integer.
+ Label done_convert;
+ __ JumpIfSmi(r3, &done_convert);
+ __ Push(r3);
+ __ CallRuntime(Runtime::kToInteger, 1);
+ __ bind(&done_convert);
+ context()->Plug(r3);
+}
+
+
void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK_EQ(args->length(), 1);
}
+void FullCodeGenerator::EmitToInteger(CallRuntime* expr) {
+ ZoneList<Expression*>* args = expr->arguments();
+ DCHECK_EQ(1, args->length());
+
+ // Load the argument into rax and convert it.
+ VisitForAccumulatorValue(args->at(0));
+
+ // Convert the object to an integer.
+ Label done_convert;
+ __ JumpIfSmi(rax, &done_convert, Label::kNear);
+ __ Push(rax);
+ __ CallRuntime(Runtime::kToInteger, 1);
+ __ bind(&done_convert);
+ context()->Plug(rax);
+}
+
+
void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK_EQ(args->length(), 1);
}
+void FullCodeGenerator::EmitToInteger(CallRuntime* expr) {
+ ZoneList<Expression*>* args = expr->arguments();
+ DCHECK_EQ(1, args->length());
+
+ // Load the argument into eax and convert it.
+ VisitForAccumulatorValue(args->at(0));
+
+ // Convert the object to an integer.
+ Label done_convert;
+ __ JumpIfSmi(eax, &done_convert, Label::kNear);
+ __ Push(eax);
+ __ CallRuntime(Runtime::kToInteger, 1);
+ __ bind(&done_convert);
+ context()->Plug(eax);
+}
+
+
void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK_EQ(args->length(), 1);
(static_cast<uint64_t>(kHoleNanUpper32) << 32) | kHoleNanLower32;
+// ES6 section 20.1.2.6 Number.MAX_SAFE_INTEGER
+const double kMaxSafeInteger = 9007199254740991.0; // 2^53-1
+
+
// The order of this enum has to be kept in sync with the predicates below.
enum VariableMode {
// User declared variables:
return false;
}
- var n = $toInteger(fromIndex);
+ var n = TO_INTEGER(fromIndex);
var k;
if (n >= 0) {
CHECK_OBJECT_COERCIBLE(this, "Array.prototype.includes");
var array = TO_OBJECT(this);
- var length = $toLength(array.length);
+ var length = TO_LENGTH(array.length);
return InnerArrayIncludes(searchElement, fromIndex, array, length);
}
CHECK_OBJECT_COERCIBLE(this, "Array.prototype.copyWithin");
var array = TO_OBJECT(this);
- var length = $toLength(array.length);
+ var length = TO_LENGTH(array.length);
return InnerArrayCopyWithin(target, start, end, array, length);
}
CHECK_OBJECT_COERCIBLE(this, "Array.prototype.find");
var array = TO_OBJECT(this);
- var length = $toInteger(array.length);
+ var length = TO_INTEGER(array.length);
return InnerArrayFind(predicate, thisArg, array, length);
}
CHECK_OBJECT_COERCIBLE(this, "Array.prototype.findIndex");
var array = TO_OBJECT(this);
- var length = $toInteger(array.length);
+ var length = TO_INTEGER(array.length);
return InnerArrayFindIndex(predicate, thisArg, array, length);
}
k++;
}
} else {
- var len = $toLength(items.length);
+ var len = TO_LENGTH(items.length);
result = %IsConstructor(this) ? new this(len) : new GlobalArray(len);
for (k = 0; k < len; ++k) {
function AtomicsCompareExchangeJS(sta, index, oldValue, newValue) {
CheckSharedIntegerTypedArray(sta);
- index = $toInteger(index);
+ index = TO_INTEGER(index);
if (index < 0 || index >= %_TypedArrayGetLength(sta)) {
return UNDEFINED;
}
function AtomicsLoadJS(sta, index) {
CheckSharedIntegerTypedArray(sta);
- index = $toInteger(index);
+ index = TO_INTEGER(index);
if (index < 0 || index >= %_TypedArrayGetLength(sta)) {
return UNDEFINED;
}
function AtomicsStoreJS(sta, index, value) {
CheckSharedIntegerTypedArray(sta);
- index = $toInteger(index);
+ index = TO_INTEGER(index);
if (index < 0 || index >= %_TypedArrayGetLength(sta)) {
return UNDEFINED;
}
function AtomicsAddJS(ia, index, value) {
CheckSharedIntegerTypedArray(ia);
- index = $toInteger(index);
+ index = TO_INTEGER(index);
if (index < 0 || index >= %_TypedArrayGetLength(ia)) {
return UNDEFINED;
}
function AtomicsSubJS(ia, index, value) {
CheckSharedIntegerTypedArray(ia);
- index = $toInteger(index);
+ index = TO_INTEGER(index);
if (index < 0 || index >= %_TypedArrayGetLength(ia)) {
return UNDEFINED;
}
function AtomicsAndJS(ia, index, value) {
CheckSharedIntegerTypedArray(ia);
- index = $toInteger(index);
+ index = TO_INTEGER(index);
if (index < 0 || index >= %_TypedArrayGetLength(ia)) {
return UNDEFINED;
}
function AtomicsOrJS(ia, index, value) {
CheckSharedIntegerTypedArray(ia);
- index = $toInteger(index);
+ index = TO_INTEGER(index);
if (index < 0 || index >= %_TypedArrayGetLength(ia)) {
return UNDEFINED;
}
function AtomicsXorJS(ia, index, value) {
CheckSharedIntegerTypedArray(ia);
- index = $toInteger(index);
+ index = TO_INTEGER(index);
if (index < 0 || index >= %_TypedArrayGetLength(ia)) {
return UNDEFINED;
}
function AtomicsExchangeJS(ia, index, value) {
CheckSharedIntegerTypedArray(ia);
- index = $toInteger(index);
+ index = TO_INTEGER(index);
if (index < 0 || index >= %_TypedArrayGetLength(ia)) {
return UNDEFINED;
}
function AtomicsFutexWaitJS(ia, index, value, timeout) {
CheckSharedInteger32TypedArray(ia);
- index = $toInteger(index);
+ index = TO_INTEGER(index);
if (index < 0 || index >= %_TypedArrayGetLength(ia)) {
return UNDEFINED;
}
function AtomicsFutexWakeJS(ia, index, count) {
CheckSharedInteger32TypedArray(ia);
- index = $toInteger(index);
+ index = TO_INTEGER(index);
if (index < 0 || index >= %_TypedArrayGetLength(ia)) {
return UNDEFINED;
}
- count = MathMax(0, $toInteger(count));
+ count = MathMax(0, TO_INTEGER(count));
return %AtomicsFutexWake(ia, index, count);
}
function AtomicsFutexWakeOrRequeueJS(ia, index1, count, value, index2) {
CheckSharedInteger32TypedArray(ia);
- index1 = $toInteger(index1);
- count = MathMax(0, $toInteger(count));
+ index1 = TO_INTEGER(index1);
+ count = MathMax(0, TO_INTEGER(count));
value = TO_INT32(value);
- index2 = $toInteger(index2);
+ index2 = TO_INTEGER(index2);
if (index1 < 0 || index1 >= %_TypedArrayGetLength(ia) ||
index2 < 0 || index2 >= %_TypedArrayGetLength(ia)) {
return UNDEFINED;
}
+void HOptimizedGraphBuilder::GenerateToInteger(CallRuntime* call) {
+ DCHECK_EQ(1, call->arguments()->length());
+ CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
+ HValue* input = Pop();
+ if (input->type().IsSmi()) {
+ return ast_context()->ReturnValue(input);
+ } else {
+ IfBuilder if_inputissmi(this);
+ if_inputissmi.If<HIsSmiAndBranch>(input);
+ if_inputissmi.Then();
+ {
+ // Return the input value.
+ Push(input);
+ Add<HSimulate>(call->id(), FIXED_SIMULATE);
+ }
+ if_inputissmi.Else();
+ {
+ Add<HPushArguments>(input);
+ Push(Add<HCallRuntime>(Runtime::FunctionForId(Runtime::kToInteger), 1));
+ Add<HSimulate>(call->id(), FIXED_SIMULATE);
+ }
+ if_inputissmi.End();
+ return ast_context()->ReturnValue(Pop());
+ }
+}
+
+
void HOptimizedGraphBuilder::GenerateToObject(CallRuntime* call) {
DCHECK_EQ(1, call->arguments()->length());
CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
F(OneByteSeqStringSetChar) \
F(TwoByteSeqStringSetChar) \
F(ObjectEquals) \
+ F(ToInteger) \
F(ToObject) \
F(ToString) \
F(IsFunction) \
}
var gap;
if (IS_NUMBER(space)) {
- space = MathMax(0, MathMin($toInteger(space), 10));
+ space = MathMax(0, MathMin(TO_INTEGER(space), 10));
gap = %_SubString(" ", 0, space);
} else if (IS_STRING(space)) {
if (space.length > 10) {
# Inline macros. Use %IS_VAR to make sure arg is evaluated only once.
macro NUMBER_IS_NAN(arg) = (!%_IsSmi(%IS_VAR(arg)) && !(arg == arg));
macro NUMBER_IS_FINITE(arg) = (%_IsSmi(%IS_VAR(arg)) || ((arg == arg) && (arg != 1/0) && (arg != -1/0)));
-macro TO_INTEGER(arg) = (%_IsSmi(%IS_VAR(arg)) ? arg : %NumberToInteger(ToNumber(arg)));
-macro TO_INTEGER_FOR_SIDE_EFFECT(arg) = (%_IsSmi(%IS_VAR(arg)) ? arg : ToNumber(arg));
+macro TO_INTEGER(arg) = (%_ToInteger(arg));
macro TO_INTEGER_MAP_MINUS_ZERO(arg) = (%_IsSmi(%IS_VAR(arg)) ? arg : %NumberToIntegerMapMinusZero(ToNumber(arg)));
macro TO_INT32(arg) = (arg | 0);
macro TO_UINT32(arg) = (arg >>> 0);
-macro TO_LENGTH_OR_UINT32(arg) = (harmony_tolength ? $toLength(arg) : TO_UINT32(arg));
+macro TO_LENGTH(arg) = (%ToLength(arg));
+macro TO_LENGTH_OR_UINT32(arg) = (harmony_tolength ? TO_LENGTH(arg) : TO_UINT32(arg));
macro TO_STRING(arg) = (%_ToString(arg));
macro TO_NUMBER_INLINE(arg) = (IS_NUMBER(%IS_VAR(arg)) ? arg : $nonNumberToNumber(arg));
macro TO_OBJECT(arg) = (%_ToObject(arg));
if (!IS_SPEC_OBJECT(arg)) throw MakeTypeError(kObserveInvalidAccept);
- var len = $toInteger(arg.length);
+ var len = TO_INTEGER(arg.length);
if (len < 0) len = 0;
return TypeMapCreateFromList(arg, len);
}
+// static
+MaybeHandle<Object> Object::ToInteger(Isolate* isolate, Handle<Object> input) {
+ ASSIGN_RETURN_ON_EXCEPTION(isolate, input, ToNumber(input), Object);
+ return isolate->factory()->NewNumber(DoubleToInteger(input->Number()));
+}
+
+
+// static
+MaybeHandle<Object> Object::ToInt32(Isolate* isolate, Handle<Object> input) {
+ ASSIGN_RETURN_ON_EXCEPTION(isolate, input, ToNumber(input), Object);
+ return isolate->factory()->NewNumberFromInt(DoubleToInt32(input->Number()));
+}
+
+
+// static
+MaybeHandle<Object> Object::ToUint32(Isolate* isolate, Handle<Object> input) {
+ ASSIGN_RETURN_ON_EXCEPTION(isolate, input, ToNumber(input), Object);
+ return isolate->factory()->NewNumberFromUint(DoubleToUint32(input->Number()));
+}
+
+
// static
MaybeHandle<String> Object::ToString(Isolate* isolate, Handle<Object> input) {
while (true) {
}
+// static
+MaybeHandle<Object> Object::ToLength(Isolate* isolate, Handle<Object> input) {
+ ASSIGN_RETURN_ON_EXCEPTION(isolate, input, ToNumber(input), Object);
+ double len = DoubleToInteger(input->Number());
+ if (len <= 0.0) {
+ len = 0.0;
+ } else if (len >= kMaxSafeInteger) {
+ len = kMaxSafeInteger;
+ }
+ return isolate->factory()->NewNumber(len);
+}
+
+
bool Object::BooleanValue() {
if (IsBoolean()) return IsTrue();
if (IsSmi()) return Smi::cast(this)->value() != 0;
// ES6 section 7.1.3 ToNumber
MUST_USE_RESULT static MaybeHandle<Object> ToNumber(Handle<Object> input);
+ // ES6 section 7.1.4 ToInteger
+ MUST_USE_RESULT static MaybeHandle<Object> ToInteger(Isolate* isolate,
+ Handle<Object> input);
+
+ // ES6 section 7.1.5 ToInt32
+ MUST_USE_RESULT static MaybeHandle<Object> ToInt32(Isolate* isolate,
+ Handle<Object> input);
+
+ // ES6 section 7.1.6 ToUint32
+ MUST_USE_RESULT static MaybeHandle<Object> ToUint32(Isolate* isolate,
+ Handle<Object> input);
+
// ES6 section 7.1.12 ToString
MUST_USE_RESULT static MaybeHandle<String> ToString(Isolate* isolate,
Handle<Object> input);
+ // ES6 section 7.1.15 ToLength
+ MUST_USE_RESULT static MaybeHandle<Object> ToLength(Isolate* isolate,
+ Handle<Object> input);
+
// ES6 section 7.3.9 GetMethod
MUST_USE_RESULT static MaybeHandle<Object> GetMethod(
Handle<JSReceiver> receiver, Handle<Name> name);
var $nonNumberToNumber;
var $sameValue;
var $sameValueZero;
-var $toInteger;
-var $toLength;
var $toNumber;
var $toPositiveInteger;
throw %make_type_error(kWrongArgs, "Reflect.apply");
}
- length = %to_length_fun(args.length);
+ length = TO_LENGTH(args.length);
// We can handle any number of apply arguments if the stack is
// big enough, but sanity check the value to avoid overflow when
throw %make_type_error(kWrongArgs, "Reflect.construct");
}
- length = %to_length_fun(args.length);
+ length = TO_LENGTH(args.length);
// We can handle any number of apply arguments if the stack is
// big enough, but sanity check the value to avoid overflow when
}
-// ECMA-262, section 9.4, page 34.
-function ToInteger(x) {
- if (%_IsSmi(x)) return x;
- return %NumberToInteger(ToNumber(x));
-}
-
-
-// ES6, draft 08-24-14, section 7.1.15
-function ToLength(arg) {
- arg = ToInteger(arg);
- if (arg < 0) return 0;
- return arg < kMaxSafeInteger ? arg : kMaxSafeInteger;
-}
-
-
// ES5, section 9.12
function SameValue(x, y) {
if (typeof x != typeof y) return false;
$nonNumberToNumber = NonNumberToNumber;
$sameValue = SameValue;
$sameValueZero = SameValueZero;
-$toInteger = ToInteger;
-$toLength = ToLength;
$toNumber = ToNumber;
$toPositiveInteger = ToPositiveInteger;
%InstallToContext([
"concat_iterable_to_array", ConcatIterableToArray,
"non_number_to_number", NonNumberToNumber,
- "to_integer_fun", ToInteger,
- "to_length_fun", ToLength,
"to_number_fun", ToNumber,
]);
utils.Export(function(to) {
to.ToBoolean = ToBoolean;
- to.ToLength = ToLength;
to.ToNumber = ToNumber;
to.ToString = ToString;
});
}
-RUNTIME_FUNCTION(Runtime_NumberToInteger) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 1);
-
- CONVERT_DOUBLE_ARG_CHECKED(number, 0);
- return *isolate->factory()->NewNumber(DoubleToInteger(number));
-}
-
-
RUNTIME_FUNCTION(Runtime_NumberToIntegerMapMinusZero) {
HandleScope scope(isolate);
DCHECK(args.length() == 1);
}
+RUNTIME_FUNCTION(Runtime_ToInteger) {
+ HandleScope scope(isolate);
+ DCHECK_EQ(1, args.length());
+ CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
+ Object::ToInteger(isolate, input));
+ return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_ToLength) {
+ HandleScope scope(isolate);
+ DCHECK_EQ(1, args.length());
+ CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
+ Object::ToLength(isolate, input));
+ return *result;
+}
+
+
RUNTIME_FUNCTION(Runtime_ToString) {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
F(StringParseFloat, 1, 1) \
F(NumberToString, 1, 1) \
F(NumberToStringSkipCache, 1, 1) \
- F(NumberToInteger, 1, 1) \
F(NumberToIntegerMapMinusZero, 1, 1) \
F(NumberToSmi, 1, 1) \
F(NumberImul, 2, 1) \
F(ToPrimitive_Number, 1, 1) \
F(ToPrimitive_String, 1, 1) \
F(ToNumber, 1, 1) \
+ F(ToInteger, 1, 1) \
+ F(ToLength, 1, 1) \
F(ToString, 1, 1) \
F(ToName, 1, 1) \
F(Equals, 2, 1) \
if (IS_REGEXP(regexp)) {
// Emulate RegExp.prototype.exec's side effect in step 5, even though
// value is discarded.
- var lastIndex = regexp.lastIndex;
- TO_INTEGER_FOR_SIDE_EFFECT(lastIndex);
+ var lastIndex = TO_INTEGER(regexp.lastIndex);
if (!regexp.global) return RegExpExecNoTests(regexp, subject, 0);
var result = %StringMatch(subject, regexp, RegExpLastMatchInfo);
if (result !== null) $regexpLastMatchInfoOverride = null;
if (IS_REGEXP(search)) {
// Emulate RegExp.prototype.exec's side effect in step 5, even if
// value is discarded.
- var lastIndex = search.lastIndex;
- TO_INTEGER_FOR_SIDE_EFFECT(lastIndex);
+ var lastIndex = TO_INTEGER(search.lastIndex);
if (!IS_CALLABLE(replace)) {
replace = TO_STRING(replace);
CHECK_OBJECT_COERCIBLE(this, "String.prototype.repeat");
var s = TO_STRING(this);
- var n = $toInteger(count);
+ var n = TO_INTEGER(count);
// The maximum string length is stored in a smi, so a longer repeat
// must result in a range error.
if (n < 0 || n > %_MaxSmi()) throw MakeRangeError(kInvalidCountValue);
if (%_ArgumentsLength() > 1) {
var arg = %_Arguments(1); // position
if (!IS_UNDEFINED(arg)) {
- pos = $toInteger(arg);
+ pos = TO_INTEGER(arg);
}
}
if (%_ArgumentsLength() > 1) {
var arg = %_Arguments(1); // position
if (!IS_UNDEFINED(arg)) {
- pos = $toInteger(arg);
+ pos = TO_INTEGER(arg);
}
}
var numberOfSubstitutions = %_ArgumentsLength();
var cooked = TO_OBJECT(callSite);
var raw = TO_OBJECT(cooked.raw);
- var literalSegments = $toLength(raw.length);
+ var literalSegments = TO_LENGTH(raw.length);
if (literalSegments <= 0) return "";
var result = TO_STRING(raw[0]);
}
return;
}
- l = $toLength(l);
+ l = TO_LENGTH(l);
if (intOffset + l > this.length) {
throw MakeRangeError(kTypedArraySetSourceTooLarge);
}