[JAEGER] Merge from fatval branch.

This commit is contained in:
David Anderson 2010-06-17 13:22:59 -07:00
commit 9c4e1303c3
23 changed files with 394 additions and 425 deletions

View File

@ -768,298 +768,3 @@ nsICanvasRenderingContextWebGL_VertexAttrib4fv(JSContext *cx, uintN argc, jsval
{
return helper_nsICanvasRenderingContextWebGL_VertexAttrib_x_fv(cx, argc, vp, 4);
}
#ifdef JS_TRACER
static inline jsval FASTCALL
helper_nsICanvasRenderingContextWebGL_Uniform_x_iv_tn(JSContext *cx, JSObject *obj, JSObject *locationobj,
JSObject *arg, int nElements)
{
XPC_QS_ASSERT_CONTEXT_OK(cx);
nsICanvasRenderingContextWebGL *self;
xpc_qsSelfRef selfref;
xpc_qsArgValArray<3> vp(cx);
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, &vp.array[0], nsnull)) {
js_SetTraceableNativeFailed(cx);
return JSVAL_VOID;
}
js::AutoValueRooter obj_tvr(cx);
nsIWebGLUniformLocation *location;
xpc_qsSelfRef location_selfref;
nsresult rv_convert_arg0
= xpc_qsUnwrapThis(cx, locationobj, nsnull, &location, &location_selfref.ptr, &vp.array[1], nsnull);
if (NS_FAILED(rv_convert_arg0)) {
js_SetTraceableNativeFailed(cx);
return JSVAL_VOID;
}
js::TypedArray *wa = 0;
if (helper_isInt32Array(arg)) {
wa = js::TypedArray::fromJSObject(arg);
} else if (JS_IsArrayObject(cx, arg)) {
JSObject *nobj = js_CreateTypedArrayWithArray(cx, js::TypedArray::TYPE_INT32, arg);
if (!nobj) {
// XXX this will likely return a strange error message if it goes wrong
js_SetTraceableNativeFailed(cx);
return JSVAL_VOID;
}
*obj_tvr.jsval_addr() = OBJECT_TO_JSVAL(nobj);
wa = js::TypedArray::fromJSObject(nobj);
} else {
xpc_qsThrowMethodFailedWithDetails(cx, NS_ERROR_FAILURE, "nsICanvasRenderingContextWebGL", "uniformNiv");
js_SetTraceableNativeFailed(cx);
return JSVAL_VOID;
}
nsresult rv;
if (nElements == 1) {
rv = self->Uniform1iv_array(location, wa);
} else if (nElements == 2) {
rv = self->Uniform2iv_array(location, wa);
} else if (nElements == 3) {
rv = self->Uniform3iv_array(location, wa);
} else if (nElements == 4) {
rv = self->Uniform4iv_array(location, wa);
}
if (NS_FAILED(rv)) {
xpc_qsThrowMethodFailedWithDetails(cx, rv, "nsICanvasRenderingContextWebGL", "uniformNiv");
js_SetTraceableNativeFailed(cx);
}
return JSVAL_VOID;
}
static inline jsval FASTCALL
helper_nsICanvasRenderingContextWebGL_Uniform_x_fv_tn(JSContext *cx, JSObject *obj, JSObject *locationobj,
JSObject *arg, int nElements)
{
XPC_QS_ASSERT_CONTEXT_OK(cx);
nsICanvasRenderingContextWebGL *self;
xpc_qsSelfRef selfref;
xpc_qsArgValArray<3> vp(cx);
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, &vp.array[0], nsnull)) {
js_SetTraceableNativeFailed(cx);
return JSVAL_VOID;
}
js::AutoValueRooter obj_tvr(cx);
nsIWebGLUniformLocation *location;
xpc_qsSelfRef location_selfref;
nsresult rv_convert_arg0
= xpc_qsUnwrapThis(cx, locationobj, nsnull, &location, &location_selfref.ptr, &vp.array[1], nsnull);
if (NS_FAILED(rv_convert_arg0)) {
js_SetTraceableNativeFailed(cx);
return JSVAL_VOID;
}
js::TypedArray *wa = 0;
if (helper_isFloat32Array(arg)) {
wa = js::TypedArray::fromJSObject(arg);
} else if (JS_IsArrayObject(cx, arg)) {
JSObject *nobj = js_CreateTypedArrayWithArray(cx, js::TypedArray::TYPE_FLOAT32, arg);
if (!nobj) {
// XXX this will likely return a strange error message if it goes wrong
js_SetTraceableNativeFailed(cx);
return JSVAL_VOID;
}
*obj_tvr.jsval_addr() = OBJECT_TO_JSVAL(nobj);
wa = js::TypedArray::fromJSObject(nobj);
} else {
xpc_qsThrowMethodFailedWithDetails(cx, NS_ERROR_FAILURE, "nsICanvasRenderingContextWebGL", "uniformNfv");
js_SetTraceableNativeFailed(cx);
return JSVAL_VOID;
}
nsresult rv;
if (nElements == 1) {
rv = self->Uniform1fv_array(location, wa);
} else if (nElements == 2) {
rv = self->Uniform2fv_array(location, wa);
} else if (nElements == 3) {
rv = self->Uniform3fv_array(location, wa);
} else if (nElements == 4) {
rv = self->Uniform4fv_array(location, wa);
}
if (NS_FAILED(rv)) {
xpc_qsThrowMethodFailedWithDetails(cx, rv, "nsICanvasRenderingContextWebGL", "uniformNfv");
js_SetTraceableNativeFailed(cx);
}
return JSVAL_VOID;
}
static inline jsval FASTCALL
helper_nsICanvasRenderingContextWebGL_UniformMatrix_x_fv_tn(JSContext *cx, JSObject *obj, JSObject *locationobj,
JSBool transpose, JSObject *arg, int nElements)
{
XPC_QS_ASSERT_CONTEXT_OK(cx);
nsICanvasRenderingContextWebGL *self;
xpc_qsSelfRef selfref;
xpc_qsArgValArray<4> vp(cx);
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, &vp.array[0], nsnull)) {
js_SetTraceableNativeFailed(cx);
return JSVAL_VOID;
}
js::AutoValueRooter obj_tvr(cx);
nsIWebGLUniformLocation *location;
xpc_qsSelfRef location_selfref;
nsresult rv_convert_arg0
= xpc_qsUnwrapThis(cx, locationobj, nsnull, &location, &location_selfref.ptr, &vp.array[1], nsnull);
if (NS_FAILED(rv_convert_arg0)) {
js_SetTraceableNativeFailed(cx);
return JSVAL_VOID;
}
js::TypedArray *wa = 0;
if (helper_isFloat32Array(arg)) {
wa = js::TypedArray::fromJSObject(arg);
} else if (JS_IsArrayObject(cx, arg)) {
JSObject *nobj = js_CreateTypedArrayWithArray(cx, js::TypedArray::TYPE_FLOAT32, arg);
if (!nobj) {
// XXX this will likely return a strange error message if it goes wrong
js_SetTraceableNativeFailed(cx);
return JSVAL_VOID;
}
*obj_tvr.jsval_addr() = OBJECT_TO_JSVAL(nobj);
wa = js::TypedArray::fromJSObject(nobj);
} else {
xpc_qsThrowMethodFailedWithDetails(cx, NS_ERROR_FAILURE, "nsICanvasRenderingContextWebGL", "uniformMatrixNfv");
js_SetTraceableNativeFailed(cx);
return JSVAL_VOID;
}
nsresult rv;
if (nElements == 2) {
rv = self->UniformMatrix2fv_array(location, transpose, wa);
} else if (nElements == 3) {
rv = self->UniformMatrix3fv_array(location, transpose, wa);
} else if (nElements == 4) {
rv = self->UniformMatrix4fv_array(location, transpose, wa);
}
if (NS_FAILED(rv)) {
xpc_qsThrowMethodFailedWithDetails(cx, rv, "nsICanvasRenderingContextWebGL", "uniformMatrixNfv");
js_SetTraceableNativeFailed(cx);
}
return JSVAL_VOID;
}
static jsval FASTCALL
nsICanvasRenderingContextWebGL_Uniform1iv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg)
{
return helper_nsICanvasRenderingContextWebGL_Uniform_x_iv_tn(cx, obj, location, arg, 1);
}
JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform1iv,
(4, (static, JSVAL_FAIL, nsICanvasRenderingContextWebGL_Uniform1iv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACC_STORE_ANY)))
static jsval FASTCALL
nsICanvasRenderingContextWebGL_Uniform2iv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg)
{
return helper_nsICanvasRenderingContextWebGL_Uniform_x_iv_tn(cx, obj, location, arg, 2);
}
JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform2iv,
(4, (static, JSVAL_FAIL, nsICanvasRenderingContextWebGL_Uniform2iv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACC_STORE_ANY)))
static jsval FASTCALL
nsICanvasRenderingContextWebGL_Uniform3iv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg)
{
return helper_nsICanvasRenderingContextWebGL_Uniform_x_iv_tn(cx, obj, location, arg, 3);
}
JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform3iv,
(4, (static, JSVAL_FAIL, nsICanvasRenderingContextWebGL_Uniform3iv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACC_STORE_ANY)))
static jsval FASTCALL
nsICanvasRenderingContextWebGL_Uniform4iv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg)
{
return helper_nsICanvasRenderingContextWebGL_Uniform_x_iv_tn(cx, obj, location, arg, 4);
}
JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform4iv,
(4, (static, JSVAL_FAIL, nsICanvasRenderingContextWebGL_Uniform4iv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACC_STORE_ANY)))
static jsval FASTCALL
nsICanvasRenderingContextWebGL_Uniform1fv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg)
{
return helper_nsICanvasRenderingContextWebGL_Uniform_x_fv_tn(cx, obj, location, arg, 1);
}
JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform1fv,
(4, (static, JSVAL_FAIL, nsICanvasRenderingContextWebGL_Uniform1fv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACC_STORE_ANY)))
static jsval FASTCALL
nsICanvasRenderingContextWebGL_Uniform2fv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg)
{
return helper_nsICanvasRenderingContextWebGL_Uniform_x_fv_tn(cx, obj, location, arg, 2);
}
JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform2fv,
(4, (static, JSVAL_FAIL, nsICanvasRenderingContextWebGL_Uniform2fv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACC_STORE_ANY)))
static jsval FASTCALL
nsICanvasRenderingContextWebGL_Uniform3fv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg)
{
return helper_nsICanvasRenderingContextWebGL_Uniform_x_fv_tn(cx, obj, location, arg, 3);
}
JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform3fv,
(4, (static, JSVAL_FAIL, nsICanvasRenderingContextWebGL_Uniform3fv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACC_STORE_ANY)))
static jsval FASTCALL
nsICanvasRenderingContextWebGL_Uniform4fv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg)
{
return helper_nsICanvasRenderingContextWebGL_Uniform_x_fv_tn(cx, obj, location, arg, 4);
}
JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform4fv,
(4, (static, JSVAL_FAIL, nsICanvasRenderingContextWebGL_Uniform4fv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACC_STORE_ANY)))
static jsval FASTCALL
nsICanvasRenderingContextWebGL_UniformMatrix2fv_tn(JSContext *cx, JSObject *obj, JSObject *loc, JSBool transpose, JSObject *arg)
{
return helper_nsICanvasRenderingContextWebGL_UniformMatrix_x_fv_tn(cx, obj, loc, transpose, arg, 2);
}
JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_UniformMatrix2fv,
(5, (static, JSVAL_FAIL, nsICanvasRenderingContextWebGL_UniformMatrix2fv_tn, CONTEXT, THIS, OBJECT, BOOL, OBJECT, 0, nanojit::ACC_STORE_ANY)))
static jsval FASTCALL
nsICanvasRenderingContextWebGL_UniformMatrix3fv_tn(JSContext *cx, JSObject *obj, JSObject *loc, JSBool transpose, JSObject *arg)
{
return helper_nsICanvasRenderingContextWebGL_UniformMatrix_x_fv_tn(cx, obj, loc, transpose, arg, 3);
}
JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_UniformMatrix3fv,
(5, (static, JSVAL_FAIL, nsICanvasRenderingContextWebGL_UniformMatrix3fv_tn, CONTEXT, THIS, OBJECT, BOOL, OBJECT, 0, nanojit::ACC_STORE_ANY)))
static jsval FASTCALL
nsICanvasRenderingContextWebGL_UniformMatrix4fv_tn(JSContext *cx, JSObject *obj, JSObject *loc, JSBool transpose, JSObject *arg)
{
return helper_nsICanvasRenderingContextWebGL_UniformMatrix_x_fv_tn(cx, obj, loc, transpose, arg, 4);
}
JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_UniformMatrix4fv,
(5, (static, JSVAL_FAIL, nsICanvasRenderingContextWebGL_UniformMatrix4fv_tn, CONTEXT, THIS, OBJECT, BOOL, OBJECT, 0, nanojit::ACC_STORE_ANY)))
#endif /* JS_TRACER */

