public static void marshal(CodeWriterAttribute code, Class[] param) {
    int stack = 1;
    int index = 1;

    for (int i = 0; i < param.length; i++) {
      Class type = param[i];

      if (boolean.class.equals(type)
          || byte.class.equals(type)
          || short.class.equals(type)
          || int.class.equals(type)) {
        code.pushIntVar(index);
        index += 1;
        stack += 1;
      } else if (long.class.equals(type)) {
        code.pushLongVar(index);
        index += 2;
        stack += 2;
      } else if (float.class.equals(type)) {
        code.pushFloatVar(index);
        index += 1;
        stack += 1;
      } else if (double.class.equals(type)) {
        code.pushDoubleVar(index);
        index += 2;
        stack += 2;
      } else {
        code.pushObjectVar(index);
        index += 1;
        stack += 1;
      }
    }
  }
  public static void generateConstructor(
      JavaClass jClass, String superClassName, Constructor baseCtor) {
    Class[] types = baseCtor.getParameterTypes();

    StringBuilder sb = new StringBuilder();
    createDescriptor(sb, types);
    sb.append("V");

    String descriptor = sb.toString();

    JavaMethod ctor = jClass.createMethod("<init>", descriptor);

    ctor.setAccessFlags(Modifier.PUBLIC);

    CodeWriterAttribute code = ctor.createCodeWriter();
    code.setMaxLocals(5 + 2 * types.length);
    code.setMaxStack(5 + 2 * types.length);

    code.pushObjectVar(0);

    marshal(code, types);

    code.invokespecial(superClassName, "<init>", descriptor, 1, 0);
    code.addReturn();
    code.close();
  }
  private void generateWriteReplace(JavaClass jClass) {
    JavaField jField = jClass.createField("__caucho_handle", "Ljava/lang/Object;");
    jField.setAccessFlags(Modifier.PRIVATE);

    JavaMethod jMethod = jClass.createMethod("writeReplace", "()Ljava/lang/Object;");

    jMethod.setAccessFlags(Modifier.PRIVATE);

    CodeWriterAttribute code = jMethod.createCodeWriter();
    code.setMaxLocals(5);
    code.setMaxStack(5);

    code.pushObjectVar(0);
    code.getField(jClass.getThisClass(), "__caucho_handle", "Ljava/lang/Object;");

    code.addObjectReturn();

    code.close();
  }
  private void generateSetHandle(JavaClass jClass) {
    /*
    JavaField jField
      = jClass.createField("__caucho_handle", "Ljava/lang/Object;");
    jField.setAccessFlags(Modifier.PRIVATE);
    */

    JavaMethod jMethod = jClass.createMethod("setSerializationHandle", "(Ljava/lang/Object;)V");

    jMethod.setAccessFlags(Modifier.PUBLIC);

    CodeWriterAttribute code = jMethod.createCodeWriter();
    code.setMaxLocals(5);
    code.setMaxStack(5);

    code.pushObjectVar(0);
    code.pushObjectVar(1);
    code.putField(jClass.getThisClass(), "__caucho_handle", "Ljava/lang/Object;");

    code.addReturn();

    code.close();
  }