Beispiel #1
0
        private void FindRegion(IodineMethod method, List <ReachableRegion> regions, int start)
        {
            if (IsReachable(regions, start))
            {
                return;
            }

            for (int i = start; i < method.Body.Count; i++)
            {
                Instruction ins = method.Body [i];

                if (ins.OperationCode == Opcode.Jump)
                {
                    regions.Add(new ReachableRegion(start, i));
                    FindRegion(method, regions, ins.Argument);
                    return;
                }
                else if (ins.OperationCode == Opcode.JumpIfTrue ||
                         ins.OperationCode == Opcode.JumpIfFalse ||
                         ins.OperationCode == Opcode.PushExceptionHandler)
                {
                    regions.Add(new ReachableRegion(start, i));
                    FindRegion(method, regions, i + 1);
                    FindRegion(method, regions, ins.Argument);
                    return;
                }
                else if (ins.OperationCode == Opcode.Return)
                {
                    regions.Add(new ReachableRegion(start, i));
                    return;
                }
            }
            regions.Add(new ReachableRegion(start, method.Body.Count));
        }
 public void PerformOptimization(IodineMethod method)
 {
     while (PerformMethodOptimization(method) > 0)
     {
         ;
     }
 }
Beispiel #3
0
        public override void Accept(LambdaExpression lambda)
        {
            symbolTable.NextScope();

            int          locals     = methodBuilder.LocalCount > 0 ? methodBuilder.LocalCount : symbolTable.CurrentScope.SymbolCount;
            IodineMethod anonMethod = new IodineMethod(methodBuilder, methodBuilder.Module, null, lambda.InstanceMethod,
                                                       lambda.Parameters.Count, locals);
            FunctionCompiler compiler = new FunctionCompiler(symbolTable, anonMethod);

            for (int i = 0; i < lambda.Parameters.Count; i++)
            {
                anonMethod.Parameters [lambda.Parameters [i]] = symbolTable.GetSymbol
                                                                    (lambda.Parameters [i]).Index;
            }
            lambda.Children [0].Visit(compiler);
            anonMethod.EmitInstruction(lambda.Location, Opcode.LoadNull);
            anonMethod.Variadic = lambda.Variadic;
            anonMethod.FinalizeLabels();
            methodBuilder.EmitInstruction(lambda.Location, Opcode.LoadConst,
                                          methodBuilder.Module.DefineConstant(anonMethod));
            if (methodBuilder.LocalCount > 0)
            {
                methodBuilder.EmitInstruction(lambda.Location, Opcode.BuildClosure);
            }
            symbolTable.LeaveScope();
        }
Beispiel #4
0
        public void PerformOptimization(IodineMethod method)
        {
            List <ReachableRegion> regions = new List <ReachableRegion> ();
            int reachableSize = 0;

            FindRegion(method, regions, 0);
            foreach (ReachableRegion region in regions)
            {
                reachableSize += region.Size + 1;
            }
            Instruction[] oldInstructions = method.Body.ToArray();
            Instruction[] newInstructions = new Instruction[method.Body.Count];
            int           next            = 0;

            for (int i = 0; i < method.Body.Count; i++)
            {
                if (IsReachable(regions, i))
                {
                    newInstructions [next++] = oldInstructions [i];
                }
                else
                {
                    ShiftLabels(next, oldInstructions);
                    ShiftLabels(next, newInstructions);
                }
            }
            method.Body.Clear();
            method.Body.AddRange(newInstructions);
        }
Beispiel #5
0
        private IodineMethod CompileMethod(FunctionDeclaration funcDecl)
        {
            symbolTable.NextScope();
            IodineMethod methodBuilder = new IodineMethod(module, funcDecl.Name, funcDecl.InstanceMethod,
                                                          funcDecl.Parameters.Count,
                                                          symbolTable.CurrentScope.SymbolCount);
            FunctionCompiler compiler = new FunctionCompiler(symbolTable,
                                                             methodBuilder);

            methodBuilder.Variadic           = funcDecl.Variadic;
            methodBuilder.AcceptsKeywordArgs = funcDecl.AcceptsKeywordArgs;
            for (int i = 0; i < funcDecl.Parameters.Count; i++)
            {
                methodBuilder.Parameters [funcDecl.Parameters [i]] = symbolTable.GetSymbol
                                                                         (funcDecl.Parameters [i]).Index;
            }
            funcDecl.Children [0].Visit(compiler);
            AstNode lastNode = funcDecl.Children [0].LastOrDefault();

            if (lastNode != null)
            {
                methodBuilder.EmitInstruction(lastNode.Location, Opcode.LoadNull);
            }
            else
            {
                methodBuilder.EmitInstruction(funcDecl.Location, Opcode.LoadNull);
            }
            methodBuilder.FinalizeLabels();
            symbolTable.LeaveScope();
            return(methodBuilder);
        }
