Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Wrighton <david_wrighton@outlook.com>2017-07-25 01:48:17 +0300
committerMorgan Brown <morganb@microsoft.com>2017-09-15 01:33:25 +0300
commite1dc0fa42676c5486e869982168e9f41db80f815 (patch)
treef0610e6e66758f4876c886bb08af73017b051077 /src/ILCompiler.WebAssembly
parentc9ff51b2ef7da92dcf8664a64f07736e0e8752c5 (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.cs28
-rw-r--r--src/ILCompiler.WebAssembly/src/CodeGen/ILToWebAssemblyImporter.cs126
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)