Package clojure.asm.commons

Examples of clojure.asm.commons.GeneratorAdapter


  }

  public void doEmitStatic(ObjExpr fn, ClassVisitor cv){
    Method ms = new Method("invokeStatic", getReturnType(), argtypes);

    GeneratorAdapter gen = new GeneratorAdapter(ACC_PUBLIC + ACC_STATIC,
                                                ms,
                                                null,
                                                //todo don't hardwire this
                                                EXCEPTION_TYPES,
                                                cv);
    gen.visitCode();
    Label loopLabel = gen.mark();
    gen.visitLineNumber(line, loopLabel);
    try
      {
      Var.pushThreadBindings(RT.map(LOOP_LABEL, loopLabel, METHOD, this));
      emitBody(objx, gen, retClass, body);

      Label end = gen.mark();
      for(ISeq lbs = argLocals.seq(); lbs != null; lbs = lbs.next())
        {
        LocalBinding lb = (LocalBinding) lbs.first();
        gen.visitLocalVariable(lb.name, argtypes[lb.idx].getDescriptor(), null, loopLabel, end, lb.idx);
        }
      }
    catch(Exception e)
      {
      throw Util.sneakyThrow(e);
      }
    finally
      {
      Var.popThreadBindings();
      }

    gen.returnValue();
    //gen.visitMaxs(1, 1);
    gen.endMethod();

  //generate the regular invoke, calling the static method
    Method m = new Method(getMethodName(), OBJECT_TYPE, getArgTypes());

    gen = new GeneratorAdapter(ACC_PUBLIC,
                               m,
                               null,
                               //todo don't hardwire this
                               EXCEPTION_TYPES,
                               cv);
    gen.visitCode();
    for(int i = 0; i < argtypes.length; i++)
      {
      gen.loadArg(i);
      HostExpr.emitUnboxArg(fn, gen, argclasses[i]);
      }
    gen.invokeStatic(objx.objtype, ms);
    gen.box(getReturnType());


    gen.returnValue();
    //gen.visitMaxs(1, 1);
    gen.endMethod();

  }
View Full Code Here


//      cv.visitField(ACC_PRIVATE + ACC_STATIC + ACC_FINAL
//          , varCallsiteName(i), IFN_TYPE.getDescriptor(), null, null);
//      }

    //static init for constants, keywords and vars
    GeneratorAdapter clinitgen = new GeneratorAdapter(ACC_PUBLIC + ACC_STATIC,
                                                      Method.getMethod("void <clinit> ()"),
                                                      null,
                                                      null,
                                                      cv);
    clinitgen.visitCode();
    clinitgen.visitLineNumber(line, clinitgen.mark());

    if(constants.count() > 0)
      {
      emitConstants(clinitgen);
      }

    if(keywordCallsites.count() > 0)
      emitKeywordCallsites(clinitgen);

    /*
    for(int i=0;i<varCallsites.count();i++)
      {
      Label skipLabel = clinitgen.newLabel();
      Label endLabel = clinitgen.newLabel();
      Var var = (Var) varCallsites.nth(i);
      clinitgen.push(var.ns.name.toString());
      clinitgen.push(var.sym.toString());
      clinitgen.invokeStatic(RT_TYPE, Method.getMethod("clojure.lang.Var var(String,String)"));
      clinitgen.dup();
      clinitgen.invokeVirtual(VAR_TYPE,Method.getMethod("boolean hasRoot()"));
      clinitgen.ifZCmp(GeneratorAdapter.EQ,skipLabel);

      clinitgen.invokeVirtual(VAR_TYPE,Method.getMethod("Object getRoot()"));
            clinitgen.dup();
            clinitgen.instanceOf(AFUNCTION_TYPE);
            clinitgen.ifZCmp(GeneratorAdapter.EQ,skipLabel);
      clinitgen.checkCast(IFN_TYPE);
      clinitgen.putStatic(objtype, varCallsiteName(i), IFN_TYPE);
      clinitgen.goTo(endLabel);

      clinitgen.mark(skipLabel);
      clinitgen.pop();

      clinitgen.mark(endLabel);
      }
        */
    clinitgen.returnValue();

    clinitgen.endMethod();
    if(supportsMeta())
      {
      cv.visitField(ACC_FINAL, "__meta", IPERSISTENTMAP_TYPE.getDescriptor(), null, null);
      }
    //instance fields for closed-overs
    for(ISeq s = RT.keys(closes); s != null; s = s.next())
      {
      LocalBinding lb = (LocalBinding) s.first();
      if(isDeftype())
        {
        int access = isVolatile(lb) ? ACC_VOLATILE :
                     isMutable(lb) ? 0 :
                     (ACC_PUBLIC + ACC_FINAL);
        FieldVisitor fv;
        if(lb.getPrimitiveType() != null)
          fv = cv.visitField(access
              , lb.name, Type.getType(lb.getPrimitiveType()).getDescriptor(),
                  null, null);
        else
        //todo - when closed-overs are fields, use more specific types here and in ctor and emitLocal?
          fv = cv.visitField(access
              , lb.name, OBJECT_TYPE.getDescriptor(), null, null);
        addAnnotation(fv, RT.meta(lb.sym));
        }
      else
        {
        //todo - only enable this non-private+writability for letfns where we need it
        if(lb.getPrimitiveType() != null)
          cv.visitField(0 + (isVolatile(lb) ? ACC_VOLATILE : 0)
              , lb.name, Type.getType(lb.getPrimitiveType()).getDescriptor(),
                  null, null);
        else
          cv.visitField(0 //+ (oneTimeUse ? 0 : ACC_FINAL)
              , lb.name, OBJECT_TYPE.getDescriptor(), null, null);
        }
      }

    //instance fields for callsites and thunks
    for(int i=0;i<protocolCallsites.count();i++)
      {
      cv.visitField(ACC_PRIVATE, cachedClassName(i), CLASS_TYPE.getDescriptor(), null, null);
      cv.visitField(ACC_PRIVATE, cachedProtoFnName(i), AFUNCTION_TYPE.getDescriptor(), null, null);
      cv.visitField(ACC_PRIVATE, cachedProtoImplName(i), IFN_TYPE.getDescriptor(), null, null);     
      }

     //ctor that takes closed-overs and inits base + fields
    Method m = new Method("<init>", Type.VOID_TYPE, ctorTypes());
    GeneratorAdapter ctorgen = new GeneratorAdapter(ACC_PUBLIC,
                                                    m,
                                                    null,
                                                    null,
                                                    cv);
    Label start = ctorgen.newLabel();
    Label end = ctorgen.newLabel();
    ctorgen.visitCode();
    ctorgen.visitLineNumber(line, ctorgen.mark());
    ctorgen.visitLabel(start);
    ctorgen.loadThis();
