mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 768446 - Remove StackIter::sp_ (r=dvander)
--HG-- extra : rebase_source : 4a2e40e8cc8d8bddcefd2a2687354b5dacd3f248
This commit is contained in:
parent
1437538c15
commit
18656f0a0a
@ -12,6 +12,6 @@ try {
|
||||
new x;
|
||||
}
|
||||
catch (e) {
|
||||
assertEq(e.message, 'new x is not a constructor');
|
||||
assertEq(String(e.message).indexOf('is not a constructor') === -1, false);
|
||||
}
|
||||
throw "ExitCleanly"
|
||||
|
@ -258,7 +258,6 @@ JS_ConvertArgumentsVA(JSContext *cx, unsigned argc, jsval *argv, const char *for
|
||||
jsval *sp;
|
||||
JSBool required;
|
||||
char c;
|
||||
JSFunction *fun;
|
||||
double d;
|
||||
JSString *str;
|
||||
JSObject *obj;
|
||||
@ -277,8 +276,7 @@ JS_ConvertArgumentsVA(JSContext *cx, unsigned argc, jsval *argv, const char *for
|
||||
}
|
||||
if (sp == argv + argc) {
|
||||
if (required) {
|
||||
fun = js_ValueToFunction(cx, &argv[-2], 0);
|
||||
if (fun) {
|
||||
if (JSFunction *fun = ReportIfNotFunction(cx, argv[-2])) {
|
||||
char numBuf[12];
|
||||
JS_snprintf(numBuf, sizeof numBuf, "%u", argc);
|
||||
JSAutoByteString funNameBytes;
|
||||
@ -342,7 +340,7 @@ JS_ConvertArgumentsVA(JSContext *cx, unsigned argc, jsval *argv, const char *for
|
||||
*va_arg(ap, JSObject **) = obj;
|
||||
break;
|
||||
case 'f':
|
||||
obj = js_ValueToFunction(cx, sp, 0);
|
||||
obj = ReportIfNotFunction(cx, *sp);
|
||||
if (!obj)
|
||||
return JS_FALSE;
|
||||
*sp = OBJECT_TO_JSVAL(obj);
|
||||
@ -436,7 +434,7 @@ JS_ConvertValue(JSContext *cx, jsval v, JSType type, jsval *vp)
|
||||
break;
|
||||
case JSTYPE_FUNCTION:
|
||||
*vp = v;
|
||||
obj = js_ValueToFunction(cx, vp, JSV2F_SEARCH_STACK);
|
||||
obj = ReportIfNotFunction(cx, *vp);
|
||||
ok = (obj != NULL);
|
||||
break;
|
||||
case JSTYPE_STRING:
|
||||
@ -479,7 +477,7 @@ JS_ValueToFunction(JSContext *cx, jsval v)
|
||||
AssertNoGC(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, v);
|
||||
return js_ValueToFunction(cx, &v, JSV2F_SEARCH_STACK);
|
||||
return ReportIfNotFunction(cx, v);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSFunction *)
|
||||
@ -488,7 +486,7 @@ JS_ValueToConstructor(JSContext *cx, jsval v)
|
||||
AssertNoGC(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, v);
|
||||
return js_ValueToFunction(cx, &v, JSV2F_SEARCH_STACK);
|
||||
return ReportIfNotFunction(cx, v);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSString *)
|
||||
@ -4612,12 +4610,7 @@ JS_CloneFunctionObject(JSContext *cx, JSObject *funobj, JSObject *parent_)
|
||||
}
|
||||
|
||||
if (!funobj->isFunction()) {
|
||||
/*
|
||||
* We cannot clone this object, so fail (we used to return funobj, bad
|
||||
* idea, but we changed incompatibly to teach any abusers a lesson!).
|
||||
*/
|
||||
Value v = ObjectValue(*funobj);
|
||||
js_ReportIsNotFunction(cx, &v, 0);
|
||||
ReportIsNotFunction(cx, ObjectValue(*funobj));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -3209,7 +3209,7 @@ array_readonlyCommon(JSContext *cx, CallArgs &args)
|
||||
js_ReportMissingArg(cx, args.calleev(), 0);
|
||||
return false;
|
||||
}
|
||||
RootedObject callable(cx, js_ValueToCallableObject(cx, &args[0], JSV2F_SEARCH_STACK));
|
||||
RootedObject callable(cx, ValueToCallable(cx, &args[0]));
|
||||
if (!callable)
|
||||
return false;
|
||||
|
||||
@ -3301,7 +3301,7 @@ array_map(JSContext *cx, unsigned argc, Value *vp)
|
||||
js_ReportMissingArg(cx, args.calleev(), 0);
|
||||
return false;
|
||||
}
|
||||
RootedObject callable(cx, js_ValueToCallableObject(cx, &args[0], JSV2F_SEARCH_STACK));
|
||||
RootedObject callable(cx, ValueToCallable(cx, &args[0]));
|
||||
if (!callable)
|
||||
return false;
|
||||
|
||||
@ -3377,7 +3377,7 @@ array_filter(JSContext *cx, unsigned argc, Value *vp)
|
||||
js_ReportMissingArg(cx, args.calleev(), 0);
|
||||
return false;
|
||||
}
|
||||
RootedObject callable(cx, js_ValueToCallableObject(cx, &args[0], JSV2F_SEARCH_STACK));
|
||||
RootedObject callable(cx, ValueToCallable(cx, &args[0]));
|
||||
if (!callable)
|
||||
return false;
|
||||
|
||||
@ -3485,7 +3485,7 @@ array_reduceCommon(JSContext *cx, CallArgs &args)
|
||||
js_ReportMissingArg(cx, args.calleev(), 0);
|
||||
return false;
|
||||
}
|
||||
JSObject *callable = js_ValueToCallableObject(cx, &args[0], JSV2F_SEARCH_STACK);
|
||||
JSObject *callable = ValueToCallable(cx, &args[0]);
|
||||
if (!callable)
|
||||
return false;
|
||||
|
||||
|
@ -1350,63 +1350,3 @@ js_DefineFunction(JSContext *cx, HandleObject obj, HandleId id, Native native,
|
||||
|
||||
return fun;
|
||||
}
|
||||
|
||||
JS_STATIC_ASSERT((JSV2F_CONSTRUCT & JSV2F_SEARCH_STACK) == 0);
|
||||
|
||||
JSFunction *
|
||||
js_ValueToFunction(JSContext *cx, const Value *vp, unsigned flags)
|
||||
{
|
||||
JSFunction *fun;
|
||||
if (!IsFunctionObject(*vp, &fun)) {
|
||||
js_ReportIsNotFunction(cx, vp, flags);
|
||||
return NULL;
|
||||
}
|
||||
return fun;
|
||||
}
|
||||
|
||||
JSObject *
|
||||
js_ValueToCallableObject(JSContext *cx, Value *vp, unsigned flags)
|
||||
{
|
||||
if (vp->isObject()) {
|
||||
JSObject *callable = &vp->toObject();
|
||||
if (callable->isCallable())
|
||||
return callable;
|
||||
}
|
||||
|
||||
js_ReportIsNotFunction(cx, vp, flags);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
js_ReportIsNotFunction(JSContext *cx, const Value *vp, unsigned flags)
|
||||
{
|
||||
const char *name = NULL, *source = NULL;
|
||||
unsigned error = (flags & JSV2F_CONSTRUCT) ? JSMSG_NOT_CONSTRUCTOR : JSMSG_NOT_FUNCTION;
|
||||
|
||||
/*
|
||||
* We try to the print the code that produced vp if vp is a value in the
|
||||
* most recent interpreted stack frame. Note that additional values, not
|
||||
* directly produced by the script, may have been pushed onto the frame's
|
||||
* expression stack (e.g. by pushInvokeArgs) thereby incrementing sp past
|
||||
* the depth simulated by ReconstructPCStack.
|
||||
*
|
||||
* Conversely, values may have been popped from the stack in preparation
|
||||
* for a call (e.g., by SplatApplyArgs). Since we must pass an offset from
|
||||
* the top of the simulated stack to js_ReportValueError3, we do bounds
|
||||
* checking using the minimum of both the simulated and actual stack depth.
|
||||
*/
|
||||
ptrdiff_t spindex = 0;
|
||||
|
||||
ScriptFrameIter i(cx);
|
||||
if (!i.done()) {
|
||||
unsigned depth = js_ReconstructStackDepth(cx, i.script(), i.pc());
|
||||
Value *simsp = i.fp()->base() + depth;
|
||||
if (i.fp()->base() <= vp && vp < Min(simsp, i.spFuzzy()))
|
||||
spindex = vp - simsp;
|
||||
}
|
||||
|
||||
if (!spindex)
|
||||
spindex = ((flags & JSV2F_SEARCH_STACK) ? JSDVG_SEARCH_STACK : JSDVG_IGNORE_STACK);
|
||||
|
||||
js_ReportValueError3(cx, error, spindex, *vp, NULL, name, source);
|
||||
}
|
||||
|
@ -219,21 +219,6 @@ js_DefineFunction(JSContext *cx, js::HandleObject obj, js::HandleId id, JSNative
|
||||
unsigned nargs, unsigned flags,
|
||||
js::gc::AllocKind kind = JSFunction::FinalizeKind);
|
||||
|
||||
/*
|
||||
* Flags for js_ValueToFunction and js_ReportIsNotFunction.
|
||||
*/
|
||||
#define JSV2F_CONSTRUCT INITIAL_CONSTRUCT
|
||||
#define JSV2F_SEARCH_STACK 0x10000
|
||||
|
||||
extern JSFunction *
|
||||
js_ValueToFunction(JSContext *cx, const js::Value *vp, unsigned flags);
|
||||
|
||||
extern JSObject *
|
||||
js_ValueToCallableObject(JSContext *cx, js::Value *vp, unsigned flags);
|
||||
|
||||
extern void
|
||||
js_ReportIsNotFunction(JSContext *cx, const js::Value *vp, unsigned flags);
|
||||
|
||||
namespace js {
|
||||
|
||||
/*
|
||||
|
@ -216,6 +216,36 @@ NoSuchMethod(JSContext *cx, unsigned argc, Value *vp)
|
||||
|
||||
#endif /* JS_HAS_NO_SUCH_METHOD */
|
||||
|
||||
bool
|
||||
js::ReportIsNotFunction(JSContext *cx, const Value &v, MaybeConstruct construct)
|
||||
{
|
||||
unsigned error = construct ? JSMSG_NOT_CONSTRUCTOR : JSMSG_NOT_FUNCTION;
|
||||
js_ReportValueError3(cx, error, JSDVG_SEARCH_STACK, v, NULL, NULL, NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
js::ReportIsNotFunction(JSContext *cx, const Value *vp, MaybeConstruct construct)
|
||||
{
|
||||
ptrdiff_t spIndex = cx->stack.spIndexOf(vp);
|
||||
unsigned error = construct ? JSMSG_NOT_CONSTRUCTOR : JSMSG_NOT_FUNCTION;
|
||||
js_ReportValueError3(cx, error, spIndex, *vp, NULL, NULL, NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
JSObject *
|
||||
js::ValueToCallable(JSContext *cx, const Value *vp, MaybeConstruct construct)
|
||||
{
|
||||
if (vp->isObject()) {
|
||||
JSObject *callable = &vp->toObject();
|
||||
if (callable->isCallable())
|
||||
return callable;
|
||||
}
|
||||
|
||||
ReportIsNotFunction(cx, vp, construct);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool
|
||||
js::RunScript(JSContext *cx, JSScript *script, StackFrame *fp)
|
||||
{
|
||||
@ -282,10 +312,8 @@ js::InvokeKernel(JSContext *cx, CallArgs args, MaybeConstruct construct)
|
||||
/* MaybeConstruct is a subset of InitialFrameFlags */
|
||||
InitialFrameFlags initial = (InitialFrameFlags) construct;
|
||||
|
||||
if (args.calleev().isPrimitive()) {
|
||||
js_ReportIsNotFunction(cx, &args.calleev(), ToReportFlags(initial));
|
||||
return false;
|
||||
}
|
||||
if (args.calleev().isPrimitive())
|
||||
return ReportIsNotFunction(cx, &args.calleev(), construct);
|
||||
|
||||
JSObject &callee = args.callee();
|
||||
Class *clasp = callee.getClass();
|
||||
@ -297,10 +325,8 @@ js::InvokeKernel(JSContext *cx, CallArgs args, MaybeConstruct construct)
|
||||
return NoSuchMethod(cx, args.length(), args.base());
|
||||
#endif
|
||||
JS_ASSERT_IF(construct, !clasp->construct);
|
||||
if (!clasp->call) {
|
||||
js_ReportIsNotFunction(cx, &args.calleev(), ToReportFlags(initial));
|
||||
return false;
|
||||
}
|
||||
if (!clasp->call)
|
||||
return ReportIsNotFunction(cx, &args.calleev(), construct);
|
||||
return CallJSNative(cx, clasp->call, args);
|
||||
}
|
||||
|
||||
@ -359,42 +385,41 @@ js::Invoke(JSContext *cx, const Value &thisv, const Value &fval, unsigned argc,
|
||||
}
|
||||
|
||||
bool
|
||||
js::InvokeConstructorKernel(JSContext *cx, const CallArgs &argsRef)
|
||||
js::InvokeConstructorKernel(JSContext *cx, CallArgs args)
|
||||
{
|
||||
JS_ASSERT(!FunctionClass.construct);
|
||||
CallArgs args = argsRef;
|
||||
|
||||
args.thisv().setMagic(JS_IS_CONSTRUCTING);
|
||||
|
||||
if (args.calleev().isObject()) {
|
||||
JSObject *callee = &args.callee();
|
||||
Class *clasp = callee->getClass();
|
||||
if (clasp == &FunctionClass) {
|
||||
JSFunction *fun = callee->toFunction();
|
||||
if (!args.calleev().isObject())
|
||||
return ReportIsNotFunction(cx, &args.calleev(), CONSTRUCT);
|
||||
|
||||
if (fun->isNativeConstructor()) {
|
||||
Probes::calloutBegin(cx, fun);
|
||||
bool ok = CallJSNativeConstructor(cx, fun->native(), args);
|
||||
Probes::calloutEnd(cx, fun);
|
||||
return ok;
|
||||
}
|
||||
JSObject &callee = args.callee();
|
||||
if (callee.isFunction()) {
|
||||
JSFunction *fun = callee.toFunction();
|
||||
|
||||
if (!fun->isInterpretedConstructor())
|
||||
goto error;
|
||||
|
||||
if (!InvokeKernel(cx, args, CONSTRUCT))
|
||||
return false;
|
||||
|
||||
JS_ASSERT(args.rval().isObject());
|
||||
return true;
|
||||
if (fun->isNativeConstructor()) {
|
||||
Probes::calloutBegin(cx, fun);
|
||||
bool ok = CallJSNativeConstructor(cx, fun->native(), args);
|
||||
Probes::calloutEnd(cx, fun);
|
||||
return ok;
|
||||
}
|
||||
if (clasp->construct)
|
||||
return CallJSNativeConstructor(cx, clasp->construct, args);
|
||||
|
||||
if (!fun->isInterpretedConstructor())
|
||||
return ReportIsNotFunction(cx, &args.calleev(), CONSTRUCT);
|
||||
|
||||
if (!InvokeKernel(cx, args, CONSTRUCT))
|
||||
return false;
|
||||
|
||||
JS_ASSERT(args.rval().isObject());
|
||||
return true;
|
||||
}
|
||||
|
||||
error:
|
||||
js_ReportIsNotFunction(cx, &args.calleev(), JSV2F_CONSTRUCT);
|
||||
return false;
|
||||
Class *clasp = callee.getClass();
|
||||
if (!clasp->construct)
|
||||
return ReportIsNotFunction(cx, &args.calleev(), CONSTRUCT);
|
||||
|
||||
return CallJSNativeConstructor(cx, clasp->construct, args);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -3226,7 +3251,7 @@ BEGIN_CASE(JSOP_SPREAD)
|
||||
regs.sp--;
|
||||
}
|
||||
END_CASE(JSOP_SPREAD)
|
||||
|
||||
|
||||
{
|
||||
BEGIN_CASE(JSOP_GOSUB)
|
||||
PUSH_BOOLEAN(false);
|
||||
|
@ -81,6 +81,25 @@ enum MaybeConstruct {
|
||||
CONSTRUCT = INITIAL_CONSTRUCT
|
||||
};
|
||||
|
||||
extern bool
|
||||
ReportIsNotFunction(JSContext *cx, const Value &v, MaybeConstruct construct = NO_CONSTRUCT);
|
||||
|
||||
extern bool
|
||||
ReportIsNotFunction(JSContext *cx, const Value *vp, MaybeConstruct construct = NO_CONSTRUCT);
|
||||
|
||||
extern JSObject *
|
||||
ValueToCallable(JSContext *cx, const Value *vp, MaybeConstruct construct = NO_CONSTRUCT);
|
||||
|
||||
inline JSFunction *
|
||||
ReportIfNotFunction(JSContext *cx, const Value &v, MaybeConstruct construct = NO_CONSTRUCT)
|
||||
{
|
||||
if (v.isObject() && v.toObject().isFunction())
|
||||
return v.toObject().toFunction();
|
||||
|
||||
ReportIsNotFunction(cx, v, construct);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* InvokeKernel assumes that the given args have been pushed on the top of the
|
||||
* VM stack. Additionally, if 'args' is contained in a CallArgsList, that they
|
||||
@ -124,7 +143,7 @@ InvokeGetterOrSetter(JSContext *cx, JSObject *obj, const Value &fval, unsigned a
|
||||
* (e.g. 'new') handling the the creation of the new 'this' object.
|
||||
*/
|
||||
extern bool
|
||||
InvokeConstructorKernel(JSContext *cx, const CallArgs &args);
|
||||
InvokeConstructorKernel(JSContext *cx, CallArgs args);
|
||||
|
||||
/* See the InvokeArgsGuard overload of Invoke. */
|
||||
inline bool
|
||||
|
@ -1190,7 +1190,7 @@ obj_watch(JSContext *cx, unsigned argc, Value *vp)
|
||||
return false;
|
||||
}
|
||||
|
||||
RootedObject callable(cx, js_ValueToCallableObject(cx, &vp[3], 0));
|
||||
RootedObject callable(cx, ValueToCallable(cx, &vp[3]));
|
||||
if (!callable)
|
||||
return false;
|
||||
|
||||
@ -6324,20 +6324,6 @@ js_DumpStackFrame(JSContext *cx, StackFrame *start)
|
||||
fprintf(stderr, " pc = %p\n", pc);
|
||||
fprintf(stderr, " current op: %s\n", js_CodeName[*pc]);
|
||||
}
|
||||
Value *sp = i.spFuzzy();
|
||||
fprintf(stderr, " slots: %p\n", (void *) fp->slots());
|
||||
fprintf(stderr, " sp: %p = slots + %u\n", (void *) sp, (unsigned) (sp - fp->slots()));
|
||||
if (sp - fp->slots() < 10000) { // sanity
|
||||
for (Value *p = fp->slots(); p < sp; p++) {
|
||||
fprintf(stderr, " %p: ", (void *) p);
|
||||
dumpValue(*p);
|
||||
fputc('\n', stderr);
|
||||
}
|
||||
}
|
||||
if (fp->hasArgs()) {
|
||||
fprintf(stderr, " actuals: %p (%u) ", (void *) fp->actuals(), (unsigned) fp->numActualArgs());
|
||||
fprintf(stderr, " formals: %p (%u)\n", (void *) fp->formals(), (unsigned) fp->numFormalArgs());
|
||||
}
|
||||
MaybeDumpObject("blockChain", fp->maybeBlockChain());
|
||||
if (!fp->isDummyFrame()) {
|
||||
MaybeDumpValue("this", fp->thisValue());
|
||||
|
@ -264,18 +264,14 @@ bool
|
||||
BaseProxyHandler::call(JSContext *cx, JSObject *proxy, unsigned argc,
|
||||
Value *vp)
|
||||
{
|
||||
Value v = UndefinedValue();
|
||||
js_ReportIsNotFunction(cx, &v, 0);
|
||||
return false;
|
||||
return ReportIsNotFunction(cx, UndefinedValue());
|
||||
}
|
||||
|
||||
bool
|
||||
BaseProxyHandler::construct(JSContext *cx, JSObject *proxy, unsigned argc,
|
||||
Value *argv, Value *rval)
|
||||
{
|
||||
Value v = UndefinedValue();
|
||||
js_ReportIsNotFunction(cx, &v, JSV2F_CONSTRUCT);
|
||||
return false;
|
||||
return ReportIsNotFunction(cx, UndefinedValue(), CONSTRUCT);
|
||||
}
|
||||
|
||||
JSString *
|
||||
@ -1819,12 +1815,12 @@ proxy_createFunction(JSContext *cx, unsigned argc, Value *vp)
|
||||
return false;
|
||||
parent = proto->getParent();
|
||||
|
||||
JSObject *call = js_ValueToCallableObject(cx, &vp[3], JSV2F_SEARCH_STACK);
|
||||
JSObject *call = ValueToCallable(cx, &vp[3]);
|
||||
if (!call)
|
||||
return false;
|
||||
JSObject *construct = NULL;
|
||||
if (argc > 2) {
|
||||
construct = js_ValueToCallableObject(cx, &vp[4], JSV2F_SEARCH_STACK);
|
||||
construct = ValueToCallable(cx, &vp[4]);
|
||||
if (!construct)
|
||||
return false;
|
||||
}
|
||||
|
@ -351,8 +351,7 @@ DirectWrapper::fun_toString(JSContext *cx, JSObject *wrapper, unsigned indent)
|
||||
// Perform some default behavior that doesn't leak any information.
|
||||
if (wrapper->isCallable())
|
||||
return JS_NewStringCopyZ(cx, "function () {\n [native code]\n}");
|
||||
js::Value v = ObjectValue(*wrapper);
|
||||
js_ReportIsNotFunction(cx, &v, 0);
|
||||
ReportIsNotFunction(cx, ObjectValue(*wrapper));
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
|
@ -9,9 +9,9 @@ function checkConstruct(thing, buggy) {
|
||||
assertEq(0, 1, "not reached " + thing);
|
||||
} catch (e) {
|
||||
if (buggy)
|
||||
assertEq(e.message, "new thing is not a constructor");
|
||||
assertEq(String(e.message).indexOf("is not a constructor") === -1, false);
|
||||
else
|
||||
assertEq(e.message, "thing is not a constructor");
|
||||
assertEq(String(e.message).indexOf("thing is not a constructor") === -1, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -142,17 +142,17 @@ function test()
|
||||
} catch (e) {
|
||||
s = e + "";
|
||||
}
|
||||
expect("TypeError: o.hello() is not a function", s);
|
||||
expect("TypeError: ({}) is not a function", s);
|
||||
s = "no exception";
|
||||
try {
|
||||
eval("o.hello()");
|
||||
} catch (e) {
|
||||
s = e + "";
|
||||
}
|
||||
expect("TypeError: o.hello() is not a function", s);
|
||||
expect("TypeError: ({}) is not a function", s);
|
||||
s = "no exception";
|
||||
try { [2, 3, 0].sort({}); } catch (e) { s = e + ""; }
|
||||
expect("TypeError: [2, 3, 0].sort({}) is not a function", s);
|
||||
expect("TypeError: ({}) is not a function", s);
|
||||
|
||||
/*
|
||||
* Generator expressions.
|
||||
|
@ -1581,17 +1581,14 @@ Debugger::setHookImpl(JSContext *cx, unsigned argc, Value *vp, Hook which)
|
||||
JS_ASSERT(which >= 0 && which < HookCount);
|
||||
REQUIRE_ARGC("Debugger.setHook", 1);
|
||||
THIS_DEBUGGER(cx, argc, vp, "setHook", args, dbg);
|
||||
const Value &v = args[0];
|
||||
if (v.isObject()) {
|
||||
if (!v.toObject().isCallable()) {
|
||||
js_ReportIsNotFunction(cx, vp, JSV2F_SEARCH_STACK);
|
||||
return false;
|
||||
}
|
||||
} else if (!v.isUndefined()) {
|
||||
if (args[0].isObject()) {
|
||||
if (!args[0].toObject().isCallable())
|
||||
return ReportIsNotFunction(cx, &args[0]);
|
||||
} else if (!args[0].isUndefined()) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NOT_CALLABLE_OR_UNDEFINED);
|
||||
return false;
|
||||
}
|
||||
dbg->object->setReservedSlot(JSSLOT_DEBUG_HOOK_START + which, v);
|
||||
dbg->object->setReservedSlot(JSSLOT_DEBUG_HOOK_START + which, args[0]);
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ js::ReportIncompatibleMethod(JSContext *cx, CallReceiver call, Class *clasp)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (JSFunction *fun = js_ValueToFunction(cx, &call.calleev(), 0)) {
|
||||
if (JSFunction *fun = ReportIfNotFunction(cx, call.calleev())) {
|
||||
JSAutoByteString funNameBytes;
|
||||
if (const char *funName = GetFunctionNameBytes(cx, fun, &funNameBytes)) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_INCOMPATIBLE_PROTO,
|
||||
|
@ -798,6 +798,20 @@ ContextStack::~ContextStack()
|
||||
JS_ASSERT(!seg_);
|
||||
}
|
||||
|
||||
ptrdiff_t
|
||||
ContextStack::spIndexOf(const Value *vp)
|
||||
{
|
||||
if (!hasfp() || !fp()->isScriptFrame())
|
||||
return JSDVG_SEARCH_STACK;
|
||||
|
||||
Value *base = fp()->base();
|
||||
Value *sp = regs().sp;
|
||||
if (vp < base || vp >= sp)
|
||||
return JSDVG_SEARCH_STACK;
|
||||
|
||||
return vp - sp;
|
||||
}
|
||||
|
||||
bool
|
||||
ContextStack::onTop() const
|
||||
{
|
||||
@ -1154,7 +1168,6 @@ ContextStack::restoreFrameChain()
|
||||
void
|
||||
StackIter::poisonRegs()
|
||||
{
|
||||
sp_ = (Value *)0xbad;
|
||||
pc_ = (jsbytecode *)0xbad;
|
||||
script_ = (JSScript *)0xbad;
|
||||
}
|
||||
@ -1169,36 +1182,6 @@ StackIter::popFrame()
|
||||
InlinedSite *inline_;
|
||||
pc_ = oldfp->prevpc(&inline_);
|
||||
JS_ASSERT(!inline_);
|
||||
|
||||
/*
|
||||
* If there is a CallArgsList element between oldfp and fp_, then sp_
|
||||
* is ignored, so we only consider the case where there is no
|
||||
* intervening CallArgsList. The stack representation is not optimized
|
||||
* for this operation so we need to do a full case analysis of how
|
||||
* frames are pushed by considering each ContextStack::push*Frame.
|
||||
*/
|
||||
if (oldfp->isGeneratorFrame()) {
|
||||
/* Generator's args do not overlap with the caller's expr stack. */
|
||||
sp_ = oldfp->generatorArgsSnapshotBegin();
|
||||
} else if (oldfp->isNonEvalFunctionFrame()) {
|
||||
/*
|
||||
* When Invoke is called from a native, there will be an enclosing
|
||||
* pushInvokeArgs which pushes a CallArgsList element so we can
|
||||
* ignore that case. The other two cases of function call frames are
|
||||
* Invoke called directly from script and pushInlineFrmae. In both
|
||||
* cases, the actual arguments of the callee should be included in
|
||||
* the caller's expr stack.
|
||||
*/
|
||||
sp_ = oldfp->actuals() + oldfp->numActualArgs();
|
||||
} else if (oldfp->isFramePushedByExecute()) {
|
||||
/* pushExecuteFrame pushes exactly (callee, this) before frame. */
|
||||
sp_ = (Value *)oldfp - 2;
|
||||
} else {
|
||||
/* pushDummyFrame pushes exactly 0 slots before frame. */
|
||||
JS_ASSERT(oldfp->isDummyFrame());
|
||||
sp_ = (Value *)oldfp;
|
||||
}
|
||||
|
||||
script_ = fp_->maybeScript();
|
||||
} else {
|
||||
poisonRegs();
|
||||
@ -1211,19 +1194,14 @@ StackIter::popCall()
|
||||
CallArgsList *oldCall = calls_;
|
||||
JS_ASSERT(seg_->contains(oldCall));
|
||||
calls_ = calls_->prev();
|
||||
if (seg_->contains(fp_)) {
|
||||
/* pc_ keeps its same value. */
|
||||
sp_ = oldCall->base();
|
||||
} else {
|
||||
if (!seg_->contains(fp_))
|
||||
poisonRegs();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
StackIter::settleOnNewSegment()
|
||||
{
|
||||
if (FrameRegs *regs = seg_->maybeRegs()) {
|
||||
sp_ = regs->sp;
|
||||
pc_ = regs->pc;
|
||||
if (fp_)
|
||||
script_ = fp_->maybeScript();
|
||||
@ -1317,17 +1295,6 @@ StackIter::settleOnNewState()
|
||||
|
||||
state_ = SCRIPTED;
|
||||
script_ = fp_->script();
|
||||
|
||||
/*
|
||||
* Check sp and pc. JM's getter ICs may push 2 extra values on the
|
||||
* stack; this is okay since the methodjit reserves some extra slots
|
||||
* for loop temporaries.
|
||||
*/
|
||||
if (*pc_ == JSOP_GETPROP || *pc_ == JSOP_CALLPROP)
|
||||
JS_ASSERT(sp_ >= fp_->base() && sp_ <= fp_->slots() + script_->nslots + 2);
|
||||
else if (*pc_ != JSOP_FUNAPPLY)
|
||||
JS_ASSERT(sp_ >= fp_->base() && sp_ <= fp_->slots() + script_->nslots);
|
||||
JS_ASSERT(pc_ >= script_->code && pc_ < script_->code + script_->length);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -411,8 +411,6 @@ class StackFrame
|
||||
friend class CallObject;
|
||||
friend class ClonedBlockObject;
|
||||
friend class ArgumentsObject;
|
||||
friend void ::js_DumpStackFrame(JSContext *, StackFrame *);
|
||||
friend void ::js_ReportIsNotFunction(JSContext *, const js::Value *, unsigned);
|
||||
#ifdef JS_METHODJIT
|
||||
friend class mjit::CallCompiler;
|
||||
friend class mjit::GetPropCompiler;
|
||||
@ -1140,12 +1138,6 @@ class StackFrame
|
||||
|
||||
static const size_t VALUES_PER_STACK_FRAME = sizeof(StackFrame) / sizeof(Value);
|
||||
|
||||
static inline unsigned
|
||||
ToReportFlags(InitialFrameFlags initial)
|
||||
{
|
||||
return unsigned(initial & StackFrame::CONSTRUCTING);
|
||||
}
|
||||
|
||||
static inline StackFrame::Flags
|
||||
ToFrameFlags(InitialFrameFlags initial)
|
||||
{
|
||||
@ -1587,6 +1579,14 @@ class ContextStack
|
||||
*/
|
||||
inline bool hasfp() const { return seg_ && seg_->maybeRegs(); }
|
||||
|
||||
/*
|
||||
* Return the spindex value for 'vp' which can be used to call
|
||||
* DecompileValueGenerator. (The spindex is either the negative offset of
|
||||
* 'vp' from 'sp', if 'vp' points to a value in the innermost scripted
|
||||
* stack frame, otherwise it is JSDVG_SEARCH_STACK.)
|
||||
*/
|
||||
ptrdiff_t spIndexOf(const Value *vp);
|
||||
|
||||
/*
|
||||
* Return the most recent script activation's registers with the same
|
||||
* caveat as hasfp regarding JS_SaveFrameChain.
|
||||
@ -1783,7 +1783,6 @@ class StackIter
|
||||
CallArgsList *calls_;
|
||||
|
||||
StackSegment *seg_;
|
||||
Value *sp_;
|
||||
jsbytecode *pc_;
|
||||
JSScript *script_;
|
||||
CallArgs args_;
|
||||
@ -1823,14 +1822,6 @@ class StackIter
|
||||
Value calleev() const;
|
||||
Value thisv() const;
|
||||
|
||||
/*
|
||||
* 'spFuzzy' is a best-effort approximiation of the frame's sp. It is only
|
||||
* guaranteed to point to a safe range above fp's base and below fp's next.
|
||||
* Ideally, we'd remove this altogether... wait, I'll do that in the next
|
||||
* patch.
|
||||
*/
|
||||
Value *spFuzzy() const { JS_ASSERT(isScript()); return sp_; }
|
||||
|
||||
CallArgs nativeArgs() const { JS_ASSERT(isNativeCall()); return args_; }
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user