View File

@ -9119,7 +9119,6 @@ nsHTMLDocumentSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
// If we have (or just created) a helper, pass the resolve flags
// to the helper as its private data.
// TODO: fix
JS_ASSERT(false && "Relying on dirty private = int details");
if (helper && !::JS_SetPrivate(cx, helper, FlagsToPrivate(flags))) {
nsDOMClassInfo::ThrowJSException(cx, NS_ERROR_UNEXPECTED);

View File

@ -268,6 +268,12 @@ JSVAL_IS_UNDERLYING_TYPE_OF_PRIVATE(jsval v)
return JSVAL_IS_UNDERLYING_TYPE_OF_PRIVATE_IMPL(l);
}
static JS_ALWAYS_INLINE JSBool
JSVAL_MAY_BE_PRIVATE(jsval v)
{
return JSVAL_IS_UNDERLYING_TYPE_OF_PRIVATE(v);
}
/* Lock and unlock the GC thing held by a jsval. */
#define JSVAL_LOCK(cx,v) (JSVAL_IS_GCTHING(v) \
? JS_LockGCThing(cx, JSVAL_TO_GCTHING(v)) \
@ -3031,6 +3037,7 @@ class Value
* uses of public jsval members in jsapi.h/jspubtd.h.
*/
friend class PrimitiveValue;
friend jsdouble UnboxDoubleHelper(uint32 mask, uint32 payload);
protected:
/* Type masks */

View File

