本文整理汇总了C++中JSStackFrame类的典型用法代码示例。如果您正苦于以下问题:C++ JSStackFrame类的具体用法?C++ JSStackFrame怎么用?C++ JSStackFrame使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了JSStackFrame类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: EvaluateExcessFrame
/*
* Given a frame newer than the entry frame, try to finish it. If it's at a
* return position, pop the frame. If it's at a safe point, execute it in
* Jaeger code. Otherwise, try to interpret until a safe point.
*
* While this function is guaranteed to make progress, it may not actually
* finish or pop the current frame. It can either:
* 1) Finalize a finished frame, or
* 2) Finish and finalize the frame in the Method JIT, or
* 3) Interpret, which can:
* a) Propagate an error, or
* b) Finish the frame, but not finalize it, or
* c) Abruptly leave at any point in the frame, or in a newer frame
* pushed by a call, that has method JIT'd code.
*/
static bool
EvaluateExcessFrame(VMFrame &f, JSStackFrame *entryFrame)
{
JSContext *cx = f.cx;
JSStackFrame *fp = cx->fp();
/*
* A "finished" frame is when the interpreter rested on a STOP,
* RETURN, RETRVAL, etc. We check for finished frames BEFORE looking
* for a safe point. If the frame was finished, we could have already
* called ScriptEpilogue(), and entering the JIT could call it twice.
*/
if (!fp->hasImacropc() && FrameIsFinished(cx))
return HandleFinishedFrame(f, entryFrame);
if (void *ncode = AtSafePoint(cx)) {
if (!JaegerShotAtSafePoint(cx, ncode))
return false;
InlineReturn(f);
AdvanceReturnPC(cx);
return true;
}
return PartialInterpret(f);
}
示例2: AtSafePoint
/* Returns whether the current PC has method JIT'd code. */
static inline void *
AtSafePoint(JSContext *cx)
{
JSStackFrame *fp = cx->fp();
if (fp->hasImacropc())
return false;
JSScript *script = fp->script();
return script->maybeNativeCodeForPC(fp->isConstructing(), cx->regs->pc);
}
示例3: THROW
void JS_FASTCALL
stubs::CreateThis(VMFrame &f, JSObject *proto)
{
JSContext *cx = f.cx;
JSStackFrame *fp = f.fp();
JSObject *callee = &fp->callee();
JSObject *obj = js_CreateThisForFunctionWithProto(cx, callee, proto);
if (!obj)
THROW();
fp->formalArgs()[-1].setObject(*obj);
}
示例4: UncachedInlineCall
static inline bool
UncachedInlineCall(VMFrame &f, uint32 flags, void **pret, bool *unjittable, uint32 argc)
{
JSContext *cx = f.cx;
Value *vp = f.regs.sp - (argc + 2);
JSObject &callee = vp->toObject();
JSFunction *newfun = callee.getFunctionPrivate();
JSScript *newscript = newfun->script();
/* Get pointer to new frame/slots, prepare arguments. */
StackSpace &stack = cx->stack();
JSStackFrame *newfp = stack.getInlineFrameWithinLimit(cx, f.regs.sp, argc,
newfun, newscript, &flags,
f.entryfp, &f.stackLimit);
if (JS_UNLIKELY(!newfp))
return false;
/* Initialize frame, locals. */
newfp->initCallFrame(cx, callee, newfun, argc, flags);
SetValueRangeToUndefined(newfp->slots(), newscript->nfixed);
/* Officially push the frame. */
stack.pushInlineFrame(cx, newscript, newfp, &f.regs);
JS_ASSERT(newfp == f.regs.fp);
/* Scope with a call object parented by callee's parent. */
if (newfun->isHeavyweight() && !js::CreateFunCallObject(cx, newfp))
return false;
/* Try to compile if not already compiled. */
if (newscript->getJITStatus(newfp->isConstructing()) == JITScript_None) {
CompileStatus status = CanMethodJIT(cx, newscript, newfp, CompileRequest_Interpreter);
if (status == Compile_Error) {
/* A runtime exception was thrown, get out. */
InlineReturn(f);
return false;
}
if (status == Compile_Abort)
*unjittable = true;
}
/* If newscript was successfully compiled, run it. */
if (JITScript *jit = newscript->getJIT(newfp->isConstructing())) {
*pret = jit->invokeEntry;
return true;
}
/* Otherwise, run newscript in the interpreter. */
bool ok = !!Interpret(cx, cx->fp());
InlineReturn(f);
*pret = NULL;
return ok;
}
示例5: InlineReturn
/*
* Clean up a frame and return.
*/
static void
InlineReturn(VMFrame &f)
{
JSContext *cx = f.cx;
JSStackFrame *fp = f.regs.fp;
JS_ASSERT(f.fp() != f.entryfp);
JS_ASSERT(!js_IsActiveWithOrBlock(cx, &fp->scopeChain(), 0));
Value *newsp = fp->actualArgs() - 1;
newsp[-1] = fp->returnValue();
cx->stack().popInlineFrame(cx, fp->prev(), newsp);
}
示例6: PartialInterpret
/*
* Interprets until either a safe point is reached that has method JIT'd
* code, or the current frame tries to return.
*/
static inline JSBool
PartialInterpret(VMFrame &f)
{
JSContext *cx = f.cx;
JSStackFrame *fp = cx->fp();
#ifdef DEBUG
JSScript *script = fp->script();
JS_ASSERT(!fp->finishedInInterpreter());
JS_ASSERT(fp->hasImacropc() ||
!script->maybeNativeCodeForPC(fp->isConstructing(), cx->regs->pc));
#endif
JSBool ok = JS_TRUE;
ok = Interpret(cx, fp, 0, JSINTERP_SAFEPOINT);
return ok;
}
示例7: THROWV
void * JS_FASTCALL
stubs::CompileFunction(VMFrame &f, uint32 nactual)
{
/*
* We have a partially constructed frame. That's not really good enough to
* compile though because we could throw, so get a full, adjusted frame.
*/
JSContext *cx = f.cx;
JSStackFrame *fp = f.fp();
/*
* Since we can only use members set by initCallFrameCallerHalf,
* we must carefully extract the callee from the nactual.
*/
JSObject &callee = fp->formalArgsEnd()[-(int(nactual) + 2)].toObject();
JSFunction *fun = callee.getFunctionPrivate();
JSScript *script = fun->script();
/*
* FixupArity/RemovePartialFrame expect to be called after the early
* prologue.
*/
fp->initCallFrameEarlyPrologue(fun, nactual);
if (nactual != fp->numFormalArgs()) {
fp = (JSStackFrame *)FixupArity(f, nactual);
if (!fp)
return NULL;
}
/* Finish frame initialization. */
fp->initCallFrameLatePrologue();
/* These would have been initialized by the prologue. */
f.regs.fp = fp;
f.regs.sp = fp->base();
f.regs.pc = script->code;
if (fun->isHeavyweight() && !js::CreateFunCallObject(cx, fp))
THROWV(NULL);
CompileStatus status = CanMethodJIT(cx, script, fp, CompileRequest_JIT);
if (status == Compile_Okay)
return script->getJIT(fp->isConstructing())->invokeEntry;
/* Function did not compile... interpret it. */
JSBool ok = Interpret(cx, fp);
InlineReturn(f);
if (!ok)
THROWV(NULL);
return NULL;
}
示例8: JS_ASSERT
/*
* This function must only be called after the early prologue, since it depends
* on fp->exec.fun.
*/
void * JS_FASTCALL
stubs::FixupArity(VMFrame &f, uint32 nactual)
{
JSContext *cx = f.cx;
JSStackFrame *oldfp = f.fp();
JS_ASSERT(nactual != oldfp->numFormalArgs());
/*
* Grossssss! *move* the stack frame. If this ends up being perf-critical,
* we can figure out how to spot-optimize it. Be careful to touch only the
* members that have been initialized by initCallFrameCallerHalf and the
* early prologue.
*/
uint32 flags = oldfp->isConstructingFlag();
JSFunction *fun = oldfp->fun();
void *ncode = oldfp->nativeReturnAddress();
/* Pop the inline frame. */
f.fp() = oldfp->prev();
f.regs.sp = (Value*) oldfp;
/* Reserve enough space for a callee frame. */
JSStackFrame *newfp = cx->stack().getInlineFrameWithinLimit(cx, (Value*) oldfp, nactual,
fun, fun->script(), &flags,
f.entryfp, &f.stackLimit);
if (!newfp) {
/*
* The PC is not coherent with the current frame, so fix it up for
* exception handling.
*/
f.regs.pc = f.jit()->nativeToPC(ncode);
THROWV(NULL);
}
/* Reset the part of the stack frame set by the caller. */
newfp->initCallFrameCallerHalf(cx, flags, ncode);
/* Reset the part of the stack frame set by the prologue up to now. */
newfp->initCallFrameEarlyPrologue(fun, nactual);
/* The caller takes care of assigning fp to regs. */
return newfp;
}
示例9:
void JS_FASTCALL
stubs::EnterScript(VMFrame &f)
{
JSStackFrame *fp = f.fp();
JSContext *cx = f.cx;
if (fp->script()->debugMode) {
if (fp->isExecuteFrame()) {
JSInterpreterHook hook = cx->debugHooks->executeHook;
if (JS_UNLIKELY(hook != NULL))
fp->setHookData(hook(cx, fp, JS_TRUE, 0, cx->debugHooks->executeHookData));
} else {
JSInterpreterHook hook = cx->debugHooks->callHook;
if (JS_UNLIKELY(hook != NULL))
fp->setHookData(hook(cx, fp, JS_TRUE, 0, cx->debugHooks->callHookData));
}
}
Probes::enterJSFun(cx, fp->maybeFun(), fp->script());
}
示例10: hook
void JS_FASTCALL
stubs::LeaveScript(VMFrame &f)
{
JSStackFrame *fp = f.fp();
JSContext *cx = f.cx;
Probes::exitJSFun(cx, fp->maybeFun(), fp->maybeScript());
if (fp->script()->debugMode) {
void *hookData;
JSInterpreterHook hook =
fp->isExecuteFrame() ? cx->debugHooks->executeHook : cx->debugHooks->callHook;
if (JS_UNLIKELY(hook != NULL) && (hookData = fp->maybeHookData())) {
JSBool ok = JS_TRUE;
hook(cx, fp, JS_FALSE, &ok, hookData);
if (!ok)
THROW();
}
}
}
示例11: RunTracer
void *
RunTracer(VMFrame &f)
#endif
{
JSContext *cx = f.cx;
JSStackFrame *entryFrame = f.fp();
TracePointAction tpa;
/* :TODO: nuke PIC? */
if (!cx->traceJitEnabled)
return NULL;
/*
* Force initialization of the entry frame's scope chain and return value,
* if necessary. The tracer can query the scope chain without needing to
* check the HAS_SCOPECHAIN flag, and the frame is guaranteed to have the
* correct return value stored if we trace/interpret through to the end
* of the frame.
*/
entryFrame->scopeChain();
entryFrame->returnValue();
bool blacklist;
uintN inlineCallCount = 0;
void **traceData;
uintN *traceEpoch;
uint32 *loopCounter;
uint32 hits;
#if JS_MONOIC
traceData = &ic.traceData;
traceEpoch = &ic.traceEpoch;
loopCounter = &ic.loopCounter;
*loopCounter = 1;
hits = ic.loopCounterStart;
#else
traceData = NULL;
traceEpoch = NULL;
loopCounter = NULL;
hits = 1;
#endif
tpa = MonitorTracePoint(f.cx, inlineCallCount, &blacklist, traceData, traceEpoch,
loopCounter, hits);
JS_ASSERT(!TRACE_RECORDER(cx));
#if JS_MONOIC
ic.loopCounterStart = *loopCounter;
if (blacklist)
DisableTraceHint(entryFrame->jit(), ic);
#endif
// Even though ExecuteTree() bypasses the interpreter, it should propagate
// error failures correctly.
JS_ASSERT_IF(cx->isExceptionPending(), tpa == TPA_Error);
f.fp() = cx->fp();
JS_ASSERT(f.fp() == cx->fp());
switch (tpa) {
case TPA_Nothing:
return NULL;
case TPA_Error:
if (!HandleErrorInExcessFrame(f, entryFrame, f.fp()->finishedInInterpreter()))
THROWV(NULL);
JS_ASSERT(!cx->fp()->hasImacropc());
break;
case TPA_RanStuff:
case TPA_Recorded:
break;
}
/*
* The tracer could have dropped us off on any frame at any position.
* Well, it could not have removed frames (recursion is disabled).
*
* Frames after the entryFrame cannot be entered via JaegerShotAtSafePoint()
* unless each is at a safe point. We can JaegerShotAtSafePoint these
* frames individually, but we must unwind to the entryFrame.
*
* Note carefully that JaegerShotAtSafePoint can resume methods at
* arbitrary safe points whereas JaegerShot cannot.
*
* If we land on entryFrame without a safe point in sight, we'll end up
* at the RETURN op. This is an edge case with two paths:
*
* 1) The entryFrame is the last inline frame. If it fell on a RETURN,
* move the return value down.
* 2) The entryFrame is NOT the last inline frame. Pop the frame.
*
* In both cases, we hijack the stub to return to the force-return
* trampoline. This trampoline simulates the frame-popping portion of
* emitReturn (except without the benefit of the FrameState) and will
* produce the necessary register state to return to the caller.
*/
restart:
/* Step 1. Finish frames created after the entry frame. */
if (!FinishExcessFrames(f, entryFrame))
THROWV(NULL);
//.........这里部分代码省略.........
示例12: FindExceptionHandler
static jsbytecode *
FindExceptionHandler(JSContext *cx)
{
JSStackFrame *fp = cx->fp();
JSScript *script = fp->script();
top:
if (cx->isExceptionPending() && JSScript::isValidOffset(script->trynotesOffset)) {
// The PC is updated before every stub call, so we can use it here.
unsigned offset = cx->regs->pc - script->main;
JSTryNoteArray *tnarray = script->trynotes();
for (unsigned i = 0; i < tnarray->length; ++i) {
JSTryNote *tn = &tnarray->vector[i];
// The following if condition actually tests two separate conditions:
// (1) offset - tn->start >= tn->length
// means the PC is not in the range of this try note, so we
// should continue searching, after considering:
// (2) offset - tn->start == tn->length
// means the PC is at the first op of the exception handler
// for this try note. This happens when an exception is thrown
// during recording: the interpreter sets the PC to the handler
// and then exits. In this case, we are in fact at the right
// exception handler.
//
// Hypothetically, the op we are at might have thrown an
// exception, in which case this would not be the right handler.
// But the first ops of exception handlers generated by our
// bytecode compiler cannot throw, so this is not possible.
if (offset - tn->start > tn->length)
continue;
if (tn->stackDepth > cx->regs->sp - fp->base())
continue;
jsbytecode *pc = script->main + tn->start + tn->length;
JSBool ok = js_UnwindScope(cx, tn->stackDepth, JS_TRUE);
JS_ASSERT(cx->regs->sp == fp->base() + tn->stackDepth);
switch (tn->kind) {
case JSTRY_CATCH:
JS_ASSERT(js_GetOpcode(cx, fp->script(), pc) == JSOP_ENTERBLOCK);
#if JS_HAS_GENERATORS
/* Catch cannot intercept the closing of a generator. */
if (JS_UNLIKELY(cx->getPendingException().isMagic(JS_GENERATOR_CLOSING)))
break;
#endif
/*
* Don't clear cx->throwing to save cx->exception from GC
* until it is pushed to the stack via [exception] in the
* catch block.
*/
return pc;
case JSTRY_FINALLY:
/*
* Push (true, exception) pair for finally to indicate that
* [retsub] should rethrow the exception.
*/
cx->regs->sp[0].setBoolean(true);
cx->regs->sp[1] = cx->getPendingException();
cx->regs->sp += 2;
cx->clearPendingException();
return pc;
case JSTRY_ITER:
{
/*
* This is similar to JSOP_ENDITER in the interpreter loop,
* except the code now uses the stack slot normally used by
* JSOP_NEXTITER, namely regs.sp[-1] before the regs.sp -= 2
* adjustment and regs.sp[1] after, to save and restore the
* pending exception.
*/
Value v = cx->getPendingException();
JS_ASSERT(js_GetOpcode(cx, fp->script(), pc) == JSOP_ENDITER);
cx->clearPendingException();
ok = !!js_CloseIterator(cx, &cx->regs->sp[-1].toObject());
cx->regs->sp -= 1;
if (!ok)
goto top;
cx->setPendingException(v);
}
}
}
}
return NULL;
}
示例13: HandleErrorInExcessFrame
/*
* Called when an error is in progress and the topmost frame could not handle
* it. This will unwind to a given frame, or find and align to an exception
* handler in the process.
*/
static inline bool
HandleErrorInExcessFrame(VMFrame &f, JSStackFrame *stopFp, bool searchedTopmostFrame = true)
{
JSContext *cx = f.cx;
/*
* Callers of this called either Interpret() or JaegerShot(), which would
* have searched for exception handlers already. If we see stopFp, just
* return false. Otherwise, pop the frame, since it's guaranteed useless.
*
* Note that this also guarantees ScriptEpilogue() has been called.
*/
JSStackFrame *fp = cx->fp();
if (searchedTopmostFrame) {
/*
* This is a special case meaning that fp->finishedInInterpreter() is
* true. If so, and fp == stopFp, our only choice is to propagate this
* error up, back to the method JIT, and then to js_InternalThrow,
* where this becomes a special case. See the comment there and bug
* 624100.
*/
if (fp == stopFp)
return false;
/*
* Otherwise, the protocol here (like Invoke) is to assume that the
* execution mode finished the frame, and to just pop it.
*/
InlineReturn(f);
}
/* Remove the bottom frame. */
bool returnOK = false;
for (;;) {
fp = cx->fp();
/* Clear imacros. */
if (fp->hasImacropc()) {
cx->regs->pc = fp->imacropc();
fp->clearImacropc();
}
JS_ASSERT(!fp->hasImacropc());
/* If there's an exception and a handler, set the pc and leave. */
if (cx->isExceptionPending()) {
jsbytecode *pc = FindExceptionHandler(cx);
if (pc) {
cx->regs->pc = pc;
returnOK = true;
break;
}
}
/* Don't unwind if this was the entry frame. */
if (fp == stopFp)
break;
/* Unwind and return. */
returnOK &= bool(js_UnwindScope(cx, 0, returnOK || cx->isExceptionPending()));
returnOK = ScriptEpilogue(cx, fp, returnOK);
InlineReturn(f);
}
JS_ASSERT(&f.regs == cx->regs);
JS_ASSERT_IF(!returnOK, cx->fp() == stopFp);
return returnOK;
}
示例14: js_InternalThrow
extern "C" void *
js_InternalThrow(VMFrame &f)
{
JSContext *cx = f.cx;
// It's possible that from within RunTracer(), Interpret() returned with
// an error and finished the frame (i.e., called ScriptEpilogue), but has
// not yet performed an inline return.
//
// In this case, RunTracer() has no choice but to propagate the error
// up to the method JIT, and thus to this function. But ScriptEpilogue()
// has already been called. Detect this, and avoid double-finishing the
// frame. See HandleErrorInExcessFrame() and bug 624100.
if (f.fp()->finishedInInterpreter()) {
// If it's the last frame, just propagate the failure up again.
if (f.fp() == f.entryfp)
return NULL;
InlineReturn(f);
}
// Make sure sp is up to date.
JS_ASSERT(cx->regs == &f.regs);
// Call the throw hook if necessary
JSThrowHook handler = f.cx->debugHooks->throwHook;
if (handler) {
Value rval;
switch (handler(cx, cx->fp()->script(), cx->regs->pc, Jsvalify(&rval),
cx->debugHooks->throwHookData)) {
case JSTRAP_ERROR:
cx->clearPendingException();
return NULL;
case JSTRAP_RETURN:
cx->clearPendingException();
cx->fp()->setReturnValue(rval);
return JS_FUNC_TO_DATA_PTR(void *,
cx->jaegerCompartment()->forceReturnTrampoline());
case JSTRAP_THROW:
cx->setPendingException(rval);
break;
default:
break;
}
}
jsbytecode *pc = NULL;
for (;;) {
pc = FindExceptionHandler(cx);
if (pc)
break;
// The JIT guarantees that ScriptEpilogue() has always been run
// upon exiting to its caller. This is important for consistency,
// where execution modes make similar guarantees about prologues
// and epilogues. RunTracer(), Interpret(), and Invoke() all
// rely on this property.
JS_ASSERT(!f.fp()->finishedInInterpreter());
js_UnwindScope(cx, 0, cx->isExceptionPending());
ScriptEpilogue(f.cx, f.fp(), false);
// Don't remove the last frame, this is the responsibility of
// JaegerShot()'s caller. We only guarantee that ScriptEpilogue()
// has been run.
if (f.entryfp == f.fp())
break;
JS_ASSERT(f.regs.sp == cx->regs->sp);
InlineReturn(f);
}
JS_ASSERT(f.regs.sp == cx->regs->sp);
if (!pc)
return NULL;
JSStackFrame *fp = cx->fp();
JSScript *script = fp->script();
return script->nativeCodeForPC(fp->isConstructing(), pc);
}
示例15: Exception
static JSBool
Exception(JSContext *cx, uintN argc, Value *vp)
{
JSString *message, *filename;
JSStackFrame *fp;
/*
* ECMA ed. 3, 15.11.1 requires Error, etc., to construct even when
* called as functions, without operator new. But as we do not give
* each constructor a distinct JSClass, whose .name member is used by
* NewNativeClassInstance to find the class prototype, we must get the
* class prototype ourselves.
*/
JSObject &callee = vp[0].toObject();
Value protov;
if (!callee.getProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.classPrototypeAtom), &protov))
return JS_FALSE;
if (!protov.isObject()) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_PROTOTYPE, "Error");
return JS_FALSE;
}
JSObject *errProto = &protov.toObject();
JSObject *obj = NewNativeClassInstance(cx, &js_ErrorClass, errProto, errProto->getParent());
if (!obj)
return JS_FALSE;
/*
* If it's a new object of class Exception, then null out the private
* data so that the finalizer doesn't attempt to free it.
*/
if (obj->getClass() == &js_ErrorClass)
obj->setPrivate(NULL);
/* Set the 'message' property. */
Value *argv = vp + 2;
if (argc != 0 && !argv[0].isUndefined()) {
message = js_ValueToString(cx, argv[0]);
if (!message)
return JS_FALSE;
argv[0].setString(message);
} else {
message = NULL;
}
/* Set the 'fileName' property. */
if (argc > 1) {
filename = js_ValueToString(cx, argv[1]);
if (!filename)
return JS_FALSE;
argv[1].setString(filename);
fp = NULL;
} else {
fp = js_GetScriptedCaller(cx, NULL);
if (fp) {
filename = FilenameToString(cx, fp->script()->filename);
if (!filename)
return JS_FALSE;
} else {
filename = cx->runtime->emptyString;
}
}
/* Set the 'lineNumber' property. */
uint32_t lineno;
if (argc > 2) {
if (!ValueToECMAUint32(cx, argv[2], &lineno))
return JS_FALSE;
} else {
if (!fp)
fp = js_GetScriptedCaller(cx, NULL);
lineno = (fp && fp->pc(cx)) ? js_FramePCToLineNumber(cx, fp) : 0;
}
if (obj->getClass() == &js_ErrorClass &&
!InitExnPrivate(cx, obj, message, filename, lineno, NULL)) {
return JS_FALSE;
}
vp->setObject(*obj);
return JS_TRUE;
}