           else m.name
         rs = new RuntimeState
         m.code.each_opcode (idx, oc) ->
-          opcodes[oc.name]?.execute rs, oc
-        "#{name}: function {\n#{rs.compile()}\n},"
+          opcodes[oc.name]?.execute rs, oc, idx
+        "#{name}: function() {\n#{rs.compile()}\n},"
   "var #{class_name} = {\n#{methods.join "\n"}\n};\n"
 
 # TODO: move to a separate file

class RuntimeState
  constructor: ->
    @_cs = []
    @blocks = []
    @locals = []
    @current_block = ''
  push: (sf) -> @_cs.push sf
  pop: -> @_cs.pop()
  cl: (idx) -> @locals[idx]
  put_cl: (idx, val) -> @locals[idx] = val
  put_cl2: (idx,val) -> @put_cl(idx,val); @put_cl(idx+1,null)
  finish_block: (str) -> @blocks.push @current_block; @current_block = ''
  compile: -> @blocks.join '\n'

class Expr


  imul: { execute: (rs) -> rs.push new BinaryOp ((a,b) ->
    "gLong.fromInt(#{a}).multiply(gLong.fromInt(#{b})).toInt()"), rs.pop(), rs.pop()
  }
  ifge: { execute: (rs, op, idx) -> rs.add_cond(
    ((a) -> "#{a} >= 0"), rs.pop(), idx + op.byte_count + 1, op.offset + idx) }
  'ireturn': { execute: (rs, op, idx) ->
    rv = rs.pop()
    rs.current_block().add_line "return #{rv};"
    rs.new_block(idx + op.byte_count)
  }
  'return': { execute: (rs, op, idx) -> rs.current_block().add_line 'return;'; }
}

root.compile = (class_file) ->
