Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  package org.dynjs.runtime.linker.java;
  
  import static me.qmx.jitescript.util.CodegenUtils.*;
  
  import java.util.Arrays;
 import java.util.Map;
 
 
 
 public class JSJavaImplementationManager {
 
     private static AtomicInteger counter = new AtomicInteger();
 
     private Map<Class<?>, Class<?>> implementations = new HashMap<>();
 
     public JSJavaImplementationManager() {
 
     }
 
     public Object getImplementationWrapper(Class<?> targetClassExecutionContext contextJSObject implementationthrows Exception {
         Class<?> implClass = getImplementationWrapper(targetClass);
 
         Constructor<?> ctor = implClass.getConstructor(ExecutionContext.classJSObject.class);
 
         return ctor.newInstance(contextimplementation);
     }
 
     public Class<?> getImplementationWrapper(Class<?> targetClass) {
         Class<?> implClass = this..get(targetClass);
         if (implClass == null) {
             implClass = createImplementationWrapper(targetClass);
             this..put(targetClassimplClass);
         }
 
         return implClass;
     }
 
     private Class<?> createImplementationWrapper(Class<?> targetClass) {
         final String className = "org/dynjs/gen/impl/" + targetClass.getSimpleName() + "JS_" + .getAndIncrement();
 
         final Class<?> superClass = (targetClass.isInterface() ? Object.class : targetClass);
         final String superClassName = p(superClass);
         String[] interfaces = null;
 
         if (targetClass.isInterface()) {
             interfaces = new String[] { p(targetClass) };
         } else {
             interfaces = new String[] {};
         }
 
         JiteClass jiteClass = new JiteClass(classNamesuperClassNameinterfaces);
 
         jiteClass.defineField("context".ci(ExecutionContext.class), null);
         jiteClass.defineField("implementation".ci(JSObject.class), null);
 
         jiteClass.defineMethod("<init>".sig(void.classExecutionContext.classJSObject.class),
                 new CodeBlock() {
                     {
                         aload(.);
                         invokespecial(superClassName"<init>"sig(void.class));
 
                         aload(.);
                         aload(1);
                         putfield(className.replace('.''/'), "context"ci(ExecutionContext.class));
 
                         aload(.);
                         aload(2);
                         putfield(className.replace('.''/'), "implementation"ci(JSObject.class));
                         aload(2);
 
                         voidreturn();
                     }
                 });
 
         defineMethods(targetClassjiteClasssuperClass);
 
         byte[] bytecode = jiteClass.toBytes(.);
 
        //ClassReader reader = new ClassReader(bytecode);
        //CheckClassAdapter.verify(reader, true, new PrintWriter(System.out));
        return cl.define(jiteClass.getClassName().replace('/''.'), bytecode);
    }
    private void defineMethods(Class<?> targetClassJiteClass jiteClassClass<?> superClass) {
        Method[] methods = targetClass.getMethods();
        for (int i = 0; i < methods.length; ++i) {
            int modifiers = methods[i].getModifiers();
            if (Modifier.isPublic(modifiers) && !Modifier.isStatic(modifiers) && !Modifier.isFinal(modifiers)) {
                defineMethod(methods[i], jiteClasssuperClass);
            }
        }
    }
    private void defineMethod(final Method methodfinal JiteClass jiteClassfinal Class<?> superClass) {
        if (method.getName().equals("equals") || method.getName().equals("hashCode") || method.getName().equals("toString")) {
            return;
        }
        final Class<?>[] params = method.getParameterTypes();
        final Class<?>[] signature = new Class<?>[params.length + 1];
        for (int i = 1; i < params.length + 1; ++i) {
            signature[i] = params[i - 1];
        }
        signature[0] = method.getReturnType();
        boolean superMethodFound = false;
        try {
            superMethodFound = (superClass.getMethod(method.getName(), method.getParameterTypes()) != null);
        } catch (NoSuchMethodException e) {
        } catch (SecurityException e) {
        }
        final boolean hasSuper = superMethodFound;
        jiteClass.defineMethod(method.getName(), method.getModifiers() & ~.sig(signature), new CodeBlock() {
            {
                LabelNode noImpl = new LabelNode();
                LabelNode complete = new LabelNode();
                aload(.);
                getfield(jiteClass.getClassName().replace('.''/'), "implementation"ci(JSObject.class));
                // obj
                aload(.);
                getfield(jiteClass.getClassName().replace('.''/'), "context"ci(ExecutionContext.class));
                // obj context
                ldc(method.getName());
                // obj context name
                invokeinterface(p(JSObject.class), "get"sig(Object.classExecutionContext.classString.class));
                // fn
                dup();
                // fn fn
                getstatic(p(Types.class), "UNDEFINED"ci(Undefined.class));
                // fn fn undef
                if_acmpeq(noImpl);
                // fn
                aload(.);
                // fn this
                getfield(jiteClass.getClassName().replace('.''/'), "context"ci(ExecutionContext.class));
                // fn context
                swap();
                // context fn
                aload(.);
                // context fn this
                ldc(params.length);
                anewarray(p(Object.class));
                // context fn this args
                for (int i = 0; i < params.length; ++i) {
                    dup();
                    // context fn this args args
                    ldci );
                    aload(i + 1);
                    // context fn this args args arg-I
                    aastore();
                    // context fn this args
                }
                // context fn this args
                invokevirtual(p(ExecutionContext.class), "call"sig(Object.classJSFunction.classObject.classObject[].class));
                // result
                go_to(complete);
                label(noImpl);
                // fn
                pop();
                if (hasSuper) {
                    aload(.);
                    for (int i = 0; i < params.length; ++i) {
                        aload(i + 1);
                    }
                    invokespecial(p(superClass), method.getName(), sig(signature));
                    if (method.getReturnType() == .) {
                        aconst_null();
                    }
                } else {
                    aconst_null();
                }
                // result
                label(complete);
                // result
                if (method.getReturnType() == .) {
                    voidreturn();
                } else {
                    aload(.);
                    invokevirtual(jiteClass.getClassName().replace('.''/'), "getClass"sig(Class.class));
                    invokevirtual(p(Class.class), "getClassLoader"sig(ClassLoader.class));
                    ldc(method.getReturnType().getName());
                    invokevirtual(p(ClassLoader.class), "loadClass"sig(Class.classString.class));
                    invokestatic(p(JavaTypes.class), "coerceTo"sig(Object.classObject.classClass.class));
                    checkcast(p(method.getReturnType()));
                    areturn();
                }
            }
        });
    }
New to GrepCode? Check out our FAQ X