зеркало из https://github.com/mozilla/gecko-dev.git
Bug 565604 - Typed-array properties don't work when accessed from an object whose prototype is a typed array. r=vlad
--HG-- extra : rebase_source : 6ac630f7a9d2cb04a9a996c2a675be41130ea2b1
This commit is contained in:
Родитель
e52ac354be
Коммит
984fff647d
|
@ -5520,7 +5520,7 @@ CloneSimpleValues(JSContext* cx,
|
|||
return SetPropertyOnValueOrObject(cx, val, rval, robj, rid);
|
||||
}
|
||||
|
||||
NS_ASSERTION(JSVAL_IS_OBJECT(val), "Not an object!");
|
||||
NS_ASSERTION(!JSVAL_IS_PRIMITIVE(val), "Not an object!");
|
||||
JSObject* obj = JSVAL_TO_OBJECT(val);
|
||||
|
||||
// Dense arrays of primitives can be cloned quickly.
|
||||
|
|
|
@ -88,7 +88,7 @@ nsICanvasRenderingContextWebGL_BufferData(JSContext *cx, uintN argc, jsval *vp)
|
|||
if (!JS_ValueToECMAInt32(cx, argv[2], &usage))
|
||||
return JS_FALSE;
|
||||
|
||||
if (JSVAL_IS_OBJECT(argv[1])) {
|
||||
if (!JSVAL_IS_PRIMITIVE(argv[1])) {
|
||||
JSObject *arg2 = JSVAL_TO_OBJECT(argv[1]);
|
||||
if (js_IsArrayBuffer(arg2)) {
|
||||
wb = js::ArrayBuffer::fromJSObject(arg2);
|
||||
|
@ -153,7 +153,7 @@ nsICanvasRenderingContextWebGL_BufferSubData(JSContext *cx, uintN argc, jsval *v
|
|||
if (!JS_ValueToECMAInt32(cx, argv[1], &offset))
|
||||
return JS_FALSE;
|
||||
|
||||
if (!JSVAL_IS_OBJECT(argv[2])) {
|
||||
if (JSVAL_IS_PRIMITIVE(argv[2])) {
|
||||
xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 2);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
@ -255,7 +255,11 @@ nsICanvasRenderingContextWebGL_TexImage2D(JSContext *cx, uintN argc, jsval *vp)
|
|||
|
||||
// then try to grab either a js::ArrayBuffer, js::TypedArray, or null
|
||||
arg9 = JSVAL_TO_OBJECT(argv[8]);
|
||||
if (js_IsArrayBuffer(arg9)) {
|
||||
if (arg9 == nsnull) {
|
||||
rv = self->TexImage2D_buf(intargs[0], intargs[1], intargs[2], intargs[3],
|
||||
intargs[4], intargs[5], intargs[6], intargs[7],
|
||||
nsnull);
|
||||
} else if (js_IsArrayBuffer(arg9)) {
|
||||
rv = self->TexImage2D_buf(intargs[0], intargs[1], intargs[2], intargs[3],
|
||||
intargs[4], intargs[5], intargs[6], intargs[7],
|
||||
js::ArrayBuffer::fromJSObject(arg9));
|
||||
|
@ -263,10 +267,6 @@ nsICanvasRenderingContextWebGL_TexImage2D(JSContext *cx, uintN argc, jsval *vp)
|
|||
rv = self->TexImage2D_array(intargs[0], intargs[1], intargs[2], intargs[3],
|
||||
intargs[4], intargs[5], intargs[6], intargs[7],
|
||||
js::TypedArray::fromJSObject(arg9));
|
||||
} else if (arg9 == nsnull) {
|
||||
rv = self->TexImage2D_buf(intargs[0], intargs[1], intargs[2], intargs[3],
|
||||
intargs[4], intargs[5], intargs[6], intargs[7],
|
||||
nsnull);
|
||||
} else {
|
||||
xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 8);
|
||||
return JS_FALSE;
|
||||
|
@ -347,7 +347,7 @@ nsICanvasRenderingContextWebGL_TexSubImage2D(JSContext *cx, uintN argc, jsval *v
|
|||
return JS_FALSE;
|
||||
}
|
||||
|
||||
if (!JSVAL_IS_OBJECT(argv[8])) {
|
||||
if (JSVAL_IS_PRIMITIVE(argv[8])) {
|
||||
xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 8);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
|
|
@ -223,40 +223,70 @@ TypedArray::isArrayIndex(JSContext *cx, jsid id, jsuint *ip)
|
|||
return false;
|
||||
}
|
||||
|
||||
typedef jsval (* TypedArrayPropertyGetter)(TypedArray *tarray);
|
||||
|
||||
template <TypedArrayPropertyGetter Get>
|
||||
class TypedArrayGetter {
|
||||
public:
|
||||
static inline bool get(JSContext *cx, JSObject *obj, jsid id, jsval *vp) {
|
||||
do {
|
||||
if (js_IsTypedArray(obj)) {
|
||||
TypedArray *tarray = TypedArray::fromJSObject(obj);
|
||||
if (tarray)
|
||||
*vp = Get(tarray);
|
||||
return true;
|
||||
}
|
||||
} while ((obj = obj->getProto()) != NULL);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
inline jsval
|
||||
getBuffer(TypedArray *tarray)
|
||||
{
|
||||
return OBJECT_TO_JSVAL(tarray->bufferJS);
|
||||
}
|
||||
|
||||
JSBool
|
||||
TypedArray::prop_getBuffer(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
||||
{
|
||||
TypedArray *tarray = fromJSObject(obj);
|
||||
if (tarray)
|
||||
*vp = OBJECT_TO_JSVAL(tarray->bufferJS);
|
||||
return true;
|
||||
return TypedArrayGetter<getBuffer>::get(cx, obj, id, vp);
|
||||
}
|
||||
|
||||
inline jsval
|
||||
getByteOffset(TypedArray *tarray)
|
||||
{
|
||||
return INT_TO_JSVAL(tarray->byteOffset);
|
||||
}
|
||||
|
||||
JSBool
|
||||
TypedArray::prop_getByteOffset(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
||||
{
|
||||
TypedArray *tarray = fromJSObject(obj);
|
||||
if (tarray)
|
||||
*vp = INT_TO_JSVAL(tarray->byteOffset);
|
||||
return true;
|
||||
return TypedArrayGetter<getByteOffset>::get(cx, obj, id, vp);
|
||||
}
|
||||
|
||||
inline jsval
|
||||
getByteLength(TypedArray *tarray)
|
||||
{
|
||||
return INT_TO_JSVAL(tarray->byteLength);
|
||||
}
|
||||
|
||||
JSBool
|
||||
TypedArray::prop_getByteLength(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
||||
{
|
||||
TypedArray *tarray = fromJSObject(obj);
|
||||
if (tarray)
|
||||
*vp = INT_TO_JSVAL(tarray->byteLength);
|
||||
return true;
|
||||
return TypedArrayGetter<getByteLength>::get(cx, obj, id, vp);
|
||||
}
|
||||
|
||||
inline jsval
|
||||
getLength(TypedArray *tarray)
|
||||
{
|
||||
return INT_TO_JSVAL(tarray->length);
|
||||
}
|
||||
|
||||
JSBool
|
||||
TypedArray::prop_getLength(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
||||
{
|
||||
TypedArray *tarray = fromJSObject(obj);
|
||||
if (tarray)
|
||||
*vp = INT_TO_JSVAL(tarray->length);
|
||||
return true;
|
||||
return TypedArrayGetter<getLength>::get(cx, obj, id, vp);
|
||||
}
|
||||
|
||||
JSBool
|
||||
|
@ -1404,15 +1434,17 @@ js_InitTypedArrayClasses(JSContext *cx, JSObject *obj)
|
|||
JS_FRIEND_API(JSBool)
|
||||
js_IsArrayBuffer(JSObject *obj)
|
||||
{
|
||||
return obj && obj->getClass() == &ArrayBuffer::jsclass;
|
||||
JS_ASSERT(obj);
|
||||
return obj->getClass() == &ArrayBuffer::jsclass;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSBool)
|
||||
js_IsTypedArray(JSObject *obj)
|
||||
{
|
||||
return obj &&
|
||||
obj->getClass() >= &TypedArray::fastClasses[0] &&
|
||||
obj->getClass() < &TypedArray::fastClasses[TypedArray::TYPE_MAX];
|
||||
JS_ASSERT(obj);
|
||||
JSClass *clasp = obj->getClass();
|
||||
return clasp >= &TypedArray::fastClasses[0] &&
|
||||
clasp < &TypedArray::fastClasses[TypedArray::TYPE_MAX];
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSObject *)
|
||||
|
@ -1536,6 +1568,8 @@ js_CreateTypedArrayWithBuffer(JSContext *cx, jsint atype, JSObject *bufArg,
|
|||
JS_FRIEND_API(JSBool)
|
||||
js_ReparentTypedArrayToScope(JSContext *cx, JSObject *obj, JSObject *scope)
|
||||
{
|
||||
JS_ASSERT(obj);
|
||||
|
||||
scope = JS_GetGlobalForObject(cx, scope);
|
||||
if (!scope)
|
||||
return JS_FALSE;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
url-prefix ../../jsreftest.html?test=js1_8_5/extensions/
|
||||
script typedarray.js
|
||||
script typedarray-prototype.js
|
||||
skip-if(!xulRuntime.shell) script worker-error.js # these tests sometimes hang in browser, bug 559954, bug 562333
|
||||
skip-if(!xulRuntime.shell) script worker-error-propagation.js
|
||||
skip-if(!xulRuntime.shell) script worker-fib.js
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/licenses/publicdomain/
|
||||
|
||||
var gTestfile = 'typedarray-prototype.js';
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 565604;
|
||||
var summary =
|
||||
"Typed-array properties don't work when accessed from an object whose " +
|
||||
"prototype (or further-descended prototype) is a typed array";
|
||||
|
||||
print(BUGNUMBER + ": " + summary);
|
||||
|
||||
/**************
|
||||
* BEGIN TEST *
|
||||
**************/
|
||||
|
||||
var o = Object.create(new Uint8Array(1));
|
||||
assertEq(o.length, 1);
|
||||
|
||||
var o2 = Object.create(o);
|
||||
assertEq(o2.length, 1);
|
||||
|
||||
var VARIABLE_OBJECT = {};
|
||||
|
||||
var props =
|
||||
[
|
||||
{ property: "length", value: 1 },
|
||||
{ property: "byteLength", value: 1 },
|
||||
{ property: "byteOffset", value: 0 },
|
||||
{ property: "buffer", value: VARIABLE_OBJECT },
|
||||
];
|
||||
for (var i = 0, sz = props.length; i < sz; i++)
|
||||
{
|
||||
var p = props[i];
|
||||
|
||||
var o = Object.create(new Uint8Array(1));
|
||||
var v = o[p.property];
|
||||
if (p.value !== VARIABLE_OBJECT)
|
||||
assertEq(o[p.property], p.value, "bad " + p.property + " (proto)");
|
||||
|
||||
var o2 = Object.create(o);
|
||||
if (p.value !== VARIABLE_OBJECT)
|
||||
assertEq(o2[p.property], p.value, "bad " + p.property + " (grand-proto)");
|
||||
assertEq(o2[p.property], v, p.property + " mismatch");
|
||||
}
|
||||
|
||||
reportCompare(true, true);
|
Загрузка…
Ссылка в новой задаче