//    if(superName != null)
      ctorgen.invokeConstructor(Type.getObjectType(superName), voidctor);
//    else if(isVariadic()) //RestFn ctor takes reqArity arg
//      {
//      ctorgen.push(variadicMethod.reqParms.count());
//      ctorgen.invokeConstructor(restFnType, restfnctor);
//      }
//    else
//      ctorgen.invokeConstructor(aFnType, voidctor);

//    if(vars.count() > 0)
//      {
//      ctorgen.loadThis();
//      ctorgen.getStatic(VAR_TYPE,"rev",Type.INT_TYPE);
//      ctorgen.push(-1);
//      ctorgen.visitInsn(Opcodes.IADD);
//      ctorgen.putField(objtype, "__varrev__", Type.INT_TYPE);
//      }

    if(supportsMeta())
      {
      ctorgen.loadThis();
      ctorgen.visitVarInsn(IPERSISTENTMAP_TYPE.getOpcode(Opcodes.ILOAD), 1);
      ctorgen.putField(objtype, "__meta", IPERSISTENTMAP_TYPE);
      }

    int a = supportsMeta()?2:1;
    for(ISeq s = RT.keys(closes); s != null; s = s.next(), ++a)
      {
      LocalBinding lb = (LocalBinding) s.first();
      ctorgen.loadThis();
      Class primc = lb.getPrimitiveType();
      if(primc != null)
        {
        ctorgen.visitVarInsn(Type.getType(primc).getOpcode(Opcodes.ILOAD), a);
        ctorgen.putField(objtype, lb.name, Type.getType(primc));
        if(primc == Long.TYPE || primc == Double.TYPE)
          ++a;
        }
      else
        {
        ctorgen.visitVarInsn(OBJECT_TYPE.getOpcode(Opcodes.ILOAD), a);
        ctorgen.putField(objtype, lb.name, OBJECT_TYPE);
        }
            closesExprs = closesExprs.cons(new LocalBindingExpr(lb, null));
      }


    ctorgen.visitLabel(end);

    ctorgen.returnValue();

    ctorgen.endMethod();

    if(altCtorDrops > 0)
      {
          //ctor that takes closed-overs and inits base + fields
      Type[] ctorTypes = ctorTypes();
      Type[] altCtorTypes = new Type[ctorTypes.length-altCtorDrops];
      for(int i=0;i<altCtorTypes.length;i++)
        altCtorTypes[i] = ctorTypes[i];
      Method alt = new Method("<init>", Type.VOID_TYPE, altCtorTypes);
      ctorgen = new GeneratorAdapter(ACC_PUBLIC,
                              alt,
                              null,
                              null,
                              cv);
      ctorgen.visitCode();
      ctorgen.loadThis();
      ctorgen.loadArgs();
      for(int i=0;i<altCtorDrops;i++)
        ctorgen.visitInsn(Opcodes.ACONST_NULL);

      ctorgen.invokeConstructor(objtype, new Method("<init>", Type.VOID_TYPE, ctorTypes));

      ctorgen.returnValue();
      ctorgen.endMethod();
      }

    if(supportsMeta())
      {
      //ctor that takes closed-overs but not meta
      Type[] ctorTypes = ctorTypes();
      Type[] noMetaCtorTypes = new Type[ctorTypes.length-1];
      for(int i=1;i<ctorTypes.length;i++)
        noMetaCtorTypes[i-1] = ctorTypes[i];
      Method alt = new Method("<init>", Type.VOID_TYPE, noMetaCtorTypes);
      ctorgen = new GeneratorAdapter(ACC_PUBLIC,
                              alt,
                              null,
                              null,
                              cv);
      ctorgen.visitCode();
      ctorgen.loadThis();
      ctorgen.visitInsn(Opcodes.ACONST_NULL)//null meta
      ctorgen.loadArgs();
      ctorgen.invokeConstructor(objtype, new Method("<init>", Type.VOID_TYPE, ctorTypes));

      ctorgen.returnValue();
      ctorgen.endMethod();

      //meta()
      Method meth = Method.getMethod("clojure.lang.IPersistentMap meta()");

      GeneratorAdapter gen = new GeneratorAdapter(ACC_PUBLIC,
                        meth,
                        null,
                        null,
                        cv);
      gen.visitCode();
      gen.loadThis();
      gen.getField(objtype,"__meta",IPERSISTENTMAP_TYPE);

      gen.returnValue();
      gen.endMethod();

      //withMeta()
      meth = Method.getMethod("clojure.lang.IObj withMeta(clojure.lang.IPersistentMap)");

      gen = new GeneratorAdapter(ACC_PUBLIC,
                        meth,
                        null,
                        null,
                        cv);
      gen.visitCode();
      gen.newInstance(objtype);
      gen.dup();
      gen.loadArg(0);

      for(ISeq s = RT.keys(closes); s != null; s = s.next(), ++a)
        {
        LocalBinding lb = (LocalBinding) s.first();
        gen.loadThis();
        Class primc = lb.getPrimitiveType();
        if(primc != null)
          {
          gen.getField(objtype, lb.name, Type.getType(primc));
          }
        else
          {
          gen.getField(objtype, lb.name, OBJECT_TYPE);
          }
        }

      gen.invokeConstructor(objtype, new Method("<init>", Type.VOID_TYPE, ctorTypes));
      gen.returnValue();
      gen.endMethod();
      }

    emitStatics(cv);
    emitMethods(cv);

    if(keywordCallsites.count() > 0)
      {
      Method meth = Method.getMethod("void swapThunk(int,clojure.lang.ILookupThunk)");

      GeneratorAdapter gen = new GeneratorAdapter(ACC_PUBLIC,
                        meth,
                        null,
                        null,
                        cv);
      gen.visitCode();
      Label endLabel = gen.newLabel();

      Label[] labels = new Label[keywordCallsites.count()];
      for(int i = 0; i < keywordCallsites.count();i++)
        {
        labels[i] = gen.newLabel();
        }
      gen.loadArg(0);
      gen.visitTableSwitchInsn(0,keywordCallsites.count()-1,endLabel,labels);

      for(int i = 0; i < keywordCallsites.count();i++)
        {
        gen.mark(labels[i]);
//        gen.loadThis();
        gen.loadArg(1);
        gen.putStatic(objtype, thunkNameStatic(i),ILOOKUP_THUNK_TYPE);
        gen.goTo(endLabel);
        }

      gen.mark(endLabel);

      gen.returnValue();
      gen.endMethod();
      }
   
    //end of class
    cv.visitEnd();

