mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
[JAEGER] Merge from fatval branch.
This commit is contained in:
commit
a020926861
@ -56,10 +56,10 @@ JS_BEGIN_EXTERN_C
|
||||
* prevents many bugs from being caught at compile time. E.g.:
|
||||
*
|
||||
* jsval v = ...
|
||||
* if (v == JS_TRUE) // should compare with JSVAL_TRUE
|
||||
* if (v == JS_TRUE) // error
|
||||
* ...
|
||||
*
|
||||
* jsid id = v; // jsid and jsval have different representations
|
||||
* jsid id = v; // error
|
||||
*
|
||||
* To catch more errors, jsval and jsid are given struct types in debug builds.
|
||||
* Struct assignment and (in C++) operator== allow correct code to be mostly
|
||||
|
@ -53,7 +53,9 @@ enum {
|
||||
JSTN_ERRTYPE_MASK = 0x07,
|
||||
JSTN_UNBOX_AFTER = 0x08,
|
||||
JSTN_MORE = 0x10,
|
||||
JSTN_CONSTRUCTOR = 0x20
|
||||
JSTN_CONSTRUCTOR = 0x20,
|
||||
JSTN_RETURN_NULLABLE_STR = 0x40,
|
||||
JSTN_RETURN_NULLABLE_OBJ = 0x80
|
||||
};
|
||||
|
||||
#define JSTN_ERRTYPE(jstn) ((jstn)->flags & JSTN_ERRTYPE_MASK)
|
||||
@ -178,7 +180,6 @@ struct ClosureVarInfo;
|
||||
* effects.
|
||||
*/
|
||||
#define _JS_CTYPE(ctype, size, pch, ach, flags) (ctype, size, pch, ach, flags)
|
||||
#define _JS_JSVAL_CTYPE(size, pch, ach, flags) (Value, size, pch, ach, (flags | JSTN_UNBOX_AFTER))
|
||||
|
||||
#define _JS_CTYPE_CONTEXT _JS_CTYPE(JSContext *, _JS_PTR,"C", "", INFALLIBLE)
|
||||
#define _JS_CTYPE_RUNTIME _JS_CTYPE(JSRuntime *, _JS_PTR,"R", "", INFALLIBLE)
|
||||
|
@ -6372,7 +6372,7 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
|
||||
* For operator new applied to other expressions than E4X ones, we emit
|
||||
* JSOP_GETPROP instead of JSOP_CALLPROP, etc. This is necessary to
|
||||
* interpose the lambda-initialized method read barrier -- see the code
|
||||
* in jsops.cpp for JSOP_LAMBDA followed by JSOP_{SET,INIT}PROP.
|
||||
* in jsinterp.cpp for JSOP_LAMBDA followed by JSOP_{SET,INIT}PROP.
|
||||
*
|
||||
* Then (or in a call case that has no explicit reference-base object)
|
||||
* we emit JSOP_NULL as a placeholder local GC root to hold the |this|
|
||||
|
@ -2939,7 +2939,7 @@ END_CASE(JSOP_MOREITER)
|
||||
BEGIN_CASE(JSOP_ENDITER)
|
||||
{
|
||||
JS_ASSERT(regs.sp - 1 >= fp->base());
|
||||
bool ok = !!js_CloseIterator(cx, regs.sp[-1]);
|
||||
bool ok = !!js_CloseIterator(cx, ®s.sp[-1].toObject());
|
||||
regs.sp--;
|
||||
if (!ok)
|
||||
goto error;
|
||||
@ -3912,6 +3912,7 @@ BEGIN_CASE(JSOP_ARGINC)
|
||||
incr = 1; incr2 = 0;
|
||||
|
||||
do_arg_incop:
|
||||
// If we initialize in the declaration, MSVC complains that the labels skip init.
|
||||
slot = GET_ARGNO(regs.pc);
|
||||
JS_ASSERT(slot < fp->fun->nargs);
|
||||
METER_SLOT_OP(op, slot);
|
||||
@ -4816,6 +4817,7 @@ END_CASE(JSOP_SETCALL)
|
||||
} \
|
||||
PUSH_OBJECT_OR_NULL(thisp); \
|
||||
JS_END_MACRO
|
||||
|
||||
BEGIN_CASE(JSOP_GETGNAME)
|
||||
BEGIN_CASE(JSOP_CALLGNAME)
|
||||
BEGIN_CASE(JSOP_NAME)
|
||||
@ -5437,7 +5439,30 @@ BEGIN_CASE(JSOP_DEFVAR)
|
||||
obj2 = obj;
|
||||
}
|
||||
|
||||
obj2->dropProperty(cx, prop);
|
||||
/*
|
||||
* Try to optimize a property we either just created, or found
|
||||
* directly in the global object, that is permanent, has a slot,
|
||||
* and has stub getter and setter, into a "fast global" accessed
|
||||
* by the JSOP_*GVAR opcodes.
|
||||
*/
|
||||
if (!fp->fun &&
|
||||
index < GlobalVarCount(fp) &&
|
||||
obj2 == obj &&
|
||||
obj->isNative()) {
|
||||
JSScopeProperty *sprop = (JSScopeProperty *) prop;
|
||||
if (!sprop->configurable() &&
|
||||
SPROP_HAS_VALID_SLOT(sprop, obj->scope()) &&
|
||||
sprop->hasDefaultGetterOrIsMethod() &&
|
||||
sprop->hasDefaultSetter()) {
|
||||
/*
|
||||
* Fast globals use frame variables to map the global name's atom
|
||||
* index to the permanent varobj slot number, tagged as a jsval.
|
||||
* The atom index for the global's name literal is identical to its
|
||||
* variable index.
|
||||
*/
|
||||
fp->slots()[index].setInt32(sprop->slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
END_CASE(JSOP_DEFVAR)
|
||||
|
||||
@ -6977,7 +7002,7 @@ END_CASE(JSOP_ARRAYPUSH)
|
||||
JS_ASSERT(js_GetOpcode(cx, fp->script, regs.pc) == JSOP_ENDITER);
|
||||
AutoValueRooter tvr(cx, cx->exception);
|
||||
cx->throwing = false;
|
||||
ok = js_CloseIterator(cx, regs.sp[-1]);
|
||||
ok = js_CloseIterator(cx, ®s.sp[-1].toObject());
|
||||
regs.sp -= 1;
|
||||
if (!ok)
|
||||
goto error;
|
||||
|
@ -785,14 +785,11 @@ CloseGenerator(JSContext *cx, JSObject *genobj);
|
||||
#endif
|
||||
|
||||
JS_FRIEND_API(JSBool)
|
||||
js_CloseIterator(JSContext *cx, const Value &v)
|
||||
js_CloseIterator(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
cx->iterValue.setMagic(JS_NO_ITER_VALUE);
|
||||
|
||||
JS_ASSERT(v.isObject());
|
||||
JSObject *obj = &v.toObject();
|
||||
Class *clasp = obj->getClass();
|
||||
|
||||
if (clasp == &js_IteratorClass.base) {
|
||||
/* Remove enumerators from the active list, which is a stack. */
|
||||
NativeIterator *ni = obj->getNativeIterator();
|
||||
|
@ -160,7 +160,7 @@ extern JS_FRIEND_API(JSBool)
|
||||
js_ValueToIterator(JSContext *cx, uintN flags, js::Value *vp);
|
||||
|
||||
extern JS_FRIEND_API(JSBool)
|
||||
js_CloseIterator(JSContext *cx, const js::Value &v);
|
||||
js_CloseIterator(JSContext *cx, JSObject *iterObj);
|
||||
|
||||
bool
|
||||
js_SuppressDeletedProperty(JSContext *cx, JSObject *obj, jsid id);
|
||||
|
@ -2697,7 +2697,7 @@ js_NonEmptyObject(JSContext* cx, JSObject* proto)
|
||||
}
|
||||
|
||||
/*
|
||||
* See comments in the JSOP_NEWINIT case of jsops.cpp why we cannot
|
||||
* See comments in the JSOP_NEWINIT case of jsinterp.cpp why we cannot
|
||||
* assume that cx owns the scope and skip the unlock call.
|
||||
*/
|
||||
JS_UNLOCK_SCOPE(cx, scope);
|
||||
|
@ -344,7 +344,7 @@ js_GetIndexFromBytecode(JSContext *cx, JSScript *script, jsbytecode *pc,
|
||||
* Unfortunately some bytecodes such as JSOP_LOOKUPSWITCH have immediates that
|
||||
* might be string or double atoms. Those opcodes cannot be used from imacros.
|
||||
* See the assertions in the JSOP_DOUBLE and JSOP_LOOKUPSWTICH* opcode cases in
|
||||
* jsops.cpp.
|
||||
* jsinterp.cpp.
|
||||
*/
|
||||
#define GET_DOUBLE_FROM_BYTECODE(script, pc, pcoff, dbl) \
|
||||
JS_BEGIN_MACRO \
|
||||
|
@ -57,6 +57,8 @@
|
||||
#include "jspubtd.h"
|
||||
#include "jsutil.h"
|
||||
|
||||
JS_BEGIN_EXTERN_C
|
||||
|
||||
/*
|
||||
* Convenience constants.
|
||||
*/
|
||||
@ -358,4 +360,6 @@ typedef JSBool
|
||||
extern JSBool js_CStringsAreUTF8;
|
||||
#endif
|
||||
|
||||
JS_END_EXTERN_C
|
||||
|
||||
#endif /* jsprvtd_h___ */
|
||||
|
@ -320,7 +320,7 @@ JSScope::initRuntimeState(JSContext *cx)
|
||||
* is less than freeslot to succeed. As the shared emptyArgumentsScope is
|
||||
* never mutated, it's safe to pretend to have all the slots possible.
|
||||
*
|
||||
* Note how the fast paths in jsops.cpp for JSOP_LENGTH and JSOP_GETELEM
|
||||
* Note how the fast paths in jsinterp.cpp for JSOP_LENGTH and JSOP_GETELEM
|
||||
* bypass resolution of scope properties for length and element indices on
|
||||
* arguments objects. This helps ensure that any arguments object needing
|
||||
* its own mutable scope (with unique shape) is a rare event.
|
||||
|
@ -218,6 +218,8 @@ TypeToChar(JSValueType type)
|
||||
case JSVAL_TYPE_FUNOBJ: return 'F';
|
||||
case JSVAL_TYPE_NONFUNOBJ: return 'O';
|
||||
case JSVAL_TYPE_BOXED: return '#';
|
||||
case JSVAL_TYPE_STRORNULL: return 's';
|
||||
case JSVAL_TYPE_OBJORNULL: return 'o';
|
||||
case JSVAL_TYPE_UNINITIALIZED: return '*';
|
||||
}
|
||||
return '?';
|
||||
@ -2631,13 +2633,13 @@ TraceRecorder::trackNativeStackUse(unsigned slots)
|
||||
static inline void
|
||||
ValueToNative(const Value &v, JSValueType type, double* slot)
|
||||
{
|
||||
if (type > JSVAL_UPPER_INCL_TYPE_OF_NUMBER_SET) {
|
||||
JS_ASSERT(type <= JSVAL_UPPER_INCL_TYPE_OF_BOXABLE_SET);
|
||||
if (type > JSVAL_UPPER_INCL_TYPE_OF_NUMBER_SET)
|
||||
v.unboxNonDoubleTo((uint64 *)slot);
|
||||
} else if (type == JSVAL_TYPE_INT32) {
|
||||
else if (type == JSVAL_TYPE_INT32)
|
||||
*(int32_t *)slot = v.isInt32() ? v.toInt32() : (int32_t)v.toDouble();
|
||||
} else {
|
||||
else
|
||||
*(double *)slot = v.toNumber();
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
int32_t _;
|
||||
@ -2804,6 +2806,12 @@ NativeToValue(JSContext* cx, Value& v, JSValueType type, double* slot)
|
||||
v.setNumber(*slot);
|
||||
} else if (JS_LIKELY(type <= JSVAL_UPPER_INCL_TYPE_OF_BOXABLE_SET)) {
|
||||
v.boxNonDoubleFrom(type, (uint64 *)slot);
|
||||
} else if (type == JSVAL_TYPE_STRORNULL) {
|
||||
JSString *str = *(JSString **)slot;
|
||||
v = str ? StringValue(str) : NullValue();
|
||||
} else if (type == JSVAL_TYPE_OBJORNULL) {
|
||||
JSObject *obj = *(JSObject **)slot;
|
||||
v = obj ? ObjectValue(*obj) : NullValue();
|
||||
} else {
|
||||
JS_ASSERT(type == JSVAL_TYPE_BOXED);
|
||||
JS_STATIC_ASSERT(sizeof(Value) == sizeof(double));
|
||||
@ -2850,6 +2858,12 @@ NativeToValue(JSContext* cx, Value& v, JSValueType type, double* slot)
|
||||
: "unnamed");
|
||||
break;
|
||||
}
|
||||
case JSVAL_TYPE_STRORNULL:
|
||||
debug_only_printf(LC_TMTracer, "nullablestr<%p> ", v.isNull() ? NULL : (void *)v.toString());
|
||||
break;
|
||||
case JSVAL_TYPE_OBJORNULL:
|
||||
debug_only_printf(LC_TMTracer, "nullablestr<%p> ", v.isNull() ? NULL : (void *)&v.toObject());
|
||||
break;
|
||||
case JSVAL_TYPE_BOXED:
|
||||
debug_only_printf(LC_TMTracer, "box<%llx> ", v.asRawBits());
|
||||
break;
|
||||
@ -4143,7 +4157,13 @@ TraceRecorder::snapshot(ExitType exitType)
|
||||
if (pendingUnboxSlot == cx->regs->sp - 2)
|
||||
pos = stackSlots - 2;
|
||||
typemap[pos] = JSVAL_TYPE_BOXED;
|
||||
}
|
||||
} else if (pendingSpecializedNative &&
|
||||
(pendingSpecializedNative->flags & JSTN_RETURN_NULLABLE_STR)) {
|
||||
typemap[stackSlots - 1] = JSVAL_TYPE_STRORNULL;
|
||||
} else if (pendingSpecializedNative &&
|
||||
(pendingSpecializedNative->flags & JSTN_RETURN_NULLABLE_OBJ)) {
|
||||
typemap[stackSlots - 1] = JSVAL_TYPE_OBJORNULL;
|
||||
}
|
||||
|
||||
/* Now restore the the original pc (after which early returns are ok). */
|
||||
if (resumeAfter) {
|
||||
@ -13394,6 +13414,11 @@ TraceRecorder::record_NativeCallComplete()
|
||||
*/
|
||||
JS_ASSERT(&v == &cx->regs->sp[-1] && get(&v) == v_ins);
|
||||
set(&v, unbox_value(v, native_rval_ins, 0, snapshot(BRANCH_EXIT)));
|
||||
} else if (pendingSpecializedNative->flags &
|
||||
(JSTN_RETURN_NULLABLE_STR | JSTN_RETURN_NULLABLE_OBJ)) {
|
||||
guard(v.isNull(),
|
||||
addName(lir->insEqP_0(v_ins), "guard(nullness)"),
|
||||
BRANCH_EXIT);
|
||||
} else if (JSTN_ERRTYPE(pendingSpecializedNative) == FAIL_NEG) {
|
||||
/* Already added i2d in functionCall. */
|
||||
JS_ASSERT(v.isNumber());
|
||||
@ -14223,7 +14248,7 @@ TraceRecorder::record_JSOP_MOREITER()
|
||||
static JSBool FASTCALL
|
||||
CloseIterator(JSContext *cx, JSObject *iterobj)
|
||||
{
|
||||
if (!js_CloseIterator(cx, ObjectValue(*iterobj))) {
|
||||
if (!js_CloseIterator(cx, iterobj)) {
|
||||
SetBuiltinError(cx);
|
||||
return false;
|
||||
}
|
||||
@ -14757,7 +14782,7 @@ JS_REQUIRES_STACK AbortableRecordingStatus
|
||||
TraceRecorder::record_JSOP_ENUMELEM()
|
||||
{
|
||||
/*
|
||||
* To quote from jsops.cpp's JSOP_ENUMELEM case:
|
||||
* To quote from jsinterp.cpp's JSOP_ENUMELEM case:
|
||||
* Funky: the value to set is under the [obj, id] pair.
|
||||
*/
|
||||
return setElem(-2, -1, -3);
|
||||
@ -14820,7 +14845,7 @@ TraceRecorder::record_JSOP_LAMBDA()
|
||||
* JSOP_SETMETHOD or JSOP_INITMETHOD, since we optimize away the clone for
|
||||
* these combinations and clone only if the "method value" escapes.
|
||||
*
|
||||
* See jsops.cpp, the JSOP_LAMBDA null closure case. The JSOP_SETMETHOD and
|
||||
* See jsinterp.cpp, the JSOP_LAMBDA null closure case. The JSOP_SETMETHOD and
|
||||
* JSOP_INITMETHOD logic governing the early ARECORD_CONTINUE returns below
|
||||
* must agree with the corresponding break-from-do-while(0) logic there.
|
||||
*/
|
||||
|
@ -40,7 +40,7 @@
|
||||
#ifndef jsvalimpl_h__
|
||||
#define jsvalimpl_h__
|
||||
/*
|
||||
* JS value implementation details needed for manipulating jsval and jsid.
|
||||
* JS value implementation details for operations on jsval and jsid.
|
||||
* Embeddings should not rely on any of the definitions in this file. For a
|
||||
* description of the value representation and the engine-internal C++ value
|
||||
* interface, js::Value, see jsvalue.h.
|
||||
@ -61,6 +61,8 @@ JS_BEGIN_EXTERN_C
|
||||
* so we just don't try to align.
|
||||
*/
|
||||
# define JSVAL_ALIGNMENT
|
||||
#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
|
||||
# define JSVAL_ALIGNMENT
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -99,6 +101,9 @@ JS_ENUM_HEADER(JSValueType, uint8)
|
||||
JSVAL_TYPE_NONFUNOBJ = 0x57,
|
||||
JSVAL_TYPE_FUNOBJ = 0x67,
|
||||
|
||||
JSVAL_TYPE_STRORNULL = 0x97,
|
||||
JSVAL_TYPE_OBJORNULL = 0x98,
|
||||
|
||||
JSVAL_TYPE_BOXED = 0x99,
|
||||
JSVAL_TYPE_UNINITIALIZED = 0xcd
|
||||
} JS_ENUM_FOOTER(JSValueType);
|
||||
@ -150,6 +155,8 @@ typedef uint8 JSValueType;
|
||||
#define JSVAL_TYPE_FUNOBJ ((uint8)0x67)
|
||||
#define JSVAL_TYPE_STRORNULL ((uint8)0x97)
|
||||
#define JSVAL_TYPE_OBJORNULL ((uint8)0x98)
|
||||
#define JSVAL_TYPE_STRORNULL ((uint8)0x97)
|
||||
#define JSVAL_TYPE_OBJORNULL ((uint8)0x98)
|
||||
#define JSVAL_TYPE_BOXED ((uint8)0x99)
|
||||
#define JSVAL_TYPE_UNINITIALIZED ((uint8)0xcd)
|
||||
|
||||
|
@ -697,7 +697,12 @@ Reify(JSContext *cx, JSCompartment *origin, Value *vp)
|
||||
if (!origin->wrap(cx, &obj))
|
||||
return false;
|
||||
|
||||
/* Wrap the elements in the iterator's snapshot. */
|
||||
/*
|
||||
* Wrap the elements in the iterator's snapshot.
|
||||
* N.B. the order of closing/creating iterators is important due to the
|
||||
* implicit cx->enumerators state.
|
||||
*/
|
||||
|
||||
if (ni->isKeyIter()) {
|
||||
size_t length = ni->numKeys();
|
||||
AutoIdVector keys(cx);
|
||||
@ -711,27 +716,25 @@ Reify(JSContext *cx, JSCompartment *origin, Value *vp)
|
||||
}
|
||||
}
|
||||
|
||||
if (!VectorToKeyIterator(cx, obj, ni->flags, keys, vp))
|
||||
return false;
|
||||
} else {
|
||||
size_t length = ni->numValues();
|
||||
AutoValueVector vals(cx);
|
||||
if (length > 0) {
|
||||
if (!vals.resize(length))
|
||||
return false;
|
||||
for (size_t i = 0; i < length; ++i) {
|
||||
vals[i] = ni->beginValue()[i];
|
||||
if (!origin->wrap(cx, &vals[i]))
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!VectorToValueIterator(cx, obj, ni->flags, vals, vp))
|
||||
return false;
|
||||
return js_CloseIterator(cx, iterObj) &&
|
||||
VectorToKeyIterator(cx, obj, ni->flags, keys, vp);
|
||||
}
|
||||
|
||||
return js_CloseIterator(cx, *vp);
|
||||
size_t length = ni->numValues();
|
||||
AutoValueVector vals(cx);
|
||||
if (length > 0) {
|
||||
if (!vals.resize(length))
|
||||
return false;
|
||||
for (size_t i = 0; i < length; ++i) {
|
||||
vals[i] = ni->beginValue()[i];
|
||||
if (!origin->wrap(cx, &vals[i]))
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return js_CloseIterator(cx, iterObj) &&
|
||||
VectorToValueIterator(cx, obj, ni->flags, vals, vp);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -150,7 +150,7 @@ top:
|
||||
AutoValueRooter tvr(cx, cx->exception);
|
||||
JS_ASSERT(js_GetOpcode(cx, fp->script, pc) == JSOP_ENDITER);
|
||||
cx->throwing = JS_FALSE;
|
||||
ok = !!js_CloseIterator(cx, cx->regs->sp[-1]);
|
||||
ok = !!js_CloseIterator(cx, &cx->regs->sp[-1].toObject());
|
||||
cx->regs->sp -= 1;
|
||||
if (!ok)
|
||||
goto top;
|
||||
|
@ -2158,7 +2158,7 @@ void JS_FASTCALL
|
||||
stubs::EndIter(VMFrame &f)
|
||||
{
|
||||
JS_ASSERT(f.regs.sp - 1 >= f.fp->base());
|
||||
if (!js_CloseIterator(f.cx, f.regs.sp[-1]))
|
||||
if (!js_CloseIterator(f.cx, &f.regs.sp[-1].toObject()))
|
||||
THROW();
|
||||
}
|
||||
|
||||
|
1
js/src/trace-test/tests/basic/testIteratorReification.js
Normal file
1
js/src/trace-test/tests/basic/testIteratorReification.js
Normal file
@ -0,0 +1 @@
|
||||
for (b in evalcx('')) {}
|
@ -164,9 +164,7 @@ DEFINES += \
|
||||
$(addprefix -D,$(filter AVMPLUS%,$(CONFIG))) \
|
||||
$(NULL)
|
||||
|
||||
# TODO: add this back again
|
||||
#ENABLE_TRACEABLE_FLAGS = --enable-traceables
|
||||
ENABLE_TRACEABLE_FLAGS =
|
||||
ENABLE_TRACEABLE_FLAGS = --enable-traceables
|
||||
|
||||
endif # ENABLE_JIT
|
||||
|
||||
|
@ -1006,7 +1006,7 @@ def writeQuickStub(f, customMethodCalls, member, stubName, isSetter=False):
|
||||
# Only these types can be returned (note: no strings);
|
||||
# if the type isn't one of these, then defaultTraceType is used
|
||||
traceReturnTypeMap = {
|
||||
'void': ("jsval ", "JSVAL", "JSVAL_VOID"),
|
||||
'void': ("uint32 ", "UINT32", "0"),
|
||||
'boolean': ("JSBool ", "BOOL", "JS_FALSE"),
|
||||
'short': ("int32 ", "INT32", "0"),
|
||||
'unsigned short': ("uint32 ", "UINT32", "0"),
|
||||
@ -1015,41 +1015,60 @@ traceReturnTypeMap = {
|
||||
'float': ("jsdouble ", "DOUBLE", "0"),
|
||||
'double': ("jsdouble ", "DOUBLE", "0"),
|
||||
'octet': ("uint32 ", "UINT32", "0"),
|
||||
'jsval': ("jsval ", "JSVAL", "JSVAL_VOID")
|
||||
'[astring]': ("JSString *", "STRING_OR_NULL", "nsnull"),
|
||||
'[domstring]': ("JSString *", "STRING_OR_NULL", "nsnull"),
|
||||
'[cstring]': ("JSString *", "STRING_OR_NULL", "nsnull"),
|
||||
'string': ("JSString *", "STRING_OR_NULL", "nsnull"),
|
||||
'wstring': ("JSString *", "STRING_OR_NULL", "nsnull")
|
||||
}
|
||||
|
||||
# This list extends the above list, but includes types that
|
||||
# are valid for arguments only, namely strings.
|
||||
traceTypeMap = traceReturnTypeMap.copy()
|
||||
traceTypeMap.update({
|
||||
'[astring]': ("JSString *", "STRING", "nsnull"),
|
||||
'[domstring]': ("JSString *", "STRING", "nsnull"),
|
||||
'[cstring]': ("JSString *", "STRING", "nsnull"),
|
||||
'string': ("JSString *", "STRING", "nsnull"),
|
||||
'wstring': ("JSString *", "STRING", "nsnull"),
|
||||
traceParamTypeMap = traceReturnTypeMap.copy()
|
||||
traceParamTypeMap.update({
|
||||
'void': ("uint32 ", "UINT32"),
|
||||
'boolean': ("JSBool ", "BOOL"),
|
||||
'short': ("int32 ", "INT32"),
|
||||
'unsigned short': ("uint32 ", "UINT32"),
|
||||
'long': ("int32 ", "INT32"),
|
||||
'unsigned long': ("uint32 ", "UINT32"),
|
||||
'float': ("jsdouble ", "DOUBLE"),
|
||||
'double': ("jsdouble ", "DOUBLE"),
|
||||
'octet': ("uint32 ", "UINT32"),
|
||||
'[astring]': ("JSString *", "STRING"),
|
||||
'[domstring]': ("JSString *", "STRING"),
|
||||
'[cstring]': ("JSString *", "STRING"),
|
||||
'string': ("JSString *", "STRING"),
|
||||
'wstring': ("JSString *", "STRING"),
|
||||
})
|
||||
|
||||
defaultTraceType = ("jsval ", "JSVAL", "JSVAL_VOID")
|
||||
defaultReturnTraceType = ("JSObject *", "OBJECT_OR_NULL", "nsnull")
|
||||
defaultParamTraceType = ("js::ValueArgType ", "VALUE")
|
||||
|
||||
def getTraceType(type):
|
||||
def getTraceParamType(type):
|
||||
assert type is not '[jsval]'
|
||||
type = getBuiltinOrNativeTypeName(type)
|
||||
return traceTypeMap.get(type, defaultTraceType)[0]
|
||||
return traceParamTypeMap.get(type, defaultParamTraceType)[0]
|
||||
|
||||
def getTraceReturnType(type):
|
||||
assert type is not '[jsval]'
|
||||
type = getBuiltinOrNativeTypeName(type)
|
||||
return traceReturnTypeMap.get(type, defaultTraceType)[0]
|
||||
return traceReturnTypeMap.get(type, defaultReturnTraceType)[0]
|
||||
|
||||
def getTraceInfoType(type):
|
||||
def getTraceInfoParamType(type):
|
||||
assert type is not '[jsval]'
|
||||
type = getBuiltinOrNativeTypeName(type)
|
||||
return traceTypeMap.get(type, defaultTraceType)[1]
|
||||
return traceParamTypeMap.get(type, defaultParamTraceType)[1]
|
||||
|
||||
def getTraceInfoReturnType(type):
|
||||
assert type is not '[jsval]'
|
||||
type = getBuiltinOrNativeTypeName(type)
|
||||
return traceReturnTypeMap.get(type, defaultTraceType)[1]
|
||||
return traceReturnTypeMap.get(type, defaultReturnTraceType)[1]
|
||||
|
||||
def getTraceInfoDefaultReturn(type):
|
||||
assert type is not '[jsval]'
|
||||
type = getBuiltinOrNativeTypeName(type)
|
||||
return traceTypeMap.get(type, defaultTraceType)[2]
|
||||
return traceReturnTypeMap.get(type, defaultReturnTraceType)[2]
|
||||
|
||||
def getFailureString(retval, indent):
|
||||
assert indent > 0
|
||||
@ -1120,7 +1139,7 @@ def writeTraceableArgumentConversion(f, member, i, name, type, haveCcx,
|
||||
assert haveCcx
|
||||
template = (
|
||||
" nsCOMPtr<nsIVariant> ${name}(already_AddRefed<nsIVariant>("
|
||||
"XPCVariant::newVariant(ccx, ${argVal})));\n"
|
||||
"XPCVariant::newVariant(ccx, js::Jsvalify(js::ValueArgToConstRef(${argVal})))));\n"
|
||||
" if (!${name}) {\n")
|
||||
f.write(substitute(template, params))
|
||||
writeFailure(f, getTraceInfoDefaultReturn(member.realtype), 2)
|
||||
@ -1134,7 +1153,7 @@ def writeTraceableArgumentConversion(f, member, i, name, type, haveCcx,
|
||||
f.write(" %s *%s;\n" % (type.name, name))
|
||||
f.write(" xpc_qsSelfRef %sref;\n" % name)
|
||||
f.write(" rv = xpc_qsUnwrapArg<%s>("
|
||||
"cx, %s, &%s, &%sref.ptr, &vp.array[%d]);\n"
|
||||
"cx, js::Jsvalify(js::ValueArgToConstRef(%s)), &%s, &%sref.ptr, &vp.array[%d]);\n"
|
||||
% (type.name, argVal, name, name, 2 + i))
|
||||
f.write(" if (NS_FAILED(rv)) {\n")
|
||||
if haveCcx:
|
||||
@ -1154,7 +1173,7 @@ def writeTraceableArgumentConversion(f, member, i, name, type, haveCcx,
|
||||
|
||||
traceableResultConvTemplates = {
|
||||
'void':
|
||||
" return JSVAL_VOID;\n",
|
||||
" return 0;\n",
|
||||
'octet':
|
||||
" return uint32(result);\n",
|
||||
'short':
|
||||
@ -1172,21 +1191,20 @@ traceableResultConvTemplates = {
|
||||
'double':
|
||||
" return jsdouble(result);\n",
|
||||
'[domstring]':
|
||||
" jsval rval;\n"
|
||||
" if (!xpc_qsStringToJsval(cx, result, &rval)) {\n"
|
||||
" JSString *rval;\n"
|
||||
" if (!xpc_qsStringToJsstring(cx, result, &rval)) {\n"
|
||||
" JS_ReportOutOfMemory(cx);\n${errorStr}"
|
||||
" return rval;\n",
|
||||
'[astring]':
|
||||
" jsval rval;\n"
|
||||
" if (!xpc_qsStringToJsval(cx, result, &rval)) {\n"
|
||||
" JSString *rval;\n"
|
||||
" if (!xpc_qsStringToJsstring(cx, result, &rval)) {\n"
|
||||
" JS_ReportOutOfMemory(cx);\n${errorStr}"
|
||||
" return rval;\n",
|
||||
'[jsval]':
|
||||
" return vp.array[0];\n"
|
||||
" return rval;\n"
|
||||
}
|
||||
|
||||
def writeTraceableResultConv(f, type):
|
||||
typeName = getBuiltinOrNativeTypeName(type)
|
||||
assert typeName is not '[jsval]'
|
||||
if typeName is not None:
|
||||
template = traceableResultConvTemplates.get(typeName)
|
||||
if template is not None:
|
||||
@ -1206,7 +1224,7 @@ def writeTraceableResultConv(f, type):
|
||||
% (type.name, type.name))
|
||||
f.write(" if (!ok) {\n");
|
||||
writeFailure(f, getTraceInfoDefaultReturn(type), 2)
|
||||
f.write(" return vp.array[0];\n")
|
||||
f.write(" return JSVAL_TO_OBJECT(vp.array[0]);\n")
|
||||
return
|
||||
|
||||
warn("Unable to convert result of type %s" % typeName)
|
||||
@ -1242,8 +1260,8 @@ def writeTraceableQuickStub(f, customMethodCalls, member, stubName):
|
||||
f.write(", JSObject *callee")
|
||||
traceInfo["params"].append("CALLEE")
|
||||
for i, param in enumerate(member.params):
|
||||
f.write(", %s_arg%d" % (getTraceType(param.realtype), i))
|
||||
traceInfo["params"].append(getTraceInfoType(param.realtype))
|
||||
f.write(", %s_arg%d" % (getTraceParamType(param.realtype), i))
|
||||
traceInfo["params"].append(getTraceInfoParamType(param.realtype))
|
||||
f.write(")\n{\n");
|
||||
f.write(" XPC_QS_ASSERT_CONTEXT_OK(cx);\n")
|
||||
|
||||
|
@ -3341,16 +3341,6 @@ XPCWrappedNative::HandlePossibleNameCaseError(XPCCallContext& ccx,
|
||||
XPCNativeInterface* iface,
|
||||
jsid name)
|
||||
{
|
||||
if(!ccx.IsValid())
|
||||
return;
|
||||
|
||||
JSString* oldJSStr;
|
||||
JSString* newJSStr;
|
||||
PRUnichar* oldStr;
|
||||
PRUnichar* newStr;
|
||||
XPCNativeMember* member;
|
||||
XPCNativeInterface* localIface;
|
||||
|
||||
// TODO: remove this all more thoroughly.
|
||||
}
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user