mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 07:42:04 +00:00
Bug 734215 - Typed array property access should allow proxies. r=luke
This commit is contained in:
parent
718ba96e5c
commit
c34b5ceff4
@ -1,8 +1,13 @@
|
||||
// |jit-test| error: ReferenceError
|
||||
// vim: set ts=4 sw=4 tw=99 et:
|
||||
|
||||
// Note: modified from original test, which used Uint32Array in place of Array,
|
||||
// because the behavior has changed in a way that this will throw a TypeError
|
||||
// before it gets to testing what used to crash. I have no idea whether this
|
||||
// would actually crash the original version it was written for.
|
||||
try {
|
||||
(function () {
|
||||
__proto__ = Uint32Array()
|
||||
__proto__ = Array()
|
||||
}())
|
||||
} catch (e) {}(function () {
|
||||
length, ([eval()] ? x : 7)
|
||||
|
@ -118,7 +118,9 @@ DEFINE_ATOM(hasOwn, "hasOwn")
|
||||
DEFINE_ATOM(keys, "keys")
|
||||
DEFINE_ATOM(iterate, "iterate")
|
||||
DEFINE_PROTOTYPE_ATOM(WeakMap)
|
||||
DEFINE_ATOM(buffer, "buffer")
|
||||
DEFINE_ATOM(byteLength, "byteLength")
|
||||
DEFINE_ATOM(byteOffset, "byteOffset")
|
||||
DEFINE_KEYWORD_ATOM(return)
|
||||
DEFINE_KEYWORD_ATOM(throw)
|
||||
DEFINE_ATOM(url, "url")
|
||||
|
@ -403,23 +403,23 @@ JS_WriteTypedArray(JSStructuredCloneWriter *w, jsval v)
|
||||
bool
|
||||
JSStructuredCloneWriter::writeTypedArray(JSObject *arr)
|
||||
{
|
||||
if (!out.writePair(ArrayTypeToTag(TypedArray::getType(arr)), TypedArray::getLength(arr)))
|
||||
if (!out.writePair(ArrayTypeToTag(TypedArray::type(arr)), TypedArray::length(arr)))
|
||||
return false;
|
||||
|
||||
switch (TypedArray::getType(arr)) {
|
||||
switch (TypedArray::type(arr)) {
|
||||
case TypedArray::TYPE_INT8:
|
||||
case TypedArray::TYPE_UINT8:
|
||||
case TypedArray::TYPE_UINT8_CLAMPED:
|
||||
return out.writeArray((const uint8_t *) TypedArray::getDataOffset(arr), TypedArray::getLength(arr));
|
||||
return out.writeArray((const uint8_t *) TypedArray::viewData(arr), TypedArray::length(arr));
|
||||
case TypedArray::TYPE_INT16:
|
||||
case TypedArray::TYPE_UINT16:
|
||||
return out.writeArray((const uint16_t *) TypedArray::getDataOffset(arr), TypedArray::getLength(arr));
|
||||
return out.writeArray((const uint16_t *) TypedArray::viewData(arr), TypedArray::length(arr));
|
||||
case TypedArray::TYPE_INT32:
|
||||
case TypedArray::TYPE_UINT32:
|
||||
case TypedArray::TYPE_FLOAT32:
|
||||
return out.writeArray((const uint32_t *) TypedArray::getDataOffset(arr), TypedArray::getLength(arr));
|
||||
return out.writeArray((const uint32_t *) TypedArray::viewData(arr), TypedArray::length(arr));
|
||||
case TypedArray::TYPE_FLOAT64:
|
||||
return out.writeArray((const uint64_t *) TypedArray::getDataOffset(arr), TypedArray::getLength(arr));
|
||||
return out.writeArray((const uint64_t *) TypedArray::viewData(arr), TypedArray::length(arr));
|
||||
default:
|
||||
JS_NOT_REACHED("unknown TypedArray type");
|
||||
return false;
|
||||
@ -719,7 +719,7 @@ JSStructuredCloneReader::readTypedArray(uint32_t tag, uint32_t nelems, Value *vp
|
||||
return false;
|
||||
vp->setObject(*obj);
|
||||
|
||||
JS_ASSERT(TypedArray::getLength(obj) == nelems);
|
||||
JS_ASSERT(TypedArray::length(obj) == nelems);
|
||||
switch (tag) {
|
||||
case SCTAG_TYPED_ARRAY_INT8:
|
||||
return in.readArray((uint8_t*) JS_GetInt8ArrayData(obj, context()), nelems);
|
||||
|
@ -201,7 +201,7 @@ GetPropertyOperation(JSContext *cx, jsbytecode *pc, const Value &lval, Value *vp
|
||||
}
|
||||
|
||||
if (obj->isTypedArray()) {
|
||||
*vp = Int32Value(TypedArray::getLength(obj));
|
||||
*vp = Int32Value(TypedArray::length(obj));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -118,16 +118,17 @@ getArrayBuffer(JSObject *obj)
|
||||
}
|
||||
|
||||
JSBool
|
||||
ArrayBufferObject::prop_getByteLength(JSContext *cx, HandleObject obj, HandleId id, Value *vp)
|
||||
ArrayBufferObject::byteLengthGetter(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
ArrayBufferObject *buffer = getArrayBuffer(obj);
|
||||
if (!buffer) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_INCOMPATIBLE_PROTO, "ArrayBuffer", "byteLength", "object");
|
||||
return false;
|
||||
}
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
vp->setInt32(int32_t(buffer->byteLength()));
|
||||
JSObject *thisObj;
|
||||
if (!NonGenericMethodGuard(cx, args, byteLengthGetter, &ArrayBufferClass, &thisObj))
|
||||
return false;
|
||||
if (!thisObj)
|
||||
return true;
|
||||
|
||||
JS_SET_RVAL(cx, vp, Int32Value(thisObj->asArrayBuffer().byteLength()));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -766,7 +767,7 @@ inline bool
|
||||
TypedArray::isArrayIndex(JSContext *cx, JSObject *obj, jsid id, uint32_t *ip)
|
||||
{
|
||||
uint32_t index;
|
||||
if (js_IdIsIndex(id, &index) && index < getLength(obj)) {
|
||||
if (js_IdIsIndex(id, &index) && index < length(obj)) {
|
||||
if (ip)
|
||||
*ip = index;
|
||||
return true;
|
||||
@ -782,70 +783,6 @@ js::IsDataView(JSObject* obj)
|
||||
return obj->isDataView();
|
||||
}
|
||||
|
||||
/*
|
||||
* For now (until slots directly hold data)
|
||||
* slots data element points to the JSObject representing the ArrayBuffer.
|
||||
*/
|
||||
JSBool
|
||||
TypedArray::prop_getBuffer(JSContext *cx, HandleObject obj, HandleId id, Value *vp)
|
||||
{
|
||||
JSObject *tarray = getTypedArray(obj);
|
||||
|
||||
if (!tarray) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_INCOMPATIBLE_PROTO, "TypedArray", "buffer", "object");
|
||||
return false;
|
||||
}
|
||||
|
||||
JS_SET_RVAL(cx, vp, ObjectValue(*TypedArray::getBuffer(tarray)));
|
||||
return true;
|
||||
}
|
||||
|
||||
JSBool
|
||||
TypedArray::prop_getByteOffset(JSContext *cx, HandleObject obj, HandleId id, Value *vp)
|
||||
{
|
||||
JSObject *tarray = getTypedArray(obj);
|
||||
|
||||
if (!tarray) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_INCOMPATIBLE_PROTO, "TypedArray", "byteOffset", "object");
|
||||
return false;
|
||||
}
|
||||
|
||||
JS_SET_RVAL(cx, vp, Int32Value(TypedArray::getByteOffset(tarray)));
|
||||
return true;
|
||||
}
|
||||
|
||||
JSBool
|
||||
TypedArray::prop_getByteLength(JSContext *cx, HandleObject obj, HandleId id, Value *vp)
|
||||
{
|
||||
JSObject *tarray = getTypedArray(obj);
|
||||
|
||||
if (!tarray) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_INCOMPATIBLE_PROTO, "TypedArray", "byteLength", "object");
|
||||
return false;
|
||||
}
|
||||
|
||||
JS_SET_RVAL(cx, vp, Int32Value(TypedArray::getByteLength(tarray)));
|
||||
return true;
|
||||
}
|
||||
|
||||
JSBool
|
||||
TypedArray::prop_getLength(JSContext *cx, HandleObject obj, HandleId id, Value *vp)
|
||||
{
|
||||
JSObject *tarray = getTypedArray(obj);
|
||||
|
||||
if (!tarray) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_INCOMPATIBLE_PROTO, "TypedArray", "length", "object");
|
||||
return false;
|
||||
}
|
||||
|
||||
JS_SET_RVAL(cx, vp, Int32Value(TypedArray::getLength(tarray)));
|
||||
return true;
|
||||
}
|
||||
|
||||
JSBool
|
||||
TypedArray::obj_lookupGeneric(JSContext *cx, HandleObject obj, HandleId id,
|
||||
JSObject **objp, JSProperty **propp)
|
||||
@ -884,7 +821,7 @@ TypedArray::obj_lookupElement(JSContext *cx, HandleObject obj, uint32_t index,
|
||||
JSObject *tarray = getTypedArray(obj);
|
||||
JS_ASSERT(tarray);
|
||||
|
||||
if (index < getLength(tarray)) {
|
||||
if (index < length(tarray)) {
|
||||
*propp = PROPERTY_FOUND;
|
||||
*objp = obj;
|
||||
return true;
|
||||
@ -1070,7 +1007,7 @@ class TypedArrayTemplate
|
||||
JSObject *tarray = getTypedArray(obj);
|
||||
|
||||
if (name == cx->runtime->atomState.lengthAtom) {
|
||||
vp->setNumber(getLength(tarray));
|
||||
*vp = lengthValue(tarray);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1088,7 +1025,7 @@ class TypedArrayTemplate
|
||||
{
|
||||
JSObject *tarray = getTypedArray(obj);
|
||||
|
||||
if (index < getLength(tarray)) {
|
||||
if (index < length(tarray)) {
|
||||
copyIndexToValue(cx, tarray, index, vp);
|
||||
return true;
|
||||
}
|
||||
@ -1144,7 +1081,7 @@ class TypedArrayTemplate
|
||||
// Fast-path the common case of index < length
|
||||
JSObject *tarray = getTypedArray(obj);
|
||||
|
||||
if (index < getLength(tarray)) {
|
||||
if (index < length(tarray)) {
|
||||
// this inline function is specialized for each type
|
||||
copyIndexToValue(cx, tarray, index, vp);
|
||||
*present = true;
|
||||
@ -1189,7 +1126,7 @@ class TypedArrayTemplate
|
||||
setElementTail(JSContext *cx, JSObject *tarray, uint32_t index, Value *vp, JSBool strict)
|
||||
{
|
||||
JS_ASSERT(tarray);
|
||||
JS_ASSERT(index < getLength(tarray));
|
||||
JS_ASSERT(index < length(tarray));
|
||||
|
||||
if (vp->isInt32()) {
|
||||
setIndex(tarray, index, NativeType(vp->toInt32()));
|
||||
@ -1231,7 +1168,7 @@ class TypedArrayTemplate
|
||||
JS_ASSERT(tarray);
|
||||
|
||||
if (JSID_IS_ATOM(id, cx->runtime->atomState.lengthAtom)) {
|
||||
vp->setNumber(getLength(tarray));
|
||||
vp->setNumber(length(tarray));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1263,7 +1200,7 @@ class TypedArrayTemplate
|
||||
RootedObject tarray(cx, getTypedArray(obj));
|
||||
JS_ASSERT(tarray);
|
||||
|
||||
if (index >= getLength(tarray)) {
|
||||
if (index >= length(tarray)) {
|
||||
// Silent ignore is better than an exception here, because
|
||||
// at some point we may want to support other properties on
|
||||
// these objects. This is especially true when these arrays
|
||||
@ -1336,7 +1273,7 @@ class TypedArrayTemplate
|
||||
JSObject *tarray = getTypedArray(obj);
|
||||
JS_ASSERT(tarray);
|
||||
|
||||
if (index < getLength(tarray)) {
|
||||
if (index < length(tarray)) {
|
||||
rval->setBoolean(false);
|
||||
return true;
|
||||
}
|
||||
@ -1368,13 +1305,13 @@ class TypedArrayTemplate
|
||||
case JSENUMERATE_INIT_ALL:
|
||||
statep->setBoolean(true);
|
||||
if (idp)
|
||||
*idp = ::INT_TO_JSID(getLength(tarray) + 1);
|
||||
*idp = ::INT_TO_JSID(length(tarray) + 1);
|
||||
break;
|
||||
|
||||
case JSENUMERATE_INIT:
|
||||
statep->setInt32(0);
|
||||
if (idp)
|
||||
*idp = ::INT_TO_JSID(getLength(tarray));
|
||||
*idp = ::INT_TO_JSID(length(tarray));
|
||||
break;
|
||||
|
||||
case JSENUMERATE_NEXT:
|
||||
@ -1383,11 +1320,11 @@ class TypedArrayTemplate
|
||||
statep->setInt32(0);
|
||||
} else {
|
||||
uint32_t index = statep->toInt32();
|
||||
if (index < getLength(tarray)) {
|
||||
if (index < length(tarray)) {
|
||||
*idp = ::INT_TO_JSID(index);
|
||||
statep->setInt32(index + 1);
|
||||
} else {
|
||||
JS_ASSERT(index == getLength(tarray));
|
||||
JS_ASSERT(index == length(tarray));
|
||||
statep->setNull();
|
||||
}
|
||||
}
|
||||
@ -1462,13 +1399,16 @@ class TypedArrayTemplate
|
||||
return NULL;
|
||||
obj->setLastPropertyInfallible(empty);
|
||||
|
||||
DebugOnly<uint32_t> bufferByteLength = buffer->byteLength();
|
||||
JS_ASSERT(bufferByteLength - getByteOffset(obj) >= getByteLength(obj));
|
||||
JS_ASSERT(getByteOffset(obj) <= bufferByteLength);
|
||||
JS_ASSERT(buffer->dataPointer() <= getDataOffset(obj));
|
||||
JS_ASSERT(getDataOffset(obj) <= offsetData(obj, bufferByteLength));
|
||||
#ifdef DEBUG
|
||||
uint32_t bufferByteLength = buffer->byteLength();
|
||||
uint32_t arrayByteLength = static_cast<uint32_t>(byteLengthValue(obj).toInt32());
|
||||
uint32_t arrayByteOffset = static_cast<uint32_t>(byteOffsetValue(obj).toInt32());
|
||||
JS_ASSERT(buffer->dataPointer() <= viewData(obj));
|
||||
JS_ASSERT(bufferByteLength - byteOffsetValue(obj).toInt32() >= arrayByteLength);
|
||||
JS_ASSERT(arrayByteOffset <= bufferByteLength);
|
||||
|
||||
JS_ASSERT(obj->numFixedSlots() == NUM_FIXED_SLOTS);
|
||||
#endif
|
||||
|
||||
return obj;
|
||||
}
|
||||
@ -1567,6 +1507,61 @@ class TypedArrayTemplate
|
||||
return fromBuffer(cx, dataObj, byteOffset, length, proto);
|
||||
}
|
||||
|
||||
// ValueGetter is a function that takes an unwrapped typed array object and
|
||||
// returns a Value. Given such a function, Getter<> is a native that
|
||||
// retrieves a given Value, probably from a slot on the object.
|
||||
template<Value ValueGetter(JSObject *)>
|
||||
static JSBool
|
||||
Getter(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
JSObject *thisObj;
|
||||
if (!NonGenericMethodGuard(cx, args, Getter<ValueGetter>, fastClass(), &thisObj))
|
||||
return false;
|
||||
if (!thisObj)
|
||||
return true;
|
||||
|
||||
JS_SET_RVAL(cx, vp, ValueGetter(thisObj));
|
||||
return true;
|
||||
}
|
||||
|
||||
// Define an accessor for a read-only property that invokes a native getter
|
||||
template<Value ValueGetter(JSObject *)>
|
||||
static bool
|
||||
DefineGetter(JSContext *cx, PropertyName *name, HandleObject proto)
|
||||
{
|
||||
RootedId id(cx, NameToId(name));
|
||||
unsigned flags = JSPROP_PERMANENT | JSPROP_READONLY | JSPROP_SHARED | JSPROP_GETTER;
|
||||
|
||||
Rooted<GlobalObject*> global(cx, &cx->compartment->global());
|
||||
JSObject *getter = js_NewFunction(cx, NULL, Getter<ValueGetter>, 0, 0, global, NULL);
|
||||
if (!getter)
|
||||
return false;
|
||||
|
||||
return DefineNativeProperty(cx, proto, id, UndefinedValue(),
|
||||
JS_DATA_TO_FUNC_PTR(PropertyOp, getter), NULL,
|
||||
flags, 0, 0);
|
||||
}
|
||||
|
||||
static
|
||||
bool defineGetters(JSContext *cx, HandleObject proto)
|
||||
{
|
||||
if (!DefineGetter<lengthValue>(cx, cx->runtime->atomState.lengthAtom, proto))
|
||||
return false;
|
||||
|
||||
if (!DefineGetter<bufferValue>(cx, cx->runtime->atomState.bufferAtom, proto))
|
||||
return false;
|
||||
|
||||
if (!DefineGetter<byteLengthValue>(cx, cx->runtime->atomState.byteLengthAtom, proto))
|
||||
return false;
|
||||
|
||||
if (!DefineGetter<byteOffsetValue>(cx, cx->runtime->atomState.byteOffsetAtom, proto))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* subarray(start[, end]) */
|
||||
static JSBool
|
||||
fun_subarray(JSContext *cx, unsigned argc, Value *vp)
|
||||
@ -1584,8 +1579,8 @@ class TypedArrayTemplate
|
||||
return true;
|
||||
|
||||
// these are the default values
|
||||
uint32_t begin = 0, end = getLength(tarray);
|
||||
uint32_t length = getLength(tarray);
|
||||
uint32_t begin = 0, end = length(tarray);
|
||||
uint32_t length = TypedArray::length(tarray);
|
||||
|
||||
if (args.length() > 0) {
|
||||
if (!ToClampedIndex(cx, args[0], length, &begin))
|
||||
@ -1629,7 +1624,7 @@ class TypedArrayTemplate
|
||||
uint32_t dest;
|
||||
|
||||
JSObject *tarray = getTypedArray(obj);
|
||||
uint32_t length = getLength(tarray);
|
||||
uint32_t length = TypedArray::length(tarray);
|
||||
if (!ToClampedIndex(cx, args[0], length, &srcBegin) ||
|
||||
!ToClampedIndex(cx, args[1], length, &srcEnd) ||
|
||||
!ToClampedIndex(cx, args[2], length, &dest) ||
|
||||
@ -1651,7 +1646,8 @@ class TypedArrayTemplate
|
||||
uint32_t byteSrc = srcBegin * sizeof(NativeType);
|
||||
uint32_t byteSize = nelts * sizeof(NativeType);
|
||||
|
||||
DebugOnly<uint32_t> viewByteLength = getByteLength(tarray);
|
||||
#ifdef DEBUG
|
||||
uint32_t viewByteLength = byteLengthValue(tarray).toInt32();
|
||||
JS_ASSERT(byteDest <= viewByteLength);
|
||||
JS_ASSERT(byteSrc <= viewByteLength);
|
||||
JS_ASSERT(byteDest + byteSize <= viewByteLength);
|
||||
@ -1660,8 +1656,9 @@ class TypedArrayTemplate
|
||||
// Should not overflow because size is limited to 2^31
|
||||
JS_ASSERT(byteDest + byteSize >= byteDest);
|
||||
JS_ASSERT(byteSrc + byteSize >= byteSrc);
|
||||
#endif
|
||||
|
||||
uint8_t *data = static_cast<uint8_t*>(getDataOffset(tarray));
|
||||
uint8_t *data = static_cast<uint8_t*>(viewData(tarray));
|
||||
memmove(&data[byteDest], &data[byteSrc], byteSize);
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
@ -1694,7 +1691,7 @@ class TypedArrayTemplate
|
||||
if (!ToInt32(cx, args[1], &offset))
|
||||
return false;
|
||||
|
||||
if (offset < 0 || uint32_t(offset) > getLength(tarray)) {
|
||||
if (offset < 0 || uint32_t(offset) > length(tarray)) {
|
||||
// the given offset is bogus
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_TYPED_ARRAY_BAD_INDEX, "2");
|
||||
return false;
|
||||
@ -1709,7 +1706,7 @@ class TypedArrayTemplate
|
||||
RootedObject arg0(cx, args[0].toObjectOrNull());
|
||||
RootedObject src(cx, getTypedArray(arg0));
|
||||
if (src) {
|
||||
if (getLength(src) > getLength(tarray) - offset) {
|
||||
if (length(src) > length(tarray) - offset) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_ARRAY_LENGTH);
|
||||
return false;
|
||||
}
|
||||
@ -1723,7 +1720,7 @@ class TypedArrayTemplate
|
||||
return false;
|
||||
|
||||
// avoid overflow; we know that offset <= length
|
||||
if (len > getLength(tarray) - offset) {
|
||||
if (len > length(tarray) - offset) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_ARRAY_LENGTH);
|
||||
return false;
|
||||
}
|
||||
@ -1857,13 +1854,13 @@ class TypedArrayTemplate
|
||||
static const NativeType
|
||||
getIndex(JSObject *obj, uint32_t index)
|
||||
{
|
||||
return *(static_cast<const NativeType*>(getDataOffset(obj)) + index);
|
||||
return *(static_cast<const NativeType*>(viewData(obj)) + index);
|
||||
}
|
||||
|
||||
static void
|
||||
setIndex(JSObject *obj, uint32_t index, NativeType val)
|
||||
{
|
||||
*(static_cast<NativeType*>(getDataOffset(obj)) + index) = val;
|
||||
*(static_cast<NativeType*>(viewData(obj)) + index) = val;
|
||||
}
|
||||
|
||||
static void copyIndexToValue(JSContext *cx, JSObject *tarray, uint32_t index, Value *vp);
|
||||
@ -1873,18 +1870,19 @@ class TypedArrayTemplate
|
||||
{
|
||||
JS_ASSERT(tarray);
|
||||
|
||||
JS_ASSERT(begin <= getLength(tarray));
|
||||
JS_ASSERT(end <= getLength(tarray));
|
||||
JS_ASSERT(begin <= length(tarray));
|
||||
JS_ASSERT(end <= length(tarray));
|
||||
|
||||
RootedObject bufobj(cx, getBuffer(tarray));
|
||||
RootedObject bufobj(cx, buffer(tarray));
|
||||
JS_ASSERT(bufobj);
|
||||
|
||||
JS_ASSERT(begin <= end);
|
||||
uint32_t length = end - begin;
|
||||
|
||||
JS_ASSERT(begin < UINT32_MAX / sizeof(NativeType));
|
||||
JS_ASSERT(UINT32_MAX - begin * sizeof(NativeType) >= getByteOffset(tarray));
|
||||
uint32_t byteOffset = getByteOffset(tarray) + begin * sizeof(NativeType);
|
||||
uint32_t arrayByteOffset = byteOffsetValue(tarray).toInt32();
|
||||
JS_ASSERT(UINT32_MAX - begin * sizeof(NativeType) >= arrayByteOffset);
|
||||
uint32_t byteOffset = arrayByteOffset + begin * sizeof(NativeType);
|
||||
|
||||
return makeInstance(cx, bufobj, byteOffset, length);
|
||||
}
|
||||
@ -1933,9 +1931,9 @@ class TypedArrayTemplate
|
||||
thisTypedArrayObj = getTypedArray(thisTypedArrayObj);
|
||||
JS_ASSERT(thisTypedArrayObj);
|
||||
|
||||
JS_ASSERT(offset <= getLength(thisTypedArrayObj));
|
||||
JS_ASSERT(len <= getLength(thisTypedArrayObj) - offset);
|
||||
NativeType *dest = static_cast<NativeType*>(getDataOffset(thisTypedArrayObj)) + offset;
|
||||
JS_ASSERT(offset <= length(thisTypedArrayObj));
|
||||
JS_ASSERT(len <= length(thisTypedArrayObj) - offset);
|
||||
NativeType *dest = static_cast<NativeType*>(viewData(thisTypedArrayObj)) + offset;
|
||||
SkipRoot skip(cx, &dest);
|
||||
|
||||
if (ar->isDenseArray() && ar->getDenseArrayInitializedLength() >= len) {
|
||||
@ -1968,65 +1966,65 @@ class TypedArrayTemplate
|
||||
thisTypedArrayObj = getTypedArray(thisTypedArrayObj);
|
||||
JS_ASSERT(thisTypedArrayObj);
|
||||
|
||||
JS_ASSERT(offset <= getLength(thisTypedArrayObj));
|
||||
JS_ASSERT(getLength(tarray) <= getLength(thisTypedArrayObj) - offset);
|
||||
if (getBuffer(tarray) == getBuffer(thisTypedArrayObj))
|
||||
JS_ASSERT(offset <= length(thisTypedArrayObj));
|
||||
JS_ASSERT(length(tarray) <= length(thisTypedArrayObj) - offset);
|
||||
if (buffer(tarray) == buffer(thisTypedArrayObj))
|
||||
return copyFromWithOverlap(cx, thisTypedArrayObj, tarray, offset);
|
||||
|
||||
NativeType *dest = static_cast<NativeType*>((void*)getDataOffset(thisTypedArrayObj)) + offset;
|
||||
NativeType *dest = static_cast<NativeType*>(viewData(thisTypedArrayObj)) + offset;
|
||||
|
||||
if (getType(tarray) == getType(thisTypedArrayObj)) {
|
||||
js_memcpy(dest, getDataOffset(tarray), getByteLength(tarray));
|
||||
if (type(tarray) == type(thisTypedArrayObj)) {
|
||||
js_memcpy(dest, viewData(tarray), byteLengthValue(tarray).toInt32());
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned srclen = getLength(tarray);
|
||||
switch (getType(tarray)) {
|
||||
unsigned srclen = length(tarray);
|
||||
switch (type(tarray)) {
|
||||
case TypedArray::TYPE_INT8: {
|
||||
int8_t *src = static_cast<int8_t*>(getDataOffset(tarray));
|
||||
int8_t *src = static_cast<int8_t*>(viewData(tarray));
|
||||
for (unsigned i = 0; i < srclen; ++i)
|
||||
*dest++ = NativeType(*src++);
|
||||
break;
|
||||
}
|
||||
case TypedArray::TYPE_UINT8:
|
||||
case TypedArray::TYPE_UINT8_CLAMPED: {
|
||||
uint8_t *src = static_cast<uint8_t*>(getDataOffset(tarray));
|
||||
uint8_t *src = static_cast<uint8_t*>(viewData(tarray));
|
||||
for (unsigned i = 0; i < srclen; ++i)
|
||||
*dest++ = NativeType(*src++);
|
||||
break;
|
||||
}
|
||||
case TypedArray::TYPE_INT16: {
|
||||
int16_t *src = static_cast<int16_t*>(getDataOffset(tarray));
|
||||
int16_t *src = static_cast<int16_t*>(viewData(tarray));
|
||||
for (unsigned i = 0; i < srclen; ++i)
|
||||
*dest++ = NativeType(*src++);
|
||||
break;
|
||||
}
|
||||
case TypedArray::TYPE_UINT16: {
|
||||
uint16_t *src = static_cast<uint16_t*>(getDataOffset(tarray));
|
||||
uint16_t *src = static_cast<uint16_t*>(viewData(tarray));
|
||||
for (unsigned i = 0; i < srclen; ++i)
|
||||
*dest++ = NativeType(*src++);
|
||||
break;
|
||||
}
|
||||
case TypedArray::TYPE_INT32: {
|
||||
int32_t *src = static_cast<int32_t*>(getDataOffset(tarray));
|
||||
int32_t *src = static_cast<int32_t*>(viewData(tarray));
|
||||
for (unsigned i = 0; i < srclen; ++i)
|
||||
*dest++ = NativeType(*src++);
|
||||
break;
|
||||
}
|
||||
case TypedArray::TYPE_UINT32: {
|
||||
uint32_t *src = static_cast<uint32_t*>(getDataOffset(tarray));
|
||||
uint32_t *src = static_cast<uint32_t*>(viewData(tarray));
|
||||
for (unsigned i = 0; i < srclen; ++i)
|
||||
*dest++ = NativeType(*src++);
|
||||
break;
|
||||
}
|
||||
case TypedArray::TYPE_FLOAT32: {
|
||||
float *src = static_cast<float*>(getDataOffset(tarray));
|
||||
float *src = static_cast<float*>(viewData(tarray));
|
||||
for (unsigned i = 0; i < srclen; ++i)
|
||||
*dest++ = NativeType(*src++);
|
||||
break;
|
||||
}
|
||||
case TypedArray::TYPE_FLOAT64: {
|
||||
double *src = static_cast<double*>(getDataOffset(tarray));
|
||||
double *src = static_cast<double*>(viewData(tarray));
|
||||
for (unsigned i = 0; i < srclen; ++i)
|
||||
*dest++ = NativeType(*src++);
|
||||
break;
|
||||
@ -2042,69 +2040,70 @@ class TypedArrayTemplate
|
||||
static bool
|
||||
copyFromWithOverlap(JSContext *cx, JSObject *self, JSObject *tarray, uint32_t offset)
|
||||
{
|
||||
JS_ASSERT(offset <= getLength(self));
|
||||
JS_ASSERT(offset <= length(self));
|
||||
|
||||
NativeType *dest = static_cast<NativeType*>(getDataOffset(self)) + offset;
|
||||
NativeType *dest = static_cast<NativeType*>(viewData(self)) + offset;
|
||||
uint32_t byteLength = byteLengthValue(tarray).toInt32();
|
||||
|
||||
if (getType(tarray) == getType(self)) {
|
||||
memmove(dest, getDataOffset(tarray), getByteLength(tarray));
|
||||
if (type(tarray) == type(self)) {
|
||||
memmove(dest, viewData(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 = cx->malloc_(getByteLength(tarray));
|
||||
void *srcbuf = cx->malloc_(byteLength);
|
||||
if (!srcbuf)
|
||||
return false;
|
||||
js_memcpy(srcbuf, getDataOffset(tarray), getByteLength(tarray));
|
||||
js_memcpy(srcbuf, viewData(tarray), byteLength);
|
||||
|
||||
switch (getType(tarray)) {
|
||||
switch (type(tarray)) {
|
||||
case TypedArray::TYPE_INT8: {
|
||||
int8_t *src = (int8_t*) srcbuf;
|
||||
for (unsigned i = 0; i < getLength(tarray); ++i)
|
||||
for (unsigned i = 0; i < length(tarray); ++i)
|
||||
*dest++ = NativeType(*src++);
|
||||
break;
|
||||
}
|
||||
case TypedArray::TYPE_UINT8:
|
||||
case TypedArray::TYPE_UINT8_CLAMPED: {
|
||||
uint8_t *src = (uint8_t*) srcbuf;
|
||||
for (unsigned i = 0; i < getLength(tarray); ++i)
|
||||
for (unsigned i = 0; i < length(tarray); ++i)
|
||||
*dest++ = NativeType(*src++);
|
||||
break;
|
||||
}
|
||||
case TypedArray::TYPE_INT16: {
|
||||
int16_t *src = (int16_t*) srcbuf;
|
||||
for (unsigned i = 0; i < getLength(tarray); ++i)
|
||||
for (unsigned i = 0; i < length(tarray); ++i)
|
||||
*dest++ = NativeType(*src++);
|
||||
break;
|
||||
}
|
||||
case TypedArray::TYPE_UINT16: {
|
||||
uint16_t *src = (uint16_t*) srcbuf;
|
||||
for (unsigned i = 0; i < getLength(tarray); ++i)
|
||||
for (unsigned i = 0; i < length(tarray); ++i)
|
||||
*dest++ = NativeType(*src++);
|
||||
break;
|
||||
}
|
||||
case TypedArray::TYPE_INT32: {
|
||||
int32_t *src = (int32_t*) srcbuf;
|
||||
for (unsigned i = 0; i < getLength(tarray); ++i)
|
||||
for (unsigned i = 0; i < length(tarray); ++i)
|
||||
*dest++ = NativeType(*src++);
|
||||
break;
|
||||
}
|
||||
case TypedArray::TYPE_UINT32: {
|
||||
uint32_t *src = (uint32_t*) srcbuf;
|
||||
for (unsigned i = 0; i < getLength(tarray); ++i)
|
||||
for (unsigned i = 0; i < length(tarray); ++i)
|
||||
*dest++ = NativeType(*src++);
|
||||
break;
|
||||
}
|
||||
case TypedArray::TYPE_FLOAT32: {
|
||||
float *src = (float*) srcbuf;
|
||||
for (unsigned i = 0; i < getLength(tarray); ++i)
|
||||
for (unsigned i = 0; i < length(tarray); ++i)
|
||||
*dest++ = NativeType(*src++);
|
||||
break;
|
||||
}
|
||||
case TypedArray::TYPE_FLOAT64: {
|
||||
double *src = (double*) srcbuf;
|
||||
for (unsigned i = 0; i < getLength(tarray); ++i)
|
||||
for (unsigned i = 0; i < length(tarray); ++i)
|
||||
*dest++ = NativeType(*src++);
|
||||
break;
|
||||
}
|
||||
@ -2117,11 +2116,6 @@ class TypedArrayTemplate
|
||||
return true;
|
||||
}
|
||||
|
||||
static void *
|
||||
offsetData(JSObject *obj, uint32_t offs) {
|
||||
return (void*)(((uint8_t*)getDataOffset(obj)) + offs);
|
||||
}
|
||||
|
||||
static JSObject *
|
||||
createBufferWithSizeAndCount(JSContext *cx, uint32_t count)
|
||||
{
|
||||
@ -2313,36 +2307,6 @@ DataViewObject::construct(JSContext *cx, JSObject *bufobj, const CallArgs &args,
|
||||
return true;
|
||||
}
|
||||
|
||||
JSBool
|
||||
DataViewObject::prop_getBuffer(JSContext *cx, HandleObject obj, HandleId id, Value *vp)
|
||||
{
|
||||
if (!obj->isDataView()) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_INCOMPATIBLE_PROTO, "DataView", "buffer", "Object");
|
||||
return false;
|
||||
}
|
||||
|
||||
DataViewObject &view(obj->asDataView());
|
||||
if (view.hasBuffer())
|
||||
vp->setObject(view.arrayBuffer());
|
||||
else
|
||||
vp->setUndefined();
|
||||
return true;
|
||||
}
|
||||
|
||||
JSBool
|
||||
DataViewObject::prop_getByteOffset(JSContext *cx, HandleObject obj, HandleId id, Value *vp)
|
||||
{
|
||||
if (!obj->isDataView()) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_INCOMPATIBLE_PROTO, "DataView", "byteOffset", "Object");
|
||||
return false;
|
||||
}
|
||||
|
||||
vp->setInt32(obj->asDataView().byteOffset());
|
||||
return true;
|
||||
}
|
||||
|
||||
JSBool
|
||||
DataViewObject::constructWithProto(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
@ -2391,19 +2355,6 @@ DataViewObject::class_constructor(JSContext *cx, unsigned argc, Value *vp)
|
||||
return construct(cx, bufobj, args, NULL);
|
||||
}
|
||||
|
||||
JSBool
|
||||
DataViewObject::prop_getByteLength(JSContext *cx, HandleObject obj, HandleId id, Value *vp)
|
||||
{
|
||||
if (!obj->isDataView()) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_INCOMPATIBLE_PROTO, "DataView", "byteLength", "Object");
|
||||
return false;
|
||||
}
|
||||
|
||||
vp->setInt32(obj->asDataView().byteLength());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DataViewObject::getDataPointer(JSContext *cx, CallArgs args, size_t typeSize, uint8_t **data)
|
||||
{
|
||||
@ -2931,38 +2882,11 @@ Class js::ArrayBufferClass = {
|
||||
}
|
||||
};
|
||||
|
||||
JSPropertySpec ArrayBufferObject::jsprops[] = {
|
||||
{ "byteLength",
|
||||
-1, JSPROP_SHARED | JSPROP_PERMANENT | JSPROP_READONLY,
|
||||
ArrayBufferObject::prop_getByteLength, JS_StrictPropertyStub },
|
||||
{0,0,0,0,0}
|
||||
};
|
||||
|
||||
JSFunctionSpec ArrayBufferObject::jsfuncs[] = {
|
||||
JS_FN("slice", ArrayBufferObject::fun_slice, 2, JSFUN_GENERIC_NATIVE),
|
||||
JS_FS_END
|
||||
};
|
||||
|
||||
/*
|
||||
* shared TypedArray
|
||||
*/
|
||||
|
||||
JSPropertySpec TypedArray::jsprops[] = {
|
||||
{ js_length_str,
|
||||
-1, JSPROP_SHARED | JSPROP_PERMANENT | JSPROP_READONLY,
|
||||
TypedArray::prop_getLength, JS_StrictPropertyStub },
|
||||
{ "byteLength",
|
||||
-1, JSPROP_SHARED | JSPROP_PERMANENT | JSPROP_READONLY,
|
||||
TypedArray::prop_getByteLength, JS_StrictPropertyStub },
|
||||
{ "byteOffset",
|
||||
-1, JSPROP_SHARED | JSPROP_PERMANENT | JSPROP_READONLY,
|
||||
TypedArray::prop_getByteOffset, JS_StrictPropertyStub },
|
||||
{ "buffer",
|
||||
-1, JSPROP_SHARED | JSPROP_PERMANENT | JSPROP_READONLY,
|
||||
TypedArray::prop_getBuffer, JS_StrictPropertyStub },
|
||||
{0,0,0,0,0}
|
||||
};
|
||||
|
||||
/*
|
||||
* TypedArray boilerplate
|
||||
*/
|
||||
@ -3095,8 +3019,9 @@ IMPL_TYPED_ARRAY_JSAPI_CONSTRUCTORS(Float64, double)
|
||||
|
||||
template<class ArrayType>
|
||||
static inline JSObject *
|
||||
InitTypedArrayClass(JSContext *cx, Handle<GlobalObject*> global)
|
||||
InitTypedArrayClass(JSContext *cx)
|
||||
{
|
||||
Rooted<GlobalObject*> global(cx, &cx->compartment->global());
|
||||
RootedObject proto(cx, global->createBlankPrototype(cx, ArrayType::protoClass()));
|
||||
if (!proto)
|
||||
return NULL;
|
||||
@ -3122,7 +3047,12 @@ InitTypedArrayClass(JSContext *cx, Handle<GlobalObject*> global)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!DefinePropertiesAndBrand(cx, proto, ArrayType::jsprops, ArrayType::jsfuncs))
|
||||
RootedObject foo(cx);
|
||||
|
||||
if (!ArrayType::defineGetters(cx, proto))
|
||||
return NULL;
|
||||
|
||||
if (!JS_DefineFunctions(cx, proto, ArrayType::jsfuncs))
|
||||
return NULL;
|
||||
|
||||
if (!DefineConstructorAndPrototype(cx, global, ArrayType::key, ctor, proto))
|
||||
@ -3166,8 +3096,9 @@ Class TypedArray::protoClasses[TYPE_MAX] = {
|
||||
};
|
||||
|
||||
static JSObject *
|
||||
InitArrayBufferClass(JSContext *cx, Handle<GlobalObject*> global)
|
||||
InitArrayBufferClass(JSContext *cx)
|
||||
{
|
||||
Rooted<GlobalObject*> global(cx, &cx->compartment->global());
|
||||
RootedObject arrayBufferProto(cx, global->createBlankPrototype(cx, &ArrayBufferObject::protoClass));
|
||||
if (!arrayBufferProto)
|
||||
return NULL;
|
||||
@ -3181,7 +3112,17 @@ InitArrayBufferClass(JSContext *cx, Handle<GlobalObject*> global)
|
||||
if (!LinkConstructorAndPrototype(cx, ctor, arrayBufferProto))
|
||||
return NULL;
|
||||
|
||||
if (!DefinePropertiesAndBrand(cx, arrayBufferProto, ArrayBufferObject::jsprops, ArrayBufferObject::jsfuncs))
|
||||
RootedId byteLengthId(cx, NameToId(cx->runtime->atomState.byteLengthAtom));
|
||||
unsigned flags = JSPROP_PERMANENT | JSPROP_READONLY | JSPROP_SHARED | JSPROP_GETTER;
|
||||
JSObject *getter = js_NewFunction(cx, NULL, ArrayBufferObject::byteLengthGetter, 0, 0, global, NULL);
|
||||
if (!getter)
|
||||
return NULL;
|
||||
|
||||
if (!DefineNativeProperty(cx, arrayBufferProto, byteLengthId, UndefinedValue(),
|
||||
JS_DATA_TO_FUNC_PTR(PropertyOp, getter), NULL, flags, 0, 0))
|
||||
return NULL;
|
||||
|
||||
if (!JS_DefineFunctions(cx, arrayBufferProto, ArrayBufferObject::jsfuncs))
|
||||
return NULL;
|
||||
|
||||
if (!DefineConstructorAndPrototype(cx, global, JSProto_ArrayBuffer, ctor, arrayBufferProto))
|
||||
@ -3227,19 +3168,6 @@ Class js::DataViewClass = {
|
||||
JS_NULL_OBJECT_OPS
|
||||
};
|
||||
|
||||
JSPropertySpec DataViewObject::jsprops[] = {
|
||||
{ "byteLength",
|
||||
-1, JSPROP_SHARED | JSPROP_PERMANENT | JSPROP_READONLY,
|
||||
DataViewObject::prop_getByteLength, JS_StrictPropertyStub },
|
||||
{ "byteOffset",
|
||||
-1, JSPROP_SHARED | JSPROP_PERMANENT | JSPROP_READONLY,
|
||||
DataViewObject::prop_getByteOffset, JS_StrictPropertyStub },
|
||||
{ "buffer",
|
||||
-1, JSPROP_SHARED | JSPROP_PERMANENT | JSPROP_READONLY,
|
||||
DataViewObject::prop_getBuffer, JS_StrictPropertyStub },
|
||||
{0,0,0,0,0}
|
||||
};
|
||||
|
||||
JSFunctionSpec DataViewObject::jsfuncs[] = {
|
||||
JS_FN("getInt8", DataViewObject::fun_getInt8, 1,0),
|
||||
JS_FN("getUint8", DataViewObject::fun_getUint8, 1,0),
|
||||
@ -3260,24 +3188,65 @@ JSFunctionSpec DataViewObject::jsfuncs[] = {
|
||||
JS_FS_END
|
||||
};
|
||||
|
||||
JSObject *
|
||||
DataViewObject::initClass(JSContext *cx, GlobalObject *global)
|
||||
template<Value ValueGetter(DataViewObject &)>
|
||||
static JSBool
|
||||
DataViewGetter(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
JSObject *proto = global->createBlankPrototype(cx, &DataViewObject::protoClass);
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
JSObject *thisObj;
|
||||
if (!NonGenericMethodGuard(cx, args, DataViewGetter<ValueGetter>, &DataViewClass, &thisObj))
|
||||
return false;
|
||||
if (!thisObj)
|
||||
return true;
|
||||
|
||||
JS_SET_RVAL(cx, vp, ValueGetter(thisObj->asDataView()));
|
||||
return true;
|
||||
}
|
||||
|
||||
template<Value ValueGetter(DataViewObject&)>
|
||||
bool
|
||||
DefineDataViewGetter(JSContext *cx, PropertyName *name, HandleObject proto)
|
||||
{
|
||||
RootedId id(cx, NameToId(name));
|
||||
unsigned flags = JSPROP_PERMANENT | JSPROP_READONLY | JSPROP_SHARED | JSPROP_GETTER;
|
||||
|
||||
Rooted<GlobalObject*> global(cx, &cx->compartment->global());
|
||||
JSObject *getter = js_NewFunction(cx, NULL, DataViewGetter<ValueGetter>, 0, 0, global, NULL);
|
||||
if (!getter)
|
||||
return false;
|
||||
|
||||
return DefineNativeProperty(cx, proto, id, UndefinedValue(),
|
||||
JS_DATA_TO_FUNC_PTR(PropertyOp, getter), NULL,
|
||||
flags, 0, 0);
|
||||
}
|
||||
|
||||
JSObject *
|
||||
DataViewObject::initClass(JSContext *cx)
|
||||
{
|
||||
Rooted<GlobalObject*> global(cx, &cx->compartment->global());
|
||||
RootedObject proto(cx, global->createBlankPrototype(cx, &DataViewObject::protoClass));
|
||||
if (!proto)
|
||||
return NULL;
|
||||
|
||||
JSFunction *ctor =
|
||||
global->createConstructor(cx, DataViewObject::class_constructor,
|
||||
CLASS_NAME(cx, DataView), 3);
|
||||
|
||||
RootedFunction ctor(cx, global->createConstructor(cx, DataViewObject::class_constructor,
|
||||
CLASS_NAME(cx, DataView), 3));
|
||||
if (!ctor)
|
||||
return NULL;
|
||||
|
||||
if (!LinkConstructorAndPrototype(cx, ctor, proto))
|
||||
return NULL;
|
||||
|
||||
if (!DefinePropertiesAndBrand(cx, proto, DataViewObject::jsprops, DataViewObject::jsfuncs))
|
||||
if (!DefineDataViewGetter<bufferValue>(cx, cx->runtime->atomState.bufferAtom, proto))
|
||||
return NULL;
|
||||
|
||||
if (!DefineDataViewGetter<byteLengthValue>(cx, cx->runtime->atomState.byteLengthAtom, proto))
|
||||
return NULL;
|
||||
|
||||
if (!DefineDataViewGetter<byteOffsetValue>(cx, cx->runtime->atomState.byteOffsetAtom, proto))
|
||||
return NULL;
|
||||
|
||||
if (!JS_DefineFunctions(cx, proto, DataViewObject::jsfuncs))
|
||||
return NULL;
|
||||
|
||||
if (!DefineConstructorAndPrototype(cx, global, JSProto_DataView, ctor, proto))
|
||||
@ -3290,7 +3259,6 @@ JSObject *
|
||||
js_InitTypedArrayClasses(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
JS_ASSERT(obj->isNative());
|
||||
|
||||
Rooted<GlobalObject*> global(cx, &obj->asGlobal());
|
||||
|
||||
/* Idempotency required: we initialize several things, possibly lazily. */
|
||||
@ -3300,21 +3268,21 @@ js_InitTypedArrayClasses(JSContext *cx, JSObject *obj)
|
||||
if (stop)
|
||||
return stop;
|
||||
|
||||
if (!InitTypedArrayClass<Int8Array>(cx, global) ||
|
||||
!InitTypedArrayClass<Uint8Array>(cx, global) ||
|
||||
!InitTypedArrayClass<Int16Array>(cx, global) ||
|
||||
!InitTypedArrayClass<Uint16Array>(cx, global) ||
|
||||
!InitTypedArrayClass<Int32Array>(cx, global) ||
|
||||
!InitTypedArrayClass<Uint32Array>(cx, global) ||
|
||||
!InitTypedArrayClass<Float32Array>(cx, global) ||
|
||||
!InitTypedArrayClass<Float64Array>(cx, global) ||
|
||||
!InitTypedArrayClass<Uint8ClampedArray>(cx, global) ||
|
||||
!DataViewObject::initClass(cx, global))
|
||||
if (!InitTypedArrayClass<Int8Array>(cx) ||
|
||||
!InitTypedArrayClass<Uint8Array>(cx) ||
|
||||
!InitTypedArrayClass<Int16Array>(cx) ||
|
||||
!InitTypedArrayClass<Uint16Array>(cx) ||
|
||||
!InitTypedArrayClass<Int32Array>(cx) ||
|
||||
!InitTypedArrayClass<Uint32Array>(cx) ||
|
||||
!InitTypedArrayClass<Float32Array>(cx) ||
|
||||
!InitTypedArrayClass<Float64Array>(cx) ||
|
||||
!InitTypedArrayClass<Uint8ClampedArray>(cx) ||
|
||||
!DataViewObject::initClass(cx))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return InitArrayBufferClass(cx, global);
|
||||
return InitArrayBufferClass(cx);
|
||||
}
|
||||
|
||||
/* JS Friend API */
|
||||
@ -3432,7 +3400,7 @@ JS_GetInt8ArrayData(JSObject *obj, JSContext *cx)
|
||||
return NULL;
|
||||
JS_ASSERT(obj->isTypedArray());
|
||||
JS_ASSERT(obj->getSlot(TypedArray::FIELD_TYPE).toInt32() == ArrayBufferView::TYPE_INT8);
|
||||
return static_cast<int8_t *>(TypedArray::getDataOffset(obj));
|
||||
return static_cast<int8_t *>(TypedArray::viewData(obj));
|
||||
}
|
||||
|
||||
JS_FRIEND_API(uint8_t *)
|
||||
@ -3442,7 +3410,7 @@ JS_GetUint8ArrayData(JSObject *obj, JSContext *cx)
|
||||
return NULL;
|
||||
JS_ASSERT(obj->isTypedArray());
|
||||
JS_ASSERT(obj->getSlot(TypedArray::FIELD_TYPE).toInt32() == ArrayBufferView::TYPE_UINT8);
|
||||
return static_cast<uint8_t *>(TypedArray::getDataOffset(obj));
|
||||
return static_cast<uint8_t *>(TypedArray::viewData(obj));
|
||||
}
|
||||
|
||||
JS_FRIEND_API(uint8_t *)
|
||||
@ -3452,7 +3420,7 @@ JS_GetUint8ClampedArrayData(JSObject *obj, JSContext *cx)
|
||||
return NULL;
|
||||
JS_ASSERT(obj->isTypedArray());
|
||||
JS_ASSERT(obj->getSlot(TypedArray::FIELD_TYPE).toInt32() == ArrayBufferView::TYPE_UINT8_CLAMPED);
|
||||
return static_cast<uint8_t *>(TypedArray::getDataOffset(obj));
|
||||
return static_cast<uint8_t *>(TypedArray::viewData(obj));
|
||||
}
|
||||
|
||||
JS_FRIEND_API(int16_t *)
|
||||
@ -3462,7 +3430,7 @@ JS_GetInt16ArrayData(JSObject *obj, JSContext *cx)
|
||||
return NULL;
|
||||
JS_ASSERT(obj->isTypedArray());
|
||||
JS_ASSERT(obj->getSlot(TypedArray::FIELD_TYPE).toInt32() == ArrayBufferView::TYPE_INT16);
|
||||
return static_cast<int16_t *>(TypedArray::getDataOffset(obj));
|
||||
return static_cast<int16_t *>(TypedArray::viewData(obj));
|
||||
}
|
||||
|
||||
JS_FRIEND_API(uint16_t *)
|
||||
@ -3472,7 +3440,7 @@ JS_GetUint16ArrayData(JSObject *obj, JSContext *cx)
|
||||
return NULL;
|
||||
JS_ASSERT(obj->isTypedArray());
|
||||
JS_ASSERT(obj->getSlot(TypedArray::FIELD_TYPE).toInt32() == ArrayBufferView::TYPE_UINT16);
|
||||
return static_cast<uint16_t *>(TypedArray::getDataOffset(obj));
|
||||
return static_cast<uint16_t *>(TypedArray::viewData(obj));
|
||||
}
|
||||
|
||||
JS_FRIEND_API(int32_t *)
|
||||
@ -3482,7 +3450,7 @@ JS_GetInt32ArrayData(JSObject *obj, JSContext *cx)
|
||||
return NULL;
|
||||
JS_ASSERT(obj->isTypedArray());
|
||||
JS_ASSERT(obj->getSlot(TypedArray::FIELD_TYPE).toInt32() == ArrayBufferView::TYPE_INT32);
|
||||
return static_cast<int32_t *>(TypedArray::getDataOffset(obj));
|
||||
return static_cast<int32_t *>(TypedArray::viewData(obj));
|
||||
}
|
||||
|
||||
JS_FRIEND_API(uint32_t *)
|
||||
@ -3492,7 +3460,7 @@ JS_GetUint32ArrayData(JSObject *obj, JSContext *cx)
|
||||
return NULL;
|
||||
JS_ASSERT(obj->isTypedArray());
|
||||
JS_ASSERT(obj->getSlot(TypedArray::FIELD_TYPE).toInt32() == ArrayBufferView::TYPE_UINT32);
|
||||
return static_cast<uint32_t *>(TypedArray::getDataOffset(obj));
|
||||
return static_cast<uint32_t *>(TypedArray::viewData(obj));
|
||||
}
|
||||
|
||||
JS_FRIEND_API(float *)
|
||||
@ -3502,7 +3470,7 @@ JS_GetFloat32ArrayData(JSObject *obj, JSContext *cx)
|
||||
return NULL;
|
||||
JS_ASSERT(obj->isTypedArray());
|
||||
JS_ASSERT(obj->getSlot(TypedArray::FIELD_TYPE).toInt32() == ArrayBufferView::TYPE_FLOAT32);
|
||||
return static_cast<float *>(TypedArray::getDataOffset(obj));
|
||||
return static_cast<float *>(TypedArray::viewData(obj));
|
||||
}
|
||||
|
||||
JS_FRIEND_API(double *)
|
||||
@ -3512,7 +3480,7 @@ JS_GetFloat64ArrayData(JSObject *obj, JSContext *cx)
|
||||
return NULL;
|
||||
JS_ASSERT(obj->isTypedArray());
|
||||
JS_ASSERT(obj->getSlot(TypedArray::FIELD_TYPE).toInt32() == ArrayBufferView::TYPE_FLOAT64);
|
||||
return static_cast<double *>(TypedArray::getDataOffset(obj));
|
||||
return static_cast<double *>(TypedArray::viewData(obj));
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSBool)
|
||||
@ -3556,7 +3524,7 @@ JS_GetArrayBufferViewData(JSObject *obj, JSContext *cx)
|
||||
if (!(obj = CheckedUnwrap(cx, obj)))
|
||||
return NULL;
|
||||
JS_ASSERT(obj->isTypedArray() || obj->isDataView());
|
||||
return obj->isDataView() ? obj->asDataView().dataPointer() : TypedArray::getDataOffset(obj);
|
||||
return obj->isDataView() ? obj->asDataView().dataPointer() : TypedArray::viewData(obj);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(uint32_t)
|
||||
@ -3565,5 +3533,5 @@ JS_GetArrayBufferViewByteLength(JSObject *obj, JSContext *cx)
|
||||
if (!(obj = CheckedUnwrap(cx, obj)))
|
||||
return 0;
|
||||
JS_ASSERT(obj->isTypedArray() || obj->isDataView());
|
||||
return obj->isDataView() ? obj->asDataView().byteLength() : TypedArray::getByteLength(obj);
|
||||
return obj->isDataView() ? obj->asDataView().byteLength() : TypedArray::byteLengthValue(obj).toInt32();
|
||||
}
|
||||
|
@ -29,10 +29,9 @@ class ArrayBufferObject : public JSObject
|
||||
{
|
||||
public:
|
||||
static Class protoClass;
|
||||
static JSPropertySpec jsprops[];
|
||||
static JSFunctionSpec jsfuncs[];
|
||||
|
||||
static JSBool prop_getByteLength(JSContext *cx, HandleObject obj, HandleId id, Value *vp);
|
||||
static JSBool byteLengthGetter(JSContext *cx, unsigned argc, Value *vp);
|
||||
|
||||
static JSBool fun_slice(JSContext *cx, unsigned argc, Value *vp);
|
||||
|
||||
@ -189,13 +188,6 @@ struct TypedArray {
|
||||
// fo constructing new objects
|
||||
static Class protoClasses[TYPE_MAX];
|
||||
|
||||
static JSPropertySpec jsprops[];
|
||||
|
||||
static JSBool prop_getBuffer(JSContext *cx, HandleObject obj, HandleId id, Value *vp);
|
||||
static JSBool prop_getByteOffset(JSContext *cx, HandleObject obj, HandleId id, Value *vp);
|
||||
static JSBool prop_getByteLength(JSContext *cx, HandleObject obj, HandleId id, Value *vp);
|
||||
static JSBool prop_getLength(JSContext *cx, HandleObject obj, HandleId id, Value *vp);
|
||||
|
||||
static JSBool obj_lookupGeneric(JSContext *cx, HandleObject obj, HandleId id,
|
||||
JSObject **objp, JSProperty **propp);
|
||||
static JSBool obj_lookupProperty(JSContext *cx, HandleObject obj, HandlePropertyName name,
|
||||
@ -215,41 +207,25 @@ struct TypedArray {
|
||||
static JSBool obj_setElementAttributes(JSContext *cx, HandleObject obj, uint32_t index, unsigned *attrsp);
|
||||
static JSBool obj_setSpecialAttributes(JSContext *cx, HandleObject obj, HandleSpecialId sid, unsigned *attrsp);
|
||||
|
||||
static uint32_t getLength(JSObject *obj);
|
||||
static uint32_t getByteOffset(JSObject *obj);
|
||||
static uint32_t getByteLength(JSObject *obj);
|
||||
static uint32_t getType(JSObject *obj);
|
||||
static ArrayBufferObject * getBuffer(JSObject *obj);
|
||||
static void * getDataOffset(JSObject *obj);
|
||||
static inline Value bufferValue(JSObject *obj);
|
||||
static inline Value byteOffsetValue(JSObject *obj);
|
||||
static inline Value byteLengthValue(JSObject *obj);
|
||||
static inline Value lengthValue(JSObject *obj);
|
||||
|
||||
static inline ArrayBufferObject * buffer(JSObject *obj);
|
||||
static inline uint32_t byteOffset(JSObject *obj);
|
||||
static inline uint32_t byteLength(JSObject *obj);
|
||||
static inline uint32_t length(JSObject *obj);
|
||||
|
||||
static inline uint32_t type(JSObject *obj);
|
||||
static inline void * viewData(JSObject *obj);
|
||||
|
||||
public:
|
||||
static bool
|
||||
isArrayIndex(JSContext *cx, JSObject *obj, jsid id, uint32_t *ip = NULL);
|
||||
|
||||
static inline uint32_t slotWidth(int atype) {
|
||||
switch (atype) {
|
||||
case js::TypedArray::TYPE_INT8:
|
||||
case js::TypedArray::TYPE_UINT8:
|
||||
case js::TypedArray::TYPE_UINT8_CLAMPED:
|
||||
return 1;
|
||||
case js::TypedArray::TYPE_INT16:
|
||||
case js::TypedArray::TYPE_UINT16:
|
||||
return 2;
|
||||
case js::TypedArray::TYPE_INT32:
|
||||
case js::TypedArray::TYPE_UINT32:
|
||||
case js::TypedArray::TYPE_FLOAT32:
|
||||
return 4;
|
||||
case js::TypedArray::TYPE_FLOAT64:
|
||||
return 8;
|
||||
default:
|
||||
JS_NOT_REACHED("invalid typed array type");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int slotWidth(JSObject *obj) {
|
||||
return slotWidth(getType(obj));
|
||||
}
|
||||
static inline uint32_t slotWidth(int atype);
|
||||
static inline int slotWidth(JSObject *obj);
|
||||
|
||||
/*
|
||||
* Byte length above which created typed arrays and data views will have
|
||||
@ -298,9 +274,9 @@ class DataViewObject : public JSObject
|
||||
public:
|
||||
static const size_t RESERVED_SLOTS = 3;
|
||||
|
||||
static JSBool prop_getBuffer(JSContext *cx, HandleObject obj, HandleId id, Value *vp);
|
||||
static JSBool prop_getByteOffset(JSContext *cx, HandleObject obj, HandleId id, Value *vp);
|
||||
static JSBool prop_getByteLength(JSContext *cx, HandleObject obj, HandleId id, Value *vp);
|
||||
static inline Value bufferValue(DataViewObject &view);
|
||||
static inline Value byteOffsetValue(DataViewObject &view);
|
||||
static inline Value byteLengthValue(DataViewObject &view);
|
||||
|
||||
static JSBool class_constructor(JSContext *cx, unsigned argc, Value *vp);
|
||||
static JSBool constructWithProto(JSContext *cx, unsigned argc, Value *vp);
|
||||
@ -331,14 +307,13 @@ class DataViewObject : public JSObject
|
||||
inline JSObject & arrayBuffer();
|
||||
inline void *dataPointer();
|
||||
inline bool hasBuffer() const;
|
||||
static JSObject *initClass(JSContext *cx, GlobalObject *global);
|
||||
static JSObject *initClass(JSContext *cx);
|
||||
bool getDataPointer(JSContext *cx, CallArgs args, size_t typeSize, uint8_t **data);
|
||||
template<typename NativeType>
|
||||
bool read(JSContext *cx, CallArgs &args, NativeType *val, const char *method);
|
||||
template<typename NativeType>
|
||||
bool write(JSContext *cx, CallArgs &args, const char *method);
|
||||
private:
|
||||
static JSPropertySpec jsprops[];
|
||||
static JSFunctionSpec jsfuncs[];
|
||||
};
|
||||
|
||||
|
@ -58,42 +58,89 @@ ClampIntForUint8Array(int32_t x)
|
||||
return x;
|
||||
}
|
||||
|
||||
inline uint32_t
|
||||
TypedArray::getLength(JSObject *obj) {
|
||||
inline Value
|
||||
TypedArray::lengthValue(JSObject *obj) {
|
||||
JS_ASSERT(obj->isTypedArray());
|
||||
return obj->getFixedSlot(FIELD_LENGTH).toInt32();
|
||||
return obj->getFixedSlot(FIELD_LENGTH);
|
||||
}
|
||||
|
||||
inline uint32_t
|
||||
TypedArray::getByteOffset(JSObject *obj) {
|
||||
TypedArray::length(JSObject *obj) {
|
||||
return lengthValue(obj).toInt32();
|
||||
}
|
||||
|
||||
inline Value
|
||||
TypedArray::byteOffsetValue(JSObject *obj) {
|
||||
JS_ASSERT(obj->isTypedArray());
|
||||
return obj->getFixedSlot(FIELD_BYTEOFFSET).toInt32();
|
||||
return obj->getFixedSlot(FIELD_BYTEOFFSET);
|
||||
}
|
||||
|
||||
inline uint32_t
|
||||
TypedArray::getByteLength(JSObject *obj) {
|
||||
TypedArray::byteOffset(JSObject *obj) {
|
||||
return byteOffsetValue(obj).toInt32();
|
||||
}
|
||||
|
||||
inline Value
|
||||
TypedArray::byteLengthValue(JSObject *obj) {
|
||||
JS_ASSERT(obj->isTypedArray());
|
||||
return obj->getFixedSlot(FIELD_BYTELENGTH).toInt32();
|
||||
return obj->getFixedSlot(FIELD_BYTELENGTH);
|
||||
}
|
||||
|
||||
inline uint32_t
|
||||
TypedArray::getType(JSObject *obj) {
|
||||
TypedArray::byteLength(JSObject *obj) {
|
||||
return byteLengthValue(obj).toInt32();
|
||||
}
|
||||
|
||||
inline uint32_t
|
||||
TypedArray::type(JSObject *obj) {
|
||||
JS_ASSERT(obj->isTypedArray());
|
||||
return obj->getFixedSlot(FIELD_TYPE).toInt32();
|
||||
}
|
||||
|
||||
inline ArrayBufferObject *
|
||||
TypedArray::getBuffer(JSObject *obj) {
|
||||
inline Value
|
||||
TypedArray::bufferValue(JSObject *obj) {
|
||||
JS_ASSERT(obj->isTypedArray());
|
||||
return &obj->getFixedSlot(FIELD_BUFFER).toObject().asArrayBuffer();
|
||||
return obj->getFixedSlot(FIELD_BUFFER);
|
||||
}
|
||||
|
||||
inline ArrayBufferObject *
|
||||
TypedArray::buffer(JSObject *obj) {
|
||||
return &bufferValue(obj).toObject().asArrayBuffer();
|
||||
}
|
||||
|
||||
inline void *
|
||||
TypedArray::getDataOffset(JSObject *obj) {
|
||||
TypedArray::viewData(JSObject *obj) {
|
||||
JS_ASSERT(obj->isTypedArray());
|
||||
return (void *)obj->getPrivate(NUM_FIXED_SLOTS);
|
||||
}
|
||||
|
||||
inline uint32_t
|
||||
TypedArray::slotWidth(int atype) {
|
||||
switch (atype) {
|
||||
case js::TypedArray::TYPE_INT8:
|
||||
case js::TypedArray::TYPE_UINT8:
|
||||
case js::TypedArray::TYPE_UINT8_CLAMPED:
|
||||
return 1;
|
||||
case js::TypedArray::TYPE_INT16:
|
||||
case js::TypedArray::TYPE_UINT16:
|
||||
return 2;
|
||||
case js::TypedArray::TYPE_INT32:
|
||||
case js::TypedArray::TYPE_UINT32:
|
||||
case js::TypedArray::TYPE_FLOAT32:
|
||||
return 4;
|
||||
case js::TypedArray::TYPE_FLOAT64:
|
||||
return 8;
|
||||
default:
|
||||
JS_NOT_REACHED("invalid typed array type");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline int
|
||||
TypedArray::slotWidth(JSObject *obj) {
|
||||
return slotWidth(type(obj));
|
||||
}
|
||||
|
||||
inline DataViewObject *
|
||||
DataViewObject::create(JSContext *cx, uint32_t byteOffset, uint32_t byteLength,
|
||||
Handle<ArrayBufferObject*> arrayBuffer, JSObject *proto)
|
||||
@ -177,6 +224,24 @@ DataViewObject::hasBuffer() const
|
||||
return getReservedSlot(BUFFER_SLOT).isObject();
|
||||
}
|
||||
|
||||
inline Value
|
||||
DataViewObject::bufferValue(DataViewObject &view)
|
||||
{
|
||||
return view.hasBuffer() ? ObjectValue(view.arrayBuffer()) : UndefinedValue();
|
||||
}
|
||||
|
||||
inline Value
|
||||
DataViewObject::byteOffsetValue(DataViewObject &view)
|
||||
{
|
||||
return Int32Value(view.byteOffset());
|
||||
}
|
||||
|
||||
inline Value
|
||||
DataViewObject::byteLengthValue(DataViewObject &view)
|
||||
{
|
||||
return Int32Value(view.byteLength());
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
#endif /* jstypedarrayinlines_h */
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "CodeGenIncludes.h"
|
||||
#include "jsobjinlines.h"
|
||||
#include "jsscopeinlines.h"
|
||||
#include "jstypedarrayinlines.h"
|
||||
|
||||
namespace js {
|
||||
namespace mjit {
|
||||
|
@ -4786,7 +4786,7 @@ mjit::Compiler::jsop_getprop(PropertyName *name, JSValueType knownType,
|
||||
if (!types->hasObjectFlags(cx, types::OBJECT_FLAG_NON_TYPED_ARRAY)) {
|
||||
if (top->isConstant()) {
|
||||
JSObject *obj = &top->getValue().toObject();
|
||||
uint32_t length = TypedArray::getLength(obj);
|
||||
uint32_t length = TypedArray::length(obj);
|
||||
frame.pop();
|
||||
frame.push(Int32Value(length));
|
||||
return true;
|
||||
|
@ -1429,8 +1429,8 @@ mjit::Compiler::jsop_setelem_typed(int atype)
|
||||
frame.pinReg(objReg);
|
||||
} else if (obj->isConstant()) {
|
||||
JSObject *array = &obj->getValue().toObject();
|
||||
int32_t length = (int32_t) TypedArray::getLength(array);
|
||||
void *data = TypedArray::getDataOffset(array);
|
||||
int32_t length = (int32_t) TypedArray::length(array);
|
||||
void *data = TypedArray::viewData(array);
|
||||
|
||||
objReg = frame.allocReg();
|
||||
|
||||
@ -2029,8 +2029,8 @@ mjit::Compiler::jsop_getelem_typed(int atype)
|
||||
frame.pinReg(objReg);
|
||||
} else if (obj->isConstant()) {
|
||||
JSObject *array = &obj->getValue().toObject();
|
||||
int32_t length = (int32_t) TypedArray::getLength(array);
|
||||
void *data = TypedArray::getDataOffset(array);
|
||||
int32_t length = (int32_t) TypedArray::length(array);
|
||||
void *data = TypedArray::viewData(array);
|
||||
|
||||
objReg = frame.allocReg();
|
||||
|
||||
|
@ -2399,15 +2399,15 @@ GetElementIC::attachTypedArray(VMFrame &f, JSObject *obj, const Value &v, jsid i
|
||||
: Int32Key::FromRegister(idRemat.dataReg());
|
||||
|
||||
if (!masm.supportsFloatingPoint() &&
|
||||
(TypedArray::getType(obj) == TypedArray::TYPE_FLOAT32 ||
|
||||
TypedArray::getType(obj) == TypedArray::TYPE_FLOAT64 ||
|
||||
TypedArray::getType(obj) == TypedArray::TYPE_UINT32))
|
||||
(TypedArray::type(obj) == TypedArray::TYPE_FLOAT32 ||
|
||||
TypedArray::type(obj) == TypedArray::TYPE_FLOAT64 ||
|
||||
TypedArray::type(obj) == TypedArray::TYPE_UINT32))
|
||||
{
|
||||
return disable(f, "fpu not supported");
|
||||
}
|
||||
|
||||
MaybeRegisterID tempReg;
|
||||
masm.loadFromTypedArray(TypedArray::getType(obj), objReg, key, typeReg, objReg, tempReg);
|
||||
masm.loadFromTypedArray(TypedArray::type(obj), objReg, key, typeReg, objReg, tempReg);
|
||||
|
||||
Jump done = masm.jump();
|
||||
|
||||
@ -2713,8 +2713,8 @@ SetElementIC::attachTypedArray(VMFrame &f, JSObject *obj, int32_t key)
|
||||
masm.loadPtr(Address(objReg, TypedArray::dataOffset()), objReg);
|
||||
|
||||
if (!masm.supportsFloatingPoint() &&
|
||||
(TypedArray::getType(obj) == TypedArray::TYPE_FLOAT32 ||
|
||||
TypedArray::getType(obj) == TypedArray::TYPE_FLOAT64))
|
||||
(TypedArray::type(obj) == TypedArray::TYPE_FLOAT32 ||
|
||||
TypedArray::type(obj) == TypedArray::TYPE_FLOAT64))
|
||||
{
|
||||
return disable(f, "fpu not supported");
|
||||
}
|
||||
|
@ -96,12 +96,12 @@ ConstantFoldForIntArray(JSContext *cx, JSObject *tarray, ValueRemat *vr)
|
||||
|
||||
int32_t i32 = 0;
|
||||
if (v.isDouble()) {
|
||||
i32 = (TypedArray::getType(tarray) == js::TypedArray::TYPE_UINT8_CLAMPED)
|
||||
i32 = (TypedArray::type(tarray) == js::TypedArray::TYPE_UINT8_CLAMPED)
|
||||
? ClampDoubleToUint8(v.toDouble())
|
||||
: ToInt32(v.toDouble());
|
||||
} else if (v.isInt32()) {
|
||||
i32 = v.toInt32();
|
||||
if (TypedArray::getType(tarray) == js::TypedArray::TYPE_UINT8_CLAMPED)
|
||||
if (TypedArray::type(tarray) == js::TypedArray::TYPE_UINT8_CLAMPED)
|
||||
i32 = ClampIntForUint8Array(i32);
|
||||
} else if (v.isBoolean()) {
|
||||
i32 = v.toBoolean() ? 1 : 0;
|
||||
@ -149,7 +149,7 @@ GenConversionForIntArray(Assembler &masm, JSObject *tarray, const ValueRemat &vr
|
||||
|
||||
typedef int32_t (JS_FASTCALL *Int32CxVp)(JSContext *, Value *);
|
||||
Int32CxVp stub;
|
||||
if (TypedArray::getType(tarray) == js::TypedArray::TYPE_UINT8_CLAMPED)
|
||||
if (TypedArray::type(tarray) == js::TypedArray::TYPE_UINT8_CLAMPED)
|
||||
stub = stubs::ConvertToTypedInt<true>;
|
||||
else
|
||||
stub = stubs::ConvertToTypedInt<false>;
|
||||
@ -165,7 +165,7 @@ GenConversionForIntArray(Assembler &masm, JSObject *tarray, const ValueRemat &vr
|
||||
}
|
||||
|
||||
// Performing clamping, if needed.
|
||||
if (TypedArray::getType(tarray) == js::TypedArray::TYPE_UINT8_CLAMPED)
|
||||
if (TypedArray::type(tarray) == js::TypedArray::TYPE_UINT8_CLAMPED)
|
||||
masm.clampInt32ToUint8(vr.dataReg());
|
||||
}
|
||||
|
||||
@ -241,7 +241,7 @@ GenConversionForFloatArray(Assembler &masm, JSObject *tarray, const ValueRemat &
|
||||
if (skip2.isSet())
|
||||
skip2.get().linkTo(masm.label(), &masm);
|
||||
|
||||
if (TypedArray::getType(tarray) == js::TypedArray::TYPE_FLOAT32)
|
||||
if (TypedArray::type(tarray) == js::TypedArray::TYPE_FLOAT32)
|
||||
masm.convertDoubleToFloat(destReg, destReg);
|
||||
}
|
||||
|
||||
@ -252,7 +252,7 @@ StoreToTypedArray(JSContext *cx, Assembler &masm, JSObject *tarray, T address,
|
||||
{
|
||||
ValueRemat vr = vrIn;
|
||||
|
||||
uint32_t type = TypedArray::getType(tarray);
|
||||
uint32_t type = TypedArray::type(tarray);
|
||||
switch (type) {
|
||||
case js::TypedArray::TYPE_INT8:
|
||||
case js::TypedArray::TYPE_UINT8:
|
||||
|
@ -984,7 +984,7 @@ FileAsTypedArray(JSContext *cx, const char *pathname)
|
||||
obj = JS_NewUint8Array(cx, len);
|
||||
if (!obj)
|
||||
return NULL;
|
||||
char *buf = (char *) TypedArray::getDataOffset(obj);
|
||||
char *buf = (char *) TypedArray::viewData(obj);
|
||||
size_t cc = fread(buf, 1, len, file);
|
||||
if (cc != len) {
|
||||
JS_ReportError(cx, "can't read %s: %s", pathname,
|
||||
@ -3385,8 +3385,8 @@ Serialize(JSContext *cx, unsigned argc, jsval *vp)
|
||||
JS_free(cx, datap);
|
||||
return false;
|
||||
}
|
||||
JS_ASSERT((uintptr_t(TypedArray::getDataOffset(array)) & 7) == 0);
|
||||
js_memcpy(TypedArray::getDataOffset(array), datap, nbytes);
|
||||
JS_ASSERT((uintptr_t(TypedArray::viewData(array)) & 7) == 0);
|
||||
js_memcpy(TypedArray::viewData(array), datap, nbytes);
|
||||
JS_free(cx, datap);
|
||||
JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(array));
|
||||
return true;
|
||||
@ -3401,16 +3401,16 @@ Deserialize(JSContext *cx, unsigned argc, jsval *vp)
|
||||
JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL, JSSMSG_INVALID_ARGS, "deserialize");
|
||||
return false;
|
||||
}
|
||||
if ((TypedArray::getByteLength(obj) & 7) != 0) {
|
||||
if ((TypedArray::byteLength(obj) & 7) != 0) {
|
||||
JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL, JSSMSG_INVALID_ARGS, "deserialize");
|
||||
return false;
|
||||
}
|
||||
if ((uintptr_t(TypedArray::getDataOffset(obj)) & 7) != 0) {
|
||||
if ((uintptr_t(TypedArray::viewData(obj)) & 7) != 0) {
|
||||
JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL, JSSMSG_BAD_ALIGNMENT);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!JS_ReadStructuredClone(cx, (uint64_t *) TypedArray::getDataOffset(obj), TypedArray::getByteLength(obj),
|
||||
if (!JS_ReadStructuredClone(cx, (uint64_t *) TypedArray::viewData(obj), TypedArray::byteLength(obj),
|
||||
JS_STRUCTURED_CLONE_VERSION, v.address(), NULL, NULL)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -1615,7 +1615,7 @@ function test() {
|
||||
// alien.TypeError.
|
||||
var av = Object.create(alien_view);
|
||||
checkThrowTODO(function () av.getUint8(4), alien.TypeError);
|
||||
checkThrow(function () av.buffer, alien.TypeError);
|
||||
checkThrowTODO(function () av.buffer, alien.TypeError);
|
||||
|
||||
// view of object whose proto is buffer. This should not work per dherman.
|
||||
// Note that DataView throws a TypeError while TypedArrays create a
|
||||
|
@ -1,46 +0,0 @@
|
||||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/licenses/publicdomain/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
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);
|
@ -447,6 +447,11 @@ function test()
|
||||
check(function () isProxy(alien_buffer));
|
||||
check(function () isProxy(view)); // the real test
|
||||
|
||||
// cross-compartment property access
|
||||
check(function () alien_buffer.byteLength == 7);
|
||||
check(function () alien_view.byteLength == 7);
|
||||
check(function () view.byteLength == 7);
|
||||
|
||||
// typed array protos should be equal
|
||||
simple = new Int8Array(12);
|
||||
check(function () Object.getPrototypeOf(view) == Object.getPrototypeOf(simple));
|
||||
|
@ -8,7 +8,12 @@ assertEq(o.byteLength, 1); // should be no assertion here
|
||||
|
||||
o = {};
|
||||
o.__proto__ = new Int32Array(1);
|
||||
assertEq(o.buffer.byteLength, 4); // should be no assertion here
|
||||
try {
|
||||
o.buffer.byteLength;
|
||||
} catch (ex) {
|
||||
// o is not a platform object
|
||||
assertEq(ex instanceof TypeError, true);
|
||||
}
|
||||
|
||||
F = function () {};
|
||||
F.prototype = new Int32Array(1);
|
||||
|
Loading…
Reference in New Issue
Block a user