[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: KDE/kdelibs/kjs
From: Maks Orlovich <maksim () kde ! org>
Date: 2010-05-01 17:37:56
Message-ID: 20100501173756.1A567AC8AA () svn ! kde ! org
[Download RAW message or body]
SVN commit 1121561 by orlovich:
Simplify the call sequence a bit more, by hoisting some of the debugger checks
out to the compiler. Maybe a tiny speedup, too.
M +24 -7 bytecode/codes.def
M +28 -0 bytecode/machine.cpp.in
M +0 -21 function.cpp
M +5 -0 function.h
M +32 -3 nodes2bytecode.cpp
--- trunk/KDE/kdelibs/kjs/bytecode/codes.def #1121560:1121561
@@ -240,12 +240,6 @@
]]
}
-operation ExitEval[endsBB] {
- impl void(value val) [[
- return val;
- ]]
-}
-
operation Jump[endsBB] {
impl void jmp(addr dest) [[
pc = base + dest;
@@ -411,6 +405,17 @@
]]
}
+operation ReactivateCompletionDebug {
+ // version for inside functions + debug mode, which calls ExitContext
+ impl void(bool insideFinally, node n) [[
+ JSValue* retVal = exec->reactivateCompletion(insideFinally);
+ if (retVal) {
+ changeDebugContext(Exit, exec, n);
+ return retVal;
+ }
+ ]]
+}
+
operation Throw {
impl void throw(value exception) [[
exec->setException(exception);
@@ -438,7 +443,7 @@
]]
}
-operation Return {
+operation Return[endsBB] {
impl void return (value retVal) [[
return retVal;
]]
@@ -459,6 +464,18 @@
]]
}
+operation EnterDebugContext {
+ impl void(node n) [[
+ changeDebugContext(Enter, exec, n);
+ ]]
+}
+
+operation ExitDebugContext {
+ impl void(node n) [[
+ changeDebugContext(Exit, exec, n);
+ ]]
+}
+
// Variable stuff... Locals access can just use register addressing,
// not specific get/put, but when we have to do symbolic lookup, we use these.
--- trunk/KDE/kdelibs/kjs/bytecode/machine.cpp.in #1121560:1121561
@@ -31,6 +31,7 @@
#include "scriptfunction.h"
#include "internal.h" // for printInfo
#include "ustring.h"
+#include "debugger.h"
#include <stdio.h>
@@ -175,6 +176,33 @@
return ret;
}
+enum Dir { Enter, Exit };
+
+NEVER_INLINE void changeDebugContext(Dir d, ExecState* exec, Node* n) {
+ FunctionBodyNode* body = static_cast<FunctionBodyNode*>(n);
+ Debugger* dbg = exec->dynamicInterpreter()->debugger();
+ List args;
+ FunctionImp* fn = 0;
+
+ // Find the activation that contains arguments, fn
+ const ScopeChain& chain = exec->scopeChain();
+ for (ScopeChainIterator iter = chain.begin(); iter != chain.end(); ++iter) {
+ JSObject* scopeObj = *iter;
+
+ if (scopeObj->isActivation()) {
+ ActivationImp* act = static_cast<ActivationImp*>(scopeObj);
+ args = act->passedInArguments();
+ fn = static_cast<FunctionImp*>(act->function());
+ break;
+ }
+ }
+
+ if (d == Enter)
+ dbg->enterContext(exec, body->sourceId(), body->firstLine(), fn, args);
+ else
+ dbg->exitContext(exec, body->sourceId(), body->lastLine(), fn);
+}
+
struct DepthCleanup
{
~DepthCleanup() { --depth; }
--- trunk/KDE/kdelibs/kjs/function.cpp #1121560:1121561
@@ -165,14 +165,6 @@
activation->setup(&newExec, this, &args, stackSpace);
activation->tearOffNeededSlot() = body->tearOffAtEnd();
- if (dbg) {
- bool cont = dbg->enterContext(&newExec, body->sourceId(), body->firstLine(), this, args);
- if (!cont) {
- dbg->imp()->abort();
- return jsUndefined();
- }
- }
-
newExec.initLocalStorage(stackSpace, regs);
JSValue* result = Machine::runBlock(&newExec, body->code(), exec);
@@ -203,19 +195,6 @@
--callDepth;
#endif
- // The debugger may have been deallocated by now if the WebFrame
- // we were running in has been destroyed, so refetch it.
- // See http://bugs.webkit.org/show_bug.cgi?id=9477
- dbg = exec->dynamicInterpreter()->debugger();
-
- if (dbg) {
- int cont = dbg->exitContext(&newExec, body->sourceId(), body->lastLine(), this);
- if (!cont) {
- dbg->imp()->abort();
- return jsUndefined();
- }
- }
-
return result;
}
--- trunk/KDE/kdelibs/kjs/function.h #1121560:1121561
@@ -140,6 +140,11 @@
virtual bool isActivation() const { return true; }
void setupLocals(FunctionBodyNode* fbody);
void setupFunctionLocals(FunctionBodyNode* fbody, ExecState *exec);
+
+ const List& passedInArguments() const { return *arguments; }
+
+ // really FunctionImp, but type isn't declared yet
+ JSValue* function() { return functionSlot(); }
private:
JSValue*& functionSlot() {
return localStorage[FunctionSlot].val.valueVal;
--- trunk/KDE/kdelibs/kjs/nodes2bytecode.cpp #1121560:1121561
@@ -70,6 +70,18 @@
CodeGen::emitOp(comp, Op_AtStatement, 0, &me);
}
+static inline bool exitContextNeeded(CompileState* comp) {
+ return comp->compileType() == Debug &&
+ comp->codeType() == FunctionCode;
+}
+
+static void generateExitContextIfNeeded(CompileState* comp) {
+ if (exitContextNeeded(comp)) {
+ OpValue ourNode = OpValue::immNode(comp->functionBody());
+ CodeGen::emitOp(comp, Op_ExitDebugContext, 0, &ourNode);
+ }
+}
+
// ------------------------------ Basic literals -----------------------------------------
OpValue NullNode::generateEvalCode(CompileState*)
@@ -1405,6 +1417,9 @@
else
arg = value->generateEvalCode(comp);
+ if (!comp->inTryFinally())
+ generateExitContextIfNeeded(comp);
+
CodeGen::emitOp(comp, comp->inTryFinally() ? Op_ReturnInTryFinally : Op_Return, 0, &arg);
}
@@ -1525,7 +1540,13 @@
finallyBlock->generateExecCode(comp);
OpValue otherTryFinally = OpValue::immBool(comp->inTryFinally());
+
+ if (exitContextNeeded(comp)) {
+ OpValue ourNode = OpValue::immNode(comp->functionBody());
+ CodeGen::emitOp(comp, Op_ReactivateCompletionDebug, 0, &otherTryFinally, &ourNode);
+ } else {
CodeGen::emitOp(comp, Op_ReactivateCompletion, 0, &otherTryFinally);
+ }
comp->popNest();
}
}
@@ -1551,7 +1572,12 @@
comp->setEvalResultRegister(&evalResReg);
// There is no need to initialize this as everything will be set to undefined anyway
+ } else {
+ if (comp->compileType() == Debug) {
+ OpValue ourNode = OpValue::immNode(this);
+ CodeGen::emitOp(comp, Op_EnterDebugContext, 0, &ourNode);
}
+ }
// Set unwind..
Addr unwind = CodeGen::emitOp(comp, Op_PushExceptionHandler, 0, OpValue::dummyAddr());
@@ -1560,13 +1586,16 @@
BlockNode::generateExecCode(comp);
// Make sure we exit!
- if (comp->codeType() != FunctionCode)
- CodeGen::emitOp(comp, Op_ExitEval, 0, &evalResVal);
- else
+ if (comp->codeType() != FunctionCode) {
+ CodeGen::emitOp(comp, Op_Return, 0, &evalResVal);
+ } else {
+ generateExitContextIfNeeded(comp);
CodeGen::emitOp(comp, Op_Exit);
+ }
// Unwind stuff..
CodeGen::patchJumpToNext(comp, unwind, 0);
+ generateExitContextIfNeeded(comp);
CodeGen::emitOp(comp, Op_PropagateException);
}
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic