1 /* ****************************************************************************
3 * Copyright (c) Microsoft Corporation.
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.
11 * You must not remove this notice, or any other, from this software.
14 * ***************************************************************************/
17 using System.Collections.Generic;
18 using System.Diagnostics;
19 using System.Reflection;
20 using System.Runtime.CompilerServices;
21 using Microsoft.Scripting.Runtime;
22 using Microsoft.Scripting.Utils;
25 namespace Microsoft.Scripting.Interpreter {
26 internal sealed class CreateDelegateInstruction : Instruction {
27 private readonly LightDelegateCreator _creator;
29 internal CreateDelegateInstruction(LightDelegateCreator delegateCreator) {
30 _creator = delegateCreator;
33 public override int ConsumedStack { get { return _creator.Interpreter.ClosureSize; } }
34 public override int ProducedStack { get { return 1; } }
36 public override int Run(InterpretedFrame frame) {
37 StrongBox<object>[] closure;
38 if (ConsumedStack > 0) {
39 closure = new StrongBox<object>[ConsumedStack];
40 for (int i = closure.Length - 1; i >= 0; i--) {
41 closure[i] = (StrongBox<object>)frame.Pop();
47 Delegate d = _creator.CreateDelegate(closure);
54 internal sealed class NewInstruction : Instruction {
55 private readonly ConstructorInfo _constructor;
56 private readonly int _argCount;
58 public NewInstruction(ConstructorInfo constructor) {
59 _constructor = constructor;
60 _argCount = constructor.GetParameters().Length;
63 public override int ConsumedStack { get { return _argCount; } }
64 public override int ProducedStack { get { return 1; } }
66 public override int Run(InterpretedFrame frame) {
67 object[] args = new object[_argCount];
68 for (int i = _argCount - 1; i >= 0; i--) {
69 args[i] = frame.Pop();
74 ret = _constructor.Invoke(args);
75 } catch (TargetInvocationException e) {
76 ExceptionHelpers.UpdateForRethrow(e.InnerException);
77 throw e.InnerException;
84 public override string ToString() {
85 return "New " + _constructor.DeclaringType.Name + "(" + _constructor + ")";
89 internal sealed class DefaultValueInstruction<T> : Instruction {
90 internal DefaultValueInstruction() { }
92 public override int ConsumedStack { get { return 0; } }
93 public override int ProducedStack { get { return 1; } }
95 public override int Run(InterpretedFrame frame) {
96 frame.Push(default(T));
100 public override string ToString() {
101 return "New " + typeof(T);
105 internal sealed class TypeIsInstruction<T> : Instruction {
106 internal TypeIsInstruction() { }
108 public override int ConsumedStack { get { return 1; } }
109 public override int ProducedStack { get { return 1; } }
111 public override int Run(InterpretedFrame frame) {
112 // unfortunately Type.IsInstanceOfType() is 35-times slower than "is T" so we use generic code:
113 frame.Push(ScriptingRuntimeHelpers.BooleanToObject(frame.Pop() is T));
117 public override string ToString() {
118 return "TypeIs " + typeof(T).Name;
122 internal sealed class TypeAsInstruction<T> : Instruction {
123 internal TypeAsInstruction() { }
125 public override int ConsumedStack { get { return 1; } }
126 public override int ProducedStack { get { return 1; } }
128 public override int Run(InterpretedFrame frame) {
129 // can't use as w/o generic constraint
130 object value = frame.Pop();
139 public override string ToString() {
140 return "TypeAs " + typeof(T).Name;
144 internal sealed class TypeEqualsInstruction : Instruction {
145 public static readonly TypeEqualsInstruction Instance = new TypeEqualsInstruction();
147 public override int ConsumedStack { get { return 2; } }
148 public override int ProducedStack { get { return 1; } }
150 private TypeEqualsInstruction() {
153 public override int Run(InterpretedFrame frame) {
154 object type = frame.Pop();
155 object obj = frame.Pop();
156 frame.Push(ScriptingRuntimeHelpers.BooleanToObject(obj != null && (object)obj.GetType() == type));
160 public override string InstructionName {
161 get { return "TypeEquals()"; }
165 internal sealed class WrapToNullableInstruction<T> : Instruction {
167 readonly Type elementType;
168 ConstructorInfo ctor;
170 public override int ConsumedStack { get { return 1; } }
171 public override int ProducedStack { get { return 1; } }
173 internal WrapToNullableInstruction(Type elementType) {
174 this.elementType = elementType;
177 public override int Run(InterpretedFrame frame) {
178 var r = frame.Data[frame.StackIndex - 1];
180 // Don't need to wrap null values
184 ctor = typeof (Nullable<>).MakeGenericType (elementType).GetDeclaredConstructors ().First ();
185 frame.Data[frame.StackIndex - 1] = ctor.Invoke (new [] { r });
189 public override string InstructionName {
190 get { return "WrapTo " + typeof(T) + "?"; }