This commit is contained in:
Jason Orendorff 2010-10-22 19:11:26 -05:00
commit bfaf004fd7
22 changed files with 141 additions and 99 deletions

View File

@ -5854,7 +5854,7 @@ CloneSimpleValues(JSContext* cx,
}
// Security wrapped objects are not allowed either.
if (obj->getClass()->ext.wrappedObject)
if (obj->isWrapper() && !obj->getClass()->ext.innerObject)
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
// See if this JSObject is backed by some C++ object. If it is then we assume

View File

@ -2612,6 +2612,7 @@ arm*-*)
ENABLE_TRACEJIT=1
NANOJIT_ARCH=ARM
ENABLE_METHODJIT=1
ENABLE_MONOIC=1
AC_DEFINE(JS_CPU_ARM)
AC_DEFINE(JS_NUNBOX32)
;;

View File

@ -0,0 +1,32 @@
// vim: set ts=4 sw=4 tw=99 et:
function f(L) {
do {
L: for (var i = 0; i < L; i++) {
break L;
}
} while (0);
}
f(1);
f(1);
f(1);
f(1);
f(1);
f(1);
f(1);
f(1);
f(1);
f(1);
f(1);
f(1);
f(1);
f(1);
f(1);
f(1);
f(1);
f(1);
f(1);
f(1);
f(1);
f(1);
f(1);
f(1);

View File

@ -4057,7 +4057,8 @@ JS_PUBLIC_API(JSBool)
JS_IsArrayObject(JSContext *cx, JSObject *obj)
{
assertSameCompartment(cx, obj);
return obj->wrappedObject(cx)->isArray();
return obj->isArray() ||
(obj->isWrapper() && JSWrapper::wrappedObject(obj)->isArray());
}
JS_PUBLIC_API(JSBool)

View File

