Bug 660437: Fix conversion of non-numeric types to typed array elements, r=luke

--HG--
extra : rebase_source : 6d4fe2723b173215fa1412ab5127cb993d46c1d8
This commit is contained in:
David Mandelin 2011-12-06 14:24:39 -08:00
parent c2405549e1
commit 82a4d0b774
2 changed files with 59 additions and 17 deletions

View File

@ -0,0 +1,32 @@
function holeArray(sparse) {
var a = [,,];
if (sparse)
a.length = 1000;
return a;
}
function undefinedArray(sparse) {
var a = [ undefined, undefined, undefined ];
if (sparse)
a.length = 1000;
return a;
}
var a;
a = new Int32Array(holeArray(false));
assertEq(a[0], 0);
a = new Int32Array(holeArray(true));
assertEq(a[0], 0);
a = new Int32Array(undefinedArray(false));
assertEq(a[0], 0);
a = new Int32Array(undefinedArray(true));
assertEq(a[0], 0);
a = new Float64Array(holeArray(false));
assertEq(a[0], NaN);
a = new Float64Array(holeArray(true));
assertEq(a[0], NaN);
a = new Float64Array(undefinedArray(false));
assertEq(a[0], NaN);
a = new Float64Array(undefinedArray(true));
assertEq(a[0], NaN);

View File

@ -1706,33 +1706,40 @@ class TypedArrayTemplate
}
protected:
static NativeType
nativeFromDouble(double d)
{
if (!ArrayTypeIsFloatingPoint() && JS_UNLIKELY(JSDOUBLE_IS_NaN(d)))
return NativeType(int32(0));
if (TypeIsFloatingPoint<NativeType>())
return NativeType(d);
if (TypeIsUnsigned<NativeType>())
return NativeType(js_DoubleToECMAUint32(d));
return NativeType(js_DoubleToECMAInt32(d));
}
static NativeType
nativeFromValue(JSContext *cx, const Value &v)
{
if (v.isInt32())
return NativeType(v.toInt32());
if (v.isDouble()) {
double d = v.toDouble();
if (!ArrayTypeIsFloatingPoint() && JS_UNLIKELY(JSDOUBLE_IS_NaN(d)))
return NativeType(int32(0));
if (TypeIsFloatingPoint<NativeType>())
return NativeType(d);
if (TypeIsUnsigned<NativeType>())
return NativeType(js_DoubleToECMAUint32(d));
return NativeType(js_DoubleToECMAInt32(d));
}
if (v.isDouble())
return nativeFromDouble(v.toDouble());
if (v.isPrimitive() && !v.isMagic()) {
/*
* The condition guarantees that holes and undefined values
* are treated identically.
*/
if (v.isPrimitive() && !v.isMagic() && !v.isUndefined()) {
jsdouble dval;
JS_ALWAYS_TRUE(ToNumber(cx, v, &dval));
return NativeType(dval);
return nativeFromDouble(dval);
}
if (ArrayTypeIsFloatingPoint())
return NativeType(js_NaN);
return NativeType(int32(0));
return ArrayTypeIsFloatingPoint()
? NativeType(js_NaN)
: NativeType(int32(0));
}
static bool
@ -1751,10 +1758,13 @@ class TypedArrayTemplate
const Value *src = ar->getDenseArrayElements();
/*
* It is valid to skip the hole check here because nativeFromValue
* treats a hole as undefined.
*/
for (uintN i = 0; i < len; ++i)
*dest++ = nativeFromValue(cx, *src++);
} else {
// slow path
Value v;
for (uintN i = 0; i < len; ++i) {