diff options
author | David Wrighton <david_wrighton@outlook.com> | 2017-07-25 01:48:17 +0300 |
---|---|---|
committer | Morgan Brown <morganb@microsoft.com> | 2017-09-15 01:33:25 +0300 |
commit | e1dc0fa42676c5486e869982168e9f41db80f815 (patch) | |
tree | f0610e6e66758f4876c886bb08af73017b051077 /src/ILCompiler.WebAssembly | |
parent | c9ff51b2ef7da92dcf8664a64f07736e0e8752c5 (diff) |
Add concept of EvaluationStack
- Mostly a copy of the stack code from CppCodegen
Diffstat (limited to 'src/ILCompiler.WebAssembly')
-rw-r--r-- | src/ILCompiler.WebAssembly/src/CodeGen/EvaluationStack.cs | 28 | ||||
-rw-r--r-- | src/ILCompiler.WebAssembly/src/CodeGen/ILToWebAssemblyImporter.cs | 126 |
2 files changed, 140 insertions, 14 deletions
diff --git a/src/ILCompiler.WebAssembly/src/CodeGen/EvaluationStack.cs b/src/ILCompiler.WebAssembly/src/CodeGen/EvaluationStack.cs index 20ed6831a..af3ff1368 100644 --- a/src/ILCompiler.WebAssembly/src/CodeGen/EvaluationStack.cs +++ b/src/ILCompiler.WebAssembly/src/CodeGen/EvaluationStack.cs @@ -186,7 +186,7 @@ namespace Internal.IL /// Add representation of current entry in <paramref name="builder"/>. /// </summary> /// <param name="builder">Generation buffer used for appending new content.</param> - public abstract void Append(CppGenerationBuffer builder); + //public abstract void Append(CppGenerationBuffer builder); /// <summary> /// Create a new copy of current entry. @@ -263,10 +263,10 @@ namespace Internal.IL Value = value; } - public override void Append(CppGenerationBuffer _builder) + /*public override void Append(CppGenerationBuffer _builder) { _builder.Append(Value.ToStringInvariant()); - } + }*/ protected override void BuildRepresentation(StringBuilder s) { @@ -285,7 +285,7 @@ namespace Internal.IL { } - public override void Append(CppGenerationBuffer _builder) + /*public override void Append(CppGenerationBuffer _builder) { if (Value == Int32.MinValue) { @@ -299,7 +299,7 @@ namespace Internal.IL { _builder.Append(Value.ToStringInvariant()); } - } + }*/ public override StackEntry Duplicate() { @@ -336,7 +336,7 @@ namespace Internal.IL { } - public override void Append(CppGenerationBuffer _builder) + /*public override void Append(CppGenerationBuffer _builder) { if (Value == long.MinValue) { @@ -349,7 +349,7 @@ namespace Internal.IL _builder.Append(Value.ToStringInvariant()); _builder.Append(')'); } - } + }*/ public override StackEntry Duplicate() { @@ -390,7 +390,7 @@ namespace Internal.IL { } - public override void Append(CppGenerationBuffer _builder) + /*public override void Append(CppGenerationBuffer _builder) { long val = BitConverter.DoubleToInt64Bits(Value); _builder.Append("__uint64_to_double(0x"); @@ -414,8 +414,8 @@ namespace Internal.IL { _builder.Append(Value.ToStringInvariant()); } - _builder.Append(" */"); - } + _builder.Append(" */ //"); + //} public override StackEntry Duplicate() { @@ -443,10 +443,10 @@ namespace Internal.IL { Name = name; } - public override void Append(CppGenerationBuffer _builder) + /* public override void Append(CppGenerationBuffer _builder) { _builder.Append(Name); - } + }*/ public override StackEntry Duplicate() { @@ -500,11 +500,11 @@ namespace Internal.IL { } - public override void Append(CppGenerationBuffer _builder) + /*public override void Append(CppGenerationBuffer _builder) { _builder.Append("// FIXME: An invalid value was pushed onto the evaluation stack."); Debug.Assert(false, "Invalid stack values shouldn't be appended."); - } + }*/ public override StackEntry Duplicate() { diff --git a/src/ILCompiler.WebAssembly/src/CodeGen/ILToWebAssemblyImporter.cs b/src/ILCompiler.WebAssembly/src/CodeGen/ILToWebAssemblyImporter.cs index be130e593..62f309621 100644 --- a/src/ILCompiler.WebAssembly/src/CodeGen/ILToWebAssemblyImporter.cs +++ b/src/ILCompiler.WebAssembly/src/CodeGen/ILToWebAssemblyImporter.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Diagnostics; using Internal.TypeSystem; using ILCompiler; @@ -18,6 +19,11 @@ namespace Internal.IL private readonly byte[] _ilBytes; + /// <summary> + /// Stack of values pushed onto the IL stack: locals, arguments, values, function pointer, ... + /// </summary> + private EvaluationStack<StackEntry> _stack = new EvaluationStack<StackEntry>(0); + private class BasicBlock { // Common fields @@ -26,6 +32,8 @@ namespace Internal.IL public int StartOffset; public int EndOffset; + public EvaluationStack<StackEntry> EntryStack; + public bool TryStart; public bool FilterStart; public bool HandlerStart; @@ -57,12 +65,76 @@ namespace Internal.IL ImportBasicBlocks(); } + + /// <summary> + /// Push an expression named <paramref name="name"/> of kind <paramref name="kind"/>. + /// </summary> + /// <param name="kind">Kind of entry in stack</param> + /// <param name="name">Variable to be pushed</param> + /// <param name="type">Type if any of <paramref name="name"/></param> + private void PushExpression(StackValueKind kind, string name, TypeDesc type = null) + { + Debug.Assert(kind != StackValueKind.Unknown, "Unknown stack kind"); + + _stack.Push(new ExpressionEntry(kind, name, type)); + } + + + /// <summary> + /// Generate a cast in case the stack type of source is not identical or compatible with destination type. + /// </summary> + /// <param name="destType">Type of destination</param> + /// <param name="srcEntry">Source entry from stack</param> + private void AppendCastIfNecessary(TypeDesc destType, StackEntry srcEntry) + { + ConstantEntry constant = srcEntry as ConstantEntry; + if ((constant != null) && (constant.IsCastNecessary(destType)) || !destType.IsValueType || destType != srcEntry.Type) + { + throw new NotImplementedException(); + /* + Append("("); + Append(GetSignatureTypeNameAndAddReference(destType)); + Append(")");*/ + } + } + + private void AppendCastIfNecessary(StackValueKind dstType, TypeDesc srcType) + { + if (dstType == StackValueKind.ByRef) + { + + throw new NotImplementedException(); + /* + Append("("); + Append(GetSignatureTypeNameAndAddReference(srcType)); + Append(")");*/ + } + else + if (srcType.IsPointer) + { + throw new NotImplementedException(); + //Append("(intptr_t)"); + } + } + + private void MarkInstructionBoundary() { } private void StartImportingBasicBlock(BasicBlock basicBlock) { + _stack.Clear(); + + EvaluationStack<StackEntry> entryStack = basicBlock.EntryStack; + if (entryStack != null) + { + int n = entryStack.Length; + for (int i = 0; i < n; i++) + { + _stack.Push(entryStack[i].Duplicate()); + } + } } private void EndImportingBasicBlock(BasicBlock basicBlock) @@ -331,6 +403,60 @@ namespace Internal.IL private void ImportFallthrough(BasicBlock next) { + EvaluationStack<StackEntry> entryStack = next.EntryStack; + + if (entryStack != null) + { + if (entryStack.Length != _stack.Length) + throw new InvalidProgramException(); + + for (int i = 0; i < entryStack.Length; i++) + { + // TODO: Do we need to allow conversions? + if (entryStack[i].Kind != _stack[i].Kind) + throw new InvalidProgramException(); + + if (entryStack[i].Kind == StackValueKind.ValueType) + { + if (entryStack[i].Type != _stack[i].Type) + throw new InvalidProgramException(); + } + } + } + else + { + if (_stack.Length > 0) + { + entryStack = new EvaluationStack<StackEntry>(_stack.Length); + +#pragma warning disable 162 // Due to not implement3ed exception incrementer in for needs pragma warning disable + for (int i = 0; i < _stack.Length; i++) + { + throw new NotImplementedException(); + //entryStack.Push(NewSpillSlot(_stack[i])); + } +#pragma warning restore 162 + } + next.EntryStack = entryStack; + } + + if (entryStack != null) + { +#pragma warning disable 162// Due to not implement3ed exception incrementer in for needs pragma warning disable + for (int i = 0; i < entryStack.Length; i++) + { + throw new NotImplementedException(); + /*AppendLine(); + Append(entryStack[i]); + Append(" = "); + Append(_stack[i]); + AppendSemicolon();*/ + } +#pragma warning restore 162 + } + + MarkBasicBlock(next); + } private TypeDesc GetWellKnownType(WellKnownType wellKnownType) |