зеркало из https://github.com/mozilla/gecko-dev.git
merge
This commit is contained in:
Коммит
6c4d3e0d55
|
@ -1509,6 +1509,7 @@ static JSStdName standard_class_names[] = {
|
|||
{js_InitTypedArrayClasses, EAGER_CLASS_ATOM(Uint32Array), NULL},
|
||||
{js_InitTypedArrayClasses, EAGER_CLASS_ATOM(Float32Array), NULL},
|
||||
{js_InitTypedArrayClasses, EAGER_CLASS_ATOM(Float64Array), NULL},
|
||||
{js_InitTypedArrayClasses, EAGER_CLASS_ATOM(Uint8ClampedArray), NULL},
|
||||
|
||||
{NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
|
|
@ -576,4 +576,7 @@ JS_DECLARE_CALLINFO(js_String_p_charCodeAt0_int)
|
|||
JS_DECLARE_CALLINFO(js_String_p_charCodeAt_double_int)
|
||||
JS_DECLARE_CALLINFO(js_String_p_charCodeAt_int_int)
|
||||
|
||||
/* Defined in jstypedarray.cpp. */
|
||||
JS_DECLARE_CALLINFO(js_TypedArray_uint8_clamp_double)
|
||||
|
||||
#endif /* jsbuiltins_h___ */
|
||||
|
|
|
@ -116,6 +116,7 @@ JS_PROTO(Int32Array, 34, js_InitTypedArrayClasses)
|
|||
JS_PROTO(Uint32Array, 35, js_InitTypedArrayClasses)
|
||||
JS_PROTO(Float32Array, 36, js_InitTypedArrayClasses)
|
||||
JS_PROTO(Float64Array, 37, js_InitTypedArrayClasses)
|
||||
JS_PROTO(Uint8ClampedArray, 38, js_InitTypedArrayClasses)
|
||||
|
||||
#undef SCRIPT_INIT
|
||||
#undef XML_INIT
|
||||
|
|
|
@ -12285,9 +12285,22 @@ TraceRecorder::setElem(int lval_spindex, int idx_spindex, int v_spindex)
|
|||
tarray->type != js::TypedArray::TYPE_FLOAT32 &&
|
||||
tarray->type != js::TypedArray::TYPE_FLOAT64) {
|
||||
LIns *v_ins_int = demote(lir, v_ins);
|
||||
|
||||
if (tarray->type == js::TypedArray::TYPE_UINT8_CLAMPED) {
|
||||
/* Wrap v_ins_int in some magic to clamp it */
|
||||
v_ins_int = lir->ins_choose(lir->ins2i(LIR_lt, v_ins_int, 0),
|
||||
lir->insImm(0),
|
||||
lir->ins_choose(lir->ins2i(LIR_gt, v_ins_int, 0xff),
|
||||
lir->insImm(0xff),
|
||||
v_ins_int,
|
||||
avmplus::AvmCore::use_cmov()),
|
||||
avmplus::AvmCore::use_cmov());
|
||||
}
|
||||
|
||||
switch (tarray->type) {
|
||||
case js::TypedArray::TYPE_INT8:
|
||||
case js::TypedArray::TYPE_UINT8:
|
||||
case js::TypedArray::TYPE_UINT8_CLAMPED:
|
||||
addr_ins = lir->ins2(LIR_piadd, data_ins, pidx_ins);
|
||||
lir->insStore(LIR_stb, v_ins_int, addr_ins, 0);
|
||||
break;
|
||||
|
@ -12331,6 +12344,9 @@ TraceRecorder::setElem(int lval_spindex, int idx_spindex, int v_spindex)
|
|||
addr_ins = lir->ins2(LIR_piadd, data_ins, lir->ins2i(LIR_pilsh, pidx_ins, 3));
|
||||
lir->insStore(LIR_stfi, v_ins, addr_ins, 0);
|
||||
break;
|
||||
case js::TypedArray::TYPE_UINT8_CLAMPED:
|
||||
addr_ins = lir->ins2(LIR_piadd, data_ins, pidx_ins);
|
||||
lir->insStore(LIR_stb, lir->insCall(&js_TypedArray_uint8_clamp_double_ci, &v_ins), addr_ins, 0);
|
||||
default:
|
||||
JS_NOT_REACHED("Unknown typed array type in tracer");
|
||||
}
|
||||
|
@ -13297,6 +13313,7 @@ TraceRecorder::typedArrayElement(jsval& oval, jsval& ival, jsval*& vp, LIns*& v_
|
|||
v_ins = lir->ins1(LIR_i2f, lir->insLoad(LIR_ldsb, addr_ins, 0));
|
||||
break;
|
||||
case js::TypedArray::TYPE_UINT8:
|
||||
case js::TypedArray::TYPE_UINT8_CLAMPED:
|
||||
addr_ins = lir->ins2(LIR_piadd, data_ins, pidx_ins);
|
||||
v_ins = lir->ins1(LIR_u2f, lir->insLoad(LIR_ldzb, addr_ins, 0));
|
||||
break;
|
||||
|
|
|
@ -304,6 +304,115 @@ TypedArray::obj_setAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty
|
|||
return false;
|
||||
}
|
||||
|
||||
/* Helper clamped uint8 type */
|
||||
|
||||
int32 JS_FASTCALL
|
||||
js_TypedArray_uint8_clamp_double(const double x)
|
||||
{
|
||||
// Not < so that NaN coerces to 0
|
||||
if (!(x >= 0))
|
||||
return 0;
|
||||
|
||||
if (x > 255)
|
||||
return 255;
|
||||
|
||||
jsdouble toTruncate = x + 0.5;
|
||||
JSUint8 y = JSUint8(toTruncate);
|
||||
|
||||
/*
|
||||
* now val is rounded to nearest, ties rounded up. We want
|
||||
* rounded to nearest ties to even, so check whether we had a
|
||||
* tie.
|
||||
*/
|
||||
if (y == toTruncate) {
|
||||
/*
|
||||
* It was a tie (since adding 0.5 gave us the exact integer
|
||||
* we want). Since we rounded up, we either already have an
|
||||
* even number or we have an odd number but the number we
|
||||
* want is one less. So just unconditionally masking out the
|
||||
* ones bit should do the trick to get us the value we
|
||||
* want.
|
||||
*/
|
||||
return (y & ~1);
|
||||
}
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
JS_DEFINE_CALLINFO_1(extern, INT32, js_TypedArray_uint8_clamp_double, DOUBLE, 1, 1)
|
||||
|
||||
|
||||
struct uint8_clamped {
|
||||
uint8 val;
|
||||
|
||||
uint8_clamped() { }
|
||||
uint8_clamped(const uint8_clamped& other) : val(other.val) { }
|
||||
|
||||
// invoke our assignment helpers for constructor conversion
|
||||
uint8_clamped(uint8 x) { *this = x; }
|
||||
uint8_clamped(uint16 x) { *this = x; }
|
||||
uint8_clamped(uint32 x) { *this = x; }
|
||||
uint8_clamped(int8 x) { *this = x; }
|
||||
uint8_clamped(int16 x) { *this = x; }
|
||||
uint8_clamped(int32 x) { *this = x; }
|
||||
uint8_clamped(jsdouble x) { *this = x; }
|
||||
|
||||
inline uint8_clamped& operator= (const uint8_clamped& x) {
|
||||
val = x.val;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline uint8_clamped& operator= (uint8 x) {
|
||||
val = x;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline uint8_clamped& operator= (uint16 x) {
|
||||
val = (x > 255) ? 255 : 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline uint8_clamped& operator= (uint32 x) {
|
||||
val = (x > 255) ? 255 : 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline uint8_clamped& operator= (int8 x) {
|
||||
val = (x >= 0) ? uint8(x) : 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline uint8_clamped& operator= (int16 x) {
|
||||
val = (x >= 0)
|
||||
? ((x < 255)
|
||||
? uint8(x)
|
||||
: 255)
|
||||
: 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline uint8_clamped& operator= (int32 x) {
|
||||
val = (x >= 0)
|
||||
? ((x < 255)
|
||||
? uint8(x)
|
||||
: 255)
|
||||
: 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline uint8_clamped& operator= (const jsdouble x) {
|
||||
val = js_TypedArray_uint8_clamp_double(x);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline operator uint8() const {
|
||||
return val;
|
||||
}
|
||||
};
|
||||
|
||||
/* Make sure the compiler isn't doing some funky stuff */
|
||||
JS_STATIC_ASSERT(sizeof(uint8_clamped) == 1);
|
||||
|
||||
template<typename NativeType> static inline const int TypeIDOfType();
|
||||
template<> inline const int TypeIDOfType<int8>() { return TypedArray::TYPE_INT8; }
|
||||
template<> inline const int TypeIDOfType<uint8>() { return TypedArray::TYPE_UINT8; }
|
||||
|
@ -313,6 +422,7 @@ template<> inline const int TypeIDOfType<int32>() { return TypedArray::TYPE_INT3
|
|||
template<> inline const int TypeIDOfType<uint32>() { return TypedArray::TYPE_UINT32; }
|
||||
template<> inline const int TypeIDOfType<float>() { return TypedArray::TYPE_FLOAT32; }
|
||||
template<> inline const int TypeIDOfType<double>() { return TypedArray::TYPE_FLOAT64; }
|
||||
template<> inline const int TypeIDOfType<uint8_clamped>() { return TypedArray::TYPE_UINT8_CLAMPED; }
|
||||
|
||||
template<typename NativeType> class TypedArrayTemplate;
|
||||
|
||||
|
@ -324,6 +434,7 @@ typedef TypedArrayTemplate<int32> Int32Array;
|
|||
typedef TypedArrayTemplate<uint32> Uint32Array;
|
||||
typedef TypedArrayTemplate<float> Float32Array;
|
||||
typedef TypedArrayTemplate<double> Float64Array;
|
||||
typedef TypedArrayTemplate<uint8_clamped> Uint8ClampedArray;
|
||||
|
||||
template<typename NativeType>
|
||||
class TypedArrayTemplate
|
||||
|
@ -862,7 +973,8 @@ class TypedArrayTemplate
|
|||
*dest++ = NativeType(*src++);
|
||||
break;
|
||||
}
|
||||
case TypedArray::TYPE_UINT8: {
|
||||
case TypedArray::TYPE_UINT8:
|
||||
case TypedArray::TYPE_UINT8_CLAMPED: {
|
||||
uint8 *src = static_cast<uint8*>(tarray->data);
|
||||
for (uintN i = 0; i < length; ++i)
|
||||
*dest++ = NativeType(*src++);
|
||||
|
@ -1126,6 +1238,7 @@ IMPL_TYPED_ARRAY_STATICS(Int32Array);
|
|||
IMPL_TYPED_ARRAY_STATICS(Uint32Array);
|
||||
IMPL_TYPED_ARRAY_STATICS(Float32Array);
|
||||
IMPL_TYPED_ARRAY_STATICS(Float64Array);
|
||||
IMPL_TYPED_ARRAY_STATICS(Uint8ClampedArray);
|
||||
|
||||
JSClass TypedArray::fastClasses[TYPE_MAX] = {
|
||||
IMPL_TYPED_ARRAY_FAST_CLASS(Int8Array),
|
||||
|
@ -1135,7 +1248,8 @@ JSClass TypedArray::fastClasses[TYPE_MAX] = {
|
|||
IMPL_TYPED_ARRAY_FAST_CLASS(Int32Array),
|
||||
IMPL_TYPED_ARRAY_FAST_CLASS(Uint32Array),
|
||||
IMPL_TYPED_ARRAY_FAST_CLASS(Float32Array),
|
||||
IMPL_TYPED_ARRAY_FAST_CLASS(Float64Array)
|
||||
IMPL_TYPED_ARRAY_FAST_CLASS(Float64Array),
|
||||
IMPL_TYPED_ARRAY_FAST_CLASS(Uint8ClampedArray)
|
||||
};
|
||||
|
||||
JSClass TypedArray::slowClasses[TYPE_MAX] = {
|
||||
|
@ -1146,7 +1260,8 @@ JSClass TypedArray::slowClasses[TYPE_MAX] = {
|
|||
IMPL_TYPED_ARRAY_SLOW_CLASS(Int32Array),
|
||||
IMPL_TYPED_ARRAY_SLOW_CLASS(Uint32Array),
|
||||
IMPL_TYPED_ARRAY_SLOW_CLASS(Float32Array),
|
||||
IMPL_TYPED_ARRAY_SLOW_CLASS(Float64Array)
|
||||
IMPL_TYPED_ARRAY_SLOW_CLASS(Float64Array),
|
||||
IMPL_TYPED_ARRAY_SLOW_CLASS(Uint8ClampedArray)
|
||||
};
|
||||
|
||||
JS_FRIEND_API(JSObject *)
|
||||
|
@ -1169,6 +1284,7 @@ js_InitTypedArrayClasses(JSContext *cx, JSObject *obj)
|
|||
INIT_TYPED_ARRAY_CLASS(Uint32Array,TYPE_UINT32);
|
||||
INIT_TYPED_ARRAY_CLASS(Float32Array,TYPE_FLOAT32);
|
||||
INIT_TYPED_ARRAY_CLASS(Float64Array,TYPE_FLOAT64);
|
||||
INIT_TYPED_ARRAY_CLASS(Uint8ClampedArray,TYPE_UINT8_CLAMPED);
|
||||
|
||||
proto = js_InitClass(cx, obj, NULL, &ArrayBuffer::jsclass,
|
||||
ArrayBuffer::class_constructor, 1,
|
||||
|
@ -1237,6 +1353,9 @@ TypedArrayConstruct(JSContext *cx, jsint atype, uintN argc, jsval *argv, jsval *
|
|||
case TypedArray::TYPE_FLOAT64:
|
||||
return Float64Array::class_constructor(cx, cx->globalObject, argc, argv, rv);
|
||||
|
||||
case TypedArray::TYPE_UINT8_CLAMPED:
|
||||
return Uint8ClampedArray::class_constructor(cx, cx->globalObject, argc, argv, rv);
|
||||
|
||||
default:
|
||||
JS_NOT_REACHED("shouldn't have gotten here");
|
||||
return false;
|
||||
|
|
|
@ -102,6 +102,13 @@ struct JS_FRIEND_API(TypedArray) {
|
|||
TYPE_UINT32,
|
||||
TYPE_FLOAT32,
|
||||
TYPE_FLOAT64,
|
||||
|
||||
/*
|
||||
* Special type that's a uint8, but assignments are clamped to 0 .. 255.
|
||||
* Treat the raw data type as a uint8.
|
||||
*/
|
||||
TYPE_UINT8_CLAMPED,
|
||||
|
||||
TYPE_MAX
|
||||
};
|
||||
|
||||
|
|
|
@ -181,6 +181,19 @@ function test()
|
|||
checkThrows(function() a[-10] = 0);
|
||||
check(function() (a[0] = "10") && (a[0] == 10));
|
||||
|
||||
|
||||
// check Uint8ClampedArray, which is an extension to this extension
|
||||
a = new Uint8ClampedArray(4);
|
||||
a[0] = 128;
|
||||
a[1] = 512;
|
||||
a[2] = -123.723;
|
||||
a[3] = "foopy";
|
||||
|
||||
check(function() a[0] == 128);
|
||||
check(function() a[1] == 255);
|
||||
check(function() a[2] == 0);
|
||||
check(function() a[3] == 0);
|
||||
|
||||
print ("done");
|
||||
|
||||
reportCompare(0, TestFailCount, "typed array tests");
|
||||
|
|
Загрузка…
Ссылка в новой задаче