示例#1
0
  /** execute this method, which might be either bytecode or native. */
  public Instruction execute(ThreadInfo ti) {

    if (((attrs & MJI_NATIVE) != 0) || isNative()) {
      NativePeer nativePeer = ci.getNativePeer();
      if (nativePeer != null) {
        JVM vm = ti.getVM();
        StackFrame frame = new StackFrame(this, ti.getTopFrame());

        // since there is no enter/leave for native methods, we have to do
        // the notifications explicitly
        ti.pushFrame(frame); // Make the logic easier in listeners (e.g. vm.getLastMethod() ==
        // vm.getCurrentThread().getMethod())
        vm.notifyMethodEntered(ti, this);
        ti.popFrame(
            false); // Can't keep the frame for later in this method since nativePeer.executeMethod
        // will do work on the top of the stack
        // <2do> Allow for the frame to remain on the stack for the duration of the call to
        // nativePeer.executeMethod().

        Instruction nextInsn = nativePeer.executeMethod(ti, this);

        ti.pushFrame(frame); // Make the logic easier in listeners (e.g. vm.getLastMethod() ==
        // vm.getCurrentThread().getMethod())
        vm.notifyMethodExited(ti, this);
        ti.popFrame(false); // Can't keep the frame since we don't want to leak frames.

        return nextInsn;

      } else {
        return ti.createAndThrowException(
            "java.lang.UnsatisfiedLinkError", ci.getName() + '.' + getUniqueName() + " (no peer)");
      }

    } else {
      enter(ti);

      return ti.getPC();
    }
  }