コード例 #1
0
  /**
   * Utility method which dynamically binds a Context to the current thread, if none already exists.
   */
  public static Object callMethod(
      ContextFactory factory,
      final Scriptable thisObj,
      final Function f,
      final Object[] args,
      final long argsToWrap) {
    if (f == null) {
      // See comments in getFunction
      return Undefined.instance;
    }
    if (factory == null) {
      factory = ContextFactory.getGlobal();
    }

    final Scriptable scope = f.getParentScope();
    if (argsToWrap == 0) {
      return Context.call(factory, f, scope, thisObj, args);
    }

    Context cx = Context.getCurrentContext();
    if (cx != null) {
      return doCall(cx, scope, thisObj, f, args, argsToWrap);
    } else {
      return factory.call(
          new ContextAction() {
            public Object run(Context cx) {
              return doCall(cx, scope, thisObj, f, args, argsToWrap);
            }
          });
    }
  }
コード例 #2
0
 public static Object convertResult(Object result, Class c) {
   if (result == Undefined.instance
       && (c != ScriptRuntime.ObjectClass && c != ScriptRuntime.StringClass)) {
     // Avoid an error for an undefined value; return null instead.
     return null;
   }
   return Context.jsToJava(result, c);
 }
コード例 #3
0
  static Object js_createAdpter(Context cx, Scriptable scope, Object[] args) {
    int N = args.length;
    if (N == 0) {
      throw ScriptRuntime.typeError0("msg.adapter.zero.args");
    }

    Class superClass = null;
    Class[] intfs = new Class[N - 1];
    int interfaceCount = 0;
    for (int i = 0; i != N - 1; ++i) {
      Object arg = args[i];
      if (!(arg instanceof NativeJavaClass)) {
        throw ScriptRuntime.typeError2(
            "msg.not.java.class.arg", String.valueOf(i), ScriptRuntime.toString(arg));
      }
      Class c = ((NativeJavaClass) arg).getClassObject();
      if (!c.isInterface()) {
        if (superClass != null) {
          throw ScriptRuntime.typeError2("msg.only.one.super", superClass.getName(), c.getName());
        }
        superClass = c;
      } else {
        intfs[interfaceCount++] = c;
      }
    }

    if (superClass == null) superClass = ScriptRuntime.ObjectClass;

    Class[] interfaces = new Class[interfaceCount];
    System.arraycopy(intfs, 0, interfaces, 0, interfaceCount);
    Scriptable obj = ScriptRuntime.toObject(cx, scope, args[N - 1]);

    Class adapterClass = getAdapterClass(scope, superClass, interfaces, obj);

    Class[] ctorParms = {ScriptRuntime.ContextFactoryClass, ScriptRuntime.ScriptableClass};
    Object[] ctorArgs = {cx.getFactory(), obj};
    try {
      Object adapter = adapterClass.getConstructor(ctorParms).newInstance(ctorArgs);
      return getAdapterSelf(adapterClass, adapter);
    } catch (Exception ex) {
      throw Context.throwAsScriptRuntimeEx(ex);
    }
  }
コード例 #4
0
 public static Scriptable runScript(final Script script) {
   return (Scriptable)
       Context.call(
           new ContextAction() {
             public Object run(Context cx) {
               ScriptableObject global = ScriptRuntime.getGlobal(cx);
               script.exec(cx, global);
               return global;
             }
           });
 }
コード例 #5
0
  // Needed by NativeJavaObject de-serializer
  public static Object readAdapterObject(Scriptable self, ObjectInputStream in)
      throws IOException, ClassNotFoundException {
    ContextFactory factory;
    Context cx = Context.getCurrentContext();
    if (cx != null) {
      factory = cx.getFactory();
    } else {
      factory = null;
    }

    Class superClass = Class.forName((String) in.readObject());

    String[] interfaceNames = (String[]) in.readObject();
    Class[] interfaces = new Class[interfaceNames.length];

    for (int i = 0; i < interfaceNames.length; i++)
      interfaces[i] = Class.forName(interfaceNames[i]);

    Scriptable delegee = (Scriptable) in.readObject();

    Class adapterClass = getAdapterClass(self, superClass, interfaces, delegee);

    Class[] ctorParms = {
      ScriptRuntime.ContextFactoryClass,
      ScriptRuntime.ScriptableClass,
      ScriptRuntime.ScriptableClass
    };
    Object[] ctorArgs = {factory, delegee, self};
    try {
      return adapterClass.getConstructor(ctorParms).newInstance(ctorArgs);
    } catch (InstantiationException e) {
    } catch (IllegalAccessException e) {
    } catch (InvocationTargetException e) {
    } catch (NoSuchMethodException e) {
    }

    throw new ClassNotFoundException("adapter");
  }
コード例 #6
0
 private static Object doCall(
     Context cx,
     Scriptable scope,
     Scriptable thisObj,
     Function f,
     Object[] args,
     long argsToWrap) {
   // Wrap the rest of objects
   for (int i = 0; i != args.length; ++i) {
     if (0 != (argsToWrap & (1 << i))) {
       Object arg = args[i];
       if (!(arg instanceof Scriptable)) {
         args[i] = cx.getWrapFactory().wrap(cx, scope, arg, null);
       }
     }
   }
   return f.call(cx, scope, thisObj, args);
 }
コード例 #7
0
  private static void generateMethod(
      ClassFileWriter cfw, String genName, String methodName, Class[] parms, Class returnType) {
    StringBuffer sb = new StringBuffer();
    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", "Lorg/mozilla/javascript/ContextFactory;");

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

    // push function
    cfw.add(ByteCode.ALOAD_0);
    cfw.add(ByteCode.GETFIELD, genName, "delegee", "Lorg/mozilla/javascript/Scriptable;");
    cfw.addPush(methodName);
    cfw.addInvoke(
        ByteCode.INVOKESTATIC,
        "org/mozilla/javascript/JavaAdapter",
        "getFunction",
        "(Lorg/mozilla/javascript/Scriptable;"
            + "Ljava/lang/String;"
            + ")Lorg/mozilla/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,
        "org/mozilla/javascript/JavaAdapter",
        "callMethod",
        "(Lorg/mozilla/javascript/ContextFactory;"
            + "Lorg/mozilla/javascript/Scriptable;"
            + "Lorg/mozilla/javascript/Function;"
            + "[Ljava/lang/Object;"
            + "J"
            + ")Ljava/lang/Object;");

    generateReturnResult(cfw, returnType, true);

    cfw.stopMethod((short) paramsEnd);
  }