View Full Code Here

            , lb.name, OBJECT_TYPE.getDescriptor(), null, null);
      }

    //ctor that takes closed-overs and does nothing
    Method m = new Method("<init>", Type.VOID_TYPE, ret.ctorTypes());
    GeneratorAdapter ctorgen = new GeneratorAdapter(ACC_PUBLIC,
                                                    m,
                                                    null,
                                                    null,
                                                    cv);
    ctorgen.visitCode();
    ctorgen.loadThis();
    ctorgen.invokeConstructor(Type.getObjectType(superName), voidctor);
    ctorgen.returnValue();
    ctorgen.endMethod();

    if(ret.altCtorDrops > 0)
      {
      Type[] ctorTypes = ret.ctorTypes();
      Type[] altCtorTypes = new Type[ctorTypes.length-ret.altCtorDrops];
      for(int i=0;i<altCtorTypes.length;i++)
        altCtorTypes[i] = ctorTypes[i];
      Method alt = new Method("<init>", Type.VOID_TYPE, altCtorTypes);
      ctorgen = new GeneratorAdapter(ACC_PUBLIC,
                              alt,
                              null,
                              null,
                              cv);
      ctorgen.visitCode();
      ctorgen.loadThis();
      ctorgen.loadArgs();
      for(int i=0;i<ret.altCtorDrops;i++)
        ctorgen.visitInsn(Opcodes.ACONST_NULL);

      ctorgen.invokeConstructor(Type.getObjectType(COMPILE_STUB_PREFIX + "/" + ret.internalName),
                                new Method("<init>", Type.VOID_TYPE, ctorTypes));

      ctorgen.returnValue();
      ctorgen.endMethod();
      }
    //end of class
    cv.visitEnd();

    byte[] bytecode = cw.toByteArray();