@ -353,8 +353,9 @@ JSObject::resizeDenseArrayElements(JSContext *cx, uint32 oldcap, uint32 newcap,
setDenseArrayCapacity(newcap);
if (initializeAllSlots) {
for (uint32 i = oldcap; i < newcap; i++)
setDenseArrayElement(i, JS_ARRAY_HOLE);
Value *base = addressOfDenseArrayElement(0);
for (Value *vp = base + oldcap, *end = base + newcap; vp < end; ++vp)
vp->setMagic(JS_ARRAY_HOLE);
}
return true;
@ -900,7 +901,7 @@ js_PrototypeHasIndexedProperties(JSContext *cx, JSObject *obj)
#ifdef JS_TRACER
static inline JSBool FASTCALL
static JS_ALWAYS_INLINE JSBool FASTCALL
dense_grow(JSContext* cx, JSObject* obj, jsint i, const Value &v)
{
/*

View File

@ -103,13 +103,29 @@ js_imod(int32 a, int32 b)
}
JS_DEFINE_CALLINFO_2(extern, INT32, js_imod, INT32, INT32, 1, ACC_NONE)
namespace js {
jsdouble JS_ALWAYS_INLINE
UnboxDoubleHelper(uint32 mask, uint32 payload)
{
if (mask == JSVAL_MASK32_INT32) {
return int32(payload);
} else {
Value v;
v.data.s.u.mask32 = mask;
v.data.s.payload.u32 = payload;
return v.asDouble();
}
}
}
jsdouble FASTCALL
js_UnboxDouble(Value *v)
js_UnboxDouble(uint32 mask, uint32 payload)
{
return v->asNumber();
return UnboxDoubleHelper(mask, payload);
}
JS_DEFINE_CALLINFO_1(extern, DOUBLE, js_UnboxDouble, VALUEPTR, 1, ACC_NONE)
JS_DEFINE_CALLINFO_2(extern, DOUBLE, js_UnboxDouble, UINT32, UINT32, 1, ACC_NONE)
int32 FASTCALL
js_UnboxInt32(Value *v)
@ -259,7 +275,11 @@ HasProperty(JSContext* cx, JSObject* obj, jsid id)
JSBool FASTCALL
js_HasNamedProperty(JSContext* cx, JSObject* obj, JSString* idstr)
{
return HasProperty(cx, obj, ATOM_TO_JSID(idstr));
jsid id;
if (!js_ValueToStringId(cx, StringTag(idstr), &id))
return JS_NEITHER;
return HasProperty(cx, obj, id);
}
JS_DEFINE_CALLINFO_3(extern, BOOL, js_HasNamedProperty, CONTEXT, OBJECT, STRING, 0, ACC_STORE_ANY)

View File

@ -48,7 +48,6 @@
#include <stdlib.h>
#include <string.h>
#define __STDC_LIMIT_MACROS
#include "jsstdint.h"
#include "jstypes.h"

View File

@ -877,7 +877,7 @@ js_NumberValueToCharBuffer(JSContext *cx, const Value &v, JSCharBuffer &cb)
size_t cstrlen = strlen(cstr);
JS_ASSERT(cstrlen < arrSize);
size_t sizeBefore = cb.length();
if (!cb.growBy(cstrlen))
if (!cb.growByUninitialized(cstrlen))
return JS_FALSE;
jschar *appendBegin = cb.begin() + sizeBefore;
#ifdef DEBUG

View File

@ -162,10 +162,11 @@ typedef struct JSCompartment JSCompartment;
* TODO: explain boxing strategy
*/
#if defined(__cplusplus) || !defined(_MSC_VER)
typedef enum JSValueMask16
#if defined(_MSC_VER)
# if defined(_MSC_VER)
: uint16
#endif
# endif
{
JSVAL_MASK16_NULL = (uint16)0x0001,
JSVAL_MASK16_UNDEFINED = (uint16)0x0002,
@ -188,10 +189,30 @@ typedef enum JSValueMask16
*/
JSVAL_NANBOX_PATTERN = ((uint16)0xFFFF)
}
#if defined(__GNUC__)
# if defined(__GNUC__)
__attribute__((packed))
#endif
# endif
JSValueMask16;
#else /* defined(__cplusplus) || !defined(_MSC_VER) */
// We need this C API for MSVC, because MSVC doesn't allow us to
// make a 16-bit enum in C.
typedef uint16 JSValueMask16;
#define JSVAL_MASK16_NULL ((uint16)0x0001)
#define JSVAL_MASK16_UNDEFINED ((uint16)0x0002)
#define JSVAL_MASK16_INT32 ((uint16)0x0004)
#define JSVAL_MASK16_STRING ((uint16)0x0008)
#define JSVAL_MASK16_NONFUNOBJ ((uint16)0x0010)
#define JSVAL_MASK16_FUNOBJ ((uint16)0x0020)
#define JSVAL_MASK16_BOOLEAN ((uint16)0x0040)
#define JSVAL_MASK16_MAGIC ((uint16)0x0080)
#define JSVAL_MASK16_SINGLETON (JSVAL_MASK16_NULL | JSVAL_MASK16_UNDEFINED)
#define JSVAL_MASK16_OBJECT (JSVAL_MASK16_NONFUNOBJ | JSVAL_MASK16_FUNOBJ)
#define JSVAL_MASK16_OBJORNULL (JSVAL_MASK16_OBJECT | JSVAL_MASK16_NULL)
#define JSVAL_MASK16_GCTHING (JSVAL_MASK16_OBJECT | JSVAL_MASK16_STRING)
#define JSVAL_NANBOX_PATTERN ((uint16)0xFFFF)
#endif /* defined(__cplusplus) || !defined(_MSC_VER) */
#define JSVAL_MASK32_CLEAR ((uint32)0xFFFF0000)
@ -1116,15 +1137,15 @@ static inline JSEqualityOp Jsvalify(EqualityOp f); /* Same type as HasI
} /* namespace js */
typedef js::Class JSFunctionClassType;
extern "C" JS_FRIEND_DATA(JSFunctionClassType) js_FunctionClass;
#else /* !defined(__cplusplus) */
typedef JSClass JSFunctionClassType;
extern JS_FRIEND_DATA(JSFunctionClassType) js_FunctionClass;
#endif /* __cplusplus */
extern JS_FRIEND_DATA(JSFunctionClassType) js_FunctionClass;
typedef struct JSPretendObject
{
void *_;

View File

@ -731,17 +731,8 @@ TraceRecorder::slurpInt32Slot(LIns* addr_ins, ptrdiff_t offset, Value* vp, VMSid
{
LIns *mask_ins = lir->insLoad(LIR_ldi, addr_ins, offset + offsetof(jsval_layout, s.u.mask32),
ACC_OTHER);
guard(false,
lir->insEqI_0(lir->ins2(LIR_ori,
lir->ins2(LIR_eqi, mask_ins, INS_CONST(JSVAL_MASK32_INT32)),
lir->ins2(LIR_ltui, mask_ins, INS_CONST(JSVAL_MASK32_CLEAR)))),
exit);
LIns* space = lir->insAlloc(sizeof(int32));
LIns* args[] = { space, lir->ins2(LIR_addp, addr_ins, INS_CONST(offset)) };
LIns* result = lir->insCall(&js_TryUnboxInt32_ci, args);
guard(false, lir->insEqI_0(result), exit);
LIns* int32_ins = lir->insLoad(LIR_ldi, space, 0, ACC_OTHER);
return int32_ins;
guard(true, lir->ins2(LIR_eqi, mask_ins, INS_CONST(JSVAL_MASK32_INT32)), exit);
return lir->insLoad(LIR_ldi, addr_ins, offset + offsetof(jsval_layout, s.payload), ACC_OTHER);
}
JS_REQUIRES_STACK LIns*
@ -749,13 +740,8 @@ TraceRecorder::slurpDoubleSlot(LIns* addr_ins, ptrdiff_t offset, Value* vp, VMSi
{
LIns *mask_ins = lir->insLoad(LIR_ldi, addr_ins, offset + offsetof(jsval_layout, s.u.mask32),
ACC_OTHER);
guard(false,
lir->insEqI_0(lir->ins2(LIR_ori,
lir->ins2(LIR_eqi, mask_ins, INS_CONST(JSVAL_MASK32_INT32)),
lir->ins2(LIR_ltui, mask_ins, INS_CONST(JSVAL_MASK32_CLEAR)))),
exit);
LIns* args[] = { lir->ins2(LIR_addp, addr_ins, INS_CONST(offset)) };
return lir->insCall(&js_UnboxDouble_ci, args);
guard(true, lir->ins2(LIR_ltui, mask_ins, INS_CONST(JSVAL_MASK32_CLEAR)), exit);
return lir->insLoad(LIR_ldd, addr_ins, offset + offsetof(jsval_layout, s.payload), ACC_OTHER);
}
JS_REQUIRES_STACK LIns*

View File

@ -1901,7 +1901,7 @@ ReplaceCallback(JSContext *cx, size_t count, void *p)
return false;
size_t growth = leftlen + replen;
if (!rdata.cb.growBy(growth))
if (!rdata.cb.growByUninitialized(growth))
return false;
jschar *chars = rdata.cb.begin() + rdata.index;

View File

@ -5844,7 +5844,7 @@ JS_REQUIRES_STACK MonitorResult
TraceRecorder::recordLoopEdge(JSContext* cx, TraceRecorder* r, uintN& inlineCallCount)
{
#ifdef JS_THREADSAFE
if (cx->fp->scopeChain->getGlobal()->scope()->title.ownercx != cx) {
if (cx->fp->scopeChainObj()->getGlobal()->scope()->title.ownercx != cx) {
AbortRecording(cx, "Global object not owned by this context");
return MONITOR_NOT_RECORDING; /* we stay away from shared global objects */
}
@ -8226,6 +8226,13 @@ TraceRecorder::d2i(LIns* f, bool resultCanBeImpreciseIfFractional)
}
if (f->isCall()) {
const CallInfo* ci = f->callInfo();
if (ci == &js_UnboxDouble_ci) {
LIns *boxed = lir->insAlloc(sizeof(Value));
lir->insStore(fcallarg(f, 1), boxed, 0, ACC_OTHER);
lir->insStore(fcallarg(f, 0), boxed, sizeof(uint32), ACC_OTHER);
LIns* args[] = { boxed };
return lir->insCall(&js_UnboxInt32_ci, args);
}
if (ci == &js_StringToNumber_ci) {
LIns* args[] = { fcallarg(f, 1), fcallarg(f, 0) };
return lir->insCall(&js_StringToInt32_ci, args);
@ -9350,23 +9357,35 @@ TraceRecorder::stobj_get_slot(LIns* obj_ins, unsigned slot, LIns*& dslots_ins)
}
JS_REQUIRES_STACK LIns*
TraceRecorder::unbox_value(const Value &v, LIns *vaddr_ins, ptrdiff_t offset, VMSideExit *exit)
TraceRecorder::unbox_value(const Value &v, LIns *vaddr_ins, ptrdiff_t offset, VMSideExit *exit,
bool force_double)
{
AccSet accSet = vaddr_ins == lirbuf->sp ? ACC_STACK : ACC_OTHER;
LIns *mask_ins = lir->insLoad(LIR_ldi, vaddr_ins, offset + offsetof(jsval_layout, s.u.mask32),
accSet);
if (v.isNumber()) {
if (v.isNumber() && force_double) {
guard(false,
lir->insEqI_0(lir->ins2(LIR_ori,
lir->ins2(LIR_eqi, mask_ins, INS_CONST(JSVAL_MASK32_INT32)),
lir->ins2(LIR_ltui, mask_ins, INS_CONST(JSVAL_MASK32_CLEAR)))),
exit);
LIns* args[] = { lir->ins2(LIR_addp, vaddr_ins, INS_CONST(offset)) };
LIns *val_ins = lir->insLoad(LIR_ldi, vaddr_ins, offset + offsetof(jsval_layout, s.payload),
accSet);
LIns* args[] = { val_ins, mask_ins };
return lir->insCall(&js_UnboxDouble_ci, args);
}
LIns *val_ins = lir->insLoad(LIR_ldi, vaddr_ins, offset + offsetof(jsval_layout, s.payload),
accSet);
if (v.isInt32()) {
guard(true, lir->ins2(LIR_eqi, mask_ins, INS_CONST(JSVAL_MASK32_INT32)), exit);
return i2d(lir->insLoad(LIR_ldi, vaddr_ins, offset + offsetof(jsval_layout, s.payload), accSet));
}
if (v.isDouble()) {
guard(true, lir->ins2(LIR_ltui, mask_ins, INS_CONST(JSVAL_MASK32_CLEAR)), exit);
return lir->insLoad(LIR_ldd, vaddr_ins, offset + offsetof(jsval_layout, s.payload), accSet);
}
LIns *val_ins = NULL;
uint32 mask;
if (v.isUndefined()) {
mask = JSVAL_MASK32_UNDEFINED;
@ -9387,6 +9406,9 @@ TraceRecorder::unbox_value(const Value &v, LIns *vaddr_ins, ptrdiff_t offset, VM
} else {
JS_NOT_REACHED("bad type");
}
if (!val_ins)
val_ins = lir->insLoad(LIR_ldi, vaddr_ins, offset + offsetof(jsval_layout, s.payload),
accSet);
guard(true, lir->ins2(LIR_eqi, mask_ins, INS_CONST(mask)), exit);
return val_ins;
@ -12374,7 +12396,13 @@ TraceRecorder::setElem(int lval_spindex, int idx_spindex, int v_spindex)
LIns* res_ins;
LIns* args[] = { NULL, idx_ins, obj_ins, cx_ins };
if (v.isNumber()) {
if (isPromoteInt(v_ins)) {
if (fcallinfo(v_ins) == &js_UnboxDouble_ci) {
LIns *boxed = lir->insAlloc(sizeof(Value));
lir->insStore(fcallarg(v_ins, 1), boxed, 0, ACC_OTHER);
lir->insStore(fcallarg(v_ins, 0), boxed, sizeof(uint32), ACC_OTHER);
args[0] = boxed;
res_ins = lir->insCall(&js_Array_dense_setelem_ci, args);
} else if (isPromoteInt(v_ins)) {
args[0] = demote(lir, v_ins);
res_ins = lir->insCall(&js_Array_dense_setelem_int_ci, args);
} else {
@ -13239,7 +13267,7 @@ TraceRecorder::denseArrayElement(Value& oval, Value& ival, Value*& vp, LIns*& v_
JS_ASSERT(sizeof(Value) == 8); // The |3| in the following statement requires this.
addr_ins = lir->ins2(LIR_addp, dslots_ins,
lir->ins2ImmI(LIR_lshp, pidx_ins, 3));
v_ins = unbox_value(*vp, addr_ins, 0, exit);
v_ins = unbox_value(*vp, addr_ins, 0, exit, true);
/* Don't let the hole value escape. Turn it into an undefined. */
if (vp->isMagic()) {

View File

@ -1328,7 +1328,8 @@ class TraceRecorder
int v_spindex);
JS_REQUIRES_STACK nanojit::LIns* unbox_value(const Value &v, nanojit::LIns *vaddr_ins,
ptrdiff_t offset, VMSideExit *exit);
ptrdiff_t offset, VMSideExit *exit,
bool force_double=false);
JS_REQUIRES_STACK nanojit::LIns* unbox_value_load(const Value &v, nanojit::LIns *vload_ins,
VMSideExit *exit);
JS_REQUIRES_STACK nanojit::LIns* unbox_int(const Value &v, nanojit::LIns *vaddr_ins,

View File

@ -190,6 +190,8 @@ class Vector : AllocPolicy
bool growHeapStorageBy(size_t lengthInc);
bool convertToHeapStorage(size_t lengthInc);
template <bool InitNewElems> inline bool growByImpl(size_t inc);
/* magic constants */
static const int sMaxInlineBytes = 1024;
@ -371,6 +373,9 @@ class Vector : AllocPolicy
/* Call shrinkBy or growBy based on whether newSize > length(). */
bool resize(size_t newLength);
/* Leave new elements as uninitialized memory. */
bool growByUninitialized(size_t incr);
void clear();
bool append(const T &t);
@ -546,15 +551,17 @@ Vector<T,N,AP>::shrinkBy(size_t incr)
}
template <class T, size_t N, class AP>
inline bool
Vector<T,N,AP>::growBy(size_t incr)
template <bool InitNewElems>
JS_ALWAYS_INLINE bool
Vector<T,N,AP>::growByImpl(size_t incr)
{
ReentrancyGuard g(*this);
if (usingInlineStorage()) {
size_t freespace = sInlineCapacity - inlineLength();
if (incr <= freespace) {
T *newend = inlineEnd() + incr;
Impl::initialize(inlineEnd(), newend);
if (InitNewElems)
Impl::initialize(inlineEnd(), newend);
inlineLength() += incr;
JS_ASSERT(usingInlineStorage());
return true;
@ -574,11 +581,26 @@ Vector<T,N,AP>::growBy(size_t incr)
/* We are !usingInlineStorage(). Initialize new elements. */
JS_ASSERT(heapCapacity() - heapLength() >= incr);
T *newend = heapEnd() + incr;
Impl::initialize(heapEnd(), newend);
if (InitNewElems)
Impl::initialize(heapEnd(), newend);
heapEnd() = newend;
return true;
}
template <class T, size_t N, class AP>
inline bool
Vector<T,N,AP>::growBy(size_t incr)
{
return growByImpl<true>(incr);
}
template <class T, size_t N, class AP>
inline bool
Vector<T,N,AP>::growByUninitialized(size_t incr)
{
return growByImpl<false>(incr);
}
template <class T, size_t N, class AP>
inline bool
Vector<T,N,AP>::resize(size_t newLength)

View File

@ -0,0 +1,3 @@
// don't crash or assert
+Function("switch(\"\"){case 1:case 8:}");

View File

@ -0,0 +1,12 @@
// Don't crash
function f(o, s) {
var k = s.substr(0, 1);
var c;
for (var i = 0; i < 10; ++i) {
c = k in o;
}
return c;
}
assertEq(f({ a: 66 }, 'abc'), true);

View File

@ -159,7 +159,10 @@ DEFINES += \
$(addprefix -D,$(filter AVMPLUS%,$(CONFIG))) \
$(NULL)
ENABLE_TRACEABLE_FLAGS = --enable-traceables
# Disable traceable natives because (a) many of them return jsvals, which is
# hard to support now, and (b) we can call the basic versions from trace now
# anyway.
ENABLE_TRACEABLE_FLAGS =
endif # ENABLE_JIT

View File

@ -309,7 +309,7 @@ JSBool XPCDispConvert::JSToCOM(XPCCallContext& ccx,
case VT_R8:
{
varDest->vt = VT_R8;
varDest->dblVal = *JSVAL_TO_DOUBLE(src);
varDest->dblVal = JSVAL_TO_DOUBLE(src);
}
break;
case VT_EMPTY:

View File

@ -366,7 +366,7 @@ JSBool XPCDispInterface::Member::GetValue(XPCCallContext& ccx,
return JS_FALSE;
// Store ourselves and our native interface within the JSObject
if(!JS_SetReservedSlot(ccx, funobj, 0, PRIVATE_TO_JSVAL(this)))
if(!JS_SetReservedSlot(ccx, funobj, 0, PRIVATE_TO_JSVAL((void *) this)))
return JS_FALSE;
if(!JS_SetReservedSlot(ccx, funobj, 1, PRIVATE_TO_JSVAL(iface)))

View File

@ -386,7 +386,7 @@ STDMETHODIMP XPCDispatchTearOff::Invoke(DISPID dispIdMember, REFIID riid,
goto pre_call_clean_up;
}
sp = stackbase = args.getvp();
sp = stackbase = Jsvalify(args.getvp());
// this is a function call, so push function and 'this'
*sp++ = fval;

View File

@ -2804,7 +2804,38 @@ JS_EXPORT_API(void) DumpJSObject(JSObject* obj)
JS_EXPORT_API(void) DumpJSValue(jsval val)
{
js::DumpValue(js::Valueify(val));
printf("Dumping 0x%p.\n", (void *) val);
if(JSVAL_IS_NULL(val)) {
printf("Value is null\n");
}
else if(JSVAL_IS_OBJECT(val) || JSVAL_IS_NULL(val)) {
printf("Value is an object\n");
JSObject* obj = JSVAL_TO_OBJECT(val);
DumpJSObject(obj);
}
else if(JSVAL_IS_NUMBER(val)) {
printf("Value is a number: ");
if(JSVAL_IS_INT(val))
printf("Integer %i\n", JSVAL_TO_INT(val));
else if(JSVAL_IS_DOUBLE(val))
printf("Floating-point value %f\n", JSVAL_TO_DOUBLE(val));
}
else if(JSVAL_IS_STRING(val)) {
printf("Value is a string: ");
JSString* string = JSVAL_TO_STRING(val);
char* bytes = JS_GetStringBytes(string);
printf("<%s>\n", bytes);
}
else if(JSVAL_IS_BOOLEAN(val)) {
printf("Value is boolean: ");
printf(JSVAL_TO_BOOLEAN(val) ? "true" : "false");
}
else if(JSVAL_IS_VOID(val)) {
printf("Value is undefined\n");
}
else {
printf("No idea what this value is.\n");
}
}
JS_END_EXTERN_C

View File

@ -197,7 +197,7 @@ static JSClass sNPObjectJSWrapperClass =
typedef struct NPObjectMemberPrivate {
JSObject *npobjWrapper;
jsval fieldValue;
jsval methodName;
NPIdentifier methodName;
NPP npp;
} NPObjectMemberPrivate;
@ -598,25 +598,23 @@ nsJSObjWrapper::NP_Invalidate(NPObject *npobj)
}
static JSBool
GetProperty(JSContext *cx, JSObject *obj, NPIdentifier identifier, jsval *rval)
GetProperty(JSContext *cx, JSObject *obj, NPIdentifier id, jsval *rval)
{
jsval id = (jsval)identifier;
if (JSVAL_IS_STRING(id)) {
JSString *str = JSVAL_TO_STRING(id);
if (NPIdentifierIsString(id)) {
JSString *str = NPIdentifierToString(id);
return ::JS_GetUCProperty(cx, obj, ::JS_GetStringChars(str),
::JS_GetStringLength(str), rval);
}
NS_ASSERTION(JSVAL_IS_INT(id), "id must be either string or int!\n");
NS_ASSERTION(NPIdentifierIsInt(id), "id must be either string or int!\n");
return ::JS_GetElement(cx, obj, JSVAL_TO_INT(id), rval);
return ::JS_GetElement(cx, obj, NPIdentifierToInt(id), rval);
}
// static
bool
nsJSObjWrapper::NP_HasMethod(NPObject *npobj, NPIdentifier identifier)
nsJSObjWrapper::NP_HasMethod(NPObject *npobj, NPIdentifier id)
{
NPP npp = NPPStack::Peek();
JSContext *cx = GetJSContext(npp);
@ -639,7 +637,7 @@ nsJSObjWrapper::NP_HasMethod(NPObject *npobj, NPIdentifier identifier)
AutoJSExceptionReporter reporter(cx);
jsval v;
JSBool ok = GetProperty(cx, npjsobj->mJSObj, identifier, &v);
JSBool ok = GetProperty(cx, npjsobj->mJSObj, id, &v);
return ok && !JSVAL_IS_PRIMITIVE(v) &&
::JS_ObjectIsFunction(cx, JSVAL_TO_OBJECT(v));
@ -672,7 +670,7 @@ doInvoke(NPObject *npobj, NPIdentifier method, const NPVariant *args,
JSAutoRequest ar(cx);
AutoJSExceptionReporter reporter(cx);
if ((jsval)method != JSVAL_VOID) {
if (method != NPIdentifier_VOID) {
if (!GetProperty(cx, npjsobj->mJSObj, method, &fv) ||
::JS_TypeOfValue(cx, fv) != JSTYPE_FUNCTION) {
return PR_FALSE;
@ -742,7 +740,7 @@ nsJSObjWrapper::NP_Invoke(NPObject *npobj, NPIdentifier method,
const NPVariant *args, uint32_t argCount,
NPVariant *result)
{
if ((jsval)method == JSVAL_VOID) {
if (method == NPIdentifier_VOID) {
return PR_FALSE;
}
@ -754,13 +752,13 @@ bool
nsJSObjWrapper::NP_InvokeDefault(NPObject *npobj, const NPVariant *args,
uint32_t argCount, NPVariant *result)
{
return doInvoke(npobj, (NPIdentifier)JSVAL_VOID, args, argCount, PR_FALSE,
return doInvoke(npobj, NPIdentifier_VOID, args, argCount, PR_FALSE,
result);
}
// static
bool
nsJSObjWrapper::NP_HasProperty(NPObject *npobj, NPIdentifier identifier)
nsJSObjWrapper::NP_HasProperty(NPObject *npobj, NPIdentifier id)
{
NPP npp = NPPStack::Peek();
JSContext *cx = GetJSContext(npp);
@ -777,22 +775,21 @@ nsJSObjWrapper::NP_HasProperty(NPObject *npobj, NPIdentifier identifier)
}
nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj;
jsval id = (jsval)identifier;
JSBool found, ok = JS_FALSE;
AutoCXPusher pusher(cx);
JSAutoRequest ar(cx);
AutoJSExceptionReporter reporter(cx);
if (JSVAL_IS_STRING(id)) {
JSString *str = JSVAL_TO_STRING(id);
if (NPIdentifierIsString(id)) {
JSString *str = NPIdentifierToString(id);
ok = ::JS_HasUCProperty(cx, npjsobj->mJSObj, ::JS_GetStringChars(str),
::JS_GetStringLength(str), &found);
} else {
NS_ASSERTION(JSVAL_IS_INT(id), "id must be either string or int!\n");
NS_ASSERTION(NPIdentifierIsInt(id), "id must be either string or int!\n");
ok = ::JS_HasElement(cx, npjsobj->mJSObj, JSVAL_TO_INT(id), &found);
ok = ::JS_HasElement(cx, npjsobj->mJSObj, NPIdentifierToInt(id), &found);
}
return ok && found;
@ -800,7 +797,7 @@ nsJSObjWrapper::NP_HasProperty(NPObject *npobj, NPIdentifier identifier)
// static
bool
nsJSObjWrapper::NP_GetProperty(NPObject *npobj, NPIdentifier identifier,
nsJSObjWrapper::NP_GetProperty(NPObject *npobj, NPIdentifier id,
NPVariant *result)
{
NPP npp = NPPStack::Peek();
@ -824,13 +821,13 @@ nsJSObjWrapper::NP_GetProperty(NPObject *npobj, NPIdentifier identifier,
AutoJSExceptionReporter reporter(cx);
jsval v;
return (GetProperty(cx, npjsobj->mJSObj, identifier, &v) &&
return (GetProperty(cx, npjsobj->mJSObj, id, &v) &&
JSValToNPVariant(npp, cx, v, result));
}
// static
bool
nsJSObjWrapper::NP_SetProperty(NPObject *npobj, NPIdentifier identifier,
nsJSObjWrapper::NP_SetProperty(NPObject *npobj, NPIdentifier id,
const NPVariant *value)
{
NPP npp = NPPStack::Peek();
@ -848,7 +845,6 @@ nsJSObjWrapper::NP_SetProperty(NPObject *npobj, NPIdentifier identifier,
}
nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj;
jsval id = (jsval)identifier;
JSBool ok = JS_FALSE;
AutoCXPusher pusher(cx);
@ -858,15 +854,15 @@ nsJSObjWrapper::NP_SetProperty(NPObject *npobj, NPIdentifier identifier,
jsval v = NPVariantToJSVal(npp, cx, value);
js::AutoValueRooter tvr(cx, js::Valueify(v));
if (JSVAL_IS_STRING(id)) {
JSString *str = JSVAL_TO_STRING(id);
if (NPIdentifierIsString(id)) {
JSString *str = NPIdentifierToString(id);
ok = ::JS_SetUCProperty(cx, npjsobj->mJSObj, ::JS_GetStringChars(str),
::JS_GetStringLength(str), &v);
} else {
NS_ASSERTION(JSVAL_IS_INT(id), "id must be either string or int!\n");
NS_ASSERTION(NPIdentifierIsInt(id), "id must be either string or int!\n");
ok = ::JS_SetElement(cx, npjsobj->mJSObj, JSVAL_TO_INT(id), &v);
ok = ::JS_SetElement(cx, npjsobj->mJSObj, NPIdentifierToInt(id), &v);
}
// return ok == JS_TRUE to quiet down compiler warning, even if
@ -876,7 +872,7 @@ nsJSObjWrapper::NP_SetProperty(NPObject *npobj, NPIdentifier identifier,
// static
bool
nsJSObjWrapper::NP_RemoveProperty(NPObject *npobj, NPIdentifier identifier)
nsJSObjWrapper::NP_RemoveProperty(NPObject *npobj, NPIdentifier id)
{
NPP npp = NPPStack::Peek();
JSContext *cx = GetJSContext(npp);
@ -893,7 +889,6 @@ nsJSObjWrapper::NP_RemoveProperty(NPObject *npobj, NPIdentifier identifier)
}
nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj;
jsval id = (jsval)identifier;
JSBool ok = JS_FALSE;
AutoCXPusher pusher(cx);
@ -901,8 +896,8 @@ nsJSObjWrapper::NP_RemoveProperty(NPObject *npobj, NPIdentifier identifier)
AutoJSExceptionReporter reporter(cx);
jsval deleted = JSVAL_FALSE;
if (JSVAL_IS_STRING(id)) {
JSString *str = JSVAL_TO_STRING(id);
if (NPIdentifierIsString(id)) {
JSString *str = NPIdentifierToString(id);
ok = ::JS_DeleteUCProperty2(cx, npjsobj->mJSObj, ::JS_GetStringChars(str),
::JS_GetStringLength(str), &deleted);
@ -923,16 +918,16 @@ nsJSObjWrapper::NP_RemoveProperty(NPObject *npobj, NPIdentifier identifier)
}
}
} else {
NS_ASSERTION(JSVAL_IS_INT(id), "id must be either string or int!\n");
NS_ASSERTION(NPIdentifierIsInt(id), "id must be either string or int!\n");
ok = ::JS_DeleteElement2(cx, npjsobj->mJSObj, JSVAL_TO_INT(id), &deleted);
ok = ::JS_DeleteElement2(cx, npjsobj->mJSObj, NPIdentifierToInt(id), &deleted);
if (ok && deleted) {
// FIXME: See bug 425823, we shouldn't need to do this, and once
// that bug is fixed we can remove this code.
JSBool hasProp;
ok = ::JS_HasElement(cx, npjsobj->mJSObj, JSVAL_TO_INT(id), &hasProp);
ok = ::JS_HasElement(cx, npjsobj->mJSObj, NPIdentifierToInt(id), &hasProp);
if (ok && hasProp) {
// The property might have been deleted, but it got
@ -950,13 +945,13 @@ nsJSObjWrapper::NP_RemoveProperty(NPObject *npobj, NPIdentifier identifier)
//static
bool
nsJSObjWrapper::NP_Enumerate(NPObject *npobj, NPIdentifier **identifier,
nsJSObjWrapper::NP_Enumerate(NPObject *npobj, NPIdentifier **idarray,
uint32_t *count)
{
NPP npp = NPPStack::Peek();
JSContext *cx = GetJSContext(npp);
*identifier = 0;
*idarray = 0;
*count = 0;
if (!cx) {
@ -982,8 +977,8 @@ nsJSObjWrapper::NP_Enumerate(NPObject *npobj, NPIdentifier **identifier,
}
*count = ida->length;
*identifier = (NPIdentifier *)PR_Malloc(*count * sizeof(NPIdentifier));
if (!*identifier) {
*idarray = (NPIdentifier *)PR_Malloc(*count * sizeof(NPIdentifier));
if (!*idarray) {
ThrowJSException(cx, "Memory allocation failed for NPIdentifier!");
::JS_DestroyIdArray(cx, ida);
@ -995,26 +990,29 @@ nsJSObjWrapper::NP_Enumerate(NPObject *npobj, NPIdentifier **identifier,
jsval v;
if (!::JS_IdToValue(cx, ida->vector[i], &v)) {
::JS_DestroyIdArray(cx, ida);
PR_Free(*identifier);
PR_Free(*idarray);
return PR_FALSE;
}
NPIdentifier id;
if (JSVAL_IS_STRING(v)) {
JSString *str = JSVAL_TO_STRING(v);
if (!JS_InternUCStringN(cx, ::JS_GetStringChars(str),
::JS_GetStringLength(str))) {
::JS_DestroyIdArray(cx, ida);
PR_Free(*identifier);
PR_Free(*idarray);
return PR_FALSE;
}
id = StringToNPIdentifier(str);
} else {
NS_ASSERTION(JSVAL_IS_INT(v),
"The element in ida must be either string or int!\n");
id = IntToNPIdentifier(JSVAL_TO_INT(v));
}
(*identifier)[i] = (NPIdentifier)v;
(*idarray)[i] = id;
}
::JS_DestroyIdArray(cx, ida);
@ -1027,8 +1025,7 @@ bool
nsJSObjWrapper::NP_Construct(NPObject *npobj, const NPVariant *args,
uint32_t argCount, NPVariant *result)
{
return doInvoke(npobj, (NPIdentifier)JSVAL_VOID, args, argCount, PR_TRUE,
result);
return doInvoke(npobj, NPIdentifier_VOID, args, argCount, PR_TRUE, result);
}
@ -1205,7 +1202,8 @@ NPObjWrapper_AddProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
PluginDestructionGuard pdg(LookupNPP(npobj));
JSBool hasProperty = npobj->_class->hasProperty(npobj, (NPIdentifier)id);
NPIdentifier identifier = JSValToNPIdentifier(id);
JSBool hasProperty = npobj->_class->hasProperty(npobj, identifier);
if (!ReportExceptionIfPending(cx))
return JS_FALSE;
@ -1214,7 +1212,7 @@ NPObjWrapper_AddProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
// We must permit methods here since JS_DefineUCFunction() will add
// the function as a property
JSBool hasMethod = npobj->_class->hasMethod(npobj, (NPIdentifier)id);
JSBool hasMethod = npobj->_class->hasMethod(npobj, identifier);
if (!ReportExceptionIfPending(cx))
return JS_FALSE;
@ -1241,8 +1239,10 @@ NPObjWrapper_DelProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
PluginDestructionGuard pdg(LookupNPP(npobj));
NPIdentifier identifier = JSValToNPIdentifier(id);
if (!NPObjectIsOutOfProcessProxy(npobj)) {
JSBool hasProperty = npobj->_class->hasProperty(npobj, (NPIdentifier)id);
JSBool hasProperty = npobj->_class->hasProperty(npobj, identifier);
if (!ReportExceptionIfPending(cx))
return JS_FALSE;
@ -1250,7 +1250,7 @@ NPObjWrapper_DelProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
return JS_TRUE;
}
if (!npobj->_class->removeProperty(npobj, (NPIdentifier)id))
if (!npobj->_class->removeProperty(npobj, identifier))
*vp = JSVAL_FALSE;
return ReportExceptionIfPending(cx);
@ -1280,8 +1280,10 @@ NPObjWrapper_SetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
PluginDestructionGuard pdg(npp);
NPIdentifier identifier = JSValToNPIdentifier(id);
if (!NPObjectIsOutOfProcessProxy(npobj)) {
JSBool hasProperty = npobj->_class->hasProperty(npobj, (NPIdentifier)id);
JSBool hasProperty = npobj->_class->hasProperty(npobj, identifier);
if (!ReportExceptionIfPending(cx))
return JS_FALSE;
@ -1299,7 +1301,7 @@ NPObjWrapper_SetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
return JS_FALSE;
}
JSBool ok = npobj->_class->setProperty(npobj, (NPIdentifier)id, &npv);
JSBool ok = npobj->_class->setProperty(npobj, identifier, &npv);
_releasevariantvalue(&npv); // Release the variant
if (!ReportExceptionIfPending(cx))
return JS_FALSE;
@ -1341,6 +1343,8 @@ NPObjWrapper_GetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
NPVariant npv;
VOID_TO_NPVARIANT(npv);
NPIdentifier identifier = JSValToNPIdentifier(id);
#ifdef MOZ_IPC
if (NPObjectIsOutOfProcessProxy(npobj)) {
PluginScriptableObjectParent* actor =
@ -1350,7 +1354,7 @@ NPObjWrapper_GetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
if (!actor)
return JS_FALSE;
JSBool success = actor->GetPropertyHelper((NPIdentifier)id, &hasProperty,
JSBool success = actor->GetPropertyHelper(identifier, &hasProperty,
&hasMethod, &npv);
if (!ReportExceptionIfPending(cx)) {
if (success)
@ -1375,11 +1379,11 @@ NPObjWrapper_GetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
}
#endif
hasProperty = npobj->_class->hasProperty(npobj, (NPIdentifier)id);
hasProperty = npobj->_class->hasProperty(npobj, identifier);
if (!ReportExceptionIfPending(cx))
return JS_FALSE;
hasMethod = npobj->_class->hasMethod(npobj, (NPIdentifier)id);
hasMethod = npobj->_class->hasMethod(npobj, identifier);
if (!ReportExceptionIfPending(cx))
return JS_FALSE;
@ -1388,7 +1392,7 @@ NPObjWrapper_GetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
return CreateNPObjectMember(npp, cx, obj, npobj, id, nsnull, vp);
if (hasProperty) {
if (npobj->_class->getProperty(npobj, (NPIdentifier)id, &npv))
if (npobj->_class->getProperty(npobj, identifier, &npv))
*vp = NPVariantToJSVal(npp, cx, &npv);
_releasevariantvalue(&npv);
@ -1488,10 +1492,10 @@ CallNPMethodInternal(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
if (npobj->_class->invoke) {
JSFunction *fun = (JSFunction *)::JS_GetPrivate(cx, funobj);
jsval method = STRING_TO_JSVAL(::JS_GetFunctionId(fun));
JSString *name = ::JS_GetFunctionId(fun);
NPIdentifier id = StringToNPIdentifier(name);
ok = npobj->_class->invoke(npobj, (NPIdentifier)method, npargs, argc,
&v);
ok = npobj->_class->invoke(npobj, id, npargs, argc, &v);
} else {
ok = JS_FALSE;
@ -1610,7 +1614,8 @@ NPObjWrapper_newEnumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
enum_value = state->value;
length = state->length;
if (state->index != length) {
return ::JS_ValueToId(cx, (jsval)enum_value[state->index++], idp);
jsval val = NPIdentifierToJSVal(enum_value[state->index++]);
return ::JS_ValueToId(cx, val, idp);
}
// FALL THROUGH
@ -1643,7 +1648,9 @@ NPObjWrapper_NewResolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
PluginDestructionGuard pdg(LookupNPP(npobj));
PRBool hasProperty = npobj->_class->hasProperty(npobj, (NPIdentifier)id);
NPIdentifier identifier = JSValToNPIdentifier(id);
PRBool hasProperty = npobj->_class->hasProperty(npobj, identifier);
if (!ReportExceptionIfPending(cx))
return JS_FALSE;
@ -1670,7 +1677,7 @@ NPObjWrapper_NewResolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
return JS_TRUE;
}
PRBool hasMethod = npobj->_class->hasMethod(npobj, (NPIdentifier)id);
PRBool hasMethod = npobj->_class->hasMethod(npobj, identifier);
if (!ReportExceptionIfPending(cx))
return JS_FALSE;
@ -2141,6 +2148,8 @@ CreateNPObjectMember(NPP npp, JSContext *cx, JSObject *obj, NPObject* npobj,
::JS_SetPrivate(cx, memobj, (void *)memberPrivate);
NPIdentifier identifier = JSValToNPIdentifier(id);
jsval fieldValue;
NPVariant npv;
NPBool hasProperty;
@ -2153,7 +2162,7 @@ CreateNPObjectMember(NPP npp, JSContext *cx, JSObject *obj, NPObject* npobj,
else {
VOID_TO_NPVARIANT(npv);
NPBool hasProperty = npobj->_class->getProperty(npobj, (NPIdentifier)id,
NPBool hasProperty = npobj->_class->getProperty(npobj, identifier,
&npv);
if (!ReportExceptionIfPending(cx)) {
::JS_RemoveValueRoot(cx, vp);
@ -2178,7 +2187,7 @@ CreateNPObjectMember(NPP npp, JSContext *cx, JSObject *obj, NPObject* npobj,
memberPrivate->npobjWrapper = obj;
memberPrivate->fieldValue = fieldValue;
memberPrivate->methodName = id;
memberPrivate->methodName = identifier;
memberPrivate->npp = npp;
::JS_RemoveValueRoot(cx, vp);
@ -2277,9 +2286,10 @@ NPObjectMember_Call(JSContext *cx, JSObject *obj,
}
}
NPVariant npv;
JSBool ok;
ok = npobj->_class->invoke(npobj, (NPIdentifier)memberPrivate->methodName,
ok = npobj->_class->invoke(npobj, memberPrivate->methodName,
npargs, argc, &npv);
// Release arguments.

View File

@ -690,7 +690,7 @@ doGetIdentifier(JSContext *cx, const NPUTF8* name)
if (!str)
return NULL;
return (NPIdentifier)STRING_TO_JSVAL(str);
return StringToNPIdentifier(str);
}
#if defined(MOZ_MEMORY_WINDOWS) && !defined(MOZ_MEMORY_WINCE)
@ -1353,25 +1353,23 @@ _getintidentifier(int32_t intid)
if (!NS_IsMainThread()) {
NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_getstringidentifier called from the wrong thread\n"));
}
return (NPIdentifier)INT_TO_JSVAL(intid);
return IntToNPIdentifier(intid);
}
NPUTF8* NP_CALLBACK
_utf8fromidentifier(NPIdentifier identifier)
_utf8fromidentifier(NPIdentifier id)
{
if (!NS_IsMainThread()) {
NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_utf8fromidentifier called from the wrong thread\n"));
}
if (!identifier)
if (!id)
return NULL;
jsval v = (jsval)identifier;
if (!JSVAL_IS_STRING(v)) {
if (!NPIdentifierIsString(id)) {
return nsnull;
}
JSString *str = JSVAL_TO_STRING(v);
JSString *str = NPIdentifierToString(id);
return
ToNewUTF8String(nsDependentString((PRUnichar *)::JS_GetStringChars(str),
@ -1379,29 +1377,27 @@ _utf8fromidentifier(NPIdentifier identifier)
}
int32_t NP_CALLBACK
_intfromidentifier(NPIdentifier identifier)
_intfromidentifier(NPIdentifier id)
{
if (!NS_IsMainThread()) {
NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_intfromidentifier called from the wrong thread\n"));
}
jsval v = (jsval)identifier;
if (!JSVAL_IS_INT(v)) {
if (!NPIdentifierIsInt(id)) {
return PR_INT32_MIN;
}
return JSVAL_TO_INT(v);
return NPIdentifierToInt(id);
}
bool NP_CALLBACK
_identifierisstring(NPIdentifier identifier)
_identifierisstring(NPIdentifier id)
{
if (!NS_IsMainThread()) {
NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_identifierisstring called from the wrong thread\n"));
}
jsval v = (jsval)identifier;
return JSVAL_IS_STRING(v);
return NPIdentifierIsString(id);
}
NPObject* NP_CALLBACK

View File

@ -43,6 +43,8 @@
#include "npfunctions.h"
#include "nsPluginHost.h"
#include "jsapi.h"
#include "mozilla/PluginLibrary.h"
/*
@ -114,6 +116,129 @@ namespace mozilla {
namespace plugins {
namespace parent {
// On 32-bit platforms, sizeof(jsval) != sizeof(NPIdentifier), so we need to
// use an alternate encoding scheme. The following inline helpers provide an
// abstraction for setting and getting the values of NPIdentifiers that should
// always be used instead of casting an NPIdentifier to a jsval and using the
// jsapi.
#if JS_BITS_PER_WORD == 64
JS_STATIC_ASSERT(sizeof(NPIdentifier) == sizeof(jsval));
static inline bool
NPIdentifierIsString(NPIdentifer id)
{
return JSVAL_IS_STRING((jsval)id);
}
static inline JSString *
NPIdentifierToString(NPIdentifer id)
{
return JSVAL_TO_STRING((jsval)id);
}
static inline NPIdentifier
StringToNPIdentifier(JSString *str)
{
return (NPIdentifier)STRING_TO_JSVAL(str);
}
static inline bool
NPIdentifierIsInt(NPIdentifer id)
{
return JSVAL_IS_INT((jsval)id);
}
static inline jsint
NPIdentifierToInt(NPIdentifer id)
{
return JSVAL_TO_INT((jsval)id);
}
static inline bool
IntToNPIdentifier(JSContext *, jsint i, NPIdentifier *pid)
{
*pid = (NPIdentifier)INT_TO_JSVAL(i);
return true;
}
static inline bool
NPIdentifierIsVoid(NPIdentifier id)
{
return JSVAL_IS_VOID((NPIdentifier)id);
}
static const NPIdentifier NPIdentifier_VOID = (NPIdentifier)JSVAL_VOID;
#else /* JS_BITS_PER_WORD == 32 */
static inline bool
NPIdentifierIsString(NPIdentifier id)
{
return ((size_t)id & 0x3) == 0;
}
static inline JSString *
NPIdentifierToString(NPIdentifier id)
{
NS_ASSERTION(NPIdentifierIsString(id), "id must be string");
return (JSString *)id;
}
static inline NPIdentifier
StringToNPIdentifier(JSString *str)
{
NS_ASSERTION(((size_t)str & 3) == 0, "Strings are assumed to be at least 4-byte aligned");
return (NPIdentifier)str;
}
static inline bool
NPIdentifierIsInt(NPIdentifier id)
{
return ((size_t)id & 1) != 0;
}
static inline jsint
NPIdentifierToInt(NPIdentifier id)
{
NS_ASSERTION(NPIdentifierIsInt(id), "id must be int");
return (jsint)id >> 1;
}
static inline NPIdentifier
IntToNPIdentifier(jsint i)
{
NS_ASSERTION(i < (1 << 30) - 1, "integer id is too big, will be truncated");
return (NPIdentifier)((i << 1) | 0x1);
}
static inline bool
NPIdentifierIsVoid(NPIdentifier id)
{
return (size_t)id == 0x2;
}
static const NPIdentifier NPIdentifier_VOID = (NPIdentifier)0x2;
#endif
static inline jsval
NPIdentifierToJSVal(NPIdentifier id)
{
if (NPIdentifierIsString(id))
return STRING_TO_JSVAL(NPIdentifierToString(id));
return INT_TO_JSVAL(NPIdentifierToInt(id));
}
static inline NPIdentifier
JSValToNPIdentifier(jsval val)
{
if (JSVAL_IS_STRING(val))
return StringToNPIdentifier(JSVAL_TO_STRING(val));
return IntToNPIdentifier(JSVAL_TO_INT(val));
}
NPObject* NP_CALLBACK
_getwindowobject(NPP npp);