Merging backout (bug 664249) for possible orange r=killer

This commit is contained in:
Michael Wu 2011-08-01 21:20:23 -07:00
Родитель 45846283da c69cefd52b
Коммит f9f83bdd42
12 изменённых файлов: 283 добавлений и 368 удалений

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

@ -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 {