@ -101,6 +101,7 @@
#include "jsstr.h"
#include "jsstaticcheck.h"
#include "jsvector.h"
#include "jswrapper.h"
#include "jsatominlines.h"
#include "jscntxtinlines.h"
@ -2392,11 +2393,9 @@ array_concat(JSContext *cx, uintN argc, Value *vp)
return false;
const Value &v = p[i];
if (v.isObject()) {
JSObject *wobj;
aobj = &v.toObject();
wobj = aobj->wrappedObject(cx);
if (wobj->isArray()) {
if (aobj->isArray() ||
(aobj->isWrapper() && JSWrapper::wrappedObject(aobj)->isArray())) {
jsid id = ATOM_TO_JSID(cx->runtime->atomState.lengthAtom);
if (!aobj->getProperty(cx, id, tvr.addr()))
return false;
@ -2825,10 +2824,12 @@ array_every(JSContext *cx, uintN argc, Value *vp)
static JSBool
array_isArray(JSContext *cx, uintN argc, Value *vp)
{
JSObject *obj;
vp->setBoolean(argc > 0 &&
vp[2].isObject() &&
vp[2].toObject().wrappedObject(cx)->isArray());
return JS_TRUE;
((obj = &vp[2].toObject())->isArray() ||
(obj->isWrapper() && JSWrapper::wrappedObject(obj)->isArray())));
return true;
}
static JSFunctionSpec array_methods[] = {

View File

@ -780,7 +780,6 @@ JS_SetWatchPoint(JSContext *cx, JSObject *obj, jsid id,
PropertyOp watcher;
origobj = obj;
obj = obj->wrappedObject(cx);
OBJ_TO_INNER_OBJECT(cx, obj);
if (!obj)
return JS_FALSE;

View File

@ -2292,7 +2292,7 @@ js_fun_apply(JSContext *cx, uintN argc, Value *vp)
* Steps 4-5 (note erratum removing steps originally numbered 5 and 7 in
* original version of ES5).
*/
JSObject *aobj = vp[3].toObject().wrappedObject(cx);
JSObject *aobj = &vp[3].toObject();
jsuint length;
if (aobj->isArray()) {
length = aobj->getArrayLength();
@ -2484,7 +2484,7 @@ fun_bind(JSContext *cx, uintN argc, Value *vp)
return false;
/* Step 2. */
if (!target->wrappedObject(cx)->isCallable()) {
if (!target->isCallable()) {
if (JSString *str = js_ValueToString(cx, vp[1])) {
if (const char *bytes = js_GetStringBytes(cx, str)) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,

View File

@ -2623,7 +2623,6 @@ SetProtoCheckingForCycles(JSContext *cx, JSObject *obj, JSObject *proto)
bool cycle = false;
for (JSObject *obj2 = proto; obj2;) {
obj2 = obj2->wrappedObject(cx);
if (obj2 == obj) {
cycle = true;
break;

View File

@ -1119,8 +1119,7 @@ HasInstance(JSContext *cx, JSObject *obj, const Value *v, JSBool *bp)
static JS_ALWAYS_INLINE bool
EqualObjects(JSContext *cx, JSObject *lobj, JSObject *robj)
{
return lobj == robj ||
lobj->wrappedObject(cx) == robj->wrappedObject(cx);
return lobj == robj;
}
bool

View File

@ -111,7 +111,7 @@ Class js_IteratorClass = {
NULL, /* outerObject */
NULL, /* innerObject */
iterator_iterator,
NULL /* wrappedObject */
NULL /* unused */
}
};
@ -1165,7 +1165,7 @@ Class js_GeneratorClass = {
NULL, /* outerObject */
NULL, /* innerObject */
iterator_iterator,
NULL, /* wrappedObject */
NULL /* unused */
}
};

View File

@ -809,7 +809,7 @@ obj_toStringHelper(JSContext *cx, JSObject *obj)
if (obj->isProxy())
return JSProxy::obj_toString(cx, obj);
const char *clazz = obj->wrappedObject(cx)->getClass()->name;
const char *clazz = obj->getClass()->name;
size_t nchars = 9 + strlen(clazz); /* 9 for "[object ]" */
jschar *chars = (jschar *) cx->malloc((nchars + 1) * sizeof(jschar));
if (!chars)
@ -5715,13 +5715,6 @@ CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
JSType
js_TypeOf(JSContext *cx, JSObject *obj)
{
/*
* Unfortunately we have wrappers that are native objects and thus don't
* overwrite js_TypeOf (i.e. XPCCrossOriginWrapper), so we have to
* unwrap here.
*/
obj = obj->wrappedObject(cx);
/*
* ECMA 262, 11.4.3 says that any native object that implements
* [[Call]] should be of type "function". However, RegExp is of
@ -5741,7 +5734,7 @@ js_IsDelegate(JSContext *cx, JSObject *obj, const Value &v)
{
if (v.isPrimitive())
return false;
JSObject *obj2 = v.toObject().wrappedObject(cx);
JSObject *obj2 = &v.toObject();
while ((obj2 = obj2->getProto()) != NULL) {
if (obj2 == obj)
return true;
@ -6228,16 +6221,6 @@ js_SetReservedSlot(JSContext *cx, JSObject *obj, uint32 slot, const Value &v)
return true;
}
JSObject *
JSObject::wrappedObject(JSContext *cx) const
{
if (JSObjectOp op = getClass()->ext.wrappedObject) {
if (JSObject *obj = op(cx, const_cast<JSObject *>(this)))
return obj;
}
return const_cast<JSObject *>(this);
}
JSObject *
JSObject::getGlobal() const
{

View File

@ -1099,8 +1099,6 @@ struct JSObject : js::gc::Cell {
return (op ? op : js_TypeOf)(cx, this);
}
JSObject *wrappedObject(JSContext *cx) const;
/* These four are time-optimized to avoid stub calls. */
JSObject *thisObject(JSContext *cx) {
JSObjectOp op = getOps()->thisObject;

View File

@ -1000,7 +1000,7 @@ JS_FRIEND_API(Class) OuterWindowProxyClass = {
NULL, /* equality */
NULL, /* outerObject */
proxy_innerObject,
NULL, /* wrappedObject */
NULL /* unused */
},
{
proxy_LookupProperty,

View File

@ -10240,14 +10240,9 @@ TraceRecorder::getThis(LIns*& this_ins)
/* thisv is a reference, so it'll see the newly computed |this|. */
#ifdef DEBUG
/*
* Check that thisv is our global. It could be a XPCCrossOriginWrapper around an outer
* window object whose inner object is our global, so follow all the links as needed.
*/
JS_ASSERT(thisv.isObject());
JSObject *thisObj = thisv.toObject().wrappedObject(cx);
OBJ_TO_INNER_OBJECT(cx, thisObj);
JS_ASSERT(thisObj == globalObj);
JSObject *thisObj = &thisv.toObject();
JS_ASSERT(thisObj->getClass()->ext.innerObject);
#endif
this_ins = INS_CONSTOBJ(globalObj);
set(&thisv, this_ins);
@ -15998,6 +15993,12 @@ TraceRecorder::record_JSOP_CALLELEM()
JS_REQUIRES_STACK AbortableRecordingStatus
TraceRecorder::record_JSOP_STOP()
{
/* A return from callDepth 0 terminates the current loop, except for recursion. */
if (callDepth == 0) {
AUDIT(returnLoopExits);
return endLoop();
}
JSStackFrame *fp = cx->fp();
if (fp->hasImacropc()) {
@ -17019,6 +17020,12 @@ LoopProfile::profileOperation(JSContext* cx, JSOp op)
if (op == JSOP_INT8)
prevConst = GET_INT8(cx->regs->pc);
if (op == JSOP_GETELEM || op == JSOP_SETELEM) {
Value& lval = cx->regs->sp[op == JSOP_GETELEM ? -2 : -3];
if (lval.isObject() && js_IsTypedArray(&lval.toObject()))
increment(OP_TYPED_ARRAY);
}
prevOp = op;
if (op == JSOP_CALL) {
@ -17185,6 +17192,7 @@ LoopProfile::decide(JSContext *cx)
debug_only_printf(LC_TMProfiler, "FEATURE eval %d\n", allOps[OP_EVAL]);
debug_only_printf(LC_TMProfiler, "FEATURE new %d\n", allOps[OP_NEW]);
debug_only_printf(LC_TMProfiler, "FEATURE call %d\n", allOps[OP_CALL]);
debug_only_printf(LC_TMProfiler, "FEATURE typedarray %d\n", allOps[OP_TYPED_ARRAY]);
debug_only_printf(LC_TMProfiler, "FEATURE fwdjump %d\n", allOps[OP_FWDJUMP]);
debug_only_printf(LC_TMProfiler, "FEATURE recursive %d\n", allOps[OP_RECURSIVE]);
debug_only_printf(LC_TMProfiler, "FEATURE shortLoop %d\n", shortLoop);
@ -17218,6 +17226,11 @@ LoopProfile::decide(JSContext *cx)
/* The tracer handles these ops well because of inlining. */
goodOps += (count(OP_CALL) + count(OP_NEW))*20;
/* The tracer specialized typed array access. */
goodOps += count(OP_TYPED_ARRAY)*10;
debug_only_printf(LC_TMProfiler, "FEATURE goodOps %u\n", goodOps);
if (goodOps >= numAllOps)
traceOK = true;
}

View File

@ -686,6 +686,7 @@ public:
OP_FWDJUMP, // Jumps with positive delta
OP_NEW, // JSOP_NEW instructions
OP_RECURSIVE, // Recursive calls
OP_TYPED_ARRAY, // Accesses to typed arrays
OP_LIMIT
};

View File

@ -928,7 +928,7 @@ class TypedArrayTemplate
if (!tarray->copyFrom(cx, src, offset))
return false;
} else if (arg0->wrappedObject(cx)->isArray()) {
} else {
jsuint len;
if (!js_GetLengthProperty(cx, arg0, &len))
return false;
@ -942,10 +942,6 @@ class TypedArrayTemplate
if (!tarray->copyFrom(cx, arg0, len, offset))
return false;
} else {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_TYPED_ARRAY_BAD_ARGS);
return false;
}
vp->setUndefined();
@ -988,37 +984,18 @@ class TypedArrayTemplate
init(JSContext *cx, JSObject *other, int32 byteOffsetInt = -1, int32 lengthInt = -1)
{
type = ArrayTypeID();
ArrayBuffer *abuf;
//printf ("Constructing with type %d other %p offset %d length %d\n", type, other, byteOffset, length);
if (other->wrappedObject(cx)->isArray()) {
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;
} else if (js_IsTypedArray(other)) {
if (js_IsTypedArray(other)) {
TypedArray *tarray = TypedArray::fromJSObject(other);
JS_ASSERT(tarray);
//printf ("SizeAndCount: %d %d\n", sizeof(NativeType), tarray->length);
if (!createBufferWithSizeAndCount(cx, sizeof(NativeType), tarray->length))
return false;
if (!copyFrom(cx, tarray))
return false;
} else if (other->getClass() == &ArrayBuffer::jsclass) {
ArrayBuffer *abuf = ArrayBuffer::fromJSObject(other);
if (!abuf) {
// the arg isn't a real arraybuffer
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_TYPED_ARRAY_BAD_ARGS);
return false;
}
} else 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) {
@ -1062,9 +1039,13 @@ class TypedArrayTemplate
length = len;
data = abuf->offsetData(boffset);
} else {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_TYPED_ARRAY_BAD_ARGS);
return false;
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 true;

View File

@ -987,8 +987,7 @@ struct ClassExtension {
JSObjectOp outerObject;
JSObjectOp innerObject;
JSIteratorOp iteratorObject;
JSObjectOp wrappedObject; /* NB: infallible, null returns are
treated as the original object */
void *unused;
};
#define JS_NULL_CLASS_EXT {NULL,NULL,NULL,NULL,NULL}

View File

@ -99,7 +99,7 @@ class JS_FRIEND_API(JSWrapper) : public js::JSProxyHandler {
static JSObject *New(JSContext *cx, JSObject *obj, JSObject *proto, JSObject *parent,
JSWrapper *handler);
static inline JSObject *wrappedObject(JSObject *wrapper) {
static inline JSObject *wrappedObject(const JSObject *wrapper) {
return wrapper->getProxyPrivate().toObjectOrNull();
}

View File

@ -61,7 +61,7 @@
using namespace js;
using namespace js::mjit;
#if defined JS_POLYIC
#if defined(JS_POLYIC) || defined(JS_MONOIC)
using namespace js::mjit::ic;
#endif
@ -4298,13 +4298,6 @@ mjit::Compiler::jsop_instanceof()
if (!lhs->isTypeKnown())
isFalse = frame.testPrimitive(Assembler::Equal, lhs);
/* Quick test to avoid wrapped objects. */
masm.loadPtr(Address(obj, offsetof(JSObject, clasp)), temp);
masm.loadPtr(Address(temp, offsetof(Class, ext) +
offsetof(ClassExtension, wrappedObject)), temp);
j = masm.branchTestPtr(Assembler::NonZero, temp, temp);
stubcc.linkExit(j, Uses(3));
Address protoAddr(obj, offsetof(JSObject, proto));
Label loop = masm.label();

View File

@ -116,7 +116,7 @@ struct TraceICInfo {
bool hasSlowTraceHint : 1;
};
static const uint16 BAD_TRACEIC_INDEX = (uint16_t)-1;
static const uint16 BAD_TRACEIC_INDEX = (uint16)0xffff;
void JS_FASTCALL GetGlobalName(VMFrame &f, ic::MICInfo *ic);
void JS_FASTCALL SetGlobalName(VMFrame &f, ic::MICInfo *ic);
@ -135,7 +135,7 @@ struct EqualityICInfo {
bool generated : 1;
JSC::MacroAssembler::RegisterID tempReg : 5;
Assembler::Condition cond : 6;
Assembler::Condition cond;
};
JSBool JS_FASTCALL Equality(VMFrame &f, ic::EqualityICInfo *ic);

View File

@ -260,9 +260,9 @@ function test()
checkThrows(function() a.set(new Array(0x7fffffff)));
checkThrows(function() a.set([1,2,3], 2147483647));
checkThrows(function() a.set(ArrayBuffer.prototype));
checkThrows(function() a.set(UInt16Array.prototype));
checkThrows(function() a.set(Int32Array.prototype));
a.set(ArrayBuffer.prototype);
a.set(Int16Array.prototype);
a.set(Int32Array.prototype);
a.set([1,2,3]);
a.set([4,5,6], 3);
@ -305,12 +305,16 @@ function test()
a = new Uint8Array(0x100);
checkThrows(function() Uint32Array.prototype.slice.apply(a, [0, 0x100]));
checkThrows(function() new Int32Array(ArrayBuffer.prototype));
checkThrows(function() new Int32Array(Int32Array.prototype));
checkThrows(function() new Int32Array(Float64Array.prototype));
checkThrows(function() new Int32Array(ArrayBuffer));
checkThrows(function() new Int32Array(Int32Array));
checkThrows(function() new Int32Array(Float64Array));
// The prototypes are objects that don't have a length property, so they act
// like empty arrays.
check(function() new Int32Array(ArrayBuffer.prototype).length == 0);
check(function() new Int32Array(Int32Array.prototype).length == 0);
check(function() new Int32Array(Float64Array.prototype).length == 0);
// ArrayBuffer, Int32Array and Float64Array are native functions and have a .length
// checkThrows(function() new Int32Array(ArrayBuffer));
// checkThrows(function() new Int32Array(Int32Array));
// checkThrows(function() new Int32Array(Float64Array));
check(function() Int32Array.BYTES_PER_ELEMENT == 4);
check(function() (new Int32Array(4)).BYTES_PER_ELEMENT == 4);

View File

@ -192,6 +192,7 @@
<li><a href="about:license#sparkle">Sparkle License</a></li>
<li><a href="about:license#sunsoft">SunSoft License</a></li>
<li><a href="about:license#ucal">University of California License</a></li>
<li><a href="about:license#ucambridge">University of Cambridge License</a></li>
<li><a href="about:license#uszeged">University of Szeged License</a></li>
<li><a href="about:license#hunspell-en-US">US English Spellchecking Dictionary Licenses</a></li>
<li><a href="about:license#v8">V8 License</a></li>
@ -1949,7 +1950,7 @@ necessary. Here is a sample; alter the names:
<h1><a name="apple"></a>Apple License</h1>
<p class="correctme">This license applies to certain files in the directories <span class="path">js/src/assembler/assembler/</span>, <span class="path">js/src/assembler/wtf/</span>, and <span class="path">widget/src/cocoa</span>.</p>
<p class="correctme">This license applies to certain files in the directories <span class="path">js/src/assembler/assembler/</span>, <span class="path">js/src/assembler/wtf/</span>, <span class="path">js/src/yarr/wtf</span>, <span class="path">js/src/yarr/yarr</span>, and <span class="path">widget/src/cocoa</span>.</p>
<pre>
Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
@ -3220,6 +3221,43 @@ SUCH DAMAGE.
</pre>
<hr>
<h1><a name="ucambridge"></a>University of Cambridge License</h1>
<p class="correctme">This license applies to certain files in the directory <span class="path">js/src/yarr/pcre/</span>.</p>
<pre>
Copyright (c) 1997-2005 University of Cambridge. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the University of Cambridge nor the name of Apple
Inc. nor the names of their contributors may be used to endorse or
promote products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
</pre>
<hr>
<h1><a name="uszeged"></a>University of Szeged License</h1>