зеркало из https://github.com/mozilla/pjs.git
Backed out changeset 3b9852666565 (bug 664249) for possible orange r=killer
This commit is contained in:
Родитель
ae7db7d0ec
Коммит
e0f65464ea
|
@ -438,24 +438,24 @@ TagToArrayType(uint32_t tag)
|
|||
bool
|
||||
JSStructuredCloneWriter::writeTypedArray(JSObject *obj)
|
||||
{
|
||||
JSObject *arr = TypedArray::getTypedArray(obj);
|
||||
if (!out.writePair(ArrayTypeToTag(TypedArray::getType(arr)), TypedArray::getLength(arr)))
|
||||
TypedArray *arr = TypedArray::fromJSObject(obj);
|
||||
if (!out.writePair(ArrayTypeToTag(arr->type), arr->length))
|
||||
return false;
|
||||
|
||||
switch (TypedArray::getType(arr)) {
|
||||
switch (arr->type) {
|
||||
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 *) arr->data, arr->length);
|
||||
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 *) arr->data, arr->length);
|
||||
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 *) arr->data, arr->length);
|
||||
case TypedArray::TYPE_FLOAT64:
|
||||
return out.writeArray((const uint64_t *) TypedArray::getDataOffset(arr), TypedArray::getLength(arr));
|
||||
return out.writeArray((const uint64_t *) arr->data, arr->length);
|
||||
default:
|
||||
JS_NOT_REACHED("unknown TypedArray type");
|
||||
return false;
|
||||
|
@ -661,23 +661,23 @@ JSStructuredCloneReader::readTypedArray(uint32_t tag, uint32_t nelems, Value *vp
|
|||
return false;
|
||||
vp->setObject(*obj);
|
||||
|
||||
JSObject *arr = TypedArray::getTypedArray(obj);
|
||||
JS_ASSERT(TypedArray::getLength(arr) == nelems);
|
||||
JS_ASSERT(TypedArray::getType(arr) == atype);
|
||||
TypedArray *arr = TypedArray::fromJSObject(obj);
|
||||
JS_ASSERT(arr->length == nelems);
|
||||
JS_ASSERT(arr->type == atype);
|
||||
switch (atype) {
|
||||
case TypedArray::TYPE_INT8:
|
||||
case TypedArray::TYPE_UINT8:
|
||||
case TypedArray::TYPE_UINT8_CLAMPED:
|
||||
return in.readArray((uint8_t *) TypedArray::getDataOffset(arr), nelems);
|
||||
return in.readArray((uint8_t *) arr->data, nelems);
|
||||
case TypedArray::TYPE_INT16:
|
||||
case TypedArray::TYPE_UINT16:
|
||||
return in.readArray((uint16_t *) TypedArray::getDataOffset(arr), nelems);
|
||||
return in.readArray((uint16_t *) arr->data, nelems);
|
||||
case TypedArray::TYPE_INT32:
|
||||
case TypedArray::TYPE_UINT32:
|
||||
case TypedArray::TYPE_FLOAT32:
|
||||
return in.readArray((uint32_t *) TypedArray::getDataOffset(arr), nelems);
|
||||
return in.readArray((uint32_t *) arr->data, nelems);
|
||||
case TypedArray::TYPE_FLOAT64:
|
||||
return in.readArray((uint64_t *) TypedArray::getDataOffset(arr), nelems);
|
||||
return in.readArray((uint64_t *) arr->data, nelems);
|
||||
default:
|
||||
JS_NOT_REACHED("unknown TypedArray type");
|
||||
return false;
|
||||
|
|
|
@ -88,7 +88,6 @@
|
|||
#include "jsscopeinlines.h"
|
||||
#include "jsscriptinlines.h"
|
||||
#include "jsopcodeinlines.h"
|
||||
#include "jstypedarrayinlines.h"
|
||||
|
||||
#include "vm/Stack-inl.h"
|
||||
#include "vm/String-inl.h"
|
||||
|
@ -3558,8 +3557,8 @@ BEGIN_CASE(JSOP_LENGTH)
|
|||
}
|
||||
|
||||
if (js_IsTypedArray(obj)) {
|
||||
JSObject *tarray = TypedArray::getTypedArray(obj);
|
||||
regs.sp[-1].setInt32(TypedArray::getLength(tarray));
|
||||
TypedArray *tarray = TypedArray::fromJSObject(obj);
|
||||
regs.sp[-1].setNumber(tarray->length);
|
||||
len = JSOP_LENGTH_LENGTH;
|
||||
DO_NEXT_OP(len);
|
||||
}
|
||||
|
|
|
@ -91,7 +91,6 @@
|
|||
#include "jsscriptinlines.h"
|
||||
#include "jscntxtinlines.h"
|
||||
#include "jsopcodeinlines.h"
|
||||
#include "jstypedarrayinlines.h"
|
||||
|
||||
#include "vm/Stack-inl.h"
|
||||
|
||||
|
@ -13198,28 +13197,22 @@ TraceRecorder::setElem(int lval_spindex, int idx_spindex, int v_spindex)
|
|||
// Ensure array is a typed array and is the same type as what was written
|
||||
guardClass(obj_ins, obj->getClass(), branchExit, LOAD_CONST);
|
||||
|
||||
JSObject* tarray = js::TypedArray::getTypedArray(obj);
|
||||
js::TypedArray* tarray = js::TypedArray::fromJSObject(obj);
|
||||
|
||||
LIns* priv_ins = w.ldpObjPrivate(obj_ins);
|
||||
|
||||
// The index was on the stack and is therefore a LIR float; force it to
|
||||
// be an integer.
|
||||
CHECK_STATUS_A(makeNumberInt32(idx_ins, &idx_ins));
|
||||
|
||||
LIns* slots_ins = w.ldpObjFixedSlots(obj_ins);
|
||||
// Ensure idx >= 0 && idx < length (by using uint32)
|
||||
CHECK_STATUS_A(guard(true,
|
||||
w.name(w.ltui(idx_ins, w.ldiConstTypedArrayLength(slots_ins)),
|
||||
w.name(w.ltui(idx_ins, w.ldiConstTypedArrayLength(priv_ins)),
|
||||
"inRange"),
|
||||
OVERFLOW_EXIT, /* abortIfAlwaysExits = */true));
|
||||
|
||||
// We're now ready to store
|
||||
LIns* data_base_ins = w.ldpConstTypedArrayData(slots_ins);
|
||||
LIns* offset_ins = w.ldiConstTypedArrayByteOffset(slots_ins);
|
||||
#ifdef NANOJIT_64BIT
|
||||
LIns* data_ins = w.addp(data_base_ins, w.ui2uq(offset_ins));
|
||||
#else
|
||||
LIns* data_ins = w.addp(data_base_ins, offset_ins);
|
||||
#endif
|
||||
|
||||
LIns* data_ins = w.ldpConstTypedArrayData(priv_ins);
|
||||
LIns* pidx_ins = w.ui2p(idx_ins);
|
||||
LIns* typed_v_ins = v_ins;
|
||||
|
||||
|
@ -13246,7 +13239,7 @@ TraceRecorder::setElem(int lval_spindex, int idx_spindex, int v_spindex)
|
|||
}
|
||||
}
|
||||
|
||||
switch (js::TypedArray::getType(tarray)) {
|
||||
switch (tarray->type) {
|
||||
case js::TypedArray::TYPE_INT8:
|
||||
case js::TypedArray::TYPE_INT16:
|
||||
case js::TypedArray::TYPE_INT32:
|
||||
|
@ -13277,7 +13270,7 @@ TraceRecorder::setElem(int lval_spindex, int idx_spindex, int v_spindex)
|
|||
JS_NOT_REACHED("Unknown typed array type in tracer");
|
||||
}
|
||||
|
||||
switch (js::TypedArray::getType(tarray)) {
|
||||
switch (tarray->type) {
|
||||
case js::TypedArray::TYPE_INT8:
|
||||
case js::TypedArray::TYPE_UINT8_CLAMPED:
|
||||
case js::TypedArray::TYPE_UINT8:
|
||||
|
@ -14287,13 +14280,14 @@ TraceRecorder::typedArrayElement(Value& oval, Value& ival, Value*& vp, LIns*& v_
|
|||
CHECK_STATUS_A(makeNumberInt32(get(&ival), &idx_ins));
|
||||
LIns* pidx_ins = w.ui2p(idx_ins);
|
||||
|
||||
JSObject* tarray = js::TypedArray::getTypedArray(obj);
|
||||
js::TypedArray* tarray = js::TypedArray::fromJSObject(obj);
|
||||
JS_ASSERT(tarray);
|
||||
|
||||
LIns *slots_ins = w.ldpObjFixedSlots(obj_ins);
|
||||
/* priv_ins will load the TypedArray* */
|
||||
LIns* priv_ins = w.ldpObjPrivate(obj_ins);
|
||||
|
||||
/* Abort if out-of-range. */
|
||||
if ((jsuint) idx >= js::TypedArray::getLength(tarray))
|
||||
if ((jsuint) idx >= tarray->length)
|
||||
RETURN_STOP_A("out-of-range index on typed array");
|
||||
|
||||
/*
|
||||
|
@ -14306,20 +14300,14 @@ TraceRecorder::typedArrayElement(Value& oval, Value& ival, Value*& vp, LIns*& v_
|
|||
* length.
|
||||
*/
|
||||
guard(true,
|
||||
w.name(w.ltui(idx_ins, w.ldiConstTypedArrayLength(slots_ins)), "inRange"),
|
||||
w.name(w.ltui(idx_ins, w.ldiConstTypedArrayLength(priv_ins)), "inRange"),
|
||||
BRANCH_EXIT);
|
||||
|
||||
/* We are now ready to load. Do a different type of load
|
||||
* depending on what type of thing we're loading. */
|
||||
LIns* data_base_ins = w.ldpConstTypedArrayData(slots_ins);
|
||||
LIns* offset_ins = w.ldiConstTypedArrayByteOffset(slots_ins);
|
||||
#ifdef NANOJIT_64BIT
|
||||
LIns* data_ins = w.addp(data_base_ins, w.ui2uq(offset_ins));
|
||||
#else
|
||||
LIns* data_ins = w.addp(data_base_ins, offset_ins);
|
||||
#endif
|
||||
LIns* data_ins = w.ldpConstTypedArrayData(priv_ins);
|
||||
|
||||
switch (js::TypedArray::getType(tarray)) {
|
||||
switch (tarray->type) {
|
||||
case js::TypedArray::TYPE_INT8:
|
||||
v_ins = w.i2d(w.ldc2iTypedArrayElement(data_ins, pidx_ins));
|
||||
break;
|
||||
|
@ -16348,7 +16336,7 @@ TraceRecorder::record_JSOP_LENGTH()
|
|||
} else if (OkToTraceTypedArrays && js_IsTypedArray(obj)) {
|
||||
// Ensure array is a typed array and is the same type as what was written
|
||||
guardClass(obj_ins, obj->getClass(), snapshot(BRANCH_EXIT), LOAD_NORMAL);
|
||||
v_ins = w.i2d(w.ldiConstTypedArrayLength(w.ldpObjFixedSlots(obj_ins)));
|
||||
v_ins = w.i2d(w.ldiConstTypedArrayLength(w.ldpObjPrivate(obj_ins)));
|
||||
} else {
|
||||
if (!obj->isNative())
|
||||
RETURN_STOP_A("can't trace length property access on non-array, non-native object");
|
||||
|
|
|
@ -150,7 +150,7 @@ ArrayBuffer::class_constructor(JSContext *cx, uintN argc, Value *vp)
|
|||
}
|
||||
|
||||
static inline JSBool
|
||||
AllocateArrayBufferSlots(JSContext *cx, JSObject *obj, uint32 size)
|
||||
AllocateSlots(JSContext *cx, JSObject *obj, uint32 size)
|
||||
{
|
||||
uint32 bytes = size + sizeof(Value);
|
||||
if (size > sizeof(Value) * ARRAYBUFFER_RESERVED_SLOTS - sizeof(Value) ) {
|
||||
|
@ -204,7 +204,7 @@ ArrayBuffer::create(JSContext *cx, int32 nbytes)
|
|||
* The first 8 bytes hold the length.
|
||||
* The rest of it is a flat data store for the array buffer.
|
||||
*/
|
||||
if (!AllocateArrayBufferSlots(cx, obj, nbytes))
|
||||
if (!AllocateSlots(cx, obj, nbytes))
|
||||
return NULL;
|
||||
|
||||
JS_ASSERT(obj->getClass() == &ArrayBuffer::slowClass);
|
||||
|
@ -324,7 +324,7 @@ ArrayBuffer::obj_setProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp, J
|
|||
|
||||
JSObject *oldDelegateProto = delegate->getProto();
|
||||
|
||||
if (!js_SetPropertyHelper(cx, delegate, id, 0, vp, strict))
|
||||
if (!js_SetProperty(cx, delegate, id, vp, strict))
|
||||
return false;
|
||||
|
||||
if (delegate->getProto() != oldDelegateProto) {
|
||||
|
@ -333,7 +333,7 @@ ArrayBuffer::obj_setProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp, J
|
|||
if (!SetProto(cx, obj, vp->toObjectOrNull(), true)) {
|
||||
// this can be caused for example by setting x.__proto__ = x
|
||||
// restore delegate prototype chain
|
||||
SetProto(cx, delegate, oldDelegateProto, true);
|
||||
delegate->setProto(oldDelegateProto);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -412,19 +412,19 @@ ArrayBuffer::obj_typeOf(JSContext *cx, JSObject *obj)
|
|||
* the subclasses.
|
||||
*/
|
||||
|
||||
JSObject *
|
||||
TypedArray::getTypedArray(JSObject *obj)
|
||||
TypedArray *
|
||||
TypedArray::fromJSObject(JSObject *obj)
|
||||
{
|
||||
while (!js_IsTypedArray(obj))
|
||||
obj = obj->getProto();
|
||||
return obj;
|
||||
return reinterpret_cast<TypedArray*>(obj->getPrivate());
|
||||
}
|
||||
|
||||
inline bool
|
||||
TypedArray::isArrayIndex(JSContext *cx, JSObject *obj, jsid id, jsuint *ip)
|
||||
TypedArray::isArrayIndex(JSContext *cx, jsid id, jsuint *ip)
|
||||
{
|
||||
jsuint index;
|
||||
if (js_IdIsIndex(id, &index) && index < getLength(obj)) {
|
||||
if (js_IdIsIndex(id, &index) && index < length) {
|
||||
if (ip)
|
||||
*ip = index;
|
||||
return true;
|
||||
|
@ -433,7 +433,7 @@ TypedArray::isArrayIndex(JSContext *cx, JSObject *obj, jsid id, jsuint *ip)
|
|||
return false;
|
||||
}
|
||||
|
||||
typedef Value (* TypedArrayPropertyGetter)(JSObject *tarray);
|
||||
typedef Value (* TypedArrayPropertyGetter)(TypedArray *tarray);
|
||||
|
||||
template <TypedArrayPropertyGetter Get>
|
||||
class TypedArrayGetter {
|
||||
|
@ -441,7 +441,7 @@ class TypedArrayGetter {
|
|||
static inline bool get(JSContext *cx, JSObject *obj, jsid id, Value *vp) {
|
||||
do {
|
||||
if (js_IsTypedArray(obj)) {
|
||||
JSObject *tarray = TypedArray::getTypedArray(obj);
|
||||
TypedArray *tarray = TypedArray::fromJSObject(obj);
|
||||
if (tarray)
|
||||
*vp = Get(tarray);
|
||||
return true;
|
||||
|
@ -451,67 +451,62 @@ class TypedArrayGetter {
|
|||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* For now (until slots directly hold data)
|
||||
* slots data element points to the JSObject representing the ArrayBuffer.
|
||||
*/
|
||||
inline Value
|
||||
getBufferValue(JSObject *tarray)
|
||||
getBuffer(TypedArray *tarray)
|
||||
{
|
||||
JSObject *buffer = TypedArray::getBuffer(tarray);
|
||||
return ObjectValue(*buffer);
|
||||
return ObjectValue(*tarray->bufferJS);
|
||||
}
|
||||
|
||||
JSBool
|
||||
TypedArray::prop_getBuffer(JSContext *cx, JSObject *obj, jsid id, Value *vp)
|
||||
{
|
||||
return TypedArrayGetter<getBufferValue>::get(cx, obj, id, vp);
|
||||
return TypedArrayGetter<getBuffer>::get(cx, obj, id, vp);
|
||||
}
|
||||
|
||||
inline Value
|
||||
getByteOffsetValue(JSObject *tarray)
|
||||
getByteOffset(TypedArray *tarray)
|
||||
{
|
||||
return Int32Value(TypedArray::getByteOffset(tarray));
|
||||
return Int32Value(tarray->byteOffset);
|
||||
}
|
||||
|
||||
JSBool
|
||||
TypedArray::prop_getByteOffset(JSContext *cx, JSObject *obj, jsid id, Value *vp)
|
||||
{
|
||||
return TypedArrayGetter<getByteOffsetValue>::get(cx, obj, id, vp);
|
||||
return TypedArrayGetter<getByteOffset>::get(cx, obj, id, vp);
|
||||
}
|
||||
|
||||
inline Value
|
||||
getByteLengthValue(JSObject *tarray)
|
||||
getByteLength(TypedArray *tarray)
|
||||
{
|
||||
return Int32Value(TypedArray::getByteLength(tarray));
|
||||
return Int32Value(tarray->byteLength);
|
||||
}
|
||||
|
||||
JSBool
|
||||
TypedArray::prop_getByteLength(JSContext *cx, JSObject *obj, jsid id, Value *vp)
|
||||
{
|
||||
return TypedArrayGetter<getByteLengthValue>::get(cx, obj, id, vp);
|
||||
return TypedArrayGetter<getByteLength>::get(cx, obj, id, vp);
|
||||
}
|
||||
|
||||
inline Value
|
||||
getLengthValue(JSObject *tarray)
|
||||
getLength(TypedArray *tarray)
|
||||
{
|
||||
return Int32Value(TypedArray::getLength(tarray));
|
||||
return Int32Value(tarray->length);
|
||||
}
|
||||
|
||||
JSBool
|
||||
TypedArray::prop_getLength(JSContext *cx, JSObject *obj, jsid id, Value *vp)
|
||||
{
|
||||
return TypedArrayGetter<getLengthValue>::get(cx, obj, id, vp);
|
||||
return TypedArrayGetter<getLength>::get(cx, obj, id, vp);
|
||||
}
|
||||
|
||||
JSBool
|
||||
TypedArray::obj_lookupProperty(JSContext *cx, JSObject *obj, jsid id,
|
||||
JSObject **objp, JSProperty **propp)
|
||||
{
|
||||
JSObject *tarray = getTypedArray(obj);
|
||||
TypedArray *tarray = fromJSObject(obj);
|
||||
JS_ASSERT(tarray);
|
||||
|
||||
if (isArrayIndex(cx, tarray, id)) {
|
||||
if (tarray->isArrayIndex(cx, id)) {
|
||||
*propp = (JSProperty *) 1; /* non-null to indicate found */
|
||||
*objp = obj;
|
||||
return true;
|
||||
|
@ -527,6 +522,14 @@ TypedArray::obj_lookupProperty(JSContext *cx, JSObject *obj, jsid id,
|
|||
return proto->lookupProperty(cx, id, objp, propp);
|
||||
}
|
||||
|
||||
void
|
||||
TypedArray::obj_trace(JSTracer *trc, JSObject *obj)
|
||||
{
|
||||
TypedArray *tarray = fromJSObject(obj);
|
||||
JS_ASSERT(tarray);
|
||||
MarkObject(trc, *tarray->bufferJS, "typedarray.buffer");
|
||||
}
|
||||
|
||||
JSBool
|
||||
TypedArray::obj_getAttributes(JSContext *cx, JSObject *obj, jsid id, uintN *attrsp)
|
||||
{
|
||||
|
@ -709,28 +712,21 @@ class TypedArrayTemplate
|
|||
return &TypedArray::fastClasses[ArrayTypeID()];
|
||||
}
|
||||
|
||||
static void
|
||||
obj_trace(JSTracer *trc, JSObject *obj)
|
||||
{
|
||||
JSObject *buffer = static_cast<JSObject*>(getBuffer(obj));
|
||||
if (buffer)
|
||||
MarkObject(trc, *buffer, "typedarray.buffer");
|
||||
}
|
||||
|
||||
static JSBool
|
||||
obj_getProperty(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id, Value *vp)
|
||||
{
|
||||
JSObject *tarray = getTypedArray(obj);
|
||||
ThisTypeArray *tarray = ThisTypeArray::fromJSObject(obj);
|
||||
JS_ASSERT(tarray);
|
||||
|
||||
if (JSID_IS_ATOM(id, cx->runtime->atomState.lengthAtom)) {
|
||||
vp->setNumber(getLength(tarray));
|
||||
vp->setNumber(tarray->length);
|
||||
return true;
|
||||
}
|
||||
|
||||
jsuint index;
|
||||
if (isArrayIndex(cx, tarray, id, &index)) {
|
||||
if (tarray->isArrayIndex(cx, id, &index)) {
|
||||
// this inline function is specialized for each type
|
||||
copyIndexToValue(cx, tarray, index, vp);
|
||||
tarray->copyIndexToValue(cx, index, vp);
|
||||
} else {
|
||||
JSObject *obj2;
|
||||
JSProperty *prop;
|
||||
|
@ -761,17 +757,17 @@ class TypedArrayTemplate
|
|||
static JSBool
|
||||
obj_setProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp, JSBool strict)
|
||||
{
|
||||
JSObject *tarray = getTypedArray(obj);
|
||||
ThisTypeArray *tarray = ThisTypeArray::fromJSObject(obj);
|
||||
JS_ASSERT(tarray);
|
||||
|
||||
if (JSID_IS_ATOM(id, cx->runtime->atomState.lengthAtom)) {
|
||||
vp->setNumber(getLength(tarray));
|
||||
vp->setNumber(tarray->length);
|
||||
return true;
|
||||
}
|
||||
|
||||
jsuint index;
|
||||
// We can't just chain to js_SetPropertyHelper, because we're not a normal object.
|
||||
if (!isArrayIndex(cx, tarray, id, &index)) {
|
||||
if (!tarray->isArrayIndex(cx, id, &index)) {
|
||||
#if 0
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_TYPED_ARRAY_BAD_INDEX);
|
||||
|
@ -787,7 +783,7 @@ class TypedArrayTemplate
|
|||
}
|
||||
|
||||
if (vp->isInt32()) {
|
||||
setIndex(tarray, index, NativeType(vp->toInt32()));
|
||||
tarray->setIndex(index, NativeType(vp->toInt32()));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -817,19 +813,19 @@ class TypedArrayTemplate
|
|||
|
||||
// Assign based on characteristics of the destination type
|
||||
if (ArrayTypeIsFloatingPoint()) {
|
||||
setIndex(tarray, index, NativeType(d));
|
||||
tarray->setIndex(index, NativeType(d));
|
||||
} else if (ArrayTypeIsUnsigned()) {
|
||||
JS_ASSERT(sizeof(NativeType) <= 4);
|
||||
uint32 n = js_DoubleToECMAUint32(d);
|
||||
setIndex(tarray, index, NativeType(n));
|
||||
tarray->setIndex(index, NativeType(n));
|
||||
} else if (ArrayTypeID() == TypedArray::TYPE_UINT8_CLAMPED) {
|
||||
// The uint8_clamped type has a special rounding converter
|
||||
// for doubles.
|
||||
setIndex(tarray, index, NativeType(d));
|
||||
tarray->setIndex(index, NativeType(d));
|
||||
} else {
|
||||
JS_ASSERT(sizeof(NativeType) <= 4);
|
||||
int32 n = js_DoubleToECMAInt32(d);
|
||||
setIndex(tarray, index, NativeType(n));
|
||||
tarray->setIndex(index, NativeType(n));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -854,10 +850,10 @@ class TypedArrayTemplate
|
|||
return true;
|
||||
}
|
||||
|
||||
JSObject *tarray = TypedArray::getTypedArray(obj);
|
||||
TypedArray *tarray = TypedArray::fromJSObject(obj);
|
||||
JS_ASSERT(tarray);
|
||||
|
||||
if (isArrayIndex(cx, tarray, id)) {
|
||||
if (tarray->isArrayIndex(cx, id)) {
|
||||
rval->setBoolean(false);
|
||||
return true;
|
||||
}
|
||||
|
@ -870,7 +866,7 @@ class TypedArrayTemplate
|
|||
obj_enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
|
||||
Value *statep, jsid *idp)
|
||||
{
|
||||
JSObject *tarray = getTypedArray(obj);
|
||||
ThisTypeArray *tarray = ThisTypeArray::fromJSObject(obj);
|
||||
JS_ASSERT(tarray);
|
||||
|
||||
/*
|
||||
|
@ -882,13 +878,13 @@ class TypedArrayTemplate
|
|||
case JSENUMERATE_INIT_ALL:
|
||||
statep->setBoolean(true);
|
||||
if (idp)
|
||||
*idp = ::INT_TO_JSID(getLength(tarray) + 1);
|
||||
*idp = ::INT_TO_JSID(tarray->length + 1);
|
||||
break;
|
||||
|
||||
case JSENUMERATE_INIT:
|
||||
statep->setInt32(0);
|
||||
if (idp)
|
||||
*idp = ::INT_TO_JSID(getLength(tarray));
|
||||
*idp = ::INT_TO_JSID(tarray->length);
|
||||
break;
|
||||
|
||||
case JSENUMERATE_NEXT:
|
||||
|
@ -897,11 +893,11 @@ class TypedArrayTemplate
|
|||
statep->setInt32(0);
|
||||
} else {
|
||||
uint32 index = statep->toInt32();
|
||||
if (index < getLength(tarray)) {
|
||||
if (index < uint32(tarray->length)) {
|
||||
*idp = ::INT_TO_JSID(index);
|
||||
statep->setInt32(index + 1);
|
||||
} else {
|
||||
JS_ASSERT(index == getLength(tarray));
|
||||
JS_ASSERT(index == tarray->length);
|
||||
statep->setNull();
|
||||
}
|
||||
}
|
||||
|
@ -924,40 +920,18 @@ class TypedArrayTemplate
|
|||
static JSObject *
|
||||
createTypedArray(JSContext *cx, JSObject *bufobj, uint32 byteOffset, uint32 len)
|
||||
{
|
||||
JS_ASSERT(bufobj->getClass() == &ArrayBuffer::fastClass);
|
||||
JSObject *obj = NewBuiltinClassInstance(cx, slowClass());
|
||||
if (!obj)
|
||||
return NULL;
|
||||
|
||||
obj->setSlot(FIELD_TYPE, Int32Value(ArrayTypeID()));
|
||||
|
||||
do {
|
||||
obj->setSlot(FIELD_BUFFER, ObjectValue(*bufobj));
|
||||
/*
|
||||
* NOTE: unlike the earlier implementation where the 'data' pointed
|
||||
* directly to the right offset in the ArrayBuffer
|
||||
* this points to the base of the ArrayBuffer.
|
||||
* getIndex is modified to get the right index.
|
||||
*
|
||||
* This is because on 64 bit systems the jsval.h Private API
|
||||
* requires pointers stored in jsvals to be two-byte aligned.
|
||||
* TM and JM both need a few extra instructions to add the offset.
|
||||
*/
|
||||
obj->setSlot(FIELD_DATA, PrivateValue(ArrayBuffer::getDataOffset(bufobj)));
|
||||
} while(0);
|
||||
|
||||
obj->setSlot(FIELD_LENGTH, Int32Value(len));
|
||||
obj->setSlot(FIELD_BYTEOFFSET, Int32Value(byteOffset));
|
||||
obj->setSlot(FIELD_BYTELENGTH, Int32Value(len * sizeof(NativeType)));
|
||||
|
||||
JS_ASSERT(ArrayBuffer::getByteLength(getBuffer(obj)) - getByteOffset(obj) >= getByteLength(obj));
|
||||
JS_ASSERT(getByteOffset(obj) <= ArrayBuffer::getByteLength(getBuffer(obj)));
|
||||
JS_ASSERT(ArrayBuffer::getDataOffset(getBuffer(obj)) <= getDataOffset(obj));
|
||||
JS_ASSERT(getDataOffset(obj) <= offsetData(obj, ArrayBuffer::getByteLength(getBuffer(obj))));
|
||||
ThisTypeArray *tarray = cx->new_<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;
|
||||
|
@ -1008,16 +982,16 @@ class TypedArrayTemplate
|
|||
|
||||
/* (typedArray) */
|
||||
if (js_IsTypedArray(dataObj)) {
|
||||
JSObject *otherTypedArray = getTypedArray(dataObj);
|
||||
TypedArray *otherTypedArray = TypedArray::fromJSObject(dataObj);
|
||||
JS_ASSERT(otherTypedArray);
|
||||
|
||||
uint32 len = getLength(otherTypedArray);
|
||||
uint32 len = otherTypedArray->length;
|
||||
JSObject *bufobj = createBufferWithSizeAndCount(cx, len);
|
||||
if (!bufobj)
|
||||
return NULL;
|
||||
|
||||
JSObject *obj = createTypedArray(cx, bufobj, 0, len);
|
||||
if (!obj || !copyFromTypedArray(cx, obj, otherTypedArray, 0))
|
||||
if (!obj || !copyFrom(cx, obj, otherTypedArray, 0))
|
||||
return NULL;
|
||||
return obj;
|
||||
}
|
||||
|
@ -1050,6 +1024,14 @@ class TypedArrayTemplate
|
|||
return createTypedArrayWithOffsetLength(cx, dataObj, byteOffset, length);
|
||||
}
|
||||
|
||||
static void
|
||||
class_finalize(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
ThisTypeArray *tarray = ThisTypeArray::fromJSObject(obj);
|
||||
if (tarray)
|
||||
cx->delete_(tarray);
|
||||
}
|
||||
|
||||
/* subarray(start[, end]) */
|
||||
static JSBool
|
||||
fun_subarray(JSContext *cx, uintN argc, Value *vp)
|
||||
|
@ -1064,13 +1046,13 @@ class TypedArrayTemplate
|
|||
return false;
|
||||
}
|
||||
|
||||
JSObject *tarray = getTypedArray(obj);
|
||||
ThisTypeArray *tarray = ThisTypeArray::fromJSObject(obj);
|
||||
if (!tarray)
|
||||
return true;
|
||||
|
||||
// these are the default values
|
||||
int32_t begin = 0, end = getLength(tarray);
|
||||
int32_t length = int32(getLength(tarray));
|
||||
int32_t begin = 0, end = tarray->length;
|
||||
int32_t length = int32(tarray->length);
|
||||
|
||||
if (argc > 0) {
|
||||
Value *argv = JS_ARGV(cx, vp);
|
||||
|
@ -1121,7 +1103,7 @@ class TypedArrayTemplate
|
|||
return false;
|
||||
}
|
||||
|
||||
JSObject *tarray = getTypedArray(obj);
|
||||
ThisTypeArray *tarray = ThisTypeArray::fromJSObject(obj);
|
||||
if (!tarray)
|
||||
return true;
|
||||
|
||||
|
@ -1133,7 +1115,7 @@ class TypedArrayTemplate
|
|||
if (!ValueToInt32(cx, argv[1], &off))
|
||||
return false;
|
||||
|
||||
if (off < 0 || uint32_t(off) > getLength(tarray)) {
|
||||
if (off < 0 || uint32_t(off) > tarray->length) {
|
||||
// the given offset is bogus
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_TYPED_ARRAY_BAD_ARGS);
|
||||
|
@ -1152,16 +1134,16 @@ class TypedArrayTemplate
|
|||
|
||||
JSObject *arg0 = argv[0].toObjectOrNull();
|
||||
if (js_IsTypedArray(arg0)) {
|
||||
JSObject *src = TypedArray::getTypedArray(arg0);
|
||||
TypedArray *src = TypedArray::fromJSObject(arg0);
|
||||
if (!src ||
|
||||
getLength(src) > getLength(tarray) - offset)
|
||||
src->length > tarray->length - offset)
|
||||
{
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_TYPED_ARRAY_BAD_ARGS);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!copyFromTypedArray(cx, obj, src, offset))
|
||||
if (!copyFrom(cx, obj, src, offset))
|
||||
return false;
|
||||
} else {
|
||||
jsuint len;
|
||||
|
@ -1169,13 +1151,13 @@ class TypedArrayTemplate
|
|||
return false;
|
||||
|
||||
// avoid overflow; we know that offset <= length
|
||||
if (len > getLength(tarray) - offset) {
|
||||
if (len > tarray->length - offset) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_TYPED_ARRAY_BAD_ARGS);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!copyFromArray(cx, obj, arg0, len, offset))
|
||||
if (!copyFrom(cx, obj, arg0, len, offset))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1183,7 +1165,35 @@ class TypedArrayTemplate
|
|||
return true;
|
||||
}
|
||||
|
||||
static ThisTypeArray *
|
||||
fromJSObject(JSObject *obj)
|
||||
{
|
||||
JS_ASSERT(obj->getClass() == fastClass());
|
||||
return reinterpret_cast<ThisTypeArray*>(obj->getPrivate());
|
||||
}
|
||||
|
||||
public:
|
||||
TypedArrayTemplate(JSObject *bufobj, uint32 byteOffset, uint32 len)
|
||||
{
|
||||
JS_ASSERT(bufobj->getClass() == &ArrayBuffer::fastClass);
|
||||
|
||||
type = ArrayTypeID();
|
||||
bufferJS = bufobj;
|
||||
length = 0;
|
||||
|
||||
this->byteOffset = byteOffset;
|
||||
|
||||
JS_ASSERT(byteOffset <= ArrayBuffer::getByteLength(bufferJS));
|
||||
this->data = offsetData(bufferJS, byteOffset);
|
||||
JS_ASSERT(ArrayBuffer::getDataOffset(bufferJS) <= this->data);
|
||||
JS_ASSERT(this->data <= offsetData(bufferJS, ArrayBuffer::getByteLength(bufferJS)));
|
||||
|
||||
this->byteLength = len * sizeof(NativeType);
|
||||
JS_ASSERT(ArrayBuffer::getByteLength(bufferJS) - byteOffset >= this->byteLength);
|
||||
|
||||
this->length = len;
|
||||
}
|
||||
|
||||
static JSObject *
|
||||
createTypedArrayWithOffsetLength(JSContext *cx, JSObject *other,
|
||||
int32 byteOffsetInt, int32 lengthInt)
|
||||
|
@ -1244,44 +1254,44 @@ class TypedArrayTemplate
|
|||
return NULL;
|
||||
|
||||
JSObject *obj = createTypedArray(cx, bufobj, 0, len);
|
||||
if (!obj || !copyFromArray(cx, obj, other, len))
|
||||
if (!obj || !copyFrom(cx, obj, other, len))
|
||||
return NULL;
|
||||
return obj;
|
||||
}
|
||||
|
||||
static const NativeType
|
||||
getIndex(JSObject *obj, uint32 index)
|
||||
const NativeType
|
||||
getIndex(uint32 index) const
|
||||
{
|
||||
return *(static_cast<const NativeType*>(getDataOffset(obj)) + index);
|
||||
return *(static_cast<const NativeType*>(data) + index);
|
||||
}
|
||||
|
||||
static void
|
||||
setIndex(JSObject *obj, uint32 index, NativeType val)
|
||||
void
|
||||
setIndex(uint32 index, NativeType val)
|
||||
{
|
||||
*(static_cast<NativeType*>(getDataOffset(obj)) + index) = val;
|
||||
*(static_cast<NativeType*>(data) + index) = val;
|
||||
}
|
||||
|
||||
static void copyIndexToValue(JSContext *cx, JSObject *tarray, uint32 index, Value *vp);
|
||||
inline void copyIndexToValue(JSContext *cx, uint32 index, Value *vp);
|
||||
|
||||
static JSObject *
|
||||
createSubarray(JSContext *cx, JSObject *tarray, uint32 begin, uint32 end)
|
||||
createSubarray(JSContext *cx, ThisTypeArray *tarray, uint32 begin, uint32 end)
|
||||
{
|
||||
JS_ASSERT(tarray);
|
||||
|
||||
JS_ASSERT(0 <= begin);
|
||||
JS_ASSERT(begin <= getLength(tarray));
|
||||
JS_ASSERT(begin <= tarray->length);
|
||||
JS_ASSERT(0 <= end);
|
||||
JS_ASSERT(end <= getLength(tarray));
|
||||
JS_ASSERT(end <= tarray->length);
|
||||
|
||||
JSObject *bufobj = getBuffer(tarray);
|
||||
JSObject *bufobj = tarray->bufferJS;
|
||||
JS_ASSERT(bufobj);
|
||||
|
||||
JS_ASSERT(begin <= end);
|
||||
uint32 length = end - begin;
|
||||
|
||||
JS_ASSERT(begin < UINT32_MAX / sizeof(NativeType));
|
||||
JS_ASSERT(UINT32_MAX - begin * sizeof(NativeType) >= getByteOffset(tarray));
|
||||
uint32 byteOffset = getByteOffset(tarray) + begin * sizeof(NativeType);
|
||||
JS_ASSERT(UINT32_MAX - begin * sizeof(NativeType) >= tarray->byteOffset);
|
||||
uint32 byteOffset = tarray->byteOffset + begin * sizeof(NativeType);
|
||||
|
||||
return createTypedArray(cx, bufobj, byteOffset, length);
|
||||
}
|
||||
|
@ -1317,15 +1327,15 @@ class TypedArrayTemplate
|
|||
}
|
||||
|
||||
static bool
|
||||
copyFromArray(JSContext *cx, JSObject *thisTypedArrayObj,
|
||||
copyFrom(JSContext *cx, JSObject *thisTypedArrayObj,
|
||||
JSObject *ar, jsuint len, jsuint offset = 0)
|
||||
{
|
||||
thisTypedArrayObj = getTypedArray(thisTypedArrayObj);
|
||||
JS_ASSERT(thisTypedArrayObj);
|
||||
ThisTypeArray *thisTypedArray = fromJSObject(thisTypedArrayObj);
|
||||
JS_ASSERT(thisTypedArray);
|
||||
|
||||
JS_ASSERT(offset <= getLength(thisTypedArrayObj));
|
||||
JS_ASSERT(len <= getLength(thisTypedArrayObj) - offset);
|
||||
NativeType *dest = static_cast<NativeType*>(getDataOffset(thisTypedArrayObj)) + offset;
|
||||
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);
|
||||
|
@ -1349,70 +1359,70 @@ class TypedArrayTemplate
|
|||
}
|
||||
|
||||
static bool
|
||||
copyFromTypedArray(JSContext *cx, JSObject *thisTypedArrayObj, JSObject *tarray, jsuint offset)
|
||||
copyFrom(JSContext *cx, JSObject *thisTypedArrayObj, TypedArray *tarray, jsuint offset)
|
||||
{
|
||||
thisTypedArrayObj = getTypedArray(thisTypedArrayObj);
|
||||
JS_ASSERT(thisTypedArrayObj);
|
||||
ThisTypeArray *thisTypedArray = fromJSObject(thisTypedArrayObj);
|
||||
JS_ASSERT(thisTypedArray);
|
||||
|
||||
JS_ASSERT(offset <= getLength(thisTypedArrayObj));
|
||||
JS_ASSERT(getLength(tarray) <= getLength(thisTypedArrayObj) - offset);
|
||||
if (getBuffer(tarray) == getBuffer(thisTypedArrayObj))
|
||||
return copyFromWithOverlap(cx, thisTypedArrayObj, tarray, offset);
|
||||
JS_ASSERT(offset <= thisTypedArray->length);
|
||||
JS_ASSERT(tarray->length <= thisTypedArray->length - offset);
|
||||
if (tarray->bufferJS == thisTypedArray->bufferJS)
|
||||
return thisTypedArray->copyFromWithOverlap(cx, tarray, offset);
|
||||
|
||||
NativeType *dest = static_cast<NativeType*>((void*)getDataOffset(thisTypedArrayObj)) + offset;
|
||||
NativeType *dest = static_cast<NativeType*>(thisTypedArray->data) + offset;
|
||||
|
||||
if (getType(tarray) == getType(thisTypedArrayObj)) {
|
||||
memcpy(dest, getDataOffset(tarray), getByteLength(tarray));
|
||||
if (tarray->type == thisTypedArray->type) {
|
||||
memcpy(dest, tarray->data, tarray->byteLength);
|
||||
return true;
|
||||
}
|
||||
|
||||
uintN srclen = getLength(tarray);
|
||||
switch (getType(tarray)) {
|
||||
uintN srclen = tarray->length;
|
||||
switch (tarray->type) {
|
||||
case TypedArray::TYPE_INT8: {
|
||||
int8 *src = static_cast<int8*>(getDataOffset(tarray));
|
||||
int8 *src = static_cast<int8*>(tarray->data);
|
||||
for (uintN i = 0; i < srclen; ++i)
|
||||
*dest++ = NativeType(*src++);
|
||||
break;
|
||||
}
|
||||
case TypedArray::TYPE_UINT8:
|
||||
case TypedArray::TYPE_UINT8_CLAMPED: {
|
||||
uint8 *src = static_cast<uint8*>(getDataOffset(tarray));
|
||||
uint8 *src = static_cast<uint8*>(tarray->data);
|
||||
for (uintN i = 0; i < srclen; ++i)
|
||||
*dest++ = NativeType(*src++);
|
||||
break;
|
||||
}
|
||||
case TypedArray::TYPE_INT16: {
|
||||
int16 *src = static_cast<int16*>(getDataOffset(tarray));
|
||||
int16 *src = static_cast<int16*>(tarray->data);
|
||||
for (uintN i = 0; i < srclen; ++i)
|
||||
*dest++ = NativeType(*src++);
|
||||
break;
|
||||
}
|
||||
case TypedArray::TYPE_UINT16: {
|
||||
uint16 *src = static_cast<uint16*>(getDataOffset(tarray));
|
||||
uint16 *src = static_cast<uint16*>(tarray->data);
|
||||
for (uintN i = 0; i < srclen; ++i)
|
||||
*dest++ = NativeType(*src++);
|
||||
break;
|
||||
}
|
||||
case TypedArray::TYPE_INT32: {
|
||||
int32 *src = static_cast<int32*>(getDataOffset(tarray));
|
||||
int32 *src = static_cast<int32*>(tarray->data);
|
||||
for (uintN i = 0; i < srclen; ++i)
|
||||
*dest++ = NativeType(*src++);
|
||||
break;
|
||||
}
|
||||
case TypedArray::TYPE_UINT32: {
|
||||
uint32 *src = static_cast<uint32*>(getDataOffset(tarray));
|
||||
uint32 *src = static_cast<uint32*>(tarray->data);
|
||||
for (uintN 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*>(tarray->data);
|
||||
for (uintN 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*>(tarray->data);
|
||||
for (uintN i = 0; i < srclen; ++i)
|
||||
*dest++ = NativeType(*src++);
|
||||
break;
|
||||
|
@ -1425,72 +1435,72 @@ class TypedArrayTemplate
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
copyFromWithOverlap(JSContext *cx, JSObject *self, JSObject *tarray, jsuint offset)
|
||||
bool
|
||||
copyFromWithOverlap(JSContext *cx, TypedArray *tarray, jsuint offset)
|
||||
{
|
||||
JS_ASSERT(offset <= getLength(self));
|
||||
JS_ASSERT(offset <= length);
|
||||
|
||||
NativeType *dest = static_cast<NativeType*>(getDataOffset(self)) + offset;
|
||||
NativeType *dest = static_cast<NativeType*>(data) + offset;
|
||||
|
||||
if (getType(tarray) == getType(self)) {
|
||||
memmove(dest, getDataOffset(tarray), getByteLength(tarray));
|
||||
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 = cx->malloc_(getLength(tarray));
|
||||
void *srcbuf = cx->malloc_(tarray->byteLength);
|
||||
if (!srcbuf)
|
||||
return false;
|
||||
memcpy(srcbuf, getDataOffset(tarray), getByteLength(tarray));
|
||||
memcpy(srcbuf, tarray->data, tarray->byteLength);
|
||||
|
||||
switch (getType(tarray)) {
|
||||
switch (tarray->type) {
|
||||
case TypedArray::TYPE_INT8: {
|
||||
int8 *src = (int8*) srcbuf;
|
||||
for (uintN i = 0; i < getLength(tarray); ++i)
|
||||
for (uintN i = 0; i < tarray->length; ++i)
|
||||
*dest++ = NativeType(*src++);
|
||||
break;
|
||||
}
|
||||
case TypedArray::TYPE_UINT8:
|
||||
case TypedArray::TYPE_UINT8_CLAMPED: {
|
||||
uint8 *src = (uint8*) srcbuf;
|
||||
for (uintN i = 0; i < getLength(tarray); ++i)
|
||||
for (uintN i = 0; i < tarray->length; ++i)
|
||||
*dest++ = NativeType(*src++);
|
||||
break;
|
||||
}
|
||||
case TypedArray::TYPE_INT16: {
|
||||
int16 *src = (int16*) srcbuf;
|
||||
for (uintN i = 0; i < getLength(tarray); ++i)
|
||||
for (uintN i = 0; i < tarray->length; ++i)
|
||||
*dest++ = NativeType(*src++);
|
||||
break;
|
||||
}
|
||||
case TypedArray::TYPE_UINT16: {
|
||||
uint16 *src = (uint16*) srcbuf;
|
||||
for (uintN i = 0; i < getLength(tarray); ++i)
|
||||
for (uintN i = 0; i < tarray->length; ++i)
|
||||
*dest++ = NativeType(*src++);
|
||||
break;
|
||||
}
|
||||
case TypedArray::TYPE_INT32: {
|
||||
int32 *src = (int32*) srcbuf;
|
||||
for (uintN i = 0; i < getLength(tarray); ++i)
|
||||
for (uintN i = 0; i < tarray->length; ++i)
|
||||
*dest++ = NativeType(*src++);
|
||||
break;
|
||||
}
|
||||
case TypedArray::TYPE_UINT32: {
|
||||
uint32 *src = (uint32*) srcbuf;
|
||||
for (uintN i = 0; i < getLength(tarray); ++i)
|
||||
for (uintN i = 0; i < tarray->length; ++i)
|
||||
*dest++ = NativeType(*src++);
|
||||
break;
|
||||
}
|
||||
case TypedArray::TYPE_FLOAT32: {
|
||||
float *src = (float*) srcbuf;
|
||||
for (uintN i = 0; i < getLength(tarray); ++i)
|
||||
for (uintN i = 0; i < tarray->length; ++i)
|
||||
*dest++ = NativeType(*src++);
|
||||
break;
|
||||
}
|
||||
case TypedArray::TYPE_FLOAT64: {
|
||||
double *src = (double*) srcbuf;
|
||||
for (uintN i = 0; i < getLength(tarray); ++i)
|
||||
for (uintN i = 0; i < tarray->length; ++i)
|
||||
*dest++ = NativeType(*src++);
|
||||
break;
|
||||
}
|
||||
|
@ -1503,9 +1513,9 @@ class TypedArrayTemplate
|
|||
return true;
|
||||
}
|
||||
|
||||
static void *
|
||||
void *
|
||||
offsetData(JSObject *obj, uint32 offs) {
|
||||
return (void*)(((uint8*)getDataOffset(obj)) + offs);
|
||||
return (void*)(((uint8*)ArrayBuffer::getDataOffset(obj)) + offs);
|
||||
}
|
||||
|
||||
static JSObject *
|
||||
|
@ -1527,35 +1537,35 @@ class TypedArrayTemplate
|
|||
// less than 32-bits in size.
|
||||
template<typename NativeType>
|
||||
void
|
||||
TypedArrayTemplate<NativeType>::copyIndexToValue(JSContext *cx, JSObject *tarray, uint32 index, Value *vp)
|
||||
TypedArrayTemplate<NativeType>::copyIndexToValue(JSContext *cx, uint32 index, Value *vp)
|
||||
{
|
||||
JS_STATIC_ASSERT(sizeof(NativeType) < 4);
|
||||
|
||||
vp->setInt32(getIndex(tarray, index));
|
||||
vp->setInt32(getIndex(index));
|
||||
}
|
||||
|
||||
// and we need to specialize for 32-bit integers and floats
|
||||
template<>
|
||||
void
|
||||
TypedArrayTemplate<int32>::copyIndexToValue(JSContext *cx, JSObject *tarray, uint32 index, Value *vp)
|
||||
TypedArrayTemplate<int32>::copyIndexToValue(JSContext *cx, uint32 index, Value *vp)
|
||||
{
|
||||
int32 val = getIndex(tarray, index);
|
||||
int32 val = getIndex(index);
|
||||
vp->setInt32(val);
|
||||
}
|
||||
|
||||
template<>
|
||||
void
|
||||
TypedArrayTemplate<uint32>::copyIndexToValue(JSContext *cx, JSObject *tarray, uint32 index, Value *vp)
|
||||
TypedArrayTemplate<uint32>::copyIndexToValue(JSContext *cx, uint32 index, Value *vp)
|
||||
{
|
||||
uint32 val = getIndex(tarray, index);
|
||||
uint32 val = getIndex(index);
|
||||
vp->setNumber(val);
|
||||
}
|
||||
|
||||
template<>
|
||||
void
|
||||
TypedArrayTemplate<float>::copyIndexToValue(JSContext *cx, JSObject *tarray, uint32 index, Value *vp)
|
||||
TypedArrayTemplate<float>::copyIndexToValue(JSContext *cx, uint32 index, Value *vp)
|
||||
{
|
||||
float val = getIndex(tarray, index);
|
||||
float val = getIndex(index);
|
||||
double dval = val;
|
||||
|
||||
/*
|
||||
|
@ -1576,9 +1586,9 @@ TypedArrayTemplate<float>::copyIndexToValue(JSContext *cx, JSObject *tarray, uin
|
|||
|
||||
template<>
|
||||
void
|
||||
TypedArrayTemplate<double>::copyIndexToValue(JSContext *cx, JSObject *tarray, uint32 index, Value *vp)
|
||||
TypedArrayTemplate<double>::copyIndexToValue(JSContext *cx, uint32 index, Value *vp)
|
||||
{
|
||||
double val = getIndex(tarray, index);
|
||||
double val = getIndex(index);
|
||||
|
||||
/*
|
||||
* Doubles in typed arrays could be typed-punned arrays of integers. This
|
||||
|
@ -1686,16 +1696,15 @@ JSPropertySpec TypedArray::jsprops[] = {
|
|||
|
||||
#define IMPL_TYPED_ARRAY_STATICS(_typedArray) \
|
||||
template<> JSFunctionSpec _typedArray::jsfuncs[] = { \
|
||||
JS_FN("subarray", _typedArray::fun_subarray, 2, JSFUN_GENERIC_NATIVE), \
|
||||
JS_FN("set", _typedArray::fun_set, 2, JSFUN_GENERIC_NATIVE), \
|
||||
JS_FN("subarray", _typedArray::fun_subarray, 2, 0), \
|
||||
JS_FN("set", _typedArray::fun_set, 2, 0), \
|
||||
JS_FS_END \
|
||||
}
|
||||
|
||||
#define IMPL_TYPED_ARRAY_SLOW_CLASS(_typedArray) \
|
||||
{ \
|
||||
#_typedArray, \
|
||||
JSCLASS_HAS_RESERVED_SLOTS(TypedArray::FIELD_MAX) | \
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_##_typedArray), \
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_HAS_CACHED_PROTO(JSProto_##_typedArray), \
|
||||
PropertyStub, /* addProperty */ \
|
||||
PropertyStub, /* delProperty */ \
|
||||
PropertyStub, /* getProperty */ \
|
||||
|
@ -1709,8 +1718,7 @@ template<> JSFunctionSpec _typedArray::jsfuncs[] = { \
|
|||
#define IMPL_TYPED_ARRAY_FAST_CLASS(_typedArray) \
|
||||
{ \
|
||||
#_typedArray, \
|
||||
JSCLASS_HAS_RESERVED_SLOTS(TypedArray::FIELD_MAX) | \
|
||||
Class::NON_NATIVE, \
|
||||
Class::NON_NATIVE | JSCLASS_HAS_PRIVATE, \
|
||||
PropertyStub, /* addProperty */ \
|
||||
PropertyStub, /* delProperty */ \
|
||||
PropertyStub, /* getProperty */ \
|
||||
|
@ -1718,14 +1726,14 @@ template<> JSFunctionSpec _typedArray::jsfuncs[] = { \
|
|||
EnumerateStub, \
|
||||
ResolveStub, \
|
||||
ConvertStub, \
|
||||
NULL, /* finalize */ \
|
||||
_typedArray::class_finalize, \
|
||||
NULL, /* reserved0 */ \
|
||||
NULL, /* checkAccess */ \
|
||||
NULL, /* call */ \
|
||||
NULL, /* construct */ \
|
||||
NULL, /* xdrObject */ \
|
||||
NULL, /* hasInstance */ \
|
||||
_typedArray::obj_trace, /* trace */ \
|
||||
_typedArray::obj_trace, \
|
||||
JS_NULL_CLASS_EXT, \
|
||||
{ \
|
||||
_typedArray::obj_lookupProperty, \
|
||||
|
@ -1765,6 +1773,7 @@ do { \
|
|||
{ \
|
||||
return NULL; \
|
||||
} \
|
||||
proto->setPrivate(0); \
|
||||
} while (0)
|
||||
|
||||
IMPL_TYPED_ARRAY_STATICS(Int8Array);
|
||||
|
@ -1836,7 +1845,7 @@ js_InitTypedArrayClasses(JSContext *cx, JSObject *obj)
|
|||
* This is required otherwise the length of a
|
||||
* ArrayBuffer's prototype is undefined.
|
||||
*/
|
||||
if (!AllocateArrayBufferSlots(cx, proto, 0))
|
||||
if (!AllocateSlots(cx, proto, 0))
|
||||
return NULL;
|
||||
return proto;
|
||||
}
|
||||
|
|
|
@ -141,16 +141,6 @@ struct JS_FRIEND_API(TypedArray) {
|
|||
TYPE_MAX
|
||||
};
|
||||
|
||||
enum {
|
||||
FIELD_LENGTH = 0,
|
||||
FIELD_BYTEOFFSET,
|
||||
FIELD_BYTELENGTH,
|
||||
FIELD_TYPE,
|
||||
FIELD_BUFFER,
|
||||
FIELD_DATA,
|
||||
FIELD_MAX
|
||||
};
|
||||
|
||||
// and MUST NOT be used to construct new objects.
|
||||
static Class fastClasses[TYPE_MAX];
|
||||
|
||||
|
@ -160,7 +150,7 @@ struct JS_FRIEND_API(TypedArray) {
|
|||
|
||||
static JSPropertySpec jsprops[];
|
||||
|
||||
static JSObject *getTypedArray(JSObject *obj);
|
||||
static TypedArray *fromJSObject(JSObject *obj);
|
||||
|
||||
static JSBool prop_getBuffer(JSContext *cx, JSObject *obj, jsid id, Value *vp);
|
||||
static JSBool prop_getByteOffset(JSContext *cx, JSObject *obj, jsid id, Value *vp);
|
||||
|
@ -170,25 +160,33 @@ struct JS_FRIEND_API(TypedArray) {
|
|||
static JSBool obj_lookupProperty(JSContext *cx, JSObject *obj, jsid id,
|
||||
JSObject **objp, JSProperty **propp);
|
||||
|
||||
static void obj_trace(JSTracer *trc, JSObject *obj);
|
||||
|
||||
static JSBool obj_getAttributes(JSContext *cx, JSObject *obj, jsid id, uintN *attrsp);
|
||||
|
||||
static JSBool obj_setAttributes(JSContext *cx, JSObject *obj, jsid id, uintN *attrsp);
|
||||
|
||||
static JSUint32 getLength(JSObject *obj);
|
||||
static JSUint32 getByteOffset(JSObject *obj);
|
||||
static JSUint32 getByteLength(JSObject *obj);
|
||||
static JSUint32 getType(JSObject *obj);
|
||||
static JSObject * getBuffer(JSObject *obj);
|
||||
static void * getDataOffset(JSObject *obj);
|
||||
|
||||
static int32 lengthOffset() { return offsetof(TypedArray, length); }
|
||||
static int32 dataOffset() { return offsetof(TypedArray, data); }
|
||||
static int32 typeOffset() { return offsetof(TypedArray, type); }
|
||||
static void *offsetData(JSObject *obj, uint32 offs);
|
||||
|
||||
public:
|
||||
static bool
|
||||
isArrayIndex(JSContext *cx, JSObject *obj, jsid id, jsuint *ip = NULL);
|
||||
TypedArray() : bufferJS(0) { }
|
||||
|
||||
static inline int slotWidth(JSObject *obj) {
|
||||
switch (getType(obj)) {
|
||||
bool isArrayIndex(JSContext *cx, jsid id, jsuint *ip = NULL);
|
||||
bool valid() { return bufferJS != 0; }
|
||||
|
||||
JSObject *bufferJS;
|
||||
uint32 byteOffset;
|
||||
uint32 byteLength;
|
||||
uint32 length;
|
||||
uint32 type;
|
||||
|
||||
void *data;
|
||||
|
||||
inline int slotWidth() const {
|
||||
switch (type) {
|
||||
case js::TypedArray::TYPE_INT8:
|
||||
case js::TypedArray::TYPE_UINT8:
|
||||
case js::TypedArray::TYPE_UINT8_CLAMPED:
|
||||
|
|
|
@ -56,35 +56,5 @@ ArrayBuffer::getDataOffset(JSObject *obj) {
|
|||
uint64 *base = ((uint64*)obj->getSlotsPtr()) + 1;
|
||||
return (uint8*) base;
|
||||
}
|
||||
|
||||
inline JSUint32
|
||||
TypedArray::getLength(JSObject *obj) {
|
||||
return obj->getSlot(FIELD_LENGTH).toInt32();
|
||||
}
|
||||
|
||||
inline JSUint32
|
||||
TypedArray::getByteOffset(JSObject *obj) {
|
||||
return obj->getSlot(FIELD_BYTEOFFSET).toInt32();
|
||||
}
|
||||
|
||||
inline JSUint32
|
||||
TypedArray::getByteLength(JSObject *obj) {
|
||||
return obj->getSlot(FIELD_BYTELENGTH).toInt32();
|
||||
}
|
||||
|
||||
inline JSUint32
|
||||
TypedArray::getType(JSObject *obj) {
|
||||
return obj->getSlot(FIELD_TYPE).toInt32();
|
||||
}
|
||||
|
||||
inline JSObject *
|
||||
TypedArray::getBuffer(JSObject *obj) {
|
||||
return &obj->getSlot(FIELD_BUFFER).toObject();
|
||||
}
|
||||
|
||||
inline void *
|
||||
TypedArray::getDataOffset(JSObject *obj) {
|
||||
return (void *)((uint8*)obj->getSlot(FIELD_DATA).toPrivate() + getByteOffset(obj));
|
||||
}
|
||||
}
|
||||
#endif /* jstypedarrayinlines_h */
|
||||
|
|
|
@ -2467,12 +2467,11 @@ GetElementIC::attachTypedArray(JSContext *cx, JSObject *obj, const Value &v, jsi
|
|||
Jump claspGuard = masm.testObjClass(Assembler::NotEqual, objReg, obj->getClass());
|
||||
|
||||
// Get the internal typed array.
|
||||
masm.loadPtr(Address(objReg, JSObject::offsetOfSlots()), objReg);
|
||||
masm.loadPtr(Address(objReg, offsetof(JSObject, privateData)), objReg);
|
||||
|
||||
// Bounds check.
|
||||
Jump outOfBounds;
|
||||
Address typedArrayLength(objReg, sizeof(uint64) * js::TypedArray::FIELD_LENGTH);
|
||||
typedArrayLength = masm.payloadOf(typedArrayLength);
|
||||
Address typedArrayLength(objReg, js::TypedArray::lengthOffset());
|
||||
if (idRemat.isConstant()) {
|
||||
JS_ASSERT(idRemat.value().toInt32() == v.toInt32());
|
||||
outOfBounds = masm.branch32(Assembler::BelowOrEqual, typedArrayLength, Imm32(v.toInt32()));
|
||||
|
@ -2481,15 +2480,10 @@ GetElementIC::attachTypedArray(JSContext *cx, JSObject *obj, const Value &v, jsi
|
|||
}
|
||||
|
||||
// Load the array's packed data vector.
|
||||
Address data_base(objReg, sizeof(Value) * js::TypedArray::FIELD_DATA);
|
||||
masm.loadPrivate(data_base, objReg);
|
||||
|
||||
JSObject *tarray = js::TypedArray::getTypedArray(obj);
|
||||
int shift = js::TypedArray::slotWidth(tarray);
|
||||
|
||||
int byteOffset = js::TypedArray::getByteOffset(tarray);
|
||||
masm.addPtr(Imm32(byteOffset), objReg);
|
||||
masm.loadPtr(Address(objReg, js::TypedArray::dataOffset()), objReg);
|
||||
|
||||
js::TypedArray *tarray = js::TypedArray::fromJSObject(obj);
|
||||
int shift = tarray->slotWidth();
|
||||
if (idRemat.isConstant()) {
|
||||
int32 index = v.toInt32();
|
||||
Address addr(objReg, index * shift);
|
||||
|
@ -2810,31 +2804,26 @@ SetElementIC::attachTypedArray(JSContext *cx, JSObject *obj, int32 key)
|
|||
JS_ASSERT(!inlineClaspGuardPatched);
|
||||
|
||||
Assembler masm;
|
||||
//masm.breakpoint();
|
||||
|
||||
// Guard on this typed array's clasp.
|
||||
Jump claspGuard = masm.testObjClass(Assembler::NotEqual, objReg, obj->getClass());
|
||||
|
||||
// Get the internal typed array.
|
||||
masm.loadPtr(Address(objReg, JSObject::offsetOfSlots()), objReg);
|
||||
masm.loadPtr(Address(objReg, offsetof(JSObject, privateData)), objReg);
|
||||
|
||||
// Bounds check.
|
||||
Jump outOfBounds;
|
||||
Address typedArrayLength(objReg, sizeof(uint64) * js::TypedArray::FIELD_LENGTH);
|
||||
typedArrayLength = masm.payloadOf(typedArrayLength);
|
||||
Address typedArrayLength(objReg, js::TypedArray::lengthOffset());
|
||||
if (hasConstantKey)
|
||||
outOfBounds = masm.branch32(Assembler::BelowOrEqual, typedArrayLength, Imm32(keyValue));
|
||||
else
|
||||
outOfBounds = masm.branch32(Assembler::BelowOrEqual, typedArrayLength, keyReg);
|
||||
|
||||
// Load the array's packed data vector.
|
||||
JSObject *tarray = js::TypedArray::getTypedArray(obj);
|
||||
int byteOffset = js::TypedArray::getByteOffset(tarray);
|
||||
Address base_data(objReg, sizeof(uint64) * js::TypedArray::FIELD_DATA);
|
||||
masm.loadPrivate(base_data, objReg);
|
||||
masm.addPtr(Imm32(byteOffset), objReg);
|
||||
js::TypedArray *tarray = js::TypedArray::fromJSObject(obj);
|
||||
masm.loadPtr(Address(objReg, js::TypedArray::dataOffset()), objReg);
|
||||
|
||||
int shift = js::TypedArray::slotWidth(obj);
|
||||
int shift = tarray->slotWidth();
|
||||
if (hasConstantKey) {
|
||||
Address addr(objReg, keyValue * shift);
|
||||
if (!StoreToTypedArray(cx, masm, tarray, addr, vr, volatileMask))
|
||||
|
|
|
@ -44,7 +44,6 @@
|
|||
#include "jstypedarray.h"
|
||||
|
||||
#include "jsnuminlines.h"
|
||||
#include "jstypedarrayinlines.h"
|
||||
|
||||
namespace js {
|
||||
namespace mjit {
|
||||
|
@ -59,10 +58,10 @@ typedef JSC::MacroAssembler::ImmDouble ImmDouble;
|
|||
|
||||
template <typename T>
|
||||
static void
|
||||
LoadFromTypedArray(Assembler &masm, JSObject *tarray, T address,
|
||||
LoadFromTypedArray(Assembler &masm, js::TypedArray *tarray, T address,
|
||||
RegisterID typeReg, RegisterID dataReg)
|
||||
{
|
||||
switch (TypedArray::getType(tarray)) {
|
||||
switch (tarray->type) {
|
||||
case js::TypedArray::TYPE_INT8:
|
||||
masm.load8SignExtend(address, dataReg);
|
||||
masm.move(ImmType(JSVAL_TYPE_INT32), typeReg);
|
||||
|
@ -97,7 +96,7 @@ LoadFromTypedArray(Assembler &masm, JSObject *tarray, T address,
|
|||
case js::TypedArray::TYPE_FLOAT32:
|
||||
case js::TypedArray::TYPE_FLOAT64:
|
||||
{
|
||||
if (TypedArray::getType(tarray) == js::TypedArray::TYPE_FLOAT32)
|
||||
if (tarray->type == js::TypedArray::TYPE_FLOAT32)
|
||||
masm.loadFloat(address, FPRegisters::First);
|
||||
else
|
||||
masm.loadDouble(address, FPRegisters::First);
|
||||
|
@ -164,7 +163,7 @@ ClampIntForUint8Array(int32 x)
|
|||
}
|
||||
|
||||
static inline bool
|
||||
ConstantFoldForIntArray(JSContext *cx, JSObject *tarray, ValueRemat *vr)
|
||||
ConstantFoldForIntArray(JSContext *cx, js::TypedArray *tarray, ValueRemat *vr)
|
||||
{
|
||||
if (!vr->isTypeKnown())
|
||||
return true;
|
||||
|
@ -192,12 +191,12 @@ ConstantFoldForIntArray(JSContext *cx, JSObject *tarray, ValueRemat *vr)
|
|||
|
||||
int32 i32 = 0;
|
||||
if (v.isDouble()) {
|
||||
i32 = (TypedArray::getType(tarray) == js::TypedArray::TYPE_UINT8_CLAMPED)
|
||||
i32 = (tarray->type == js::TypedArray::TYPE_UINT8_CLAMPED)
|
||||
? js_TypedArray_uint8_clamp_double(v.toDouble())
|
||||
: js_DoubleToECMAInt32(v.toDouble());
|
||||
} else if (v.isInt32()) {
|
||||
i32 = v.toInt32();
|
||||
if (TypedArray::getType(tarray) == js::TypedArray::TYPE_UINT8_CLAMPED)
|
||||
if (tarray->type == js::TypedArray::TYPE_UINT8_CLAMPED)
|
||||
i32 = ClampIntForUint8Array(i32);
|
||||
} else if (v.isBoolean()) {
|
||||
i32 = v.toBoolean() ? 1 : 0;
|
||||
|
@ -212,9 +211,9 @@ ConstantFoldForIntArray(JSContext *cx, JSObject *tarray, ValueRemat *vr)
|
|||
|
||||
template <typename S, typename T>
|
||||
static void
|
||||
StoreToIntArray(Assembler &masm, JSObject *tarray, S src, T address)
|
||||
StoreToIntArray(Assembler &masm, js::TypedArray *tarray, S src, T address)
|
||||
{
|
||||
switch (TypedArray::getType(tarray)) {
|
||||
switch (tarray->type) {
|
||||
case js::TypedArray::TYPE_INT8:
|
||||
case js::TypedArray::TYPE_UINT8:
|
||||
case js::TypedArray::TYPE_UINT8_CLAMPED:
|
||||
|
@ -235,9 +234,9 @@ StoreToIntArray(Assembler &masm, JSObject *tarray, S src, T address)
|
|||
|
||||
template <typename S, typename T>
|
||||
static void
|
||||
StoreToFloatArray(Assembler &masm, JSObject *tarray, S src, T address)
|
||||
StoreToFloatArray(Assembler &masm, js::TypedArray *tarray, S src, T address)
|
||||
{
|
||||
if (TypedArray::getType(tarray) == js::TypedArray::TYPE_FLOAT32)
|
||||
if (tarray->type == js::TypedArray::TYPE_FLOAT32)
|
||||
masm.storeFloat(src, address);
|
||||
else
|
||||
masm.storeDouble(src, address);
|
||||
|
@ -249,7 +248,7 @@ StoreToFloatArray(Assembler &masm, JSObject *tarray, S src, T address)
|
|||
// used to ensure that |dataReg| (and volatile registers) are preserved
|
||||
// across any conversion process.
|
||||
static void
|
||||
GenConversionForIntArray(Assembler &masm, JSObject *tarray, const ValueRemat &vr,
|
||||
GenConversionForIntArray(Assembler &masm, js::TypedArray *tarray, const ValueRemat &vr,
|
||||
uint32 saveMask)
|
||||
{
|
||||
if (vr.isConstant()) {
|
||||
|
@ -278,7 +277,7 @@ GenConversionForIntArray(Assembler &masm, JSObject *tarray, const ValueRemat &vr
|
|||
|
||||
typedef int32 (JS_FASTCALL *Int32CxVp)(JSContext *, Value *);
|
||||
Int32CxVp stub;
|
||||
if (TypedArray::getType(tarray) == js::TypedArray::TYPE_UINT8_CLAMPED)
|
||||
if (tarray->type == js::TypedArray::TYPE_UINT8_CLAMPED)
|
||||
stub = stubs::ConvertToTypedInt<true>;
|
||||
else
|
||||
stub = stubs::ConvertToTypedInt<false>;
|
||||
|
@ -294,7 +293,7 @@ GenConversionForIntArray(Assembler &masm, JSObject *tarray, const ValueRemat &vr
|
|||
}
|
||||
|
||||
// Performing clamping, if needed.
|
||||
if (TypedArray::getType(tarray) == js::TypedArray::TYPE_UINT8_CLAMPED) {
|
||||
if (tarray->type == js::TypedArray::TYPE_UINT8_CLAMPED) {
|
||||
// cmp dr, 0
|
||||
// jge _min
|
||||
// mov dr, 0
|
||||
|
@ -324,7 +323,7 @@ GenConversionForIntArray(Assembler &masm, JSObject *tarray, const ValueRemat &vr
|
|||
// Constants are left untouched. Any other value is placed into
|
||||
// FPRegisters::First.
|
||||
static void
|
||||
GenConversionForFloatArray(Assembler &masm, JSObject *tarray, const ValueRemat &vr,
|
||||
GenConversionForFloatArray(Assembler &masm, js::TypedArray *tarray, const ValueRemat &vr,
|
||||
FPRegisterID destReg, uint32 saveMask)
|
||||
{
|
||||
if (vr.isConstant()) {
|
||||
|
@ -389,18 +388,18 @@ 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 (tarray->type == js::TypedArray::TYPE_FLOAT32)
|
||||
masm.convertDoubleToFloat(destReg, destReg);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static bool
|
||||
StoreToTypedArray(JSContext *cx, Assembler &masm, JSObject *tarray, T address,
|
||||
StoreToTypedArray(JSContext *cx, Assembler &masm, js::TypedArray *tarray, T address,
|
||||
const ValueRemat &vrIn, uint32 saveMask)
|
||||
{
|
||||
ValueRemat vr = vrIn;
|
||||
|
||||
switch (TypedArray::getType(tarray)) {
|
||||
switch (tarray->type) {
|
||||
case js::TypedArray::TYPE_INT8:
|
||||
case js::TypedArray::TYPE_UINT8:
|
||||
case js::TypedArray::TYPE_UINT8_CLAMPED:
|
||||
|
@ -429,11 +428,11 @@ StoreToTypedArray(JSContext *cx, Assembler &masm, JSObject *tarray, T address,
|
|||
// for the conversion call. This is because the object and key may be
|
||||
// in temporary registers, and we want to restore those without killing
|
||||
// the mutated RHS.
|
||||
bool singleByte = (TypedArray::getType(tarray) == js::TypedArray::TYPE_INT8 ||
|
||||
TypedArray::getType(tarray) == js::TypedArray::TYPE_UINT8 ||
|
||||
TypedArray::getType(tarray) == js::TypedArray::TYPE_UINT8_CLAMPED);
|
||||
bool singleByte = (tarray->type == js::TypedArray::TYPE_INT8 ||
|
||||
tarray->type == js::TypedArray::TYPE_UINT8 ||
|
||||
tarray->type == js::TypedArray::TYPE_UINT8_CLAMPED);
|
||||
bool mayNeedConversion = (!vr.isTypeKnown() || vr.knownType() != JSVAL_TYPE_INT32);
|
||||
bool mayNeedClamping = !vr.isConstant() && (TypedArray::getType(tarray) == js::TypedArray::TYPE_UINT8_CLAMPED);
|
||||
bool mayNeedClamping = !vr.isConstant() && (tarray->type == js::TypedArray::TYPE_UINT8_CLAMPED);
|
||||
bool needsSingleByteReg = singleByte &&
|
||||
!vr.isConstant() &&
|
||||
!(Registers::SingleByteRegs & Registers::maskReg(vr.dataReg()));
|
||||
|
|
|
@ -74,7 +74,6 @@
|
|||
#include "jsscope.h"
|
||||
#include "jsscript.h"
|
||||
#include "jstypedarray.h"
|
||||
#include "jstypedarrayinlines.h"
|
||||
#include "jsxml.h"
|
||||
#include "jsperf.h"
|
||||
|
||||
|
@ -884,7 +883,7 @@ FileAsTypedArray(JSContext *cx, const char *pathname)
|
|||
obj = js_CreateTypedArray(cx, TypedArray::TYPE_UINT8, len);
|
||||
if (!obj)
|
||||
return NULL;
|
||||
char *buf = (char *) TypedArray::getDataOffset(TypedArray::getTypedArray(obj));
|
||||
char *buf = (char *) TypedArray::fromJSObject(obj)->data;
|
||||
size_t cc = fread(buf, 1, len, file);
|
||||
if (cc != len) {
|
||||
JS_ReportError(cx, "can't read %s: %s", pathname,
|
||||
|
@ -4330,9 +4329,9 @@ Serialize(JSContext *cx, uintN argc, jsval *vp)
|
|||
JS_free(cx, datap);
|
||||
return false;
|
||||
}
|
||||
JSObject *array = TypedArray::getTypedArray(arrayobj);
|
||||
JS_ASSERT((uintptr_t(TypedArray::getDataOffset(array)) & 7) == 0);
|
||||
memcpy(TypedArray::getDataOffset(array), datap, nbytes);
|
||||
TypedArray *array = TypedArray::fromJSObject(arrayobj);
|
||||
JS_ASSERT((uintptr_t(array->data) & 7) == 0);
|
||||
memcpy(array->data, datap, nbytes);
|
||||
JS_free(cx, datap);
|
||||
JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(arrayobj));
|
||||
return true;
|
||||
|
@ -4347,17 +4346,17 @@ Deserialize(JSContext *cx, uintN argc, jsval *vp)
|
|||
JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL, JSSMSG_INVALID_ARGS, "deserialize");
|
||||
return false;
|
||||
}
|
||||
JSObject *array = TypedArray::getTypedArray(obj);
|
||||
if ((TypedArray::getByteLength(array) & 7) != 0) {
|
||||
TypedArray *array = TypedArray::fromJSObject(obj);
|
||||
if ((array->byteLength & 7) != 0) {
|
||||
JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL, JSSMSG_INVALID_ARGS, "deserialize");
|
||||
return false;
|
||||
}
|
||||
if ((uintptr_t(TypedArray::getDataOffset(array)) & 7) != 0) {
|
||||
if ((uintptr_t(array->data) & 7) != 0) {
|
||||
JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL, JSSMSG_BAD_ALIGNMENT);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!JS_ReadStructuredClone(cx, (uint64 *) TypedArray::getDataOffset(array), TypedArray::getByteLength(array),
|
||||
if (!JS_ReadStructuredClone(cx, (uint64 *) array->data, array->byteLength,
|
||||
JS_STRUCTURED_CLONE_VERSION, &v, NULL, NULL)) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -376,14 +376,6 @@ function test()
|
|||
check(function() a.length == 121);
|
||||
for (var i = 0; i < a.length; i++)
|
||||
check(function() a[i] == 0)
|
||||
|
||||
// check that TM generated byte offset is right (requires run with -j)
|
||||
a = new Uint8Array(100);
|
||||
a[99] = 5;
|
||||
b = new Uint8Array(a.buffer, 9); // force a offset
|
||||
// use a loop to invoke the TM
|
||||
for (var i = 0; i < b.length; i++)
|
||||
check(function() b[90] == 5)
|
||||
print ("done");
|
||||
|
||||
reportCompare(0, TestFailCount, "typed array tests");
|
||||
|
|
|
@ -459,13 +459,13 @@ void ValidateWriter::checkAccSet(LOpcode op, LIns *base, int32_t disp, AccSet ac
|
|||
break;
|
||||
|
||||
case ACCSET_TARRAY:
|
||||
// we actually just want the JSObject itself
|
||||
// This check is imperfect.
|
||||
//
|
||||
// base = ldp.objprivate ...[offsetof(JSObject, privateData)]
|
||||
// ins = ld{i,p}.tarray base[<disp within TypedArray>]
|
||||
ok = (op == LIR_ldi || op == LIR_ldp); /*&&*/
|
||||
//match(base, LIR_ldp, ACCSET_OBJ_SLOTS, offsetof(JSObject, slots));
|
||||
ok = (op == LIR_ldi || op == LIR_ldp) &&
|
||||
dispWithin(TypedArray) &&
|
||||
match(base, LIR_ldp, ACCSET_OBJ_PRIVATE, offsetof(JSObject, privateData));
|
||||
break;
|
||||
|
||||
case ACCSET_TARRAY_DATA:
|
||||
|
@ -475,12 +475,9 @@ void ValidateWriter::checkAccSet(LOpcode op, LIns *base, int32_t disp, AccSet ac
|
|||
// base_oprnd1 = ldp.tarray/c ...[TypedArray::dataOffset()]
|
||||
// base = addp base_oprnd1, ...
|
||||
// ins = {ld,st}X.tdata base[...]
|
||||
ok = true;
|
||||
//ok = isConstPrivatePtr(base, TypedArray::FIELD_DATA);
|
||||
JS_ASSERT(ok);
|
||||
//ok = match(base, LIR_ldp, ACCSET_TARRAY, LOAD_CONST, sizeof(js::Value) * js::TypedArray::FIELD_DATA) ||
|
||||
//((base->isop(LIR_addp) &&
|
||||
//match(base->oprnd1(), LIR_ldp, ACCSET_TARRAY, sizeof(js::Value) * js::TypedArray::FIELD_DATA)));
|
||||
ok = match(base, LIR_ldp, ACCSET_TARRAY, LOAD_CONST, TypedArray::dataOffset()) ||
|
||||
(base->isop(LIR_addp) &&
|
||||
match(base->oprnd1(), LIR_ldp, ACCSET_TARRAY, LOAD_CONST, TypedArray::dataOffset()));
|
||||
break;
|
||||
|
||||
case ACCSET_ITER:
|
||||
|
|
|
@ -533,41 +533,16 @@ class Writer
|
|||
"slots");
|
||||
}
|
||||
|
||||
nj::LIns *ldpObjFixedSlots(nj::LIns *obj) const {
|
||||
//return name(lir->insLoad(nj::LIR_ldp, obj, sizeof(JSObject), ACCSET_SLOTS),
|
||||
#if JS_BITS_PER_WORD == 32
|
||||
return name(lir->ins2(nj::LIR_addp, obj, lir->insImmI(sizeof(JSObject))),
|
||||
#else
|
||||
return name(lir->ins2(nj::LIR_addp, obj, lir->insImmQ(sizeof(JSObject))),
|
||||
#endif
|
||||
"fixed_slots");
|
||||
}
|
||||
|
||||
nj::LIns *ldiConstTypedArrayLength(nj::LIns *array) const {
|
||||
return name(lir->insLoad(nj::LIR_ldi, array, sizeof(Value) * js::TypedArray::FIELD_LENGTH + sPayloadOffset, ACCSET_TARRAY,
|
||||
return name(lir->insLoad(nj::LIR_ldi, array, js::TypedArray::lengthOffset(), ACCSET_TARRAY,
|
||||
nj::LOAD_CONST),
|
||||
"typedArrayLength");
|
||||
}
|
||||
|
||||
nj::LIns *ldiConstTypedArrayByteOffset(nj::LIns *array) const {
|
||||
return name(lir->insLoad(nj::LIR_ldi, array, sizeof(Value) * js::TypedArray::FIELD_BYTEOFFSET + sPayloadOffset, ACCSET_TARRAY,
|
||||
nj::LOAD_CONST),
|
||||
"typedArrayByteOffset");
|
||||
}
|
||||
|
||||
nj::LIns *ldpConstTypedArrayData(nj::LIns *array) const {
|
||||
//return name(lir->insLoad(nj::LIR_ldp, array, sizeof(Value) * js::TypedArray::FIELD_DATA + sPayloadOffset, ACCSET_TARRAY,
|
||||
//nj::LOAD_CONST),
|
||||
//"typedElems");
|
||||
uint32 offset = sizeof(Value) * js::TypedArray::FIELD_DATA + sPayloadOffset;
|
||||
#if JS_BITS_PER_WORD == 32
|
||||
return name(lir->insLoad(nj::LIR_ldi, array, offset, ACCSET_TARRAY, nj::LOAD_CONST), "typedArrayData");
|
||||
#elif JS_BITS_PER_WORD == 64
|
||||
/* N.B. On 64-bit, privatized value are encoded differently from other pointers. */
|
||||
nj::LIns *v_ins = lir->insLoad(nj::LIR_ldq, array, offset,
|
||||
ACCSET_TARRAY, nj::LOAD_CONST);
|
||||
return name(lshqN(v_ins, 1), "typedArrayData");
|
||||
#endif
|
||||
return name(lir->insLoad(nj::LIR_ldp, array, js::TypedArray::dataOffset(), ACCSET_TARRAY,
|
||||
nj::LOAD_CONST),
|
||||
"typedElems");
|
||||
}
|
||||
|
||||
nj::LIns *ldc2iTypedArrayElement(nj::LIns *elems, nj::LIns *index) const {
|
||||
|
|
Загрузка…
Ссылка в новой задаче