blob: 66516d17428988db30ed2e60e2d96e3b68a88649 [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2011, 2022 Stephan Wahlbrink and others.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
# which is available at https://www.apache.org/licenses/LICENSE-2.0.
#
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
#
# Contributors:
# Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
#=============================================================================*/
package org.eclipse.statet.rj.server.dbg;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.statet.rj.data.RJIO;
import org.eclipse.statet.rj.data.RJIOExternalizable;
public class CallStack implements RJIOExternalizable {
public static final int FLAG_TOPFRAME= 0x00001000;
public static final int FLAG_NOSTEPPING= 0x00000100;
public static final int FLAG_SOURCE= 0x00000010;
public static final int FLAG_COMMAND= 0x00000020;
private final List<? extends Frame> frames;
public CallStack(final List<? extends Frame> list, final boolean setDefaultFlags) {
this.frames= list;
if (setDefaultFlags) {
setDefaultFlags();
}
}
public CallStack(final RJIO io) throws IOException {
final int l= io.readInt();
final ArrayList<Frame> list= new ArrayList<>(l);
for (int i= 0; i < l; i++) {
final Frame frame= new Frame(i, io.readString());
frame.handle= io.readLong();
frame.fileName= io.readString();
frame.fileTimestamp= io.readLong();
frame.exprSrcref= io.readIntArray();
frame.flags= io.readInt();
list.add(frame);
}
this.frames= list;
}
@Override
public void writeExternal(final RJIO io) throws IOException {
final int l= this.frames.size();
io.writeInt(l);
for (int i= 0; i < l; i++) {
final Frame frame= this.frames.get(i);
io.writeString(frame.getCall());
io.writeLong(frame.handle);
io.writeString(frame.fileName);
io.writeLong(frame.fileTimestamp);
io.writeIntArray(frame.exprSrcref, (frame.exprSrcref != null) ? 6 : -1);
io.writeInt(frame.flags);
}
}
protected void setDefaultFlags() {
final int n= this.frames.size();
for (int i= 0; i < n; i++) {
final Frame frame0= this.frames.get(i);
if (frame0.getCall() != null) {
if (frame0.getCall().startsWith("source(")) { //$NON-NLS-1$
Frame frame1;
Frame frame2;
if (i+1 < n && (frame1= this.frames.get(i+1)).getCall() != null
&& frame1.getCall().startsWith("eval.with.vis(") ) { //$NON-NLS-1$
frame0.addFlags((FLAG_SOURCE | 0));
frame1.addFlags((FLAG_SOURCE | 1));
i++;
if (i+1 < n && (frame2= this.frames.get(i+1)).getCall() != null
&& frame2.getCall().startsWith("eval.with.vis(") ) { //$NON-NLS-1$
frame2.addFlags((FLAG_SOURCE | 2));
i++;
}
}
else if (i+2 < n && (frame1= this.frames.get(i+1)).getCall() != null
&& frame1.getCall().startsWith("withVisible(") //$NON-NLS-1$
&& (frame2= this.frames.get(i+2)).getCall() != null
&& frame2.getCall().startsWith("eval(") ) { //$NON-NLS-1$
frame0.addFlags((FLAG_SOURCE | 0));
frame1.addFlags((FLAG_SOURCE | 1));
frame2.addFlags((FLAG_SOURCE | 2));
i+= 2;
if (i+1 < n && (frame2= this.frames.get(i+1)).getCall() != null
&& frame2.getCall().startsWith("eval(") ) { //$NON-NLS-1$
frame2.addFlags((FLAG_SOURCE | 3));
i++;
}
}
}
else if (frame0.getCall().startsWith("rj:::.statet.evalCommand(") //$NON-NLS-1$
|| frame0.getCall().startsWith(".statet.evalCommand(") ) { //$NON-NLS-1$
frame0.addFlags((FLAG_COMMAND | 0));
final Frame frame1;
if (i+1 < n && (frame1= this.frames.get(i+1)).getCall() != null
&& frame1.getCall().startsWith("eval(") ) { //$NON-NLS-1$
frame1.addFlags((FLAG_COMMAND | 1));
i++;
final Frame frame2;
if (i+1 < n && (frame2= this.frames.get(i+1)).getCall() != null
&& frame2.getCall().startsWith("eval(") ) { //$NON-NLS-1$
frame2.addFlags((FLAG_COMMAND | 2));
i++;
}
}
}
}
}
this.frames.get(n-1).addFlags(FLAG_TOPFRAME);
}
public List<? extends Frame> getFrames() {
return this.frames;
}
public Frame findFrame(final long handle) {
for (int i= 0; i < this.frames.size(); i++) {
final Frame frame= this.frames.get(i);
if (frame.getHandle() == handle) {
return frame;
}
}
return null;
}
}