Example #1
0
        // See StringConcatFactory in jdk sources
        private static List <Exprent> ExtractParameters(List <PooledConstant> bootstrapArguments
                                                        , InvocationExprent expr)
        {
            List <Exprent> parameters = expr.GetLstParameters();

            if (bootstrapArguments != null)
            {
                PooledConstant constant = bootstrapArguments[0];
                if (constant.type == ICodeConstants.CONSTANT_String)
                {
                    string         recipe      = ((PrimitiveConstant)constant).GetString();
                    List <Exprent> res         = new List <Exprent>();
                    StringBuilder  acc         = new StringBuilder();
                    int            parameterId = 0;
                    for (int i = 0; i < recipe.Length; i++)
                    {
                        char c = recipe[i];
                        if (c == Tag_Const || c == Tag_Arg)
                        {
                            // Detected a special tag, flush all accumulated characters
                            // as a constant first:
                            if (acc.Length > 0)
                            {
                                res.Add(new ConstExprent(VarType.Vartype_String, acc.ToString(), expr.bytecode));
                                acc.Length = 0;
                            }
                            if (c == Tag_Const)
                            {
                            }
                            // skip for now
                            if (c == Tag_Arg)
                            {
                                res.Add(parameters[parameterId++]);
                            }
                        }
                        else
                        {
                            // Not a special characters, this is a constant embedded into
                            // the recipe itself.
                            acc.Append(c);
                        }
                    }
                    // Flush the remaining characters as constant:
                    if (acc.Length > 0)
                    {
                        res.Add(new ConstExprent(VarType.Vartype_String, acc.ToString(), expr.bytecode));
                    }
                    return(res);
                }
            }
            return(new List <Exprent>(parameters));
        }
        public InvocationExprent(int opcode, LinkConstant cn, List <PooledConstant> bootstrapArguments
                                 , ListStack <Exprent> stack, HashSet <int> bytecodeOffsets)
            : this()
        {
            name      = cn.elementname;
            classname = cn.classname;
            this.bootstrapArguments = bootstrapArguments;
            switch (opcode)
            {
            case ICodeConstants.opc_invokestatic:
            {
                invocationTyp = Invoke_Static;
                break;
            }

            case ICodeConstants.opc_invokespecial:
            {
                invocationTyp = Invoke_Special;
                break;
            }

            case ICodeConstants.opc_invokevirtual:
            {
                invocationTyp = Invoke_Virtual;
                break;
            }

            case ICodeConstants.opc_invokeinterface:
            {
                invocationTyp = Invoke_Interface;
                break;
            }

            case ICodeConstants.opc_invokedynamic:
            {
                invocationTyp = Invoke_Dynamic;
                classname     = "java/lang/Class";
                // dummy class name
                invokeDynamicClassSuffix = "##Lambda_" + cn.index1 + "_" + cn.index2;
                break;
            }
            }
            if (ICodeConstants.Init_Name.Equals(name))
            {
                functype = Typ_Init;
            }
            else if (ICodeConstants.Clinit_Name.Equals(name))
            {
                functype = Typ_Clinit;
            }
            stringDescriptor = cn.descriptor;
            descriptor       = MethodDescriptor.ParseDescriptor(cn.descriptor);
            foreach (VarType ignored in descriptor.@params)
            {
                lstParameters.Add(0, stack.Pop());
            }
            if (opcode == ICodeConstants.opc_invokedynamic)
            {
                int dynamicInvocationType = -1;
                if (bootstrapArguments != null)
                {
                    if (bootstrapArguments.Count > 1)
                    {
                        // INVOKEDYNAMIC is used not only for lambdas
                        PooledConstant link = bootstrapArguments[1];
                        if (link is LinkConstant)
                        {
                            dynamicInvocationType = ((LinkConstant)link).index1;
                        }
                    }
                }
                if (dynamicInvocationType == ICodeConstants.CONSTANT_MethodHandle_REF_invokeStatic)
                {
                    isStatic__ = true;
                }
                else if (!(lstParameters.Count == 0))
                {
                    // FIXME: remove the first parameter completely from the list. It's the object type for a virtual lambda method.
                    instance = lstParameters[0];
                }
            }
            else if (opcode == ICodeConstants.opc_invokestatic)
            {
                isStatic__ = true;
            }
            else
            {
                instance = stack.Pop();
            }
            AddBytecodeOffsets(bytecodeOffsets);
        }