From 3cc7adc7c4c12d3b054f904359a170b4a5ad43b4 Mon Sep 17 00:00:00 2001 From: bmeurer Date: Sun, 9 Aug 2015 21:54:20 -0700 Subject: [PATCH] [runtime] Simplify TO_INT32/TO_UINT32 abstract operations. No need to provide TO_INT32/TO_UINT32 functions for every native context, as they can be implemented in terms of TO_NUMBER more easily and efficiently. Also remove the obsolete TO_BOOLEAN_FUN_INDEX from the native contexts. Review URL: https://codereview.chromium.org/1275013004 Cr-Commit-Position: refs/heads/master@{#30080} --- include/v8.h | 2 +- src/array.js | 6 +++--- src/bootstrapper.cc | 2 -- src/contexts.h | 5 ----- src/execution.cc | 26 ++++++++++++++------------ src/harmony-atomics.js | 2 +- src/macros.py | 2 +- src/runtime.js | 20 +------------------- src/runtime/runtime-numbers.cc | 18 ------------------ src/runtime/runtime.h | 2 -- src/v8natives.js | 4 ++-- 11 files changed, 23 insertions(+), 66 deletions(-) diff --git a/include/v8.h b/include/v8.h index 19373a139..6e01bd4fe 100644 --- a/include/v8.h +++ b/include/v8.h @@ -6920,7 +6920,7 @@ class Internals { static const int kJSObjectHeaderSize = 3 * kApiPointerSize; static const int kFixedArrayHeaderSize = 2 * kApiPointerSize; static const int kContextHeaderSize = 2 * kApiPointerSize; - static const int kContextEmbedderDataIndex = 86; + static const int kContextEmbedderDataIndex = 83; static const int kFullStringRepresentationMask = 0x07; static const int kStringEncodingMask = 0x4; static const int kExternalTwoByteRepresentationTag = 0x02; diff --git a/src/array.js b/src/array.js index 7d0fdcafb..cfaa324d1 100644 --- a/src/array.js +++ b/src/array.js @@ -1232,7 +1232,7 @@ function ArrayFilter(f, receiver) { // Pull out the length so that modifications to the length in the // loop will not affect the looping and side effects are visible. var array = TO_OBJECT(this); - var length = $toUint32(array.length); + var length = TO_UINT32(array.length); var accumulator = InnerArrayFilter(f, receiver, array, length); var result = new GlobalArray(); %MoveArrayContents(accumulator, result); @@ -1543,7 +1543,7 @@ function ArrayReduce(callback, current) { // Pull out the length so that modifications to the length in the // loop will not affect the looping and side effects are visible. var array = TO_OBJECT(this); - var length = $toUint32(array.length); + var length = TO_UINT32(array.length); return InnerArrayReduce(callback, current, array, length, %_ArgumentsLength()); } @@ -1586,7 +1586,7 @@ function ArrayReduceRight(callback, current) { // Pull out the length so that side effects are visible before the // callback function is checked. var array = TO_OBJECT(this); - var length = $toUint32(array.length); + var length = TO_UINT32(array.length); return InnerArrayReduceRight(callback, current, array, length, %_ArgumentsLength()); } diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc index 3074661e1..12a64d9eb 100644 --- a/src/bootstrapper.cc +++ b/src/bootstrapper.cc @@ -1717,8 +1717,6 @@ void Genesis::InstallNativeFunctions() { INSTALL_NATIVE(JSFunction, "$toString", to_string_fun); INSTALL_NATIVE(JSFunction, "$toDetailString", to_detail_string_fun); INSTALL_NATIVE(JSFunction, "$toInteger", to_integer_fun); - INSTALL_NATIVE(JSFunction, "$toUint32", to_uint32_fun); - INSTALL_NATIVE(JSFunction, "$toInt32", to_int32_fun); INSTALL_NATIVE(JSFunction, "$toLength", to_length_fun); INSTALL_NATIVE(JSFunction, "$globalEval", global_eval_fun); diff --git a/src/contexts.h b/src/contexts.h index d5b090618..a593434b2 100644 --- a/src/contexts.h +++ b/src/contexts.h @@ -104,8 +104,6 @@ enum BindingFlags { V(TO_STRING_FUN_INDEX, JSFunction, to_string_fun) \ V(TO_DETAIL_STRING_FUN_INDEX, JSFunction, to_detail_string_fun) \ V(TO_INTEGER_FUN_INDEX, JSFunction, to_integer_fun) \ - V(TO_UINT32_FUN_INDEX, JSFunction, to_uint32_fun) \ - V(TO_INT32_FUN_INDEX, JSFunction, to_int32_fun) \ V(TO_LENGTH_FUN_INDEX, JSFunction, to_length_fun) \ V(GLOBAL_EVAL_FUN_INDEX, JSFunction, global_eval_fun) \ V(ARRAY_BUFFER_FUN_INDEX, JSFunction, array_buffer_fun) \ @@ -378,9 +376,6 @@ class Context: public FixedArray { TO_STRING_FUN_INDEX, TO_DETAIL_STRING_FUN_INDEX, TO_INTEGER_FUN_INDEX, - TO_UINT32_FUN_INDEX, - TO_INT32_FUN_INDEX, - TO_BOOLEAN_FUN_INDEX, GLOBAL_EVAL_FUN_INDEX, ARRAY_BUFFER_FUN_INDEX, ARRAY_BUFFER_MAP_INDEX, diff --git a/src/execution.cc b/src/execution.cc index 687c0f99f..52cff2f79 100644 --- a/src/execution.cc +++ b/src/execution.cc @@ -554,18 +554,6 @@ MaybeHandle Execution::ToInteger( } -MaybeHandle Execution::ToUint32( - Isolate* isolate, Handle obj) { - RETURN_NATIVE_CALL(to_uint32, { obj }); -} - - -MaybeHandle Execution::ToInt32( - Isolate* isolate, Handle obj) { - RETURN_NATIVE_CALL(to_int32, { obj }); -} - - MaybeHandle Execution::ToLength( Isolate* isolate, Handle obj) { RETURN_NATIVE_CALL(to_length, { obj }); @@ -581,6 +569,13 @@ MaybeHandle Execution::NewDate(Isolate* isolate, double time) { #undef RETURN_NATIVE_CALL +MaybeHandle Execution::ToInt32(Isolate* isolate, Handle obj) { + ASSIGN_RETURN_ON_EXCEPTION(isolate, obj, Execution::ToNumber(isolate, obj), + Object); + return isolate->factory()->NewNumberFromInt(DoubleToInt32(obj->Number())); +} + + MaybeHandle Execution::ToObject(Isolate* isolate, Handle obj) { Handle receiver; if (JSReceiver::ToObject(isolate, obj).ToHandle(&receiver)) { @@ -591,6 +586,13 @@ MaybeHandle Execution::ToObject(Isolate* isolate, Handle obj) { } +MaybeHandle Execution::ToUint32(Isolate* isolate, Handle obj) { + ASSIGN_RETURN_ON_EXCEPTION(isolate, obj, Execution::ToNumber(isolate, obj), + Object); + return isolate->factory()->NewNumberFromUint(DoubleToUint32(obj->Number())); +} + + MaybeHandle Execution::NewJSRegExp(Handle pattern, Handle flags) { Isolate* isolate = pattern->GetIsolate(); diff --git a/src/harmony-atomics.js b/src/harmony-atomics.js index 3c7968b1a..96cc2145d 100644 --- a/src/harmony-atomics.js +++ b/src/harmony-atomics.js @@ -172,7 +172,7 @@ function AtomicsFutexWakeOrRequeueJS(ia, index1, count, value, index2) { CheckSharedInteger32TypedArray(ia); index1 = $toInteger(index1); count = MathMax(0, $toInteger(count)); - value = $toInt32(value); + value = TO_INT32(value); index2 = $toInteger(index2); if (index1 < 0 || index1 >= %_TypedArrayGetLength(ia) || index2 < 0 || index2 >= %_TypedArrayGetLength(ia)) { diff --git a/src/macros.py b/src/macros.py index 97a1fa8f3..124b1e7fb 100644 --- a/src/macros.py +++ b/src/macros.py @@ -149,7 +149,7 @@ macro NUMBER_IS_FINITE(arg) = (%_IsSmi(%IS_VAR(arg)) || ((arg == arg) && (arg != 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_MAP_MINUS_ZERO(arg) = (%_IsSmi(%IS_VAR(arg)) ? arg : %NumberToIntegerMapMinusZero($toNumber(arg))); -macro TO_INT32(arg) = (%_IsSmi(%IS_VAR(arg)) ? arg : (arg >> 0)); +macro TO_INT32(arg) = (arg | 0); macro TO_UINT32(arg) = (arg >>> 0); macro TO_STRING_INLINE(arg) = (IS_STRING(%IS_VAR(arg)) ? arg : $nonStringToString(arg)); macro TO_NUMBER_INLINE(arg) = (IS_NUMBER(%IS_VAR(arg)) ? arg : $nonNumberToNumber(arg)); diff --git a/src/runtime.js b/src/runtime.js index 5e37e26c3..21b3da923 100644 --- a/src/runtime.js +++ b/src/runtime.js @@ -70,7 +70,6 @@ var $nonStringToString; var $sameValue; var $sameValueZero; var $toBoolean; -var $toInt32; var $toInteger; var $toLength; var $toName; @@ -78,7 +77,6 @@ var $toNumber; var $toPositiveInteger; var $toPrimitive; var $toString; -var $toUint32; (function(global, utils) { @@ -610,7 +608,7 @@ APPLY_PREPARE = function APPLY_PREPARE(args) { } } - length = (args == null) ? 0 : %$toUint32(args.length); + length = (args == null) ? 0 : TO_UINT32(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 @@ -838,20 +836,6 @@ function ToLength(arg) { } -// ECMA-262, section 9.6, page 34. -function ToUint32(x) { - if (%_IsSmi(x) && x >= 0) return x; - return %NumberToJSUint32(ToNumber(x)); -} - - -// ECMA-262, section 9.5, page 34 -function ToInt32(x) { - if (%_IsSmi(x)) return x; - return %NumberToJSInt32(ToNumber(x)); -} - - // ES5, section 9.12 function SameValue(x, y) { if (typeof x != typeof y) return false; @@ -973,7 +957,6 @@ $nonStringToString = NonStringToString; $sameValue = SameValue; $sameValueZero = SameValueZero; $toBoolean = ToBoolean; -$toInt32 = ToInt32; $toInteger = ToInteger; $toLength = ToLength; $toName = ToName; @@ -981,6 +964,5 @@ $toNumber = ToNumber; $toPositiveInteger = ToPositiveInteger; $toPrimitive = ToPrimitive; $toString = ToString; -$toUint32 = ToUint32; }) diff --git a/src/runtime/runtime-numbers.cc b/src/runtime/runtime-numbers.cc index d9a0c9ffa..7e6712ad2 100644 --- a/src/runtime/runtime-numbers.cc +++ b/src/runtime/runtime-numbers.cc @@ -271,24 +271,6 @@ RUNTIME_FUNCTION(Runtime_NumberToIntegerMapMinusZero) { } -RUNTIME_FUNCTION(Runtime_NumberToJSUint32) { - HandleScope scope(isolate); - DCHECK(args.length() == 1); - - CONVERT_NUMBER_CHECKED(int32_t, number, Uint32, args[0]); - return *isolate->factory()->NewNumberFromUint(number); -} - - -RUNTIME_FUNCTION(Runtime_NumberToJSInt32) { - HandleScope scope(isolate); - DCHECK(args.length() == 1); - - CONVERT_DOUBLE_ARG_CHECKED(number, 0); - return *isolate->factory()->NewNumberFromInt(DoubleToInt32(number)); -} - - // Converts a Number to a Smi, if possible. Returns NaN if the number is not // a small integer. RUNTIME_FUNCTION(Runtime_NumberToSmi) { diff --git a/src/runtime/runtime.h b/src/runtime/runtime.h index 5f64b74d6..a1a2561a6 100644 --- a/src/runtime/runtime.h +++ b/src/runtime/runtime.h @@ -404,8 +404,6 @@ namespace internal { F(NumberToStringSkipCache, 1, 1) \ F(NumberToInteger, 1, 1) \ F(NumberToIntegerMapMinusZero, 1, 1) \ - F(NumberToJSUint32, 1, 1) \ - F(NumberToJSInt32, 1, 1) \ F(NumberToSmi, 1, 1) \ F(NumberAdd, 2, 1) \ F(NumberSub, 2, 1) \ diff --git a/src/v8natives.js b/src/v8natives.js index 542d70966..29481d103 100644 --- a/src/v8natives.js +++ b/src/v8natives.js @@ -803,7 +803,7 @@ function DefineObjectProperty(obj, p, desc, should_throw) { function DefineArrayProperty(obj, p, desc, should_throw) { // Step 3 - Special handling for array index. if (!IS_SYMBOL(p)) { - var index = $toUint32(p); + var index = TO_UINT32(p); var emit_splice = false; if ($toString(index) == p && index != 4294967295) { var length = obj.length; @@ -899,7 +899,7 @@ function ToNameArray(obj, trap, includeSymbols) { if (!IS_SPEC_OBJECT(obj)) { throw MakeTypeError(kProxyNonObjectPropNames, trap, obj); } - var n = $toUint32(obj.length); + var n = TO_UINT32(obj.length); var array = new GlobalArray(n); var realLength = 0; var names = { __proto__: null }; // TODO(rossberg): use sets once ready. -- 2.34.1