Merge tracemonkey to mozilla-central. a=blockers.

This commit is contained in:
Robert Sayre 2011-02-27 07:16:05 -08:00
Родитель 4f1c99769e 56fc50060b
Коммит fe41781fab
9 изменённых файлов: 268 добавлений и 286 удалений

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

@ -295,7 +295,7 @@ def parse_jitflags():
for flags in OPTIONS.jitflags.split(',') ]
for flags in jitflags:
for flag in flags:
if flag not in ('-j', '-m', '-p', '-d'):
if flag not in ('-j', '-m', '-a', '-p', '-d'):
print('Invalid jit flag: "%s"'%flag)
sys.exit(1)
return jitflags

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

@ -0,0 +1,2 @@
assertEq(/^@(A*)x(B)*/.test("@xB"), true);

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

@ -71,7 +71,7 @@ JSCompartment::JSCompartment(JSRuntime *rt)
#ifdef JS_METHODJIT
jaegerCompartment(NULL),
#endif
propertyTree(this),
propertyTree(thisForCtor()),
debugMode(rt->debugMode),
#if ENABLE_YARR_JIT
regExpAllocator(NULL),

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

@ -489,6 +489,7 @@ struct JS_FRIEND_API(JSCompartment) {
BackEdgeMap backEdgeTable;
JSCompartment *thisForCtor() { return this; }
public:
js::MathCache *getMathCache(JSContext *cx) {
return mathCache ? mathCache : allocMathCache(cx);

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

@ -717,6 +717,11 @@ Exception(JSContext *cx, uintN argc, Value *vp)
if (!callee.getProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.classPrototypeAtom), &protov))
return JS_FALSE;
if (!protov.isObject()) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_PROTOTYPE, "Error");
return JS_FALSE;
}
JSObject *errProto = &protov.toObject();
JSObject *obj = NewNativeClassInstance(cx, &js_ErrorClass, errProto, errProto->getParent());
if (!obj)

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