View Full Code Here

  protected void emitStatics(ClassVisitor cv) {
    if(this.isDeftype())
      {
      //getBasis()
      Method meth = Method.getMethod("clojure.lang.IPersistentVector getBasis()");
      GeneratorAdapter gen = new GeneratorAdapter(ACC_PUBLIC + ACC_STATIC,
                        meth,
                        null,
                        null,
                        cv);
      emitValue(hintedFields, gen);
      gen.returnValue();
      gen.endMethod();

      if (this.isDeftype() && this.fields.count() > this.hintedFields.count())
        {
        //create(IPersistentMap)
        String className = name.replace('.', '/');
View Full Code Here

      for(Class retType : e.getValue())
        {
             Method meth = new Method(m.getName(), Type.getType(retType), argTypes);

        GeneratorAdapter gen = new GeneratorAdapter(ACC_PUBLIC + ACC_BRIDGE,
                                                meth,
                                                null,
                                                //todo don't hardwire this
                                                EXCEPTION_TYPES,
                                                cv);
        gen.visitCode();
        gen.loadThis();
        gen.loadArgs();
        gen.invokeInterface(Type.getType(m.getDeclaringClass()),target);
        gen.returnValue();
        gen.endMethod();
        }
      }
  }
View Full Code Here

      {
      extypes = new Type[exclasses.length];
      for(int i=0;i<exclasses.length;i++)
        extypes[i] = Type.getType(exclasses[i]);
      }
    GeneratorAdapter gen = new GeneratorAdapter(ACC_PUBLIC,
                                                m,
                                                null,
                                                extypes,
                                                cv);
    addAnnotation(gen,methodMeta);
    for(int i = 0; i < parms.count(); i++)
      {
      IPersistentMap meta = RT.meta(parms.nth(i));
      addParameterAnnotation(gen, meta, i);
      }
    gen.visitCode();

    Label loopLabel = gen.mark();

    gen.visitLineNumber(line, loopLabel);
    try
      {
      Var.pushThreadBindings(RT.map(LOOP_LABEL, loopLabel, METHOD, this));

      emitBody(objx, gen, retClass, body);
      Label end = gen.mark();
      gen.visitLocalVariable("this", obj.objtype.getDescriptor(), null, loopLabel, end, 0);
      for(ISeq lbs = argLocals.seq(); lbs != null; lbs = lbs.next())
        {
        LocalBinding lb = (LocalBinding) lbs.first();
        gen.visitLocalVariable(lb.name, argTypes[lb.idx-1].getDescriptor(), null, loopLabel, end, lb.idx);
        }
      }
    catch(Exception e)
      {
      throw Util.sneakyThrow(e);
      }
    finally
      {
      Var.popThreadBindings();
      }

    gen.returnValue();
    //gen.visitMaxs(1, 1);
    gen.endMethod();
  }
