public Object getDefaultValue(Class<?> hint) {
   Object value;
   if (hint == null) {
     if (javaObject instanceof Boolean) {
       hint = ScriptRuntime.BooleanClass;
     }
   }
   if (hint == null || hint == ScriptRuntime.StringClass) {
     value = javaObject.toString();
   } else {
     String converterName;
     if (hint == ScriptRuntime.BooleanClass) {
       converterName = "booleanValue";
     } else if (hint == ScriptRuntime.NumberClass) {
       converterName = "doubleValue";
     } else {
       throw Context.reportRuntimeError0("msg.default.value");
     }
     Object converterObject = get(converterName, this);
     if (converterObject instanceof Function) {
       Function f = (Function) converterObject;
       value = f.call(Context.getContext(), f.getParentScope(), this, ScriptRuntime.emptyArgs);
     } else {
       if (hint == ScriptRuntime.NumberClass && javaObject instanceof Boolean) {
         boolean b = ((Boolean) javaObject).booleanValue();
         value = ScriptRuntime.wrapNumber(b ? 1.0 : 0.0);
       } else {
         value = javaObject.toString();
       }
     }
   }
   return value;
 }
示例#2
0
  private static void generateMethod(
      ClassFileWriter cfw,
      String genName,
      String methodName,
      Class<?>[] parms,
      Class<?> returnType,
      boolean convertResult) {
    StringBuilder sb = new StringBuilder();
    int paramsEnd = appendMethodSignature(parms, returnType, sb);
    String methodSignature = sb.toString();
    cfw.startMethod(methodName, methodSignature, ClassFileWriter.ACC_PUBLIC);

    // Prepare stack to call method

    // push factory
    cfw.add(ByteCode.ALOAD_0);
    cfw.add(ByteCode.GETFIELD, genName, "factory", "Laurora/javascript/ContextFactory;");

    // push self
    cfw.add(ByteCode.ALOAD_0);
    cfw.add(ByteCode.GETFIELD, genName, "self", "Laurora/javascript/Scriptable;");

    // push function
    cfw.add(ByteCode.ALOAD_0);
    cfw.add(ByteCode.GETFIELD, genName, "delegee", "Laurora/javascript/Scriptable;");
    cfw.addPush(methodName);
    cfw.addInvoke(
        ByteCode.INVOKESTATIC,
        "aurora/javascript/JavaAdapter",
        "getFunction",
        "(Laurora/javascript/Scriptable;" + "Ljava/lang/String;" + ")Laurora/javascript/Function;");

    // push arguments
    generatePushWrappedArgs(cfw, parms, parms.length);

    // push bits to indicate which parameters should be wrapped
    if (parms.length > 64) {
      // If it will be an issue, then passing a static boolean array
      // can be an option, but for now using simple bitmask
      throw Context.reportRuntimeError0(
          "JavaAdapter can not subclass methods with more then" + " 64 arguments.");
    }
    long convertionMask = 0;
    for (int i = 0; i != parms.length; ++i) {
      if (!parms[i].isPrimitive()) {
        convertionMask |= (1 << i);
      }
    }
    cfw.addPush(convertionMask);

    // go through utility method, which creates a Context to run the
    // method in.
    cfw.addInvoke(
        ByteCode.INVOKESTATIC,
        "aurora/javascript/JavaAdapter",
        "callMethod",
        "(Laurora/javascript/ContextFactory;"
            + "Laurora/javascript/Scriptable;"
            + "Laurora/javascript/Function;"
            + "[Ljava/lang/Object;"
            + "J"
            + ")Ljava/lang/Object;");

    generateReturnResult(cfw, returnType, convertResult);

    cfw.stopMethod((short) paramsEnd);
  }