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 BigInt = System.Numerics.BigInteger;
21 using System.Collections.Generic;
23 using Microsoft.Scripting.Math;
24 using Microsoft.Scripting.Utils;
26 namespace Microsoft.Scripting.Interpreter {
27 public abstract class InstructionFactory {
28 // TODO: weak table for types in a collectible assembly?
29 private static Dictionary<Type, InstructionFactory> _factories;
31 internal static InstructionFactory GetFactory(Type type) {
32 if (_factories == null) {
33 _factories = new Dictionary<Type, InstructionFactory>() {
34 { typeof(object), InstructionFactory<object>.Factory },
35 { typeof(bool), InstructionFactory<bool>.Factory },
36 { typeof(byte), InstructionFactory<byte>.Factory },
37 { typeof(sbyte), InstructionFactory<sbyte>.Factory },
38 { typeof(short), InstructionFactory<short>.Factory },
39 { typeof(ushort), InstructionFactory<ushort>.Factory },
40 { typeof(int), InstructionFactory<int>.Factory },
41 { typeof(uint), InstructionFactory<uint>.Factory },
42 { typeof(long), InstructionFactory<long>.Factory },
43 { typeof(ulong), InstructionFactory<ulong>.Factory },
44 { typeof(float), InstructionFactory<float>.Factory },
45 { typeof(double), InstructionFactory<double>.Factory },
46 { typeof(char), InstructionFactory<char>.Factory },
47 { typeof(string), InstructionFactory<string>.Factory },
49 { typeof(BigInt), InstructionFactory<BigInt>.Factory },
51 { typeof(BigInteger), InstructionFactory<BigInteger>.Factory }
56 InstructionFactory factory;
57 if (!_factories.TryGetValue(type, out factory)) {
58 factory = (InstructionFactory)typeof(InstructionFactory<>).MakeGenericType(type).GetDeclaredField("Factory").GetValue(null);
59 _factories[type] = factory;
65 internal protected abstract Instruction GetArrayItem();
66 internal protected abstract Instruction SetArrayItem();
67 internal protected abstract Instruction TypeIs();
68 internal protected abstract Instruction TypeAs();
69 internal protected abstract Instruction DefaultValue();
70 internal protected abstract Instruction NewArray();
71 internal protected abstract Instruction NewArrayInit(int elementCount);
72 internal protected abstract Instruction WrapToNullable(Type elementType);
75 public sealed class InstructionFactory<T> : InstructionFactory {
76 [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
77 public static readonly InstructionFactory Factory = new InstructionFactory<T>();
79 private Instruction _getArrayItem;
80 private Instruction _setArrayItem;
81 private Instruction _typeIs;
82 private Instruction _defaultValue;
83 private Instruction _newArray;
84 private Instruction _typeAs;
85 private Instruction _nullableWrap;
87 private InstructionFactory() { }
89 internal protected override Instruction GetArrayItem() {
90 return _getArrayItem ?? (_getArrayItem = new GetArrayItemInstruction<T>());
93 internal protected override Instruction SetArrayItem() {
94 return _setArrayItem ?? (_setArrayItem = new SetArrayItemInstruction<T>());
97 internal protected override Instruction TypeIs() {
98 return _typeIs ?? (_typeIs = new TypeIsInstruction<T>());
101 internal protected override Instruction TypeAs() {
102 return _typeAs ?? (_typeAs = new TypeAsInstruction<T>());
105 internal protected override Instruction DefaultValue() {
106 return _defaultValue ?? (_defaultValue = new DefaultValueInstruction<T>());
109 internal protected override Instruction NewArray() {
110 return _newArray ?? (_newArray = new NewArrayInstruction<T>());
113 internal protected override Instruction NewArrayInit(int elementCount) {
114 return new NewArrayInitInstruction<T>(elementCount);
117 internal protected override Instruction WrapToNullable(Type elementType) {
118 return _nullableWrap ?? (_nullableWrap = new WrapToNullableInstruction<T>(elementType));