author | Jeff Walden <jwalden@mit.edu> |
Thu, 24 Feb 2011 01:23:57 -0800 | |
changeset 63149 | 8323a963fd6c473e0890972d783775ae6f45a7e3 |
parent 63148 | d2f6db22db10a530482854838e684235a00204d8 |
child 63150 | 41218b2d043a9b80014dd1f03e190389aca71453 |
push id | 19043 |
push user | rsayre@mozilla.com |
push date | Sun, 27 Feb 2011 15:29:23 +0000 |
treeherder | mozilla-central@04e69fadcbcd [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | vlad, jorendorff |
bugs | 636078 |
milestone | 2.0b12pre |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
js/src/jstypedarray.cpp | file | annotate | diff | comparison | revisions | |
js/src/jstypedarray.h | file | annotate | diff | comparison | revisions |
--- a/js/src/jstypedarray.cpp +++ b/js/src/jstypedarray.cpp @@ -128,72 +128,66 @@ ArrayBuffer::class_finalize(JSContext *c } /* * new ArrayBuffer(byteLength) */ JSBool ArrayBuffer::class_constructor(JSContext *cx, uintN argc, Value *vp) { - return create(cx, argc, JS_ARGV(cx, vp), vp); + int32 nbytes = 0; + if (argc > 0 && !ValueToECMAInt32(cx, vp[2], &nbytes)) + return false; + + JSObject *bufobj = create(cx, nbytes); + if (!bufobj) + return false; + vp->setObject(*bufobj); + return true; } -bool -ArrayBuffer::create(JSContext *cx, uintN argc, Value *argv, Value *rval) +JSObject * +ArrayBuffer::create(JSContext *cx, int32 nbytes) { - /* N.B. there may not be an argv[-2]/argv[-1]. */ - JSObject *obj = NewBuiltinClassInstance(cx, &ArrayBuffer::jsclass); if (!obj) - return false; - - int32_t nbytes = 0; - if (argc > 0) { - if (!ValueToECMAInt32(cx, argv[0], &nbytes)) - return false; - } + return NULL; if (nbytes < 0) { /* * We're just not going to support arrays that are bigger than what will fit * as an integer value; if someone actually ever complains (validly), then we * can fix. */ - JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, - JSMSG_BAD_ARRAY_LENGTH); - return false; + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_ARRAY_LENGTH); + return NULL; } ArrayBuffer *abuf = cx->create<ArrayBuffer>(); - if (!abuf) { - JS_ReportOutOfMemory(cx); - return false; - } + if (!abuf) + return NULL; if (!abuf->allocateStorage(cx, nbytes)) { cx->destroy<ArrayBuffer>(abuf); - return false; + return NULL; } obj->setPrivate(abuf); - rval->setObject(*obj); - return true; + return obj; } bool ArrayBuffer::allocateStorage(JSContext *cx, uint32 nbytes) { JS_ASSERT(data == 0); if (nbytes) { data = cx->calloc(nbytes); - if (!data) { - JS_ReportOutOfMemory(cx); + if (!data) return false; - } } byteLength = nbytes; return true; } void ArrayBuffer::freeStorage(JSContext *cx) @@ -721,100 +715,121 @@ class TypedArrayTemplate } static JSType obj_typeOf(JSContext *cx, JSObject *obj) { return JSTYPE_OBJECT; } + static JSObject * + createTypedArray(JSContext *cx, JSObject *bufobj, uint32 byteOffset, uint32 len) + { + JSObject *obj = NewBuiltinClassInstance(cx, slowClass()); + if (!obj) + return NULL; + + ThisTypeArray *tarray = cx->create<ThisTypeArray>(bufobj, byteOffset, len); + if (!tarray) + return NULL; + + JS_ASSERT(obj->getClass() == slowClass()); + obj->setSharedNonNativeMap(); + obj->clasp = fastClass(); + obj->setPrivate(tarray); + + // FIXME Bug 599008: make it ok to call preventExtensions here. + obj->flags |= JSObject::NOT_EXTENSIBLE; + + return obj; + } + /* * new [Type]Array(length) * new [Type]Array(otherTypedArray) * new [Type]Array(JSArray) * new [Type]Array(ArrayBuffer, [optional] byteOffset, [optional] length) */ static JSBool class_constructor(JSContext *cx, uintN argc, Value *vp) { /* N.B. this is a constructor for slowClass, not fastClass! */ - return create(cx, argc, JS_ARGV(cx, vp), vp); + JSObject *obj = create(cx, argc, JS_ARGV(cx, vp)); + if (!obj) + return false; + vp->setObject(*obj); + return true; } - static JSBool - create(JSContext *cx, uintN argc, Value *argv, Value *rval) + static JSObject * + create(JSContext *cx, uintN argc, Value *argv) { /* N.B. there may not be an argv[-2]/argv[-1]. */ - JSObject *obj = NewBuiltinClassInstance(cx, slowClass()); - if (!obj) - return false; - - ThisTypeArray *tarray = 0; + /* () or (number) */ + jsuint len = 0; + if (argc == 0 || ValueIsLength(cx, argv[0], &len)) { + JSObject *bufobj = createBufferWithSizeAndCount(cx, len); + if (!bufobj) + return NULL; - // figure out the type of the first argument; - // no args is treated like an int arg of 0. - jsuint len = 0; - bool hasLen = true; - if (argc > 0) - hasLen = ValueIsLength(cx, argv[0], &len); + return createTypedArray(cx, bufobj, 0, len); + } + + /* (not an object) */ + if (!argv[0].isObject()) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_TYPED_ARRAY_BAD_ARGS); + return NULL; + } + + JSObject *dataObj = &argv[0].toObject(); - if (hasLen) { - tarray = cx->create<ThisTypeArray>(); - if (!tarray) { - JS_ReportOutOfMemory(cx); - return false; - } + /* (typedArray) */ + if (js_IsTypedArray(dataObj)) { + TypedArray *otherTypedArray = TypedArray::fromJSObject(dataObj); + JS_ASSERT(otherTypedArray); + + uint32 len = otherTypedArray->length; + JSObject *bufobj = createBufferWithSizeAndCount(cx, len); + if (!bufobj) + return NULL; - if (!tarray->init(cx, len)) { - cx->destroy<ThisTypeArray>(tarray); - return false; - } - } else if (argc > 0 && argv[0].isObject()) { - int32_t byteOffset = -1; - int32_t length = -1; + JSObject *obj = createTypedArray(cx, bufobj, 0, len); + if (!obj || !copyFrom(cx, obj, otherTypedArray, 0)) + return NULL; + return obj; + } - if (argc > 1) { - if (!ValueToInt32(cx, argv[1], &byteOffset)) - return false; - if (byteOffset < 0) { - JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, - JSMSG_TYPED_ARRAY_NEGATIVE_ARG, "1"); - return false; - } + /* (obj, byteOffset, length). */ + int32_t byteOffset = -1; + int32_t length = -1; + + if (argc > 1) { + if (!ValueToInt32(cx, argv[1], &byteOffset)) + return NULL; + if (byteOffset < 0) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_TYPED_ARRAY_NEGATIVE_ARG, "1"); + return NULL; } if (argc > 2) { if (!ValueToInt32(cx, argv[2], &length)) - return false; + return NULL; if (length < 0) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_TYPED_ARRAY_NEGATIVE_ARG, "2"); - return false; + return NULL; } } - - tarray = cx->create<ThisTypeArray>(); - if (!tarray) { - JS_ReportOutOfMemory(cx); - return false; - } - - if (!tarray->init(cx, &argv[0].toObject(), byteOffset, length)) { - cx->destroy<ThisTypeArray>(tarray); - return false; - } - } else { - JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, - JSMSG_TYPED_ARRAY_BAD_ARGS); - return false; } - rval->setObject(*obj); - return makeFastWithPrivate(cx, obj, tarray); + /* (obj, byteOffset, length) */ + return createTypedArrayWithOffsetLength(cx, dataObj, byteOffset, length); } static void class_finalize(JSContext *cx, JSObject *obj) { ThisTypeArray *tarray = ThisTypeArray::fromJSObject(obj); if (tarray) cx->destroy<ThisTypeArray>(tarray); @@ -870,35 +885,21 @@ class TypedArrayTemplate end = length; } } } if (begin > end) begin = end; - ThisTypeArray *ntarray = tarray->subarray(cx, begin, end); - if (!ntarray) { - // this should rarely ever happen - JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, - JSMSG_TYPED_ARRAY_BAD_ARGS); + JSObject *nobj = createSubarray(cx, tarray, begin, end); + if (!nobj) return false; - } - - // note the usage of NewObject here -- we don't want the - // constructor to be called! - JS_ASSERT(slowClass() != &js_FunctionClass); - JSObject *nobj = NewNonFunction<WithProto::Class>(cx, slowClass(), NULL, NULL); - if (!nobj) { - cx->destroy<ThisTypeArray>(ntarray); - return false; - } - vp->setObject(*nobj); - return makeFastWithPrivate(cx, nobj, ntarray); + return true; } /* set(array[, offset]) */ static JSBool fun_set(JSContext *cx, uintN argc, Value *vp) { JSObject *obj = ToObject(cx, &vp[1]); if (!obj) @@ -915,31 +916,33 @@ class TypedArrayTemplate return false; } ThisTypeArray *tarray = ThisTypeArray::fromJSObject(obj); if (!tarray) return true; // these are the default values - int32_t offset = 0; + int32_t off = 0; Value *argv = JS_ARGV(cx, vp); if (argc > 1) { - if (!ValueToInt32(cx, argv[1], &offset)) + if (!ValueToInt32(cx, argv[1], &off)) return false; - if (offset < 0 || uint32_t(offset) > tarray->length) { + if (off < 0 || uint32_t(off) > tarray->length) { // the given offset is bogus JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_TYPED_ARRAY_BAD_ARGS); return false; } } + uint32 offset(off); + // first arg must be either a typed array or a JS array if (argc == 0 || !argv[0].isObject()) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_TYPED_ARRAY_BAD_ARGS); return false; } JSObject *arg0 = argv[0].toObjectOrNull(); @@ -948,174 +951,168 @@ class TypedArrayTemplate if (!src || src->length > tarray->length - offset) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_TYPED_ARRAY_BAD_ARGS); return false; } - if (!tarray->copyFrom(cx, src, offset)) + if (!copyFrom(cx, obj, src, offset)) return false; } else { jsuint len; if (!js_GetLengthProperty(cx, arg0, &len)) return false; // avoid overflow; we know that offset <= length if (len > tarray->length - offset) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_TYPED_ARRAY_BAD_ARGS); return false; } - if (!tarray->copyFrom(cx, arg0, len, offset)) + if (!copyFrom(cx, obj, arg0, len, offset)) return false; } vp->setUndefined(); return true; } static ThisTypeArray * fromJSObject(JSObject *obj) { JS_ASSERT(obj->getClass() == fastClass()); return reinterpret_cast<ThisTypeArray*>(obj->getPrivate()); } - // helper used by both the constructor and Subarray() - static bool - makeFastWithPrivate(JSContext *cx, JSObject *obj, ThisTypeArray *tarray) + public: + TypedArrayTemplate(JSObject *bufobj, uint32 byteOffset, uint32 len) { - JS_ASSERT(obj->getClass() == slowClass()); - obj->setSharedNonNativeMap(); - obj->clasp = fastClass(); - obj->setPrivate(tarray); - - // FIXME bug 599008. make it ok to call preventExtensions here. - // Keeping the boolean signature of this method for now. - obj->flags |= JSObject::NOT_EXTENSIBLE; - return true; + JS_ASSERT(bufobj->getClass() == &ArrayBuffer::jsclass); + + type = ArrayTypeID(); + bufferJS = bufobj; + buffer = ArrayBuffer::fromJSObject(bufobj); + + this->byteOffset = byteOffset; + + JS_ASSERT(byteOffset <= buffer->byteLength); + this->data = buffer->offsetData(byteOffset); + JS_ASSERT(buffer->data <= this->data); + JS_ASSERT(this->data <= buffer->offsetData(buffer->byteLength)); + + this->byteLength = len * sizeof(NativeType); + JS_ASSERT(buffer->byteLength - byteOffset >= this->byteLength); + + this->length = len; } - public: - TypedArrayTemplate() { } - - bool - init(JSContext *cx, uint32 len) - { - type = ArrayTypeID(); - return createBufferWithSizeAndCount(cx, sizeof(NativeType), len); - } - - bool - init(JSContext *cx, JSObject *other, int32 byteOffsetInt = -1, int32 lengthInt = -1) + static JSObject * + createTypedArrayWithOffsetLength(JSContext *cx, JSObject *other, + int32 byteOffsetInt, int32 lengthInt) { - type = ArrayTypeID(); - ArrayBuffer *abuf; + JS_ASSERT(!js_IsTypedArray(other)); - if (js_IsTypedArray(other)) { - TypedArray *tarray = TypedArray::fromJSObject(other); - JS_ASSERT(tarray); - - if (!createBufferWithSizeAndCount(cx, sizeof(NativeType), tarray->length)) - return false; - if (!copyFrom(cx, tarray)) - return false; - } else if (other->getClass() == &ArrayBuffer::jsclass && + /* Handle creation from an ArrayBuffer not ArrayBuffer.prototype. */ + ArrayBuffer *abuf; + if (other->getClass() == &ArrayBuffer::jsclass && ((abuf = ArrayBuffer::fromJSObject(other)) != NULL)) { uint32 boffset = (byteOffsetInt < 0) ? 0 : uint32(byteOffsetInt); if (boffset > abuf->byteLength || boffset % sizeof(NativeType) != 0) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_TYPED_ARRAY_BAD_ARGS); - return false; // invalid byteOffset + return NULL; // invalid byteOffset } uint32 len; if (lengthInt < 0) { len = (abuf->byteLength - boffset) / sizeof(NativeType); if (len * sizeof(NativeType) != (abuf->byteLength - boffset)) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_TYPED_ARRAY_BAD_ARGS); - return false; // given byte array doesn't map exactly to sizeof(NativeType)*N + return NULL; // given byte array doesn't map exactly to sizeof(NativeType)*N } } else { len = (uint32) lengthInt; } // Go slowly and check for overflow. uint32 arrayByteLength = len*sizeof(NativeType); if (uint32(len) >= INT32_MAX / sizeof(NativeType) || uint32(boffset) >= INT32_MAX - arrayByteLength) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_TYPED_ARRAY_BAD_ARGS); - return false; // overflow occurred along the way when calculating boffset+len*sizeof(NativeType) + return NULL; // overflow occurred along the way when calculating boffset+len*sizeof(NativeType) } if (arrayByteLength + boffset > abuf->byteLength) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_TYPED_ARRAY_BAD_ARGS); - return false; // boffset+len is too big for the arraybuffer + return NULL; // boffset+len is too big for the arraybuffer } - buffer = abuf; - bufferJS = other; - byteOffset = boffset; - byteLength = arrayByteLength; - length = len; - data = abuf->offsetData(boffset); - } else { - jsuint len; - if (!js_GetLengthProperty(cx, other, &len)) - return false; - if (!createBufferWithSizeAndCount(cx, sizeof(NativeType), len)) - return false; - if (!copyFrom(cx, other, len)) - return false; + return createTypedArray(cx, other, boffset, len); } - return true; + /* + * Otherwise create a new typed array and copy len properties from the + * object. + */ + jsuint len; + if (!js_GetLengthProperty(cx, other, &len)) + return NULL; + + JSObject *bufobj = createBufferWithSizeAndCount(cx, len); + if (!bufobj) + return NULL; + + JSObject *obj = createTypedArray(cx, bufobj, 0, len); + if (!obj || !copyFrom(cx, obj, other, len)) + return NULL; + return obj; } const NativeType getIndex(uint32 index) const { return *(static_cast<const NativeType*>(data) + index); } void setIndex(uint32 index, NativeType val) { *(static_cast<NativeType*>(data) + index) = val; } inline void copyIndexToValue(JSContext *cx, uint32 index, Value *vp); - ThisTypeArray * - subarray(JSContext *cx, uint32 begin, uint32 end) + static JSObject * + createSubarray(JSContext *cx, ThisTypeArray *tarray, uint32 begin, uint32 end) { - if (begin > length || end > length) - return NULL; + JS_ASSERT(tarray); - ThisTypeArray *tarray = cx->create<ThisTypeArray>(); - if (!tarray) - return NULL; + JS_ASSERT(0 <= begin); + JS_ASSERT(begin <= tarray->length); + JS_ASSERT(0 <= end); + JS_ASSERT(end <= tarray->length); - tarray->buffer = buffer; - tarray->bufferJS = bufferJS; - tarray->byteOffset = byteOffset + begin * sizeof(NativeType); - tarray->byteLength = (end - begin) * sizeof(NativeType); - tarray->length = end - begin; - tarray->type = type; - tarray->data = buffer->offsetData(tarray->byteOffset); + JSObject *bufobj = tarray->bufferJS; + JS_ASSERT(bufobj); - return tarray; + JS_ASSERT(begin <= end); + uint32 length = end - begin; + + JS_ASSERT(begin < UINT32_MAX / sizeof(NativeType)); + uint32 byteOffset = begin * sizeof(NativeType); + + return createTypedArray(cx, bufobj, byteOffset, length); } protected: static NativeType nativeFromValue(JSContext *cx, const Value &v) { if (v.isInt32()) return NativeType(v.toInt32()); @@ -1134,22 +1131,26 @@ class TypedArrayTemplate } if (ArrayTypeIsFloatingPoint()) return NativeType(js_NaN); return NativeType(int32(0)); } - bool - copyFrom(JSContext *cx, JSObject *ar, jsuint len, jsuint offset = 0) + static bool + copyFrom(JSContext *cx, JSObject *thisTypedArrayObj, + JSObject *ar, jsuint len, jsuint offset = 0) { - JS_ASSERT(offset <= length); - JS_ASSERT(len <= length - offset); - NativeType *dest = static_cast<NativeType*>(data) + offset; + ThisTypeArray *thisTypedArray = fromJSObject(thisTypedArrayObj); + JS_ASSERT(thisTypedArray); + + JS_ASSERT(offset <= thisTypedArray->length); + JS_ASSERT(len <= thisTypedArray->length - offset); + NativeType *dest = static_cast<NativeType*>(thisTypedArray->data) + offset; if (ar->isDenseArray() && ar->getDenseArrayCapacity() >= len) { JS_ASSERT(ar->getArrayLength() == len); Value *src = ar->getDenseArrayElements(); for (uintN i = 0; i < len; ++i) *dest++ = nativeFromValue(cx, *src++); @@ -1162,27 +1163,30 @@ class TypedArrayTemplate return false; *dest++ = nativeFromValue(cx, v); } } return true; } - bool - copyFrom(JSContext *cx, TypedArray *tarray, jsuint offset = 0) + static bool + copyFrom(JSContext *cx, JSObject *thisTypedArrayObj, TypedArray *tarray, jsuint offset) { - JS_ASSERT(offset <= length); - JS_ASSERT(tarray->length <= length - offset); - if (tarray->buffer == buffer) - return copyFromWithOverlap(cx, tarray, offset); + ThisTypeArray *thisTypedArray = fromJSObject(thisTypedArrayObj); + JS_ASSERT(thisTypedArray); - NativeType *dest = static_cast<NativeType*>(data) + offset; + JS_ASSERT(offset <= thisTypedArray->length); + JS_ASSERT(tarray->length <= thisTypedArray->length - offset); + if (tarray->buffer == thisTypedArray->buffer) + return thisTypedArray->copyFromWithOverlap(cx, tarray, offset); - if (tarray->type == type) { + NativeType *dest = static_cast<NativeType*>(thisTypedArray->data) + offset; + + if (tarray->type == thisTypedArray->type) { memcpy(dest, tarray->data, tarray->byteLength); return true; } uintN srclen = tarray->length; switch (tarray->type) { case TypedArray::TYPE_INT8: { int8 *src = static_cast<int8*>(tarray->data); @@ -1237,34 +1241,32 @@ class TypedArrayTemplate JS_NOT_REACHED("copyFrom with a TypedArray of unknown type"); break; } return true; } bool - copyFromWithOverlap(JSContext *cx, TypedArray *tarray, jsuint offset = 0) + copyFromWithOverlap(JSContext *cx, TypedArray *tarray, jsuint offset) { JS_ASSERT(offset <= length); NativeType *dest = static_cast<NativeType*>(data) + offset; if (tarray->type == type) { memmove(dest, tarray->data, tarray->byteLength); return true; } // We have to make a copy of the source array here, since // there's overlap, and we have to convert types. - void *srcbuf = js_malloc(tarray->byteLength); - if (!srcbuf) { - js_ReportOutOfMemory(cx); + void *srcbuf = cx->malloc(tarray->byteLength); + if (!srcbuf) return false; - } memcpy(srcbuf, tarray->data, tarray->byteLength); switch (tarray->type) { case TypedArray::TYPE_INT8: { int8 *src = (int8*) srcbuf; for (uintN i = 0; i < tarray->length; ++i) *dest++ = NativeType(*src++); break; @@ -1316,52 +1318,28 @@ class TypedArrayTemplate JS_NOT_REACHED("copyFromWithOverlap with a TypedArray of unknown type"); break; } js_free(srcbuf); return true; } - bool - createBufferWithSizeAndCount(JSContext *cx, uint32 size, uint32 count) + static JSObject * + createBufferWithSizeAndCount(JSContext *cx, uint32 count) { - JS_ASSERT(size != 0); - + size_t size = sizeof(NativeType); if (size != 0 && count >= INT32_MAX / size) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NEED_DIET, "size and count"); return false; } int32 bytelen = size * count; - if (!createBufferWithByteLength(cx, bytelen)) - return false; - - length = count; - return true; - } - - bool - createBufferWithByteLength(JSContext *cx, int32 bytes) - { - Value arg = Int32Value(bytes), rval; - if (!ArrayBuffer::create(cx, 1, &arg, &rval)) - return false; - - JSObject *obj = &rval.toObject(); - - bufferJS = obj; - buffer = ArrayBuffer::fromJSObject(obj); - - byteOffset = 0; - byteLength = bytes; - data = buffer->data; - - return true; + return ArrayBuffer::create(cx, bytelen); } }; // this default implementation is only valid for integer types // less than 32-bits in size. template<typename NativeType> void TypedArrayTemplate<NativeType>::copyIndexToValue(JSContext *cx, uint32 index, Value *vp) @@ -1645,120 +1623,99 @@ js_IsTypedArray(JSObject *obj) Class *clasp = obj->getClass(); return clasp >= &TypedArray::fastClasses[0] && clasp < &TypedArray::fastClasses[TypedArray::TYPE_MAX]; } JS_FRIEND_API(JSObject *) js_CreateArrayBuffer(JSContext *cx, jsuint nbytes) { - Value arg = NumberValue(nbytes), rval; - if (!ArrayBuffer::create(cx, 1, &arg, &rval)) - return NULL; - return &rval.toObject(); + return ArrayBuffer::create(cx, nbytes); } -static inline JSBool -TypedArrayConstruct(JSContext *cx, jsint atype, uintN argc, Value *argv, Value *rv) +static inline JSObject * +TypedArrayConstruct(JSContext *cx, jsint atype, uintN argc, Value *argv) { switch (atype) { case TypedArray::TYPE_INT8: - return Int8Array::create(cx, argc, argv, rv); + return Int8Array::create(cx, argc, argv); case TypedArray::TYPE_UINT8: - return Uint8Array::create(cx, argc, argv, rv); + return Uint8Array::create(cx, argc, argv); case TypedArray::TYPE_INT16: - return Int16Array::create(cx, argc, argv, rv); + return Int16Array::create(cx, argc, argv); case TypedArray::TYPE_UINT16: - return Uint16Array::create(cx, argc, argv, rv); + return Uint16Array::create(cx, argc, argv); case TypedArray::TYPE_INT32: - return Int32Array::create(cx, argc, argv, rv); + return Int32Array::create(cx, argc, argv); case TypedArray::TYPE_UINT32: - return Uint32Array::create(cx, argc, argv, rv); + return Uint32Array::create(cx, argc, argv); case TypedArray::TYPE_FLOAT32: - return Float32Array::create(cx, argc, argv, rv); + return Float32Array::create(cx, argc, argv); case TypedArray::TYPE_FLOAT64: - return Float64Array::create(cx, argc, argv, rv); + return Float64Array::create(cx, argc, argv); case TypedArray::TYPE_UINT8_CLAMPED: - return Uint8ClampedArray::create(cx, argc, argv, rv); + return Uint8ClampedArray::create(cx, argc, argv); default: JS_NOT_REACHED("shouldn't have gotten here"); return false; } } JS_FRIEND_API(JSObject *) js_CreateTypedArray(JSContext *cx, jsint atype, jsuint nelements) { JS_ASSERT(atype >= 0 && atype < TypedArray::TYPE_MAX); - Value vals[2]; - vals[0].setInt32(nelements); - vals[1].setUndefined(); - - AutoArrayRooter tvr(cx, JS_ARRAY_LENGTH(vals), vals); - if (!TypedArrayConstruct(cx, atype, 1, &vals[0], &vals[1])) - return NULL; - - return &vals[1].toObject(); + Value nelems = Int32Value(nelements); + return TypedArrayConstruct(cx, atype, 1, &nelems); } JS_FRIEND_API(JSObject *) js_CreateTypedArrayWithArray(JSContext *cx, jsint atype, JSObject *arrayArg) { JS_ASSERT(atype >= 0 && atype < TypedArray::TYPE_MAX); - Value vals[2]; - vals[0].setObject(*arrayArg); - vals[1].setUndefined(); - - AutoArrayRooter tvr(cx, JS_ARRAY_LENGTH(vals), vals); - if (!TypedArrayConstruct(cx, atype, 1, &vals[0], &vals[1])) - return NULL; - - return &vals[1].toObject(); + Value arrval = ObjectValue(*arrayArg); + return TypedArrayConstruct(cx, atype, 1, &arrval); } JS_FRIEND_API(JSObject *) js_CreateTypedArrayWithBuffer(JSContext *cx, jsint atype, JSObject *bufArg, jsint byteoffset, jsint length) { JS_ASSERT(atype >= 0 && atype < TypedArray::TYPE_MAX); JS_ASSERT(bufArg && ArrayBuffer::fromJSObject(bufArg)); JS_ASSERT_IF(byteoffset < 0, length < 0); Value vals[4]; int argc = 1; vals[0].setObject(*bufArg); - vals[3].setUndefined(); if (byteoffset >= 0) { vals[argc].setInt32(byteoffset); argc++; } if (length >= 0) { vals[argc].setInt32(length); argc++; } AutoArrayRooter tvr(cx, JS_ARRAY_LENGTH(vals), vals); - if (!TypedArrayConstruct(cx, atype, argc, &vals[0], &vals[3])) - return NULL; - - return &vals[3].toObject(); + return TypedArrayConstruct(cx, atype, argc, &vals[0]); } JS_FRIEND_API(JSBool) js_ReparentTypedArrayToScope(JSContext *cx, JSObject *obj, JSObject *scope) { JS_ASSERT(obj); scope = JS_GetGlobalForObject(cx, scope);
--- a/js/src/jstypedarray.h +++ b/js/src/jstypedarray.h @@ -59,17 +59,17 @@ struct JS_FRIEND_API(ArrayBuffer) { static Class jsclass; static JSPropertySpec jsprops[]; static JSBool prop_getByteLength(JSContext *cx, JSObject *obj, jsid id, Value *vp); static void class_finalize(JSContext *cx, JSObject *obj); static JSBool class_constructor(JSContext *cx, uintN argc, Value *vp); - static bool create(JSContext *cx, uintN argc, Value *argv, Value *rval); + static JSObject *create(JSContext *cx, int32 nbytes); static ArrayBuffer *fromJSObject(JSObject *obj); ArrayBuffer() : data(0), byteLength() { }