⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 slotget.java

📁 A framework written in Java for implementing high-level and dynamic languages, compiling them into J
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
            || val1 instanceof FString            || val1 instanceof Symbol)          name = val1.toString();      }    if (isStatic)      {        type = language.getTypeFor(arg0);        int known = Invoke.checkKnownClass(type, comp);        if (known < 0)          return exp;        if ("class".equals(name))          {            if (known > 0)              return QuoteExp.getInstance(type.getReflectClass());            Method method              = Compilation.typeType.getDeclaredMethod("getReflectClass", 0);            return new ApplyExp(method, new Expression[] { arg0 });          }        if (type != null)          {            Expression[] nargs              = new Expression[] { new QuoteExp(type), arg1 };            ApplyExp nexp = new ApplyExp(exp.getFunction(), nargs);            nexp.setLine(exp);            exp = nexp;          }      }    else      type = arg0.getType();    if (type instanceof ClassType && name != null)      {	ClassType ctype = (ClassType) type;	ClassType caller = comp.curClass != null ? comp.curClass	  : comp.mainClass;        Member part = lookupMember(ctype, name, caller);        if (part instanceof gnu.bytecode.Field)          {            gnu.bytecode.Field field = (gnu.bytecode.Field) part;            ctype = field.getDeclaringClass();            int modifiers = field.getModifiers();            boolean isStaticField = (modifiers & Access.STATIC) != 0;            if (isStatic && ! isStaticField)              return new ErrorExp("cannot access non-static field `" + name                                  + "' using `" + getName() + '\'', comp);	    if (caller != null && ! caller.isAccessible(ctype, modifiers))	      return new ErrorExp("field "+ctype.getName()+'.'+name                                  +" is not accessible here", comp);          }        else if (part instanceof gnu.bytecode.Method)          {            gnu.bytecode.Method method = (gnu.bytecode.Method) part;            ctype = method.getDeclaringClass();	    int modifiers = method.getModifiers();            boolean isStaticMethod = method.getStaticFlag();            if (isStatic && ! isStaticMethod)              return new ErrorExp("cannot call non-static getter method `"                                  + name + "' using `" + getName() + '\'', comp);	    if (caller != null && ! caller.isAccessible(ctype, modifiers))	      return new ErrorExp( "method "+method +" is not accessible here",                                    comp);          }        if (part != null)          {            Expression[] nargs              = new Expression[] { arg0, new QuoteExp(part) };            ApplyExp nexp = new ApplyExp(exp.getFunction(), nargs);            nexp.setLine(exp);            return nexp;          }        if (type != Type.pointer_type)          comp.error('e', "no slot `"+name+"' in "+ctype.getName());      }    if (name != null && ! (type instanceof ArrayType))      {        String fname = gnu.expr.Compilation.mangleNameIfNeeded(name);        // So we can quickly check for "class" or "length".        // The name gets interned anyway when compiled.        fname = fname.intern();        String getName = ClassExp.slotToMethodName("get", name);        String isName = ClassExp.slotToMethodName("is", name);        ApplyExp nexp          = new ApplyExp(Invoke.invokeStatic,                         new Expression[] {                           QuoteExp.getInstance("gnu.kawa.reflect.SlotGet"),                           QuoteExp.getInstance("getSlotValue"),                           isStatic ? QuoteExp.trueExp : QuoteExp.falseExp,                           args[0],                           QuoteExp.getInstance(name),                           QuoteExp.getInstance(fname),                           QuoteExp.getInstance(getName),                           QuoteExp.getInstance(isName),                           QuoteExp.getInstance(language)});        nexp.setLine(exp);        return ((InlineCalls) walker).walkApplyOnly(nexp);      }    return exp;  }  public void compile (ApplyExp exp, Compilation comp, Target target)  {    Expression[] args = exp.getArgs();    Expression arg0 = args[0];    Expression arg1 = args[1];    Language language = comp.getLanguage();    Type type = isStatic ? language.getTypeFor(arg0)      : arg0.getType();    CodeAttr code = comp.getCode();    if (type instanceof ClassType && arg1 instanceof QuoteExp)      {	ClassType ctype = (ClassType) type;        Object part = ((QuoteExp) arg1).getValue();        if (part instanceof gnu.bytecode.Field)          {            gnu.bytecode.Field field = (gnu.bytecode.Field) part;            int modifiers = field.getModifiers();            boolean isStaticField = (modifiers & Access.STATIC) != 0;            args[0].compile(comp,                            isStaticField ? Target.Ignore                            : Target.pushValue(ctype));            if (isStaticField)              {                boolean inlined = false;                /*                FIXME This isn't quite safe.  We should only "inline"                the value if the field whose initializer is a constant                expression (JLS 2nd ed 15.28).  We cannot determine this                using reflection instead we have to parse the .class file.                Type ftype = field.getType();                if ((modifiers & Access.FINAL) != 0                    && ftype instanceof PrimType)                  {                    // We inline int final fields.                    // Other kinds of final fields are less obviously a win.                    char sig = ftype.getSignature().charAt(0);                    if (sig != 'F' && sig != 'D' && sig != 'J')                      {                        try                          {                            java.lang.reflect.Field rfield                              = field.getReflectField();                            int val = rfield.getInt(null);                            code.emitPushInt(val);                            inlined = true;                          }                        catch (Exception ex)                          {                          }                      }                  }                */                if (! inlined)                  code.emitGetStatic(field);               }            else              code.emitGetField(field);	    Type ftype = field.getType();	    Class fclass = ftype.getReflectClass();	    if (fclass != null)	      ftype = language.getTypeFor(fclass);	    target.compileFromStack(comp, ftype);            return;          }        if (part instanceof Method)          {            gnu.bytecode.Method method = (gnu.bytecode.Method) part;	    int modifiers = method.getModifiers();            boolean isStaticMethod = method.getStaticFlag();            args[0].compile(comp,                            isStaticMethod ? Target.Ignore                            : Target.pushValue(ctype));            if (isStaticMethod)              code.emitInvokeStatic(method);            else if (ctype.isInterface())              code.emitInvokeInterface(method);            else              code.emitInvokeVirtual(method);	    target.compileFromStack(comp, method.getReturnType());            return;          }      }    String name = ClassMethods.checkName(arg1);    if (type instanceof ArrayType && "length".equals(name) && ! isStatic)      {	args[0].compile(comp, Target.pushValue(type));	code.emitArrayLength();	target.compileFromStack(comp, LangPrimType.intType);  // FIXME	return;      }    ApplyExp.compile(exp, comp, target);  }  public Type getReturnType (Expression[] args)  {    int nargs = args.length;    if (nargs == 2)      {        Expression arg0 = args[0];        Expression arg1 = args[1];        if (arg1 instanceof QuoteExp)          {            Object part = ((QuoteExp) arg1).getValue();            if (part instanceof gnu.bytecode.Field)              return ((gnu.bytecode.Field) part).getType();            if (part instanceof gnu.bytecode.Method)              return ((gnu.bytecode.Method) part).getReturnType();            if (! isStatic && arg0.getType() instanceof ArrayType                && "length".equals(ClassMethods.checkName(arg1, true)))              return gnu.kawa.lispexpr.LangPrimType.intType;  // FIXME          }      }    return Type.pointer_type;  }  public Procedure getSetter()  {    return setter == null ? super.getSetter() : setter;  }  /**   * Convenience method to make an Expression that gets the value of a field.   * @param value evaluates to object that has the named field   * @param fieldName name of field in value   * @return expression that get the name field from value   */  public static ApplyExp makeGetField(Expression value, String fieldName)  {    Expression[] args = new Expression[2];    args[0] = value;    args[1] = new QuoteExp(fieldName);    return new ApplyExp(gnu.kawa.reflect.SlotGet.field, args);  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -