void KJSDebugWin::slotEval() { // Work out which execution state to use. If we're currently in a debugging session, // use the current context - otherwise, use the global execution state from the interpreter // corresponding to the currently displayed source file. ExecState *exec; Object thisobj; if(m_execStates.isEmpty()) { if(m_sourceSel->currentItem() < 0) return; SourceFile *sourceFile = m_sourceSelFiles.at(m_sourceSel->currentItem()); if(!sourceFile->interpreter) return; exec = sourceFile->interpreter->globalExec(); thisobj = exec->interpreter()->globalObject(); } else { exec = m_execStates.top(); thisobj = exec->context().thisValue(); } // Evaluate the js code from m_evalEdit UString code(m_evalEdit->code()); QString msg; KJSCPUGuard guard; guard.start(); Interpreter *interp = exec->interpreter(); Object obj = Object::dynamicCast(interp->globalObject().get(exec, "eval")); List args; args.append(String(code)); m_evalDepth++; Value retval = obj.call(exec, thisobj, args); m_evalDepth--; guard.stop(); // Print the return value or exception message to the console if(exec->hadException()) { Value exc = exec->exception(); exec->clearException(); msg = "Exception: " + exc.toString(interp->globalExec()).qstring(); } else { msg = retval.toString(interp->globalExec()).qstring(); } m_evalEdit->insert(msg + "\n"); updateContextList(); }
JSStringRef JSContextCreateBacktrace(JSContextRef ctx, unsigned maxStackSize) { ExecState* exec = toJS(ctx); JSLock lock(exec); unsigned count = 0; UStringBuilder builder; CallFrame* callFrame = exec; UString functionName; if (exec->callee()) { if (asObject(exec->callee())->inherits(&InternalFunction::s_info)) { functionName = asInternalFunction(exec->callee())->name(exec); builder.append("#0 "); builder.append(functionName); builder.append("() "); count++; } } while (true) { ASSERT(callFrame); int signedLineNumber; intptr_t sourceID; UString urlString; JSValue function; UString levelStr = UString::number(count); exec->interpreter()->retrieveLastCaller(callFrame, signedLineNumber, sourceID, urlString, function); if (function) functionName = asFunction(function)->name(exec); else { // Caller is unknown, but if frame is empty we should still add the frame, because // something called us, and gave us arguments. if (count) break; } unsigned lineNumber = signedLineNumber >= 0 ? signedLineNumber : 0; if (!builder.isEmpty()) builder.append("\n"); builder.append("#"); builder.append(levelStr); builder.append(" "); builder.append(functionName); builder.append("() at "); builder.append(urlString); builder.append(":"); builder.append(UString::number(lineNumber)); if (!function || ++count == maxStackSize) break; callFrame = callFrame->callerFrame(); } return OpaqueJSString::create(builder.toUString()).leakRef(); }