Пример #1
0
        private void visitSignature(DNode call, Signature signature)
        {
            for (int i = 0; i < call.numOperands && i < signature.args.Length; i++)
            {
                DNode    node = call.getOperand(i);
                Argument arg  = i < signature.args.Length
                               ? signature.args[i]
                               : signature.args[signature.args.Length - 1];

                TypeUnit tu = TypeUnit.FromArgument(arg);
                if (tu != null)
                {
                    node.addType(tu);
                }
            }

            // Peek ahead for constants.
            if (signature.args.Length > 0 &&
                signature.args[signature.args.Length - 1].type == VariableType.Variadic)
            {
                for (int i = signature.args.Length - 1; i < call.numOperands; i++)
                {
                    DNode node = call.getOperand(i);
                    if (node.type != NodeType.Constant)
                    {
                        continue;
                    }

                    DConstant constNode = (DConstant)node;
                    Variable  global    = graph_.file.lookupGlobal(constNode.value);
                    if (global != null)
                    {
                        call.replaceOperand(i, new DGlobal(global));
                        continue;
                    }

                    // Guess a string...
                    call.replaceOperand(i, new DString(graph_.file.stringFromData(constNode.value)));
                }
            }
        }
Пример #2
0
        private static bool AnalyzeHeapNode(NodeBlock block, DHeap node)
        {
            // Easy case: compiler needed a lvalue.
            if (node.uses.Count == 2)
            {
                DUse lastUse  = node.uses.Last();
                DUse firstUse = node.uses.First();
                if ((lastUse.node.type == NodeType.Call ||
                     lastUse.node.type == NodeType.SysReq) &&
                    firstUse.node.type == NodeType.Store &&
                    firstUse.index == 0)
                {
                    lastUse.node.replaceOperand(lastUse.index, firstUse.node.getOperand(1));
                    return(true);
                }

                if ((lastUse.node.type == NodeType.Call ||
                     lastUse.node.type == NodeType.SysReq) &&
                    firstUse.node.type == NodeType.MemCopy &&
                    firstUse.index == 0)
                {
                    // heap -> memcpy always reads from DAT + constant
                    DMemCopy     memcopy = (DMemCopy)firstUse.node;
                    DConstant    cv      = (DConstant)memcopy.from;
                    DInlineArray ia      = new DInlineArray(cv.value, memcopy.bytes);
                    block.nodes.insertAfter(node, ia);
                    lastUse.node.replaceOperand(lastUse.index, ia);

                    // Give the inline array some type information.
                    Signature signature = SignatureOf(lastUse.node);
                    TypeUnit  tu        = TypeUnit.FromArgument(signature.args[lastUse.index]);
                    ia.addType(tu);
                    return(true);
                }
            }

            return(false);
        }