Merge branch 'BigIntegerParse'
[mono.git] / mcs / class / dlr / Runtime / Microsoft.Dynamic / Interpreter / Instructions / ArrayOperations.cs
1 /* ****************************************************************************
2  *
3  * Copyright (c) Microsoft Corporation. 
4  *
5  * This source code is subject to terms and conditions of the Apache License, Version 2.0. A 
6  * copy of the license can be found in the License.html file at the root of this distribution. If 
7  * you cannot locate the  Apache License, Version 2.0, please send an email to 
8  * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound 
9  * by the terms of the Apache License, Version 2.0.
10  *
11  * You must not remove this notice, or any other, from this software.
12  *
13  *
14  * ***************************************************************************/
15
16 using System;
17
18 namespace Microsoft.Scripting.Interpreter {
19     public sealed class NewArrayInitInstruction<TElement> : Instruction {
20         private readonly int _elementCount;
21
22         internal NewArrayInitInstruction(int elementCount) {
23             _elementCount = elementCount;
24         }
25
26         public override int ConsumedStack { get { return _elementCount; } }
27         public override int ProducedStack { get { return 1; } }
28
29         public override int Run(InterpretedFrame frame) {
30             TElement[] array = new TElement[_elementCount];
31             for (int i = _elementCount - 1; i >= 0; i--) {
32                 array[i] = (TElement)frame.Pop();
33             }
34             frame.Push(array);
35             return +1;
36         }
37     }
38
39     public sealed class NewArrayInstruction<TElement> : Instruction {
40         internal NewArrayInstruction() { }
41
42         public override int ConsumedStack { get { return 1; } }
43         public override int ProducedStack { get { return 1; } }
44
45         public override int Run(InterpretedFrame frame) {
46             int length = (int)frame.Pop();
47             frame.Push(new TElement[length]);
48             return +1;
49         }
50     }
51
52     public sealed class NewArrayBoundsInstruction : Instruction {
53         private readonly Type _elementType;
54         private readonly int _rank;
55
56         internal NewArrayBoundsInstruction(Type elementType, int rank) {
57             _elementType = elementType;
58             _rank = rank;
59         }
60
61         public override int ConsumedStack { get { return _rank; } }
62         public override int ProducedStack { get { return 1; } }
63
64         public override int Run(InterpretedFrame frame) {
65             var lengths = new int[_rank];
66             for (int i = _rank - 1; i >= 0; i--) {
67                 lengths[i] = (int)frame.Pop();
68             }
69             var array = Array.CreateInstance(_elementType, lengths);
70             frame.Push(array);
71             return +1;
72         }
73     }
74
75     public sealed class GetArrayItemInstruction<TElement> : Instruction {
76         internal GetArrayItemInstruction() { }
77
78         public override int ConsumedStack { get { return 2; } }
79         public override int ProducedStack { get { return 1; } }
80
81         public override int Run(InterpretedFrame frame) {
82             int index = (int)frame.Pop();
83             TElement[] array = (TElement[])frame.Pop();
84             frame.Push(array[index]);
85             return +1;
86         }
87
88         public override string InstructionName {
89             get { return "GetArrayItem"; }
90         }
91     }
92
93     public sealed class GetArrayLengthInstruction : Instruction {
94         private static Instruction instance;
95
96         private GetArrayLengthInstruction() { }
97
98         public override int ConsumedStack { get { return 1; } }
99         public override int ProducedStack { get { return 1; } }
100
101         public override int Run(InterpretedFrame frame) {
102             var array = (Array)frame.Pop();
103             frame.Push(array.Length);
104             return +1;
105         }
106
107         public static Instruction Create() {
108             return instance ?? (instance = new GetArrayLengthInstruction());
109         }
110
111         public override string InstructionName {
112             get { return "GetArrayLength"; }
113         }
114     }
115
116     public sealed class SetArrayItemInstruction<TElement> : Instruction {
117         internal SetArrayItemInstruction() { }
118
119         public override int ConsumedStack { get { return 3; } }
120         public override int ProducedStack { get { return 0; } }
121
122         public override int Run(InterpretedFrame frame) {
123             TElement value = (TElement)frame.Pop();
124             int index = (int)frame.Pop();
125             TElement[] array = (TElement[])frame.Pop();
126             array[index] = value;
127             return +1;
128         }
129
130         public override string InstructionName {
131             get { return "SetArrayItem"; }
132         }
133     }
134 }