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

📄 invoke.java

📁 A framework written in Java for implementing high-level and dynamic languages, compiling them into J
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
    Language language = comp.getLanguage();    Expression[] args = exp.getArgs();    if (args.length > carg)      {	Type type = language.getTypeFor(args[carg]);	if (! (type instanceof Type))	  return exp;        checkKnownClass(type, comp);	Expression[] nargs = new Expression[args.length];	System.arraycopy(args, 0, nargs, 0, args.length);	nargs[carg] = new QuoteExp(type);	ApplyExp nexp = new ApplyExp(exp.getFunction(), nargs);        nexp.setLine(exp);        return nexp;      }    return exp;  }  public Expression inline (ApplyExp exp, ExpWalker walker)  {    Compilation comp = walker.getCompilation();    Expression[] args = exp.getArgs();    int nargs = args.length;    if (! comp.mustCompile        // This should never happen, as InlineCalls.walkApplyExp        // checks the number of arguments before inline is called.        || nargs == 0 || ((kind == 'V' || kind == '*') && nargs == 1))      return exp;    ObjectType type;    Expression arg0 = args[0];    Type type0 = (kind == 'V' || kind == '*' ? arg0.getType() : language.getTypeFor(arg0));    if (type0 instanceof PairClassType)      type = ((PairClassType) type0).instanceType;    else if (type0 instanceof ObjectType)      type = (ObjectType) type0;    else      type = null;    String name = getMethodName(args);    int margsLength, argsStartIndex, objIndex;    if (kind == 'V' || kind == '*')      // Invoke virtual      {        margsLength = nargs - 1;        argsStartIndex = 2;        objIndex = 0;      }    else if (kind == 'N')                // make new      {        margsLength = nargs;        argsStartIndex = 0;        objIndex = -1;      }    else if (kind == 'S' || kind == 's') // Invoke static      {        margsLength = nargs - 2;        argsStartIndex = 2;        objIndex = -1;      }    else if (kind == 'P')                // Invoke special      {        margsLength = nargs - 2;        argsStartIndex = 3;        objIndex = 1;      }    else      return exp;    if (kind == 'N' && type instanceof ArrayType)      {        ArrayType atype = (ArrayType) type;        Type elementType = atype.getComponentType();        Expression sizeArg = null;        boolean lengthSpecified = false;        if (args.length >= 3 && args[1] instanceof QuoteExp)          {            Object arg1 = ((QuoteExp) args[1]).getValue();            if (arg1 instanceof Keyword                 && ("length".equals(name = ((Keyword) arg1).getName())                     || "size".equals(name)))              {                sizeArg = args[2];                lengthSpecified = true;              }          }        if (sizeArg == null)          sizeArg = QuoteExp.getInstance(new Integer(args.length-1));        Expression alloc = new ApplyExp(new ArrayNew(elementType),                                        new Expression[] { sizeArg } );        if (lengthSpecified && args.length == 3)          return alloc;        LetExp let = new LetExp(new Expression[] { alloc });        Declaration adecl = let.addDeclaration((String) null, atype);        adecl.noteValue(alloc);        BeginExp begin = new BeginExp();        int index = 0;        for (int i = lengthSpecified ? 3 : 1; i < args.length;  i++)          {            Expression arg = args[i];            if (lengthSpecified && i+1 < args.length && arg instanceof QuoteExp)              {                Object key = ((QuoteExp) arg).getValue();                if (key instanceof Keyword)                  {                    String kname = ((Keyword) key).getName();                    try                      {                        index = Integer.parseInt(kname);                        arg = args[++i];                      }                    catch (Throwable ex)                      {                        comp.error('e', "non-integer keyword '"+kname+"' in array constructor");                        return exp;                      }                  }              }            begin.add(new ApplyExp(new ArraySet(elementType),                                   new Expression[] {                                     new ReferenceExp(adecl),                                     QuoteExp.getInstance(new Integer(index)),                                     arg}));            index++;          }        begin.add(new ReferenceExp(adecl));        let.body = begin;        return let;      }    else if (type != null && name != null)      {        if (type instanceof TypeValue && kind == 'N')          {            Procedure constructor = ((TypeValue) type).getConstructor();            if (constructor != null)              {                Expression[] xargs = new Expression[nargs-1];                System.arraycopy(args, 1, xargs, 0, nargs-1);                return ((InlineCalls) walker)                  .walkApplyOnly(new ApplyExp(constructor, xargs));              }          }        PrimProcedure[] methods;        int okCount, maybeCount;        ClassType caller = comp == null ? null          : comp.curClass != null ? comp.curClass          : comp.mainClass;        ObjectType ctype = (ObjectType) type;        try          {            methods = getMethods(ctype, name, caller);            long num = selectApplicable(methods, ctype, args,                                         margsLength, argsStartIndex, objIndex);            okCount = (int) (num >> 32);            maybeCount = (int) num;          }        catch (Exception ex)          {            comp.error('w', "unknown class: " + type.getName());            return exp;          }        int index = -1;        Object[] slots;        if (okCount + maybeCount == 0            && kind == 'N'            && (ClassMethods.selectApplicable(methods,                                              new Type[] { Compilation.typeClassType })                >> 32) == 1            && (slots = checkKeywords(type, args, 1, caller)) != null)          {            StringBuffer errbuf = null;            for (int i = 0;  i < slots.length;  i++)              {                if (slots[i] instanceof String)                  {                    if (errbuf == null)                      {                        errbuf = new StringBuffer();                        errbuf.append("no field or setter ");                      }                    else                      errbuf.append(", ");                    errbuf.append('`');                    errbuf.append(slots[i]);                    errbuf.append('\'');                  }              }            if (errbuf != null)              {                errbuf.append(" in class ");                errbuf.append(type.getName());                comp.error('w', errbuf.toString());                return exp;              }            else              {                ApplyExp e = new ApplyExp(methods[0],                                          new Expression[] { arg0 });                for (int i = 0;  i < slots.length;  i++)                  {                    Expression[] sargs                      = { e, new QuoteExp(slots[i]), args[2 * i + 2] };                    e = new ApplyExp(SlotSet.setFieldReturnObject, sargs);                  }                return e.setLine(exp);              }          }        int nmethods = methods.length;        if (okCount + maybeCount == 0 && kind == 'N')          {            methods = invokeStatic.getMethods(ctype, "valueOf", caller);            argsStartIndex = 1;            margsLength = nargs - 1;            long num = selectApplicable(methods, ctype, args,                                        margsLength, argsStartIndex, -1);            okCount = (int) (num >> 32);            maybeCount = (int) num;          }        if (okCount + maybeCount == 0)          {            if (comp.getBooleanOption("warn-invoke-unknown-method", true))              {                if (kind=='N')                  name = name+"/valueOf";                if (nmethods + methods.length == 0)                  comp.error('w', "no accessible method '"+name+"' in "+type.getName());                else                  comp.error('w', "no possibly applicable method '"                             +name+"' in "+type.getName());              }          }        else if (okCount == 1 || (okCount == 0 && maybeCount == 1))          index = 0;        else if (okCount > 0)          {            index = MethodProc.mostSpecific(methods, okCount);            if (index < 0)              {                if (kind == 'S')                  {                    // If we didn't find a most specific method,                    // check if there is one that is static.  If so,                    // prefer that - after all, we're using invoke-static.                    for (int i = 0;  i < okCount;  i++)                      {                        if (methods[i].getStaticFlag())                          {                            if (index >= 0)                              {                                index = -1;                                break;                              }                            else                              index = i;                          }                      }                  }              }            if (index < 0                && comp.getBooleanOption("warn-invoke-unknown-method", true))              {                StringBuffer sbuf = new StringBuffer();                sbuf.append("more than one definitely applicable method `");                sbuf.append(name);                sbuf.append("' in ");                sbuf.append(type.getName());                append(methods, okCount, sbuf);                comp.error('w', sbuf.toString());              }          }        else if (comp.getBooleanOption("warn-invoke-unknown-method", true))          {            StringBuffer sbuf = new StringBuffer();            sbuf.append("more than one possibly applicable method '");            sbuf.append(name);            sbuf.append("' in ");            sbuf.append(type.getName());            append(methods, maybeCount, sbuf);            comp.error('w', sbuf.toString());          }        if (index >= 0)          {            Expression[] margs = new Expression[margsLength];            int dst = 0;            if (objIndex >= 0)              margs[dst++] = args[objIndex];            for (int src = argsStartIndex;                  src < args.length && dst < margs.length;                  src++, dst++)              margs[dst] = args[src];            return new ApplyExp(methods[index], margs).setLine(exp);          }      }    return exp;  }  private void append (PrimProcedure[] methods, int mcount, StringBuffer sbuf)  {    for (int i = 0;  i < mcount;  i++)      {        sbuf.append("\n  candidate: ");        sbuf.append(methods[i]);      }  }  private String getMethodName(Expression[] args)  {    if (kind == 'N')      return "<init>";    int nameIndex = (kind == 'P' ? 2 : 1);    if (args.length >= nameIndex + 1)      return ClassMethods.checkName(args[nameIndex], false);    return null;  }  /** Return an ApplyExp that will call a method with given arguments.   * @param type the class containing the method we want to call.   * @param name the name of the method we want to call   * @param args the arguments to the call   * @return an ApplyExp representing the call   */  public static synchronized  ApplyExp makeInvokeStatic(ClassType type, String name, Expression[] args)  {    PrimProcedure method = getStaticMethod(type, name, args);    if (method == null)      throw new RuntimeException("missing or ambiguous method `" + name                                 + "' in " + type.getName());    return new ApplyExp(method, args);  }  public static synchronized PrimProcedure  getStaticMethod(ClassType type, String name, Expression[] args)  {    PrimProcedure[] methods = invokeStatic.getMethods(type, name, null);    long num = selectApplicable(methods, type, args, args.length, 0, -1);    int okCount = (int) (num >> 32);    int maybeCount = (int) num;    int index;    if (methods == null)      index = -1;    else if (okCount > 0)      index = MethodProc.mostSpecific(methods, okCount);    else if (maybeCount == 1)      index = 0;    else      index = -1;    return index < 0 ? null : methods[index];  }}

⌨️ 快捷键说明

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