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; }
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); }