Consider the following code. The address of each method is entered into a
vtable that's indexed by opcode. A method can be found by a single pointer
calculation vtable[ opcode ]. It interprets an opcode without the runtime
overhead of a switch statement.

// opcodemethod.cc
#include <stdio.h>

typedef bool (*TMethod)(void);

static const int MAX_OPCODE = 3;
static TMethod vtable[ MAX_OPCODE ];

static bool method1() {
  printf( "Method 1\n" );
  return true;
}

static bool method2() {
  printf( "Method 2\n" );
  return true;
}

static bool method3() {
  printf( "Method 3\n" );
  return true;
}

static bool invokeOpcode( int index ) {
  TMethod item = vtable[ index ];
  return item();
}

void example() {
  vtable[ 0 ] = method1;
  vtable[ 1 ] = method2;
  vtable[ 2 ] = method3;

  if ( invokeOpcode( 0 ) ) {
    if ( invokeOpcode( 1 ) ) {;
      invokeOpcode( 2 );
    }
  }
}

Since all of these methods must have a similar signature, building a formal
type definition lets the compiler do additional type checking. Inside
interp.cc, frame::runOpcode() ends up short and sweet, something like this:

typedef bool (frame::*TOpcodeMethod)(exception_to_throw &e);

static TOpcodeMethod vtable[ bc::MAX_OPCODE ];

bool frame::runOpcode(exception_to_throw &e)
  TOpcodeMethod item = vtable[ cur_code->code[ myPC ] ];

#ifdef PARANOID
  if ( item == NULL ) {
    kprintf( "frame.runOpcode(): VM corrupted, exiting.\n" );
    abort();
  }
#endif

  myPC++;
  return item( e );
}

void frame::loadVTable() {
  vtable[ bc::aaload ] = aaload;
  vtable[ bc::aastore ] = aastore;
  :
  vtable[ bc::aload ] = aload;
  vtable[ bc::aload_0 ] = aload_0;
  vtable[ bc::aload_1 ] = aload_1;
  vtable[ bc::aload_2 ] = aload_2;
  vtable[ bc::aload_3 ] = aload_3;
  vtable[ bc::anewarray ] = anewarray;
  vtable[ bc::areturn ] = areturn;
  vtable[ bc::arraylength ] = arraylength;
  :
  vtable[ bc::dup ] = dup;
  vtable[ bc::dup_xl ] = dup_x1;
  vtable[ bc::dup_x2 ] = dup_x2;
  vtable[ bc::dup2 ] = dup2;
  vtable[ bc::dup2_x1 ] = dup2_x1;
  vtable[ bc::dup2_x2 ] = dup2_x2;
  vtable[ bc::swap ] = swap;
}


_______________________________________________
Kernel maillist  -  [EMAIL PROTECTED]
http://jos.org/mailman/listinfo/kernel

Reply via email to