package xtc.lang.blink.agent;
/**
* The Blink support for the convenience variables in the Java
* debugger. This class in particular represent a poly-morphic
* convenience variable to hold both the java primitive and the
* reference values.
*
* @author Byeongcheol Lee
*/
public class AgentVariable {
/** The unique identifier. */
private int id;
/** The value. */
private Object value;
/** A Java expression to read the value from the Java debugger. */
private String expr;
/** The JNI type representation. */
private String jniType;
/** The Java type representation. */
private String javaType;
/** Constructor. */
private AgentVariable(int id) {this.id = id;}
/** The Blink Java multi-typed variable array. */
private static AgentVariable[] jvars;
/** The next unique variable identifier. */
private static int nextVJIdentifier;
/** The Java expression for the "jvars." */
private static final String JVARS_EXPRESSION = "xtc.lang.blink.agent.AgentVariable.jvars";
/** Perform initialization. */
public static void init() {
jvars = new AgentVariable[100];
nextVJIdentifier = 0;
}
/** Create a new instance of the convenience variable. */
private static AgentVariable createVariable() {
if (nextVJIdentifier < jvars.length) {
AgentVariable vj = new AgentVariable(nextVJIdentifier);
jvars[nextVJIdentifier] = vj;
nextVJIdentifier++;
return vj;
} else {
AgentVariable[] newJVars = new AgentVariable[jvars.length * 2];
System.arraycopy(jvars, 0, newJVars, 0, nextVJIdentifier);
jvars = newJVars;
return createVariable();
}
}
/** clean up the temp variables table. */
public static void cleanTempVars() {
for(int i = 0; i < jvars.length;i++) {
if( jvars[i] != null ) {
jvars[i] = null;
}
}
nextVJIdentifier = 0;
}
/**
* Take a boolean primitive value, create convenience variable, and
* assign the boolean value to the convenience variable.
*
* @param value
* @return The convenience variable identifier.
*/
public static int setVjFromJavaExpr(boolean value) {
AgentVariable vj = createVariable();
vj.value = new Boolean(value);
vj.expr = "((Boolean)" + JVARS_EXPRESSION + "[" + vj.id + "].value)"
+ ".getBoolean()";
vj.jniType = "jboolean";
vj.javaType = "boolean";
return vj.id;
}
/**
* Take an integer primitive value, create convenience variable, and
* assign the integer value to the convenience variable.
*
* @param value
* @return The convenience variable identifier.
*/
public static int setVjFromJavaExpr(int value) {
AgentVariable vj = createVariable();
vj.value = new Integer(value);
vj.expr = "((Integer)" + JVARS_EXPRESSION + "[" + vj.id + "].value)"
+ ".intValue()";
vj.jniType = "jint";
vj.javaType = "int";
return vj.id;
}
/**
* Take an double primitive value, create convenience variable, and
* assign the double value to the convenience variable.
*
* @param value
* @return The convenience variable identifier.
*/
public static int setVjFromJavaExpr(double value) {
AgentVariable vj = createVariable();
vj.value = new Double(value);
vj.expr = "((Double)" + JVARS_EXPRESSION + "[" + vj.id + "].value)"
+ ".doubleValue()";
vj.jniType = "jdouble";
vj.javaType = "double";
return vj.id;
}
/**
* Take an reference value, create convenience variable, and assign
* the reference value to the convenience variable.
*
* @param obj The reference.
* @return The convenience variable identifier.
*/
public static int setVjFromJavaExpr(Object obj) {
AgentVariable vj = createVariable();
if (obj != null) {
vj.value = obj;
String type = obj.getClass().getName();
if (type.equals("[D")) {
vj.expr = "((double[])" + JVARS_EXPRESSION + "[" + vj.id + "].value)";
} else {
vj.expr = "((" + type + ")" + JVARS_EXPRESSION + "[" + vj.id + "].value)";
}
vj.javaType = type;
} else {
vj.value = null;
vj.expr="null";
vj.javaType = "NULL";
}
vj.jniType = "jobject";
return vj.id;
}
/**
* Create a Java expression so that the Java debugger will read the
* value of the convenience variable.
* @param vjid The convenience variable identifier.
* @return The Java expression.
*/
public static String getVJExpr(int vjid) {
return jvars[vjid].expr;
}
/**
* Get the Java type representation of a convenience variable.
* @param vjid The convenience variable identifier.
* @return The Java expression.
*/
public static String get_java_type(int vjid) {
return jvars[vjid].javaType;
}
/**
* Get the JNI type representation of a convenience variable.
* @param vjid The convenience variable identifier.
* @return The JNI representation.
*/
public static String get_vj_jni_type(int vjid) {
return jvars[vjid].jniType;
}
/**
* Get the boolean value of the convience variable.
* @param vjid The convenience variable identifier.
* @return The boolean value.
*/
public static boolean get_vj_jboolean(int vjid) {
Object obj = jvars[vjid].value;
Boolean bobj = (Boolean)obj;
return bobj.booleanValue();
}
/**
* Get the integer value of the convience variable.
* @param vjid The convenience variable identifier.
* @return The integer value.
*/
public static int get_vj_jint(int vjid) {
Object obj = jvars[vjid].value;
Integer bobj = (Integer)obj;
return bobj.intValue();
}
/**
* Get the double value of the convience variable.
* @param vjid The convenience variable identifier.
* @return The double value.
*/
public static double get_vj_jdouble(int vjid) {
Object obj = jvars[vjid].value;
Double bobj = (Double)obj;
return bobj.doubleValue();
}
/**
* Get the reference value of the convience variable.
* @param vjid The convenience variable identifier.
* @return The reference value.
*/
public static Object get_vj_jobject(int vjid) {
Object obj = jvars[vjid].value;
Object bobj = (Object)obj;
return bobj;
}
}