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;
		}
예제 #2
0
			public IodineInstruction (IodineMethod method, Instruction instruction)
				: base (TypeDefinition)
			{
				Instruction = instruction;
				parentMethod = method;
				SetAttribute ("opcode", new IodineInteger ((long)instruction.OperationCode));
				SetAttribute ("immediate", new IodineInteger (instruction.Argument));
			}
		private void ShiftLabels (int start, Instruction[] instructions)
		{
			for (int i = 0; i < instructions.Length; i++) {
				Instruction ins = instructions [i];
				if (ins.OperationCode == Opcode.Jump ||
					ins.OperationCode == Opcode.JumpIfFalse ||
				    ins.OperationCode == Opcode.JumpIfTrue ||
				    ins.OperationCode == Opcode.PushExceptionHandler) {

					if (ins.Argument > start) {
						instructions [i] = new Instruction (ins.Location, ins.OperationCode,
							ins.Argument - 1);
					}
				}

			}
		}
		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);
		}
예제 #5
0
		public void FinalizeLabels ()
		{
			foreach (int position in labelReferences.Keys) {
				instructions [position] = new Instruction (instructions [position].Location,
					instructions [position].OperationCode,
					labelReferences [position]._Position);
			}
		}
예제 #6
0
        private IodineObject Invoke(IodineMethod method, IodineObject[] arguments)
        {
            if (method.Body.Count > 0) {
                currLoc = method.Body [0].Location;
            }

            int insCount = method.Body.Count;
            int i = 0;
            foreach (string param in method.Parameters.Keys) {
                if (method.Variadic && (method.AcceptsKeywordArgs ? i == method.Parameters.Keys.Count - 2 :
                    i == method.Parameters.Keys.Count - 1)) {
                    IodineObject[] tupleItems = new IodineObject[arguments.Length - i];
                    Array.Copy (arguments, i, tupleItems, 0, arguments.Length - i);
                    Top.StoreLocal (method.Parameters [param], new IodineTuple (tupleItems));
                } else if (i == method.Parameters.Keys.Count - 1 && method.AcceptsKeywordArgs) {
                    if (i < arguments.Length && arguments [i] is IodineHashMap) {
                        Top.StoreLocal (method.Parameters [param], arguments [i]);
                    } else {
                        Top.StoreLocal (method.Parameters [param], new IodineHashMap ());
                    }
                } else {
                    Top.StoreLocal (method.Parameters [param], arguments [i++]);
                }
            }

            StackFrame top = Top;
            while (top.InstructionPointer < insCount && !top.AbortExecution && !Top.Yielded) {
                instruction = method.Body [Top.InstructionPointer++];
                ExecuteInstruction ();
                top.Location = currLoc;
            }

            if (top.AbortExecution) {
                while (top.DisposableObjects.Count > 0) {
                    top.DisposableObjects.Pop ().Exit (this);
                }
                return IodineNull.Instance;
            }

            IodineObject retVal = last ?? IodineNull.Instance;
            EndFrame ();

            while (top.DisposableObjects.Count > 0) {
                top.DisposableObjects.Pop ().Exit (this);
            }

            return retVal;
        }