View Full Code Here

            , lb.name, OBJECT_TYPE.getDescriptor(), null, null);
      }

    //ctor that takes closed-overs and does nothing
    Method m = new Method("<init>", Type.VOID_TYPE, ret.ctorTypes());
    GeneratorAdapter ctorgen = new GeneratorAdapter(ACC_PUBLIC,
                                                    m,
                                                    null,
                                                    null,
                                                    cv);
    ctorgen.visitCode();
    ctorgen.loadThis();
    ctorgen.invokeConstructor(Type.getObjectType(superName), voidctor);
    ctorgen.returnValue();
    ctorgen.endMethod();

    if(ret.altCtorDrops > 0)
      {
      Type[] ctorTypes = ret.ctorTypes();
      Type[] altCtorTypes = new Type[ctorTypes.length-ret.altCtorDrops];
      for(int i=0;i<altCtorTypes.length;i++)
        altCtorTypes[i] = ctorTypes[i];
      Method alt = new Method("<init>", Type.VOID_TYPE, altCtorTypes);
      ctorgen = new GeneratorAdapter(ACC_PUBLIC,
                              alt,
                              null,
                              null,
                              cv);
      ctorgen.visitCode();
      ctorgen.loadThis();
      ctorgen.loadArgs();
      for(int i=0;i<ret.altCtorDrops;i++)
        ctorgen.visitInsn(Opcodes.ACONST_NULL);

      ctorgen.invokeConstructor(Type.getObjectType(COMPILE_STUB_PREFIX + "/" + ret.internalName),
                                new Method("<init>", Type.VOID_TYPE, ctorTypes));

      ctorgen.returnValue();
      ctorgen.endMethod();
      }
    //end of class
    cv.visitEnd();

    byte[] bytecode = cw.toByteArray();
View Full Code Here

  protected void emitStatics(ClassVisitor cv) {
    if(this.isDeftype())
      {
      //getBasis()
      Method meth = Method.getMethod("clojure.lang.IPersistentVector getBasis()");
      GeneratorAdapter gen = new GeneratorAdapter(ACC_PUBLIC + ACC_STATIC,
                        meth,
                        null,
                        null,
                        cv);
      emitValue(hintedFields, gen);
      gen.returnValue();
      gen.endMethod();

      if (this.isDeftype() && this.fields.count() > this.hintedFields.count())
        {
        //create(IPersistentMap)
        String className = name.replace('.', '/');
View Full Code Here

      for(Class retType : e.getValue())
        {
             Method meth = new Method(m.getName(), Type.getType(retType), argTypes);

        GeneratorAdapter gen = new GeneratorAdapter(ACC_PUBLIC + ACC_BRIDGE,
                                                meth,
                                                null,
                                                //todo don't hardwire this
                                                EXCEPTION_TYPES,
                                                cv);
        gen.visitCode();
        gen.loadThis();
        gen.loadArgs();
        gen.invokeInterface(Type.getType(m.getDeclaringClass()),target);
        gen.returnValue();
        gen.endMethod();
        }
      }
  }
View Full Code Here

  }

  public void doEmitStatic(ObjExpr fn, ClassVisitor cv){
    Method ms = new Method("invokeStatic", getReturnType(), argtypes);

    GeneratorAdapter gen = new GeneratorAdapter(ACC_PUBLIC + ACC_STATIC,
                                                ms,
                                                null,
                                                //todo don't hardwire this
                                                EXCEPTION_TYPES,
                                                cv);
    gen.visitCode();
    Label loopLabel = gen.mark();
    gen.visitLineNumber(line, loopLabel);
    try
      {
      Var.pushThreadBindings(RT.map(LOOP_LABEL, loopLabel, METHOD, this));
      emitBody(objx, gen, retClass, body);

      Label end = gen.mark();
      for(ISeq lbs = argLocals.seq(); lbs != null; lbs = lbs.next())
        {
        LocalBinding lb = (LocalBinding) lbs.first();
        gen.visitLocalVariable(lb.name, argtypes[lb.idx].getDescriptor(), null, loopLabel, end, lb.idx);
        }
      }
    catch(Exception e)
      {
      throw Util.sneakyThrow(e);
      }
    finally
      {
      Var.popThreadBindings();
      }

    gen.returnValue();
    //gen.visitMaxs(1, 1);
    gen.endMethod();

  //generate the regular invoke, calling the static method
    Method m = new Method(getMethodName(), OBJECT_TYPE, getArgTypes());

    gen = new GeneratorAdapter(ACC_PUBLIC,
                               m,
                               null,
                               //todo don't hardwire this
                               EXCEPTION_TYPES,
                               cv);
    gen.visitCode();
    for(int i = 0; i < argtypes.length; i++)
      {
      gen.loadArg(i);
      HostExpr.emitUnboxArg(fn, gen, argclasses[i]);
      }
    gen.invokeStatic(objx.objtype, ms);
    gen.box(getReturnType());


    gen.returnValue();
    //gen.visitMaxs(1, 1);
    gen.endMethod();

  }
View Full Code Here

TOP

Related Classes of clojure.asm.commons.GeneratorAdapter

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.