Beispiel #6
0
 public FunctionCompiler(SymbolTable symbolTable, IodineMethod methodBuilder,
                         Stack <IodineLabel> breakLabels, Stack <IodineLabel> continueLabels)
 {
     this.symbolTable    = symbolTable;
     this.methodBuilder  = methodBuilder;
     this.breakLabels    = breakLabels;
     this.continueLabels = continueLabels;
 }
Beispiel #7
0
 /// <summary>
 /// Initializes a new instance of the <see cref="T:Iodine.Runtime.IodineBoundMethod"/> class.
 /// </summary>
 /// <param name="self">Self.</param>
 /// <param name="method">Method.</param>
 public IodineBoundMethod(IodineObject self, IodineMethod method)
     : base(InstanceTypeDef)
 {
     Method = method;
     SetAttribute("__name__", method.Attributes ["__name__"]);
     SetAttribute("__doc__", method.Attributes ["__doc__"]);
     SetAttribute("__invoke__", method.Attributes ["__invoke__"]);
     Self = self;
 }
Beispiel #8
0
 public PatternCompiler(SymbolTable symbolTable,
                        IodineMethod methodBuilder,
                        int temporary,
                        IodineAstVisitor parent)
 {
     parentVisitor      = parent;
     this.methodBuilder = methodBuilder;
     this.symbolTable   = symbolTable;
     this.temporary     = temporary;
 }
Beispiel #9
0
 private void OptimizeObject(IodineObject obj)
 {
     foreach (IodineObject attr in obj.Attributes.Values)
     {
         if (attr is IodineMethod)
         {
             IodineMethod method = attr as IodineMethod;
             foreach (IBytecodeOptimization opt in Optimizations)
             {
                 opt.PerformOptimization(method);
             }
         }
     }
 }
Beispiel #10
0
        public IodineGenerator(StackFrame frame,
                               IodineMethod baseMethod,
                               IodineObject[] args,
                               IodineObject initialValue)
            : base(TypeDefinition)
        {
            arguments       = args;
            value           = initialValue;
            stackFrame      = frame;
            this.baseMethod = baseMethod;

            SetAttribute("__iter__", new BuiltinMethodCallback((VirtualMachine vm, IodineObject self, IodineObject [] arguments) => {
                return(GetIterator(vm));
            }, this));
        }
        private int PerformMethodOptimization(IodineMethod method)
        {
            int removed = 0;

            Instruction[] oldInstructions = method.Body.ToArray();
            Instruction[] newInstructions = new Instruction[method.Body.Count];
            int           next            = 0;
            Instruction   last            = new Instruction();

            for (int i = 0; i < method.Body.Count; i++)
            {
                Instruction curr = oldInstructions [i];
                if (i != 0 && curr.OperationCode == Opcode.Pop)
                {
                    if (last.OperationCode == Opcode.LoadLocal || last.OperationCode == Opcode.LoadGlobal ||
                        last.OperationCode == Opcode.LoadNull)
                    {
                        oldInstructions [i]     = new Instruction(curr.Location, Opcode.Nop, 0);
                        oldInstructions [i - 1] = new Instruction(curr.Location, Opcode.Nop, 0);
                        removed++;
                    }
                }
                else if (curr.OperationCode == Opcode.Jump && curr.Argument == i + 1)
                {
                    oldInstructions [i] = new Instruction(curr.Location, Opcode.Nop, 0);
                    removed++;
                }
                last = curr;
            }
            for (int i = 0; i < oldInstructions.Length; i++)
            {
                Instruction curr = oldInstructions [i];
                if (curr.OperationCode == Opcode.Nop)
                {
                    ShiftLabels(next, newInstructions);
                    ShiftLabels(next, oldInstructions);
                }
                else
                {
                    newInstructions [next++] = curr;
                }
            }
            method.Body.Clear();
            method.Body.AddRange(newInstructions);
            return(removed);
        }