@ -133,23 +133,23 @@ ArrayBuffer::class_finalize(JSContext *cx, JSObject *obj)
JSBool
ArrayBuffer::class_constructor(JSContext *cx, uintN argc, Value *vp)
{
return create(cx, argc, JS_ARGV(cx, vp), vp);
}
bool
ArrayBuffer::create(JSContext *cx, uintN argc, Value *argv, Value *rval)
{
/* N.B. there may not be an argv[-2]/argv[-1]. */
JSObject *obj = NewBuiltinClassInstance(cx, &ArrayBuffer::jsclass);
if (!obj)
int32 nbytes = 0;
if (argc > 0 && !ValueToECMAInt32(cx, vp[2], &nbytes))
return false;
int32_t nbytes = 0;
if (argc > 0) {
if (!ValueToECMAInt32(cx, argv[0], &nbytes))
return false;
}
JSObject *bufobj = create(cx, nbytes);
if (!bufobj)
return false;
vp->setObject(*bufobj);
return true;
}
JSObject *
ArrayBuffer::create(JSContext *cx, int32 nbytes)
{
JSObject *obj = NewBuiltinClassInstance(cx, &ArrayBuffer::jsclass);
if (!obj)
return NULL;
if (nbytes < 0) {
/*
@ -157,25 +157,21 @@ ArrayBuffer::create(JSContext *cx, uintN argc, Value *argv, Value *rval)
* as an integer value; if someone actually ever complains (validly), then we
* can fix.
*/
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_BAD_ARRAY_LENGTH);
return false;
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_ARRAY_LENGTH);
return NULL;
}
ArrayBuffer *abuf = cx->create<ArrayBuffer>();
if (!abuf) {
JS_ReportOutOfMemory(cx);
return false;
}
if (!abuf)
return NULL;
if (!abuf->allocateStorage(cx, nbytes)) {
cx->destroy<ArrayBuffer>(abuf);
return false;
return NULL;
}
obj->setPrivate(abuf);
rval->setObject(*obj);
return true;
return obj;
}
bool
@ -185,10 +181,8 @@ ArrayBuffer::allocateStorage(JSContext *cx, uint32 nbytes)
if (nbytes) {
data = cx->calloc(nbytes);
if (!data) {
JS_ReportOutOfMemory(cx);
if (!data)
return false;
}
}
byteLength = nbytes;
@ -726,6 +720,28 @@ class TypedArrayTemplate
return JSTYPE_OBJECT;
}
static JSObject *
createTypedArray(JSContext *cx, JSObject *bufobj, uint32 byteOffset, uint32 len)
{
JSObject *obj = NewBuiltinClassInstance(cx, slowClass());
if (!obj)
return NULL;
ThisTypeArray *tarray = cx->create<ThisTypeArray>(bufobj, byteOffset, len);
if (!tarray)
return NULL;
JS_ASSERT(obj->getClass() == slowClass());
obj->setSharedNonNativeMap();
obj->clasp = fastClass();
obj->setPrivate(tarray);
// FIXME Bug 599008: make it ok to call preventExtensions here.
obj->flags |= JSObject::NOT_EXTENSIBLE;
return obj;
}
/*
* new [Type]Array(length)
* new [Type]Array(otherTypedArray)
@ -736,80 +752,79 @@ class TypedArrayTemplate
class_constructor(JSContext *cx, uintN argc, Value *vp)
{
/* N.B. this is a constructor for slowClass, not fastClass! */
return create(cx, argc, JS_ARGV(cx, vp), vp);
JSObject *obj = create(cx, argc, JS_ARGV(cx, vp));
if (!obj)
return false;
vp->setObject(*obj);
return true;
}
static JSBool
create(JSContext *cx, uintN argc, Value *argv, Value *rval)
static JSObject *
create(JSContext *cx, uintN argc, Value *argv)
{
/* N.B. there may not be an argv[-2]/argv[-1]. */
JSObject *obj = NewBuiltinClassInstance(cx, slowClass());
if (!obj)
return false;
ThisTypeArray *tarray = 0;
// figure out the type of the first argument;
// no args is treated like an int arg of 0.
/* () or (number) */
jsuint len = 0;
bool hasLen = true;
if (argc > 0)
hasLen = ValueIsLength(cx, argv[0], &len);
if (argc == 0 || ValueIsLength(cx, argv[0], &len)) {
JSObject *bufobj = createBufferWithSizeAndCount(cx, len);
if (!bufobj)
return NULL;
if (hasLen) {
tarray = cx->create<ThisTypeArray>();
if (!tarray) {
JS_ReportOutOfMemory(cx);
return false;
}
return createTypedArray(cx, bufobj, 0, len);
}
if (!tarray->init(cx, len)) {
cx->destroy<ThisTypeArray>(tarray);
return false;
}
} else if (argc > 0 && argv[0].isObject()) {
int32_t byteOffset = -1;
int32_t length = -1;
/* (not an object) */
if (!argv[0].isObject()) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_TYPED_ARRAY_BAD_ARGS);
return NULL;
}
if (argc > 1) {
if (!ValueToInt32(cx, argv[1], &byteOffset))
return false;
if (byteOffset < 0) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_TYPED_ARRAY_NEGATIVE_ARG, "1");
return false;
}
JSObject *dataObj = &argv[0].toObject();
/* (typedArray) */
if (js_IsTypedArray(dataObj)) {
TypedArray *otherTypedArray = TypedArray::fromJSObject(dataObj);
JS_ASSERT(otherTypedArray);
uint32 len = otherTypedArray->length;
JSObject *bufobj = createBufferWithSizeAndCount(cx, len);
if (!bufobj)
return NULL;
JSObject *obj = createTypedArray(cx, bufobj, 0, len);
if (!obj || !copyFrom(cx, obj, otherTypedArray, 0))
return NULL;
return obj;
}
/* (obj, byteOffset, length). */
int32_t byteOffset = -1;
int32_t length = -1;
if (argc > 1) {
if (!ValueToInt32(cx, argv[1], &byteOffset))
return NULL;
if (byteOffset < 0) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_TYPED_ARRAY_NEGATIVE_ARG, "1");
return NULL;
}
if (argc > 2) {
if (!ValueToInt32(cx, argv[2], &length))
return false;
return NULL;
if (length < 0) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_TYPED_ARRAY_NEGATIVE_ARG, "2");
return false;
return NULL;
}
}
tarray = cx->create<ThisTypeArray>();
if (!tarray) {
JS_ReportOutOfMemory(cx);
return false;
}
if (!tarray->init(cx, &argv[0].toObject(), byteOffset, length)) {
cx->destroy<ThisTypeArray>(tarray);
return false;
}
} else {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_TYPED_ARRAY_BAD_ARGS);
return false;
}
rval->setObject(*obj);
return makeFastWithPrivate(cx, obj, tarray);
/* (obj, byteOffset, length) */
return createTypedArrayWithOffsetLength(cx, dataObj, byteOffset, length);
}
static void
@ -875,25 +890,11 @@ class TypedArrayTemplate
if (begin > end)
begin = end;
ThisTypeArray *ntarray = tarray->subarray(cx, begin, end);
if (!ntarray) {
// this should rarely ever happen
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_TYPED_ARRAY_BAD_ARGS);
JSObject *nobj = createSubarray(cx, tarray, begin, end);
if (!nobj)
return false;
}
// note the usage of NewObject here -- we don't want the
// constructor to be called!
JS_ASSERT(slowClass() != &js_FunctionClass);
JSObject *nobj = NewNonFunction<WithProto::Class>(cx, slowClass(), NULL, NULL);
if (!nobj) {
cx->destroy<ThisTypeArray>(ntarray);
return false;
}
vp->setObject(*nobj);
return makeFastWithPrivate(cx, nobj, ntarray);
return true;
}
/* set(array[, offset]) */
@ -920,14 +921,14 @@ class TypedArrayTemplate
return true;
// these are the default values
int32_t offset = 0;
int32_t off = 0;
Value *argv = JS_ARGV(cx, vp);
if (argc > 1) {
if (!ValueToInt32(cx, argv[1], &offset))
if (!ValueToInt32(cx, argv[1], &off))
return false;
if (offset < 0 || uint32_t(offset) > tarray->length) {
if (off < 0 || uint32_t(off) > tarray->length) {
// the given offset is bogus
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_TYPED_ARRAY_BAD_ARGS);
@ -935,6 +936,8 @@ class TypedArrayTemplate
}
}
uint32 offset(off);
// first arg must be either a typed array or a JS array
if (argc == 0 || !argv[0].isObject()) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
@ -953,7 +956,7 @@ class TypedArrayTemplate
return false;
}
if (!tarray->copyFrom(cx, src, offset))
if (!copyFrom(cx, obj, src, offset))
return false;
} else {
jsuint len;
@ -967,7 +970,7 @@ class TypedArrayTemplate
return false;
}
if (!tarray->copyFrom(cx, arg0, len, offset))
if (!copyFrom(cx, obj, arg0, len, offset))
return false;
}
@ -982,53 +985,44 @@ class TypedArrayTemplate
return reinterpret_cast<ThisTypeArray*>(obj->getPrivate());
}
// helper used by both the constructor and Subarray()
static bool
makeFastWithPrivate(JSContext *cx, JSObject *obj, ThisTypeArray *tarray)
{
JS_ASSERT(obj->getClass() == slowClass());
obj->setSharedNonNativeMap();
obj->clasp = fastClass();
obj->setPrivate(tarray);
// FIXME bug 599008. make it ok to call preventExtensions here.
// Keeping the boolean signature of this method for now.
obj->flags |= JSObject::NOT_EXTENSIBLE;
return true;
}
public:
TypedArrayTemplate() { }
bool
init(JSContext *cx, uint32 len)
TypedArrayTemplate(JSObject *bufobj, uint32 byteOffset, uint32 len)
{
JS_ASSERT(bufobj->getClass() == &ArrayBuffer::jsclass);
type = ArrayTypeID();
return createBufferWithSizeAndCount(cx, sizeof(NativeType), len);
bufferJS = bufobj;
buffer = ArrayBuffer::fromJSObject(bufobj);
this->byteOffset = byteOffset;
JS_ASSERT(byteOffset <= buffer->byteLength);
this->data = buffer->offsetData(byteOffset);
JS_ASSERT(buffer->data <= this->data);
JS_ASSERT(this->data <= buffer->offsetData(buffer->byteLength));
this->byteLength = len * sizeof(NativeType);
JS_ASSERT(buffer->byteLength - byteOffset >= this->byteLength);
this->length = len;
}
bool
init(JSContext *cx, JSObject *other, int32 byteOffsetInt = -1, int32 lengthInt = -1)
static JSObject *
createTypedArrayWithOffsetLength(JSContext *cx, JSObject *other,
int32 byteOffsetInt, int32 lengthInt)
{
type = ArrayTypeID();
JS_ASSERT(!js_IsTypedArray(other));
/* Handle creation from an ArrayBuffer not ArrayBuffer.prototype. */
ArrayBuffer *abuf;
if (js_IsTypedArray(other)) {
TypedArray *tarray = TypedArray::fromJSObject(other);
JS_ASSERT(tarray);
if (!createBufferWithSizeAndCount(cx, sizeof(NativeType), tarray->length))
return false;
if (!copyFrom(cx, tarray))
return false;
} else if (other->getClass() == &ArrayBuffer::jsclass &&
if (other->getClass() == &ArrayBuffer::jsclass &&
((abuf = ArrayBuffer::fromJSObject(other)) != NULL)) {
uint32 boffset = (byteOffsetInt < 0) ? 0 : uint32(byteOffsetInt);
if (boffset > abuf->byteLength || boffset % sizeof(NativeType) != 0) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_TYPED_ARRAY_BAD_ARGS);
return false; // invalid byteOffset
return NULL; // invalid byteOffset
}
uint32 len;
@ -1037,7 +1031,7 @@ class TypedArrayTemplate
if (len * sizeof(NativeType) != (abuf->byteLength - boffset)) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_TYPED_ARRAY_BAD_ARGS);
return false; // given byte array doesn't map exactly to sizeof(NativeType)*N
return NULL; // given byte array doesn't map exactly to sizeof(NativeType)*N
}
} else {
len = (uint32) lengthInt;
@ -1050,32 +1044,34 @@ class TypedArrayTemplate
{
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_TYPED_ARRAY_BAD_ARGS);
return false; // overflow occurred along the way when calculating boffset+len*sizeof(NativeType)
return NULL; // overflow occurred along the way when calculating boffset+len*sizeof(NativeType)
}
if (arrayByteLength + boffset > abuf->byteLength) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_TYPED_ARRAY_BAD_ARGS);
return false; // boffset+len is too big for the arraybuffer
return NULL; // boffset+len is too big for the arraybuffer
}
buffer = abuf;
bufferJS = other;
byteOffset = boffset;
byteLength = arrayByteLength;
length = len;
data = abuf->offsetData(boffset);
} else {
jsuint len;
if (!js_GetLengthProperty(cx, other, &len))
return false;
if (!createBufferWithSizeAndCount(cx, sizeof(NativeType), len))
return false;
if (!copyFrom(cx, other, len))
return false;
return createTypedArray(cx, other, boffset, len);
}
return true;
/*
* Otherwise create a new typed array and copy len properties from the
* object.
*/
jsuint len;
if (!js_GetLengthProperty(cx, other, &len))
return NULL;
JSObject *bufobj = createBufferWithSizeAndCount(cx, len);
if (!bufobj)
return NULL;
JSObject *obj = createTypedArray(cx, bufobj, 0, len);
if (!obj || !copyFrom(cx, obj, other, len))
return NULL;
return obj;
}
const NativeType
@ -1092,25 +1088,26 @@ class TypedArrayTemplate
inline void copyIndexToValue(JSContext *cx, uint32 index, Value *vp);
ThisTypeArray *
subarray(JSContext *cx, uint32 begin, uint32 end)
static JSObject *
createSubarray(JSContext *cx, ThisTypeArray *tarray, uint32 begin, uint32 end)
{
if (begin > length || end > length)
return NULL;
JS_ASSERT(tarray);
ThisTypeArray *tarray = cx->create<ThisTypeArray>();
if (!tarray)
return NULL;
JS_ASSERT(0 <= begin);
JS_ASSERT(begin <= tarray->length);
JS_ASSERT(0 <= end);
JS_ASSERT(end <= tarray->length);
tarray->buffer = buffer;
tarray->bufferJS = bufferJS;
tarray->byteOffset = byteOffset + begin * sizeof(NativeType);
tarray->byteLength = (end - begin) * sizeof(NativeType);
tarray->length = end - begin;
tarray->type = type;
tarray->data = buffer->offsetData(tarray->byteOffset);
JSObject *bufobj = tarray->bufferJS;
JS_ASSERT(bufobj);
return tarray;
JS_ASSERT(begin <= end);
uint32 length = end - begin;
JS_ASSERT(begin < UINT32_MAX / sizeof(NativeType));
uint32 byteOffset = begin * sizeof(NativeType);
return createTypedArray(cx, bufobj, byteOffset, length);
}
protected:
@ -1139,12 +1136,16 @@ class TypedArrayTemplate
return NativeType(int32(0));
}
bool
copyFrom(JSContext *cx, JSObject *ar, jsuint len, jsuint offset = 0)
static bool
copyFrom(JSContext *cx, JSObject *thisTypedArrayObj,
JSObject *ar, jsuint len, jsuint offset = 0)
{
JS_ASSERT(offset <= length);
JS_ASSERT(len <= length - offset);
NativeType *dest = static_cast<NativeType*>(data) + offset;
ThisTypeArray *thisTypedArray = fromJSObject(thisTypedArrayObj);
JS_ASSERT(thisTypedArray);
JS_ASSERT(offset <= thisTypedArray->length);
JS_ASSERT(len <= thisTypedArray->length - offset);
NativeType *dest = static_cast<NativeType*>(thisTypedArray->data) + offset;
if (ar->isDenseArray() && ar->getDenseArrayCapacity() >= len) {
JS_ASSERT(ar->getArrayLength() == len);
@ -1167,17 +1168,20 @@ class TypedArrayTemplate
return true;
}
bool
copyFrom(JSContext *cx, TypedArray *tarray, jsuint offset = 0)
static bool
copyFrom(JSContext *cx, JSObject *thisTypedArrayObj, TypedArray *tarray, jsuint offset)
{
JS_ASSERT(offset <= length);
JS_ASSERT(tarray->length <= length - offset);
if (tarray->buffer == buffer)
return copyFromWithOverlap(cx, tarray, offset);
ThisTypeArray *thisTypedArray = fromJSObject(thisTypedArrayObj);
JS_ASSERT(thisTypedArray);
NativeType *dest = static_cast<NativeType*>(data) + offset;
JS_ASSERT(offset <= thisTypedArray->length);
JS_ASSERT(tarray->length <= thisTypedArray->length - offset);
if (tarray->buffer == thisTypedArray->buffer)
return thisTypedArray->copyFromWithOverlap(cx, tarray, offset);
if (tarray->type == type) {
NativeType *dest = static_cast<NativeType*>(thisTypedArray->data) + offset;
if (tarray->type == thisTypedArray->type) {
memcpy(dest, tarray->data, tarray->byteLength);
return true;
}
@ -1242,7 +1246,7 @@ class TypedArrayTemplate
}
bool
copyFromWithOverlap(JSContext *cx, TypedArray *tarray, jsuint offset = 0)
copyFromWithOverlap(JSContext *cx, TypedArray *tarray, jsuint offset)
{
JS_ASSERT(offset <= length);
@ -1255,11 +1259,9 @@ class TypedArrayTemplate
// We have to make a copy of the source array here, since
// there's overlap, and we have to convert types.
void *srcbuf = js_malloc(tarray->byteLength);
if (!srcbuf) {
js_ReportOutOfMemory(cx);
void *srcbuf = cx->malloc(tarray->byteLength);
if (!srcbuf)
return false;
}
memcpy(srcbuf, tarray->data, tarray->byteLength);
switch (tarray->type) {
@ -1321,11 +1323,10 @@ class TypedArrayTemplate
return true;
}
bool
createBufferWithSizeAndCount(JSContext *cx, uint32 size, uint32 count)
static JSObject *
createBufferWithSizeAndCount(JSContext *cx, uint32 count)
{
JS_ASSERT(size != 0);
size_t size = sizeof(NativeType);
if (size != 0 && count >= INT32_MAX / size) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_NEED_DIET, "size and count");
@ -1333,30 +1334,7 @@ class TypedArrayTemplate
}
int32 bytelen = size * count;
if (!createBufferWithByteLength(cx, bytelen))
return false;
length = count;
return true;
}
bool
createBufferWithByteLength(JSContext *cx, int32 bytes)
{
Value arg = Int32Value(bytes), rval;
if (!ArrayBuffer::create(cx, 1, &arg, &rval))
return false;
JSObject *obj = &rval.toObject();
bufferJS = obj;
buffer = ArrayBuffer::fromJSObject(obj);
byteOffset = 0;
byteLength = bytes;
data = buffer->data;
return true;
return ArrayBuffer::create(cx, bytelen);
}
};
@ -1650,42 +1628,39 @@ js_IsTypedArray(JSObject *obj)
JS_FRIEND_API(JSObject *)
js_CreateArrayBuffer(JSContext *cx, jsuint nbytes)
{
Value arg = NumberValue(nbytes), rval;
if (!ArrayBuffer::create(cx, 1, &arg, &rval))
return NULL;
return &rval.toObject();
return ArrayBuffer::create(cx, nbytes);
}
static inline JSBool
TypedArrayConstruct(JSContext *cx, jsint atype, uintN argc, Value *argv, Value *rv)
static inline JSObject *
TypedArrayConstruct(JSContext *cx, jsint atype, uintN argc, Value *argv)
{
switch (atype) {
case TypedArray::TYPE_INT8:
return Int8Array::create(cx, argc, argv, rv);
return Int8Array::create(cx, argc, argv);
case TypedArray::TYPE_UINT8:
return Uint8Array::create(cx, argc, argv, rv);
return Uint8Array::create(cx, argc, argv);
case TypedArray::TYPE_INT16:
return Int16Array::create(cx, argc, argv, rv);
return Int16Array::create(cx, argc, argv);
case TypedArray::TYPE_UINT16:
return Uint16Array::create(cx, argc, argv, rv);
return Uint16Array::create(cx, argc, argv);
case TypedArray::TYPE_INT32:
return Int32Array::create(cx, argc, argv, rv);
return Int32Array::create(cx, argc, argv);
case TypedArray::TYPE_UINT32:
return Uint32Array::create(cx, argc, argv, rv);
return Uint32Array::create(cx, argc, argv);
case TypedArray::TYPE_FLOAT32:
return Float32Array::create(cx, argc, argv, rv);
return Float32Array::create(cx, argc, argv);
case TypedArray::TYPE_FLOAT64:
return Float64Array::create(cx, argc, argv, rv);
return Float64Array::create(cx, argc, argv);
case TypedArray::TYPE_UINT8_CLAMPED:
return Uint8ClampedArray::create(cx, argc, argv, rv);
return Uint8ClampedArray::create(cx, argc, argv);
default:
JS_NOT_REACHED("shouldn't have gotten here");
@ -1698,15 +1673,8 @@ js_CreateTypedArray(JSContext *cx, jsint atype, jsuint nelements)
{
JS_ASSERT(atype >= 0 && atype < TypedArray::TYPE_MAX);
Value vals[2];
vals[0].setInt32(nelements);
vals[1].setUndefined();
AutoArrayRooter tvr(cx, JS_ARRAY_LENGTH(vals), vals);
if (!TypedArrayConstruct(cx, atype, 1, &vals[0], &vals[1]))
return NULL;
return &vals[1].toObject();
Value nelems = Int32Value(nelements);
return TypedArrayConstruct(cx, atype, 1, &nelems);
}
JS_FRIEND_API(JSObject *)
@ -1714,15 +1682,8 @@ js_CreateTypedArrayWithArray(JSContext *cx, jsint atype, JSObject *arrayArg)
{
JS_ASSERT(atype >= 0 && atype < TypedArray::TYPE_MAX);
Value vals[2];
vals[0].setObject(*arrayArg);
vals[1].setUndefined();
AutoArrayRooter tvr(cx, JS_ARRAY_LENGTH(vals), vals);
if (!TypedArrayConstruct(cx, atype, 1, &vals[0], &vals[1]))
return NULL;
return &vals[1].toObject();
Value arrval = ObjectValue(*arrayArg);
return TypedArrayConstruct(cx, atype, 1, &arrval);
}
JS_FRIEND_API(JSObject *)
@ -1737,7 +1698,6 @@ js_CreateTypedArrayWithBuffer(JSContext *cx, jsint atype, JSObject *bufArg,
int argc = 1;
vals[0].setObject(*bufArg);
vals[3].setUndefined();
if (byteoffset >= 0) {
vals[argc].setInt32(byteoffset);
@ -1750,10 +1710,7 @@ js_CreateTypedArrayWithBuffer(JSContext *cx, jsint atype, JSObject *bufArg,
}
AutoArrayRooter tvr(cx, JS_ARRAY_LENGTH(vals), vals);
if (!TypedArrayConstruct(cx, atype, argc, &vals[0], &vals[3]))
return NULL;
return &vals[3].toObject();
return TypedArrayConstruct(cx, atype, argc, &vals[0]);
}
JS_FRIEND_API(JSBool)

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

@ -64,7 +64,7 @@ struct JS_FRIEND_API(ArrayBuffer) {
static JSBool class_constructor(JSContext *cx, uintN argc, Value *vp);
static bool create(JSContext *cx, uintN argc, Value *argv, Value *rval);
static JSObject *create(JSContext *cx, int32 nbytes);
static ArrayBuffer *fromJSObject(JSObject *obj);

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

@ -425,17 +425,6 @@ struct MatchStack {
while (size)
popCurrentFrame();
}
/* Return true iff the instruction pointer is currently at an optional bracket,
i.e., a bracket that may be matched zero times. */
bool atOptionalBracket() const {
/* We don't need to include OP_BRAMINZERO: we try to match the group within
the BRAMINZERO only if we have already failed to match the rest of the
regular expression. Thus, we will not be able to complete a successful
match by matching the group against the empty string anyway. */
unsigned char prevOp = currentFrame->args.instructionPtr[-1];
return prevOp == OP_BRAZERO;
}
};
static int matchError(int errorCode, MatchStack& stack)
@ -476,6 +465,27 @@ static inline void repeatInformationFromInstructionOffset(short instructionOffse
maximumRepeats = maximumRepeatsFromInstructionOffset[instructionOffset];
}
/* Helper class for passing a flag value from one op to the next that runs.
This allows us to set the flag in certain ops. When the flag is read, it
will be true only if the previous op set the flag, otherwise it is false. */
class LinearFlag {
public:
LinearFlag() : flag(false) {}
bool readAndClear() {
bool rv = flag;
flag = false;
return rv;
}
void set() {
flag = true;
}
private:
bool flag;
};
static int
match(JSArenaPool *regExpPool, const UChar* subjectPtr, const unsigned char* instructionPtr, int offsetTop, MatchData& md)
{
@ -487,6 +497,7 @@ match(JSArenaPool *regExpPool, const UChar* subjectPtr, const unsigned char* ins
bool minSatisfied;
MatchStack stack(regExpPool);
LinearFlag minSatNextBracket;
/* The opcode jump table. */
#ifdef USE_COMPUTED_GOTO_FOR_MATCH_OPCODE_LOOP
@ -552,8 +563,7 @@ RECURSE:
bracket data. */
stack.currentFrame->locals.skipBytes = 3;
/* We must compute this value at the top, before we move the instruction pointer. */
stack.currentFrame->locals.minSatisfied = instructionPtr != stack.currentFrame->args.instructionPtr &&
stack.atOptionalBracket();
stack.currentFrame->locals.minSatisfied = minSatNextBracket.readAndClear();
do {
/* We need to extract this into a variable so we can correctly pass it by value
through RECURSIVE_MATCH_NEW_GROUP, which modifies currentFrame. */
@ -658,6 +668,7 @@ RECURSE:
stack.currentFrame->locals.startOfRepeatingBracket = stack.currentFrame->args.instructionPtr + 1;
stack.currentFrame->extractBrackets(stack.currentFrame->args.instructionPtr + 1);
stack.currentFrame->saveOffsets(LOCALS(minBracket), LOCALS(limitBracket), md.offsetVector, md.offsetEnd);
minSatNextBracket.set();
RECURSIVE_MATCH_NEW_GROUP(14, stack.currentFrame->locals.startOfRepeatingBracket, stack.currentFrame->args.bracketChain, true);
if (isMatch)
RRETURN;
@ -766,11 +777,13 @@ RECURSE:
else
stack.currentFrame->restoreOffsets(LOCALS(minBracket), LOCALS(limitBracket), md.offsetVector, md.offsetEnd);
DPRINTF(("recursively matching lazy group\n"));
minSatNextBracket.set();
RECURSIVE_MATCH_NEW_GROUP(17, LOCALS(instructionPtrAtStartOfOnce), stack.currentFrame->args.bracketChain, true);
} else { /* OP_KETRMAX */
stack.currentFrame->saveOffsets(LOCALS(minBracket), LOCALS(limitBracket), md.offsetVector, md.offsetEnd);
stack.currentFrame->clobberOffsets(LOCALS(minBracket), LOCALS(limitBracket), md.offsetVector, md.offsetEnd);
DPRINTF(("recursively matching greedy group\n"));
minSatNextBracket.set();
RECURSIVE_MATCH_NEW_GROUP(18, LOCALS(instructionPtrAtStartOfOnce), stack.currentFrame->args.bracketChain, true);
if (isMatch)
RRETURN;
@ -1859,7 +1872,7 @@ RECURSE:
stack.currentFrame->locals.skipBytes = 3; /* For OP_BRAs. */
/* We must compute this value at the top, before we move the instruction pointer. */
stack.currentFrame->locals.minSatisfied = stack.atOptionalBracket();
stack.currentFrame->locals.minSatisfied = minSatNextBracket.readAndClear();
do {
/* We need to extract this into a variable so we can correctly pass it by value
through RECURSIVE_MATCH_NEW_GROUP, which modifies currentFrame. */

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

@ -110,20 +110,24 @@
<!-- =================== nsIAutoCompleteInput =================== -->
<field name="popup"><![CDATA[
var popup = null;
var popupId = this.getAttribute("autocompletepopup");
if (popupId)
popup = document.getElementById(popupId);
if (!popup) {
popup = document.createElement("panel");
popup.setAttribute("type", "autocomplete");
popup.setAttribute("noautofocus", "true");
var popupset = document.getAnonymousElementByAttribute(this, "anonid", "popupset");
popupset.appendChild(popup);
}
popup.mInput = this;
popup;
// Wrap in an anonymous function so that the var statements don't
// create properties on 'this'.
(function (that) {
var popup = null;
var popupId = that.getAttribute("autocompletepopup");
if (popupId)
popup = document.getElementById(popupId);
if (!popup) {
popup = document.createElement("panel");
popup.setAttribute("type", "autocomplete");
popup.setAttribute("noautofocus", "true");
var popupset = document.getAnonymousElementByAttribute(that, "anonid", "popupset");
popupset.appendChild(popup);
}
popup.mInput = that;
return popup;
})(this);
]]></field>
<property name="controller" onget="return this.mController;" readonly="true"/>