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:
Jeff Walden 2010-05-19 14:25:20 -07:00
Родитель e52ac354be
Коммит 984fff647d
5 изменённых файлов: 111 добавлений и 29 удалений

Просмотреть файл

@ -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);