Beispiel #12
0
        public override void Accept(FunctionDeclaration funcDecl)
        {
            symbolTable.NextScope();
            IodineMethod anonMethod = new IodineMethod(methodBuilder, methodBuilder.Module, null, funcDecl.InstanceMethod,
                                                       funcDecl.Parameters.Count, methodBuilder.LocalCount);
            FunctionCompiler compiler = new FunctionCompiler(symbolTable, anonMethod);

            for (int i = 0; i < funcDecl.Parameters.Count; i++)
            {
                anonMethod.Parameters [funcDecl.Parameters [i]] = symbolTable.GetSymbol
                                                                      (funcDecl.Parameters [i]).Index;
            }
            funcDecl.Children [0].Visit(compiler);
            anonMethod.EmitInstruction(funcDecl.Location, Opcode.LoadNull);
            anonMethod.Variadic           = funcDecl.Variadic;
            anonMethod.AcceptsKeywordArgs = funcDecl.AcceptsKeywordArgs;
            anonMethod.FinalizeLabels();
            methodBuilder.EmitInstruction(funcDecl.Location, Opcode.LoadConst,
                                          methodBuilder.Module.DefineConstant(anonMethod));
            methodBuilder.EmitInstruction(funcDecl.Location, Opcode.BuildClosure);
            methodBuilder.EmitInstruction(funcDecl.Location, Opcode.StoreLocal, symbolTable.GetSymbol(funcDecl.Name).Index);
            symbolTable.LeaveScope();
        }
Beispiel #13
0
 public void AddMethod(IodineMethod method)
 {
     Attributes [method.Name] = method;
 }
Beispiel #14
0
 public FunctionCompiler(SymbolTable symbolTable, IodineMethod methodBuilder)
 {
     this.symbolTable   = symbolTable;
     this.methodBuilder = methodBuilder;
 }
Beispiel #15
0
        public IodineClass CompileClass(ClassDeclaration classDecl)
        {
            IodineMethod constructor = CompileMethod(classDecl.Constructor);

            if (classDecl.Constructor.Children [0].Children.Count == 0 ||
                !(classDecl.Constructor.Children [0].Children [0] is SuperCallExpression))
            {
                if (classDecl.Base.Count > 0)
                {
                    foreach (string subclass in classDecl.Base)
                    {
                        string[] contract = subclass.Split('.');
                        constructor.EmitInstruction(classDecl.Location, Opcode.LoadGlobal,
                                                    constructor.Module.DefineConstant(new IodineName(contract [0])));
                        for (int j = 1; j < contract.Length; j++)
                        {
                            constructor.EmitInstruction(classDecl.Location, Opcode.LoadAttribute,
                                                        constructor.Module.DefineConstant(new IodineName(contract [0])));
                        }
                        constructor.EmitInstruction(classDecl.Location, Opcode.InvokeSuper, 0);
                    }
                }
            }
            IodineMethod     initializer = new IodineMethod(module, "__init__", false, 0, 0);
            IodineClass      clazz       = new IodineClass(classDecl.Name, initializer, constructor);
            FunctionCompiler compiler    = new FunctionCompiler(symbolTable,
                                                                clazz.Initializer);

            for (int i = 1; i < classDecl.Children.Count; i++)
            {
                if (classDecl.Children [i] is FunctionDeclaration)
                {
                    FunctionDeclaration func = classDecl.Children [i] as FunctionDeclaration;
                    if (func.InstanceMethod)
                    {
                        clazz.AddInstanceMethod(CompileMethod(func));
                    }
                    else
                    {
                        clazz.SetAttribute(func.Name, CompileMethod(func));
                    }
                }
                else if (classDecl.Children [i] is ClassDeclaration)
                {
                    ClassDeclaration subclass = classDecl.Children [i] as ClassDeclaration;
                    clazz.SetAttribute(subclass.Name, CompileClass(subclass));
                }
                else if (classDecl.Children [i] is EnumDeclaration)
                {
                    EnumDeclaration enumeration = classDecl.Children [i] as EnumDeclaration;
                    clazz.SetAttribute(enumeration.Name, CompileEnum(enumeration));
                }
                else if (classDecl.Children [i] is BinaryExpression)
                {
                    BinaryExpression expr = classDecl.Children [i] as BinaryExpression;
                    NameExpression   name = expr.Left as NameExpression;
                    expr.Right.Visit(compiler);
                    initializer.EmitInstruction(classDecl.Location, Opcode.LoadGlobal,
                                                module.DefineConstant(new
                                                                      IodineName(classDecl.Name)));
                    initializer.EmitInstruction(classDecl.Location, Opcode.StoreAttribute,
                                                module.DefineConstant(new
                                                                      IodineName(name.Value)));
                }
                else
                {
                    classDecl.Children [i].Visit(compiler);
                }
            }
            clazz.Initializer.FinalizeLabels();
            return(clazz);
        }
Beispiel #16
0
 public IodineClosure(StackFrame frame, IodineMethod target)
     : base(TypeDefinition)
 {
     this.frame = frame;
     Target     = target;
 }