autohit.vm
Class VM

java.lang.Object
  |
  +--autohit.vm.VM
Direct Known Subclasses:
Log, SimVM

public abstract class VM
extends java.lang.Object

The abstract base class for virtual machines. A derived class will implement the abstract execute() method to actually run the VM. Also, it would normally use the pause() and resume() methods to control timing (rather than overloading and re-implementing them).

The derived class MAY overload the method prepare() if it has anything it wants to do before the FIRST instruction (and only the first) is executed. For instance, it could add environment variables.

The pause() and resume() methods are not designed to be called by external threads. If you plan to wrap the derived vm in a threaded class, you may want to overload or just not use those methods outside of the vm. Also, these methods only manage state and timing; it is up the he execute() method in the derived class to actually stop execution.

This base class offers the following services: - Instruction pointer (ip) field
- Variable space allocation (vars). The variables are put into a hashtable. some convenience methods are provided.
- Scope Stack space and convenience methods.
- Scope stack dirty flag.

USE THESE SERVICES! Do not make your own ip, for instance! Methods of this class depend upon it.


Field Summary
 int ip
          Current instruction address/pointer.
protected  boolean scDirty
          Scope stack cache dirty flag.
protected  java.util.Stack scope
          Scope stack.
protected  int state
          VM state.
static int STATE_DONE
           
static int STATE_NEW
          State values for the VM.
static int STATE_NO_VM
           
static int STATE_PAUSED
           
static int STATE_RUNNING
           
static int TIME_GRAN
          Granulatiry for each tick of the VM's clock.
protected  java.util.Hashtable vars
          Variable space.
 
Constructor Summary
VM()
          Constructor.
 
Method Summary
 void discardScopeFrame()
          Discard scope frame.
abstract  void execute()
          Absract method for VM execution.
 int getIntegerVar(java.lang.String name)
          Get an Integer variable.
 int getState()
          Get VM state.
 java.lang.String getVar(java.lang.String name)
          Get a string variable.
 void pause()
          Pause execution in the VM.
 java.lang.Object popScope()
          Pop an object off the stack.
 void prepare()
          Prepare for execution of the first instruction.
 void pushScope(java.lang.Object o)
          Push an object onto the scope stack.
 void removeVar(java.lang.String name)
          Remove a variable.
 void resume()
          Resume execution in the VM.
 void setVar(java.lang.String name, java.lang.String value)
          Set a variable.
 void start()
          Start the VM.
 java.lang.String subVar(java.lang.String in)
          Variable substitution.
 int ticks()
          Number of ticks the VM has been running.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

TIME_GRAN

public static final int TIME_GRAN
Granulatiry for each tick of the VM's clock. It is used to scale the system time to the vm clock time. Currently, it is set to 1. Given the current Java implementations, this should yield a 1 millisecond tick. That is, each VM clock tick will take one millisecond.

STATE_NEW

public static final int STATE_NEW
State values for the VM.

STATE_RUNNING

public static final int STATE_RUNNING

STATE_PAUSED

public static final int STATE_PAUSED

STATE_DONE

public static final int STATE_DONE

STATE_NO_VM

public static final int STATE_NO_VM

state

protected int state
VM state.

ip

public int ip
Current instruction address/pointer. A pointer into the insrtuction Vector.

vars

protected java.util.Hashtable vars
Variable space. Use the convenience methods to access these...

scope

protected java.util.Stack scope
Scope stack. Do NOT use scope.pop() or scope.push() yourself! We must maintain the scope cache dirty flag. However, you can use peek(), empty(), and search() at your leasure().

scDirty

protected boolean scDirty
Scope stack cache dirty flag. Will be automatically set when any scope stack methods are used.
Constructor Detail

VM

public VM()
Constructor. This should be called by any derived class constructors. It does NOT set any time/clock data, so if you overload start(), be sure to do it in your start(). (Oh, and don't do it in the constructor.)
Method Detail

start

public void start()
           throws VMException
Start the VM. It will set state and timing info, then call the abstract method execute() to execute the code.

Calling this method consecutively will effectively reset the state and timing info. It is probibly a REAL BAD IDEA to call this from the execute method.

It throws any exceptions that are thrown out of execute().

Throws:
VMException -  

getState

public int getState()
Get VM state. Reports the state of the vm using the STATE_* values.

You may call this from another thread, but it isn't very reliable.

Returns:
a STATE_* value

pause

public void pause()
Pause execution in the VM. This should NOT be called by another thread.

It will only pause if the VM is running.


resume

public void resume()
Resume execution in the VM. This should NOT be called by another thread.

It will only resume if the VM is paused.


ticks

public int ticks()
Number of ticks the VM has been running. It will be scaled according to the TIME_GRAN field.

Note that it returns an int rather than a long like system time usually is. This means that the VM timing. This technically could cause some overflow problems, but I doubt a VM would ever run that long.

Returns:
number of ticks the VM has run.

setVar

public void setVar(java.lang.String name,
                   java.lang.String value)
Set a variable. If the variable doesn't exist, it will create it. Once created, a variable stays in scope for the rest of execution.
Parameters:
name - the variable name.
value - the variable value.

removeVar

public void removeVar(java.lang.String name)
Remove a variable. If the variable is not present, no error occurs.
Parameters:
name - the variable name.

getVar

public java.lang.String getVar(java.lang.String name)
                        throws VMException
Get a string variable. it will throw a VMException if the variable has not been set.
Parameters:
name - the variable name.
Returns:
the value as a String
Throws:
VMException -  
See Also:
VMException

getIntegerVar

public int getIntegerVar(java.lang.String name)
                  throws VMException
Get an Integer variable. it will throw a VMException if the variable has not been set or is not a parse-able integer.
Parameters:
name - the variable name.
Returns:
the value as an int
Throws:
VMException -  
See Also:
VMException

subVar

public java.lang.String subVar(java.lang.String in)
                        throws VMException
Variable substitution.

There won't be any errors if a substitution isn't found. It will only do one level of substitution. Either call this again to resolve a variable in the newly substituted text, or just assume it is plain text.

It will throw a VMException if the variable isn't set.

Parameters:
in - text to find substitution.
Returns:
string with substitutions.
Throws:
VMException -  
See Also:
VMException

pushScope

public void pushScope(java.lang.Object o)
Push an object onto the scope stack.
Parameters:
i - the object

popScope

public java.lang.Object popScope()
                          throws java.lang.Exception
Pop an object off the stack. USE THIS instead of scope.pop()!!! Have to dirty the cache flag... It'll throw any exception it encounters--most likely a EmptyStackException.
Returns:
an object reference

discardScopeFrame

public void discardScopeFrame()
Discard scope frame. This will remove all items on the scope to and including the top-most recent VMIScope object.

If it encounters any variable references, the variable will discarded.

It will pop the whole damned stack if it doesn't find one...


execute

public abstract void execute()
                      throws VMException
Absract method for VM execution. The derived class must implement the actual execution. This method will be automatically called by start(). Therefore, you probibly should not call start() from within this method.

The implimentation of this method should only execute ONE INSTRUCTION. Successive calls would then execute the entire program. If you do not impliment it this way, you are likely to ghost the vm's.

NOTE! An implementing method MUST throw a VMException(VMException.DONE) when it reaches the end of execution.

If the derived-class VM encounters an instruction that it does now support, it should throw a VMException.INVALID_INSTRUCTION.

See Also:
VMException

prepare

public void prepare()
             throws java.lang.Exception
Prepare for execution of the first instruction. The derived class may overload this if it has any stuff it wants to do before execute() is called the first time.
Throws:
Any - exceptions it encounters.