Skip to content

Commit

Permalink
don't push frames while pushing frames
Browse files Browse the repository at this point in the history
  • Loading branch information
softwareCobbler committed Nov 19, 2024
1 parent 66a14bc commit 84d5ba6
Show file tree
Hide file tree
Showing 7 changed files with 467 additions and 411 deletions.
9 changes: 6 additions & 3 deletions luceedebug/src/main/java/luceedebug/Agent.java
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,6 @@ private static Map<String, Integer> linearizedCoreInjectClasses() {
result.put("luceedebug.coreinject.DebugManager$1", 0);
result.put("luceedebug.coreinject.ClosureScopeLocalScopeAccessorShim", 0);
result.put("luceedebug.coreinject.ComponentScopeMarkerTraitShim", 0);
result.put("luceedebug.coreinject.DebugFrame$FrameContext", 0);
result.put("luceedebug.coreinject.LuceeVm$SteppingState", 0);
result.put("luceedebug.coreinject.LuceeVm$KlassMap", 0);
result.put("luceedebug.coreinject.LuceeVm$JdwpWorker", 0);
Expand All @@ -165,21 +164,25 @@ private static Map<String, Integer> linearizedCoreInjectClasses() {
result.put("luceedebug.coreinject.CfValueDebuggerBridge$MarkerTrait", 0);
result.put("luceedebug.coreinject.ValTracker", 0);
result.put("luceedebug.coreinject.UnsafeUtils", 0);
result.put("luceedebug.coreinject.DebugFrame", 0);
result.put("luceedebug.coreinject.CfValueDebuggerBridge$MarkerTrait$Scope", 0);
result.put("luceedebug.coreinject.DebugManager$PageContextAndOutputStream", 0);
result.put("luceedebug.coreinject.LuceeVm$ThreadMap", 0);
result.put("luceedebug.coreinject.DebugManager", 0);
result.put("luceedebug.coreinject.LuceeVm$JdwpStaticCallable", 0);
result.put("luceedebug.coreinject.CfValueDebuggerBridge", 0);
result.put("luceedebug.coreinject.DebugFrame$FrameContext$SupplierOrNull", 0);
result.put("luceedebug.coreinject.LuceeVm", 0);
result.put("luceedebug.coreinject.ValTracker$CleanerRunner", 0);
result.put("luceedebug.coreinject.ExprEvaluator", 0);

result.put("luceedebug.coreinject.ExprEvaluator$Evaluator", 0);
result.put("luceedebug.coreinject.ExprEvaluator$Lucee6Evaluator", 1);
result.put("luceedebug.coreinject.ExprEvaluator$Lucee5Evaluator", 1);

result.put("luceedebug.coreinject.frame.DebugFrame", 0);
result.put("luceedebug.coreinject.frame.Frame", 1);
result.put("luceedebug.coreinject.frame.Frame$FrameContext", 1);
result.put("luceedebug.coreinject.frame.Frame$FrameContext$SupplierOrNull", 1);
result.put("luceedebug.coreinject.frame.DummyFrame", 1);

return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import lucee.runtime.type.Array;
import luceedebug.ICfValueDebuggerBridge;
import luceedebug.IDebugEntity;
import luceedebug.coreinject.frame.DebugFrame;
import luceedebug.coreinject.frame.Frame;

public class CfValueDebuggerBridge implements ICfValueDebuggerBridge {
// Pin some ephemeral evaluated things so they don't get GC'd immediately.
Expand All @@ -32,11 +32,11 @@ public static void pin(Object obj) {
pinnedObjects.put(System.identityHashCode(obj), obj);
}

private final DebugFrame frame;
private final Frame frame;
public final Object obj;
public final long id;

public CfValueDebuggerBridge(DebugFrame frame, Object obj) {
public CfValueDebuggerBridge(Frame frame, Object obj) {
this.frame = Objects.requireNonNull(frame);
this.obj = Objects.requireNonNull(obj);
this.id = frame.valTracker.idempotentRegisterObject(obj).id;
Expand All @@ -58,7 +58,7 @@ public Scope(Map<?,?> scopelike) {
/**
* @maybeNull_which --> null means "any type"
*/
public static IDebugEntity[] getAsDebugEntity(DebugFrame frame, Object obj, IDebugEntity.DebugEntityType maybeNull_which) {
public static IDebugEntity[] getAsDebugEntity(Frame frame, Object obj, IDebugEntity.DebugEntityType maybeNull_which) {
return getAsDebugEntity(frame.valTracker, obj, maybeNull_which);
}

Expand Down
94 changes: 52 additions & 42 deletions luceedebug/src/main/java/luceedebug/coreinject/DebugManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import luceedebug.IDebugFrame;
import luceedebug.IDebugManager;
import luceedebug.coreinject.frame.DebugFrame;
import luceedebug.coreinject.frame.Frame;

public class DebugManager implements IDebugManager {

Expand Down Expand Up @@ -328,36 +329,37 @@ synchronized private String doDumpAsJSON(PageContext pageContext, Object someDum
}

public Either</*err*/String, /*ok*/Either<ICfValueDebuggerBridge, String>> evaluate(Long frameID, String expr) {
final var frame = frameByFrameID.get(frameID);
if (frame != null) {
return doEvaluate(frame, expr)
.bimap(
err -> err,
ok -> {
// what about bool, Long, etc. ?...
if (ok == null) {
return Either.Right("null");
}
else if (ok instanceof String) {
return Either.Right("\"" + ((String)ok).replaceAll("\"", "\\\"") + "\"");
}
else if (ok instanceof Number || ok instanceof Boolean) {
return Either.Right(ok.toString());
}
else {
return Either.Left(frame.trackEvalResult(ok));
}
}
);
}
else {
final var zzzframe = frameByFrameID.get(frameID);
if (!(zzzframe instanceof Frame)) {
return Either.Left("<<no such frame>>");
}

Frame frame = (Frame)zzzframe;

return doEvaluate(frame, expr)
.bimap(
err -> err,
ok -> {
// what about bool, Long, etc. ?...
if (ok == null) {
return Either.Right("null");
}
else if (ok instanceof String) {
return Either.Right("\"" + ((String)ok).replaceAll("\"", "\\\"") + "\"");
}
else if (ok instanceof Number || ok instanceof Boolean) {
return Either.Right(ok.toString());
}
else {
return Either.Left(frame.trackEvalResult(ok));
}
}
);
}

// concurrency here needs to be at the level of the DAP server?
// does the DAP server do multiple concurrent requests ... ? ... it's all one socket so probably not ? ... well many inbound messages can be being serviced ...
private Either</*err*/String, /*ok*/Object> doEvaluate(DebugFrame frame, String expr) {
private Either</*err*/String, /*ok*/Object> doEvaluate(Frame frame, String expr) {
try {
return CompletableFuture
.supplyAsync(
Expand Down Expand Up @@ -392,10 +394,18 @@ public boolean evaluateAsBooleanForConditionalBreakpoint(Thread thread, String e
if (stack.isEmpty()) {
return false;
}
return doEvaluateAsBoolean(stack.get(stack.size() - 1), expr);

DebugFrame frame = stack.get(stack.size() - 1);

if (frame instanceof Frame) {
return doEvaluateAsBoolean((Frame)frame, expr);
}
else {
return false;
}
}

private boolean doEvaluateAsBoolean(DebugFrame frame, String expr) {
private boolean doEvaluateAsBoolean(Frame frame, String expr) {
try {
return CompletableFuture
.supplyAsync(
Expand Down Expand Up @@ -482,7 +492,7 @@ synchronized public IDebugFrame[] getCfStack(Thread thread) {
if (stack == null) {
System.out.println("getCfStack called, frames was null, frames is " + cfStackByThread + ", passed thread was " + thread);
System.out.println(" thread=" + thread + " this=" + this);
return new DebugFrame[0];
return new Frame[0];
}

ArrayList<DebugFrame> result = new ArrayList<>();
Expand All @@ -501,7 +511,7 @@ synchronized public IDebugFrame[] getCfStack(Thread thread) {
}
}

return result.toArray(new DebugFrame[result.size()]);
return result.toArray(new Frame[result.size()]);
}

static class CfStepRequest {
Expand Down Expand Up @@ -570,9 +580,12 @@ public void luceedebug_stepNotificationEntry_step(int lineNumber) {
if (request == null) {
return;
}
else {
else if (frame instanceof Frame) {
request.__debug__steps++;
maybeNotifyOfStepCompletion(currentThread, frame, request, minDistanceToLuceedebugStepNotificationEntryFrame + 1, System.nanoTime());
maybeNotifyOfStepCompletion(currentThread, (Frame) frame, request, minDistanceToLuceedebugStepNotificationEntryFrame + 1, System.nanoTime());
}
else {
// no-op
}
}

Expand All @@ -596,13 +609,16 @@ public void luceedebug_stepNotificationEntry_stepAfterCompletedUdfCall() {
if (request == null) {
return;
}
else {
else if (frame instanceof Frame) {
request.__debug__steps++;
maybeNotifyOfStepCompletion(currentThread, frame, request, minDistanceToLuceedebugStepNotificationEntryFrame + 1, System.nanoTime());
maybeNotifyOfStepCompletion(currentThread, (Frame)frame, request, minDistanceToLuceedebugStepNotificationEntryFrame + 1, System.nanoTime());
}
else {
// no-op
}
}

private void maybeNotifyOfStepCompletion(Thread currentThread, DebugFrame frame, CfStepRequest request, int minDistanceToLuceedebugStepNotificationEntryFrame, long start) {
private void maybeNotifyOfStepCompletion(Thread currentThread, Frame frame, CfStepRequest request, int minDistanceToLuceedebugStepNotificationEntryFrame, long start) {
if (frame.isUdfDefaultValueInitFrame && !config_.getStepIntoUdfDefaultValueInitFrames()) {
return;
}
Expand Down Expand Up @@ -683,11 +699,7 @@ private DebugFrame maybe_pushCfFrame_worker(PageContext pageContext, String sour

final int depth = stack.size(); // first frame is frame 0, and prior to pushing the first frame the stack is length 0; next frame is frame 1, and prior to pushing it the stack is of length 1, ...

final DebugFrame frame = DebugFrame.maybeMakeFrame(sourceFilePath, depth, valTracker, pageContext);

if (frame == null) {
return null;
}
final DebugFrame frame = DebugFrame.makeFrame(sourceFilePath, depth, valTracker, pageContext);

stack.add(frame);

Expand All @@ -703,11 +715,9 @@ private DebugFrame maybe_pushCfFrame_worker(PageContext pageContext, String sour

public void pushCfFunctionDefaultValueInitializationFrame(lucee.runtime.PageContext pageContext, String sourceFilePath) {
DebugFrame frame = maybe_pushCfFrame_worker(pageContext, sourceFilePath);
if (frame == null) {
return;
if (frame instanceof Frame) {
((Frame)frame).isUdfDefaultValueInitFrame = true;
}

frame.isUdfDefaultValueInitFrame = true;
}

public void popCfFrame() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import lucee.runtime.PageContext;
import luceedebug.Either;
import luceedebug.coreinject.frame.DebugFrame;
import luceedebug.coreinject.frame.Frame;

import static luceedebug.coreinject.Utils.terminate;

Expand All @@ -27,7 +27,7 @@ class ExprEvaluator {
}
}

public static Either</*err*/String, /*ok*/Object> eval(DebugFrame frame, String expr) {
public static Either</*err*/String, /*ok*/Object> eval(Frame frame, String expr) {
return lucee5
.map(v -> v.eval(frame, expr))
.or(() -> lucee6.map(v -> v.eval(frame, expr)))
Expand All @@ -52,9 +52,9 @@ static protected String getEvaluatableSourceText(String expr) {
+ "</cfscript>";
}

protected abstract void evalIntoVariablesScope(DebugFrame frame, String expr) throws Throwable;
protected abstract void evalIntoVariablesScope(Frame frame, String expr) throws Throwable;

public Either</*err*/String, /*ok*/Object> eval(DebugFrame frame, String expr) {
public Either</*err*/String, /*ok*/Object> eval(Frame frame, String expr) {
try {
evalIntoVariablesScope(frame, expr);
var obj = consumeResult(frame);
Expand All @@ -68,7 +68,7 @@ static protected String getEvaluatableSourceText(String expr) {
/**
* get the eval'd result out of the frame's variables scope and then delete it from the variables scope.
*/
private Object consumeResult(DebugFrame frame) throws Throwable {
private Object consumeResult(Frame frame) throws Throwable {
Object evalResult = UnsafeUtils.deprecatedScopeGet(frame.getFrameContext().variables, resultName);
frame.getFrameContext().variables.remove(resultName);
return evalResult;
Expand Down Expand Up @@ -108,7 +108,7 @@ private static class Lucee5Evaluator extends Evaluator {
this.methodHandle = methodHandle;
}

protected void evalIntoVariablesScope(DebugFrame frame, String expr) throws Throwable {
protected void evalIntoVariablesScope(Frame frame, String expr) throws Throwable {
methodHandle.invoke(
/*PageContext pc*/ frame.getFrameContext().pageContext,
/*String cfml*/ Evaluator.getEvaluatableSourceText(expr),
Expand Down Expand Up @@ -148,7 +148,7 @@ private static class Lucee6Evaluator extends Evaluator {
this.methodHandle = methodHandle;
}

protected void evalIntoVariablesScope(DebugFrame frame, String expr) throws Throwable {
protected void evalIntoVariablesScope(Frame frame, String expr) throws Throwable {
methodHandle.invoke(
/*PageContext pc*/ frame.getFrameContext().pageContext,
/*String cfml*/ Evaluator.getEvaluatableSourceText(expr),
Expand Down
Loading

0 comments on commit 84d5ba6

Please sign in to comment.