diff --git a/Spec.Test/WastJson/Actions.cs b/Spec.Test/WastJson/Actions.cs index bc9b6038..7026781d 100644 --- a/Spec.Test/WastJson/Actions.cs +++ b/Spec.Test/WastJson/Actions.cs @@ -51,10 +51,17 @@ public Value[] Invoke(ref WasmRuntime runtime, ref Module? module) } if (addr == null) throw new InvalidDataException( - $"Could not get exported function {moduleName}.{Field}"); - + $"Could not get exported function {moduleName}.{Field}"); + + var options = new InvokerOptions(); + if (runtime.TraceExecution) + { + Console.Error.WriteLine($"\nInvoking wasm function {Field}"); + options.LogInstructionExecution = InstructionLogging.All; + } + //Compute type from action.Args and action.Expected - var invoker = runtime.CreateStackInvoker(addr.Value); + var invoker = runtime.CreateStackInvoker(addr.Value, options); var pVals = Args.Select(arg => arg.AsValue).ToArray(); return invoker(pVals); diff --git a/Spec.Test/WastJson/WastJson.cs b/Spec.Test/WastJson/WastJson.cs index 038b8a90..1a1d941e 100644 --- a/Spec.Test/WastJson/WastJson.cs +++ b/Spec.Test/WastJson/WastJson.cs @@ -33,5 +33,7 @@ public class WastJson public string Path { get; set; } = ""; public override string ToString() => $"{SourceFilename}"; + + public bool TraceExecution; } } \ No newline at end of file diff --git a/Spec.Test/WastJsonTestData.cs b/Spec.Test/WastJsonTestData.cs index 13f0d8a8..71dfa7fe 100644 --- a/Spec.Test/WastJsonTestData.cs +++ b/Spec.Test/WastJsonTestData.cs @@ -49,6 +49,8 @@ static WastJsonTestData() .Select(cfg => cfg.Value ?? "") .ToHashSet(); + public static bool TraceExecution => Configuration["TraceExecution"] == "True"; + public IEnumerator GetEnumerator() { var files = Directory.GetFiles(JsonDirectory, "*.json", SearchOption.AllDirectories).OrderBy(path => path); @@ -88,6 +90,7 @@ static WastJson.WastJson LoadTestDefinition(string jsonPath) throw new JsonException($"Error while parsing {jsonPath}"); testDefinition.Path = Path.GetDirectoryName(jsonPath)!; + testDefinition.TraceExecution = TraceExecution; return testDefinition; } } diff --git a/Spec.Test/WastTests.cs b/Spec.Test/WastTests.cs index cd70ff22..d7183942 100644 --- a/Spec.Test/WastTests.cs +++ b/Spec.Test/WastTests.cs @@ -42,6 +42,7 @@ public void RunWast(WastJson.WastJson file) WasmRuntime runtime = new(); env.BindToRuntime(runtime); runtime.TranspileModules = false; + runtime.TraceExecution = file.TraceExecution; Module? module = null; foreach (var command in file.Commands) diff --git a/Spec.Test/testsettings.json b/Spec.Test/testsettings.json index 79af88f7..595f6069 100644 --- a/Spec.Test/testsettings.json +++ b/Spec.Test/testsettings.json @@ -1,6 +1,7 @@ { "JsonDirectory": "../../../generated-json", "RunTranspilerTests": true, + "TraceExecution": false, "Single": null, "SkipWasts": [ "comments.wast", diff --git a/Wacs.Console/Program.cs b/Wacs.Console/Program.cs index 5876a35e..9812e9cf 100644 --- a/Wacs.Console/Program.cs +++ b/Wacs.Console/Program.cs @@ -16,6 +16,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Linq; using CommandLine; @@ -121,10 +122,22 @@ static int RunWithOptions(CommandLineOptions opts) var runtime = new WasmRuntime(); + var parseTimer = new Stopwatch(); + if (opts.LogProg) + { + parseTimer.Start(); + } + //Parse the module using var fileStream = new FileStream(opts.WasmModule, FileMode.Open); var module = BinaryModuleParser.ParseWasm(fileStream); + if (opts.LogProg) + { + parseTimer.Stop(); + System.Console.Error.WriteLine($"Parsing module took {parseTimer.ElapsedMilliseconds:#0.###}ms"); + } + if (opts.Render) { string outputFilePath = Path.ChangeExtension(opts.WasmModule, ".wat"); @@ -210,13 +223,13 @@ static int RunWithOptions(CommandLineOptions opts) if (opts.LogProg) System.Console.Error.WriteLine($"Instantiating Module {moduleName}"); + if (opts.Transpile) + runtime.TranspileModules = true; + //Validation normally happens after instantiation, but you can skip it if you did it after parsing, or you're like super confident. - var modInst = runtime.InstantiateModule(module, new RuntimeOptions { SkipModuleValidation = true }); + var modInst = runtime.InstantiateModule(module, new RuntimeOptions { SkipModuleValidation = true, TimeInstantiation = opts.LogProg}); runtime.RegisterModule(moduleName, modInst); - if (opts.Transpile) - runtime.TranspileModule(modInst); - var callOptions = new InvokerOptions { LogGas = opts.LogGas, @@ -225,6 +238,7 @@ static int RunWithOptions(CommandLineOptions opts) LogInstructionExecution = opts.LogInstructionExecution, CalculateLineNumbers = opts.CalculateLineNumbers, CollectStats = opts.CollectStats, + SynchronousExecution = true, }; //Wasm/WASI entry points diff --git a/Wacs.Console/Wacs.Console.csproj b/Wacs.Console/Wacs.Console.csproj index 3c90a389..c6c5e702 100644 --- a/Wacs.Console/Wacs.Console.csproj +++ b/Wacs.Console/Wacs.Console.csproj @@ -20,6 +20,10 @@ Wacs.Console Wacs.Console + + + TRACE;STRICT_EXECUTION + diff --git a/Wacs.Core/Attributes/OpCodeAttribute.cs b/Wacs.Core/Attributes/OpCodeAttribute.cs index 162fb483..3fb9e717 100644 --- a/Wacs.Core/Attributes/OpCodeAttribute.cs +++ b/Wacs.Core/Attributes/OpCodeAttribute.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; diff --git a/Wacs.Core/Attributes/WasmTypeAttribute.cs b/Wacs.Core/Attributes/WasmTypeAttribute.cs index 955a4fd6..78f01275 100644 --- a/Wacs.Core/Attributes/WasmTypeAttribute.cs +++ b/Wacs.Core/Attributes/WasmTypeAttribute.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using Wacs.Core.Types.Defs; diff --git a/Wacs.Core/Attributes/WatTokenAttribute.cs b/Wacs.Core/Attributes/WatTokenAttribute.cs index d4a5268a..37c286a6 100644 --- a/Wacs.Core/Attributes/WatTokenAttribute.cs +++ b/Wacs.Core/Attributes/WatTokenAttribute.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; diff --git a/Wacs.Core/Instructions/Control.cs b/Wacs.Core/Instructions/Control.cs index a357b002..035fa0bc 100644 --- a/Wacs.Core/Instructions/Control.cs +++ b/Wacs.Core/Instructions/Control.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Collections.Generic; @@ -24,11 +22,13 @@ using Wacs.Core.Instructions.Transpiler; using Wacs.Core.OpCodes; using Wacs.Core.Runtime; +using Wacs.Core.Runtime.Exceptions; using Wacs.Core.Runtime.Types; using Wacs.Core.Types; using Wacs.Core.Types.Defs; using Wacs.Core.Utilities; using Wacs.Core.Validation; +using InstructionPointer = System.Int32; // @Spec 2.4.8. Control Instructions // @Spec 5.4.1 Control Instructions @@ -46,6 +46,12 @@ public override void Validate(IWasmValidationContext context) context.SetUnreachable(); } + public override InstructionBase Link(ExecContext context, InstructionPointer pointer) + { + context.LinkUnreachable = true; + return this; + } + // @Spec 4.4.8.2. unreachable public override void Execute(ExecContext context) => throw new TrapException("unreachable"); @@ -77,7 +83,7 @@ public class InstBlock : BlockTarget, IBlockInstruction public int Count => 1; - public int Size => 1 + Block.Size; + public int BlockSize => 1 + Block.Size; public Block GetBlock(int idx) => Block; // @Spec 3.3.8.3 block @@ -106,10 +112,17 @@ public override void Validate(IWasmValidationContext context) } } + public override InstructionBase Link(ExecContext context, InstructionPointer pointer) + { + base.Link(context, pointer); + PointerAdvance = 1; + return this; + } + // @Spec 4.4.8.3. block public override void Execute(ExecContext context) { - context.EnterBlock(this, Block); + // context.Frame.PushLabel(this); } /// @@ -133,11 +146,11 @@ public BlockTarget Immediate(ValType blockType, InstructionSequence sequence) return this; } - public override string RenderText(ExecContext? context) - { - if (context == null || !context.Attributes.Live) return base.RenderText(context); - return $"{base.RenderText(context)} ;; label = @{context.Frame.LabelCount}"; - } + // public override string RenderText(ExecContext? context) + // { + // if (context == null || !context.Attributes.Live) return base.RenderText(context); + // return $"{base.RenderText(context)} ;; label = @{context.Frame.TopLabel.LabelHeight}"; + // } } //0x03 @@ -151,7 +164,7 @@ public class InstLoop : BlockTarget, IBlockInstruction public int Count => 1; - public int Size => 1 + Block.Size; + public int BlockSize => 1 + Block.Size; public Block GetBlock(int idx) => Block; // @Spec 3.3.8.4. loop @@ -180,11 +193,17 @@ public override void Validate(IWasmValidationContext context) } } + public override InstructionBase Link(ExecContext context, InstructionPointer pointer) + { + base.Link(context, pointer); + PointerAdvance = 1; + return this; + } + // @Spec 4.4.8.4. loop public override void Execute(ExecContext context) { - if (Block.Instructions.Count != 0) - context.EnterBlock(this, Block); + // context.Frame.PushLabel(this); } /// @@ -208,29 +227,32 @@ public BlockTarget Immediate(ValType blockType, InstructionSequence sequence) return this; } - public override string RenderText(ExecContext? context) - { - if (context == null || !context.Attributes.Live) return base.RenderText(context); - return $"{base.RenderText(context)} ;; label = @{context.Frame.LabelCount}"; - } + // public override string RenderText(ExecContext? context) + // { + // if (context == null || !context.Attributes.Live) return base.RenderText(context); + // return $"{base.RenderText(context)} ;; label = @{context.Frame.TopLabel.LabelHeight}"; + // } } //0x04 - public class InstIf : BlockTarget, IBlockInstruction + public class InstIf : BlockTarget, IBlockInstruction, IIfInstruction { private static readonly ByteCode IfOp = OpCode.If; - private static readonly ByteCode ElseOp = OpCode.Else; private Block ElseBlock = Block.Empty; - private int ElseCount; + private Block IfBlock = Block.Empty; + public override ByteCode Op => IfOp; + //Consume the predicate + public override int StackDiff => -1; + public ValType BlockType => IfBlock.BlockType; public int Count => ElseBlock.Length == 0 ? 1 : 2; - public int Size => 1 + IfBlock.Size + ElseBlock.Size; + public int BlockSize => 1 + IfBlock.Size + ElseBlock.Size; public Block GetBlock(int idx) => idx == 0 ? IfBlock : ElseBlock; // @Spec 3.3.8.5 if @@ -257,7 +279,8 @@ public override void Validate(IWasmValidationContext context) var elseType = context.Types.ResolveBlockType(ElseBlock.BlockType); if (!ifType.Equivalent(elseType)) - throw new ValidationException($"If block returned type {ifType} without matching else block"); + throw new ValidationException($"If block returned type {ifType}" + + $" without matching else ({elseType}) block"); if (ElseBlock.Length == 0) return; @@ -278,15 +301,11 @@ public override void Validate(IWasmValidationContext context) // @Spec 4.4.8.5. if public override void Execute(ExecContext context) { + // context.Frame.PushLabel(this); int c = context.OpStack.PopI32(); - if (c != 0) + if (c == 0) { - context.EnterBlock(this, IfBlock); - } - else - { - if (ElseCount != 0) - context.EnterBlock(this, ElseBlock); + context.InstructionPointer = Else - 1; } } @@ -313,8 +332,6 @@ public override InstructionBase Parse(BinaryReader reader) { throw new FormatException($"If block did not terminate correctly."); } - - ElseCount = ElseBlock.Instructions.Count; return this; } @@ -328,15 +345,14 @@ public BlockTarget Immediate(ValType blockType, InstructionSequence ifSeq, Instr blockType: blockType, seq: elseSeq ); - ElseCount = ElseBlock.Instructions.Count; return this; } } //0x05 - public class InstElse : InstEnd + public class InstElse : BlockTarget { - public new static readonly InstElse Inst = new(); + // public new static readonly InstElse Inst = new(); private static readonly ByteCode ElseOp = OpCode.Else; public override ByteCode Op => ElseOp; @@ -346,12 +362,38 @@ public override void Validate(IWasmValidationContext context) context.Assert(frame.Opcode == OpCode.If, "Else terminated a non-If block"); context.PushControlFrame(ElseOp, frame.Types); } + + public override InstructionBase Link(ExecContext context, InstructionPointer pointer) + { + var target = context.PeekLabel(); + target.Suboridinate = this; + + if (target is not IIfInstruction) + throw new InstantiationException($"Else block instruction mismatched to {target}"); + + EnclosingBlock = target.EnclosingBlock; + Label = target.Label; + target.Else = pointer + 1; + + //Reset and re-consume the predicate + context.LinkOpStackHeight = target.Label.StackHeight; + return this; + } + + public override void Execute(ExecContext context) + { + //Just jump out of the If block + // context.EnterSequence(End); + context.InstructionPointer = End - 1; + } } //0x0B public class InstEnd : InstructionBase { - public static readonly InstEnd Inst = new(); + public bool FunctionEnd; + + // public static readonly InstEnd Inst = new(); public override ByteCode Op => OpCode.End; public override void Validate(IWasmValidationContext context) @@ -360,69 +402,74 @@ public override void Validate(IWasmValidationContext context) context.OpStack.ReturnResults(frame.EndTypes); } - public override void Execute(ExecContext context) + public override InstructionBase Link(ExecContext context, InstructionPointer pointer) { - var label = context.Frame.Label; - switch (label.Instruction.x00) - { - case OpCode.Block: - case OpCode.If: - case OpCode.Else: - case OpCode.Loop: - case OpCode.TryTable: - context.ExitBlock(); - break; - case OpCode.Func: - case OpCode.Call: - context.FunctionReturn(); - break; - default: - //Do nothing - break; - } + var target = context.PopLabel(); + target.End = pointer; + if (target.Suboridinate != null) + target.Suboridinate.End = pointer; + + if (target is IIfInstruction && target.Else < 0) + target.Else = pointer; + + context.LinkUnreachable = false; + context.LinkOpStackHeight = target.Label.StackHeight; + context.LinkOpStackHeight -= target.Label.Parameters; + context.LinkOpStackHeight += target.Label.Results; + + if (!FunctionEnd) + PointerAdvance = 1; + + return this; } - public override string RenderText(ExecContext? context) + //Skipped unless FunctionEnd is true + public override void Execute(ExecContext context) { - if (context == null) - { - return $"{base.RenderText(context)}"; - } - var label = context.Frame.Label; - switch (label.Instruction.x00) - { - case OpCode.Block: - case OpCode.If: - case OpCode.Else: - return $"{base.RenderText(context)} (;B/@{context.Frame.LabelCount-1};)"; - case OpCode.Loop: - return $"{base.RenderText(context)} (;L/@{context.Frame.LabelCount-1};)"; - case OpCode.Func: - case OpCode.Call: - var funcAddr = context.Frame.Module.FuncAddrs[context.Frame.Index]; - var func = context.Store[funcAddr]; - var funcName = func.Id; - StringBuilder sb = new(); - if (context.Attributes.Live) - { - sb.Append(" "); - var values = new Stack(); - context.OpStack.PopResults(func.Type.ResultType, ref values); - sb.Append("["); - while (values.Count > 0) - { - sb.Append(values.Peek().ToString()); - if (values.Count > 1) - sb.Append(" "); - context.OpStack.PushValue(values.Pop()); - } - sb.Append("]"); - } - return $"{base.RenderText(context)} (;f/@{context.Frame.LabelCount-1} <- {funcName}{sb};)"; - default: - return $"{base.RenderText(context)}"; - } + context.FunctionReturn(); } + + // public override string RenderText(ExecContext? context) + // { + // if (context == null) + // { + // return $"{base.RenderText(context)}"; + // } + // var label = context.Frame.Label; + // switch (label.Instruction.x00) + // { + // case OpCode.Block: + // case OpCode.If: + // case OpCode.Else: + // return $"{base.RenderText(context)} (;B/@{context.Frame.TopLabel.LabelHeight-1};)"; + // case OpCode.Loop: + // return $"{base.RenderText(context)} (;L/@{context.Frame.TopLabel.LabelHeight-1};)"; + // case OpCode.Func: + // case OpCode.Call: + // var funcAddr = context.Frame.Module.FuncAddrs[context.Frame.Index]; + // var func = context.Store[funcAddr]; + // var funcName = func.Id; + // StringBuilder sb = new(); + // if (context.Attributes.Live) + // { + // sb.Append(" "); + // var values = new Stack(); + // context.OpStack.PopResults(func.Type.ResultType, ref values); + // sb.Append("["); + // while (values.Count > 0) + // { + // sb.Append(values.Peek().ToString()); + // if (values.Count > 1) + // sb.Append(" "); + // context.OpStack.PushValue(values.Pop()); + // } + // sb.Append("]"); + // } + // return $"{base.RenderText(context)} (;f/@{context.Frame.TopLabel.LabelHeight-1} <- {funcName}{sb};)"; + // default: + // return $"{base.RenderText(context)}"; + // } + // } } //0x0C @@ -431,6 +478,8 @@ public sealed class InstBranch : InstructionBase, IBranchInstruction private static Stack _asideVals = new(); private LabelIdx L; + private BlockTarget? LinkedLabel; + public override ByteCode Op => OpCode.Br; // @Spec 3.3.8.6. br l @@ -447,29 +496,47 @@ public override void Validate(IWasmValidationContext context) context.SetUnreachable(); } + public static BlockTarget PrecomputeStack(ExecContext context, LabelIdx labelIndex) + { + var label = context.PeekLabel(); + if (labelIndex.Value > 0) + { + for (int l = 0; l < labelIndex.Value; l++) + label = label.EnclosingBlock; + } + return label; + } + + public static void SetStackHeight(ExecContext context, BlockTarget label) + { + context.LinkOpStackHeight = label.Label.StackHeight + label.Label.Arity; + } + + public override InstructionBase Link(ExecContext context, InstructionPointer pointer) + { + LinkedLabel = PrecomputeStack(context, L); + SetStackHeight(context, LinkedLabel); + context.LinkUnreachable = true; + return this; + } + // @Spec 4.4.8.6. br l public override void Execute(ExecContext context) { - ExecuteInstruction(context, L); + ExecuteInstruction(context, LinkedLabel); } - public static void ExecuteInstruction(ExecContext context, LabelIdx labelIndex) + public static void ExecuteInstruction(ExecContext context, BlockTarget? target) { - //1. - context.Assert( context.Frame.LabelCount > (int)labelIndex.Value, - $"Instruction br failed. Context did not contain Label {labelIndex}"); - //2. - if (labelIndex.Value > 0) + var label = target?.Label switch { - var topAddr = context.Frame.PopLabels((int)(labelIndex.Value - 1)); - context.ResumeSequence(topAddr); - } - - var label = context.Frame.Label; - //3,4. + null => context.Frame.ReturnLabel, + { Instruction: { x00: OpCode.Func} } => context.Frame.ReturnLabel, + var l => l + }; + context.Assert( context.OpStack.Count >= label.Arity, $"Instruction br failed. Not enough values on the stack."); - //5. context.Assert(_asideVals.Count == 0, "Shared temporary stack had values left in it."); @@ -479,28 +546,30 @@ public static void ExecuteInstruction(ExecContext context, LabelIdx labelIndex) { //TODO Move the elements in OpStack's registers array. context.OpStack.PopResults(label.Arity, ref _asideVals); - //6. context.ResetStack(label); - //We did this in part 2 to avoid stack drilling. - // for (uint i = 0, l = labelIndex.Value; i < l; ++i) - // labels.Pop(); - //7. context.OpStack.PushResults(_asideVals); } - - //8. - if (label.Instruction.x00 == OpCode.Loop) - { - //loop targets the loop head - context.RewindSequence(); - } - else + + switch (label.Instruction.x00) { - //let InstEnd handle the continuation address and popping of the label - context.FastForwardSequence(); + //8. + case OpCode.Func: + context.InstructionPointer = label.ContinuationAddress; + break; + case OpCode.Loop: + //loop targets the loop head + // context.InstructionPointer = context.Frame.TopLabel.Head; + context.InstructionPointer = target.Head; + break; + default: + //otherwise, go to the end + // context.InstructionPointer = context.Frame.TopLabel.End - 1; + context.InstructionPointer = target.End - 1; + break; } } + /// /// @Spec 5.4.1 Control Instructions /// @@ -510,19 +579,22 @@ public override InstructionBase Parse(BinaryReader reader) return this; } - public override string RenderText(ExecContext? context) - { - if (context == null) return $"{base.RenderText(context)} {L.Value}"; - int depth = context.Frame.LabelCount - 1; - return $"{base.RenderText(context)} {L.Value} (;@{depth - L.Value};)"; - } + // public override string RenderText(ExecContext? context) + // { + // if (context == null) return $"{base.RenderText(context)} {L.Value}"; + // int depth = context.Frame.TopLabel.LabelHeight - 1; + // return $"{base.RenderText(context)} {L.Value} (;@{depth - L.Value};)"; + // } } //0x0D - public sealed class InstBranchIf : InstructionBase, IBranchInstruction, INodeConsumer + public sealed class InstBranchIf : InstructionBase, IBranchInstruction, IComplexLinkBehavior, INodeConsumer { public LabelIdx L; + private BlockTarget? LinkedLabel; + public override ByteCode Op => OpCode.BrIf; + public override int StackDiff => -1; public Action GetFunc => BranchIf; @@ -533,14 +605,20 @@ public override void Validate(IWasmValidationContext context) "Instruction br_if invalid. Could not branch to label {0}",L); //Pop the predicate - context.OpStack.PopI32(); + context.OpStack.PopI32(); // -1 var nthFrame = context.ControlStack.PeekAt((int)L.Value); //Pop values like we branch - context.OpStack.DiscardValues(nthFrame.LabelTypes); + context.OpStack.DiscardValues(nthFrame.LabelTypes); // -(N+1) //But actually, we don't, so push them back on. - context.OpStack.PushResult(nthFrame.LabelTypes); + context.OpStack.PushResult(nthFrame.LabelTypes); // -1 + } + + public override InstructionBase Link(ExecContext context, int pointer) + { + LinkedLabel = InstBranch.PrecomputeStack(context, L); + return base.Link(context, pointer); } // @Spec 4.4.8.7. br_if @@ -554,7 +632,7 @@ private void BranchIf(ExecContext context, int c) { if (c != 0) { - InstBranch.ExecuteInstruction(context, L); + InstBranch.ExecuteInstruction(context, LinkedLabel); } } @@ -567,26 +645,29 @@ public override InstructionBase Parse(BinaryReader reader) return this; } - public override string RenderText(ExecContext? context) - { - if (context == null) return $"{base.RenderText(context)} {L.Value}"; - - int depth = context.Frame.LabelCount - 1; - string taken = ""; - if (context.Attributes.Live) - { - taken = context.OpStack.Peek().Data.Int32 != 0 ? "-> " : "X: "; - } - return $"{base.RenderText(context)} {L.Value} (;{taken}@{depth - L.Value};)"; - } + // public override string RenderText(ExecContext? context) + // { + // if (context == null) return $"{base.RenderText(context)} {L.Value}"; + // + // int depth = context.Frame.TopLabel.LabelHeight - 1; + // string taken = ""; + // if (context.Attributes.Live) + // { + // taken = context.OpStack.Peek().Data.Int32 != 0 ? "-> " : "X: "; + // } + // return $"{base.RenderText(context)} {L.Value} (;{taken}@{depth - L.Value};)"; + // } } //0x0E - public sealed class InstBranchTable : InstructionBase, IBranchInstruction, INodeConsumer + public sealed class InstBranchTable : InstructionBase, IBranchInstruction, IComplexLinkBehavior, INodeConsumer { + private BlockTarget? LinkedLabeln; + private BlockTarget?[] LinkedLabels; private LabelIdx Ln; //Default m private LabelIdx[] Ls = null!; + public override ByteCode Op => OpCode.BrTable; public Action GetFunc => BranchTable; @@ -620,6 +701,18 @@ public override void Validate(IWasmValidationContext context) context.SetUnreachable(); } + public override InstructionBase Link(ExecContext context, int pointer) + { + LinkedLabeln = InstBranch.PrecomputeStack(context, Ln); + int stack = context.LinkOpStackHeight; + InstBranch.SetStackHeight(context, LinkedLabeln); + StackDiff = context.LinkOpStackHeight - stack; + + LinkedLabels = Ls.Select(l => InstBranch.PrecomputeStack(context, l)).ToArray(); + context.LinkUnreachable = true; + return this; + } + /// /// @Spec 4.4.8.8. br_table /// @@ -637,13 +730,13 @@ private void BranchTable(ExecContext context, int i) //3. if (i >= 0 && i < Ls.Length) { - var label = Ls[i]; + var label = LinkedLabels[i]; InstBranch.ExecuteInstruction(context, label); } //4. else { - InstBranch.ExecuteInstruction(context, Ln); + InstBranch.ExecuteInstruction(context, LinkedLabeln); } } @@ -660,43 +753,43 @@ public override InstructionBase Parse(BinaryReader reader) return this; } - public override string RenderText(ExecContext? context) - { - if (context==null) - return $"{base.RenderText(context)} {string.Join(" ", Ls.Select(idx => idx.Value).Select(v => $"{v}"))} {Ln.Value}"; - int depth = context.Frame.LabelCount-1; - - int index = -2; - if (context.Attributes.Live) - { - int c = context.OpStack.Peek().Data.Int32; - if (c < Ls.Length) - { - index = c; - } - else - { - index = -1; - } - } - - StringBuilder sb = new(); - int i = 0; - foreach (var idx in Ls) - { - sb.Append(" "); - sb.Append(i == index - ? $"{idx.Value} (;-> @{depth - idx.Value};)" - : $"{idx.Value} (;@{depth - idx.Value};)"); - i += 1; - } - sb.Append(index == -1 - ? $"{(i > 0 ? " " : "")}{Ln.Value} (;-> @{depth - Ln.Value};)" - : $"{(i > 0 ? " " : "")}{Ln.Value} (;@{depth - Ln.Value};)"); - - return - $"{base.RenderText(context)} {sb}"; - } + // public override string RenderText(ExecContext? context) + // { + // if (context==null) + // return $"{base.RenderText(context)} {string.Join(" ", Ls.Select(idx => idx.Value).Select(v => $"{v}"))} {Ln.Value}"; + // int depth = context.Frame.TopLabel.LabelHeight-1; + // + // int index = -2; + // if (context.Attributes.Live) + // { + // int c = context.OpStack.Peek().Data.Int32; + // if (c < Ls.Length) + // { + // index = c; + // } + // else + // { + // index = -1; + // } + // } + // + // StringBuilder sb = new(); + // int i = 0; + // foreach (var idx in Ls) + // { + // sb.Append(" "); + // sb.Append(i == index + // ? $"{idx.Value} (;-> @{depth - idx.Value};)" + // : $"{idx.Value} (;@{depth - idx.Value};)"); + // i += 1; + // } + // sb.Append(index == -1 + // ? $"{(i > 0 ? " " : "")}{Ln.Value} (;-> @{depth - Ln.Value};)" + // : $"{(i > 0 ? " " : "")}{Ln.Value} (;@{depth - Ln.Value};)"); + // + // return + // $"{base.RenderText(context)} {sb}"; + // } } //0x0F @@ -715,6 +808,12 @@ public override void Validate(IWasmValidationContext context) context.SetUnreachable(); } + public override InstructionBase Link(ExecContext context, InstructionPointer pointer) + { + context.LinkUnreachable = true; + return this; + } + // @Spec 4.4.8.9. return public override void Execute(ExecContext context) { @@ -724,14 +823,16 @@ public override void Execute(ExecContext context) int resultsHeight = context.Frame.StackHeight + resultCount; if (resultsHeight < context.OpStack.Count) context.OpStack.ShiftResults(resultCount, resultsHeight); - var address = context.PopFrame(); - context.ResumeSequence(address); + // var address = context.PopFrame(); + // context.ResumeSequence(address); + context.FunctionReturn(); } } //0x10 public sealed class InstCall : InstructionBase, ICallInstruction { + private FuncAddr linkedX; public FuncIdx X; public InstCall() @@ -766,21 +867,46 @@ public override void Validate(IWasmValidationContext context) context.OpStack.PushResult(funcType.ResultType); } + public override InstructionBase Link(ExecContext context, InstructionPointer pointer) + { + context.Assert( context.Frame.Module.FuncAddrs.Contains(X), + $"Instruction call failed. Function address for {X} was not in the Context."); + linkedX = context.Frame.Module.FuncAddrs[X]; + var inst = context.Store[linkedX]; + IsAsync = inst switch + { + FunctionInstance => false, + HostFunction hostFunction => hostFunction.IsAsync, + _ => IsAsync + }; + + var funcType = inst.Type; + int stack = context.LinkOpStackHeight; + context.LinkOpStackHeight -= funcType.ParameterTypes.Arity; + context.LinkOpStackHeight += funcType.ResultType.Arity; + //For recordkeeping + StackDiff = context.LinkOpStackHeight - stack; + + return this; + } + // @Spec 4.4.8.10. call public override void Execute(ExecContext context) { context.Assert( context.Frame.Module.FuncAddrs.Contains(X), $"Instruction call failed. Function address for {X} was not in the Context."); - var a = context.Frame.Module.FuncAddrs[X]; - context.Invoke(a); + // var a = context.Frame.Module.FuncAddrs[X]; + // context.Invoke(a); + context.Invoke(linkedX); } public override async ValueTask ExecuteAsync(ExecContext context) { context.Assert( context.Frame.Module.FuncAddrs.Contains(X), $"Instruction call failed. Function address for {X} was not in the Context."); - var a = context.Frame.Module.FuncAddrs[X]; - await context.InvokeAsync(a); + // var a = context.Frame.Module.FuncAddrs[X]; + // await context.InvokeAsync(a); + await context.InvokeAsync(linkedX); } /// @@ -892,6 +1018,29 @@ public override void Validate(IWasmValidationContext context) context.OpStack.PushResult(funcType.ResultType); } + public override InstructionBase Link(ExecContext context, InstructionPointer pointer) + { + context.Assert( context.Frame.Module.TableAddrs.Contains(X), + $"Instruction call_indirect failed. Table {X} was not in the Context."); + var ta = context.Frame.Module.TableAddrs[X]; + context.Assert( context.Store.Contains(ta), + $"Instruction call_indirect failed. TableInstance {ta} was not in the Store."); + var tab = context.Store[ta]; + context.Assert( context.Frame.Module.Types.Contains(Y), + $"Instruction call_indirect failed. Function Type {Y} was not in the Context."); + var ftExpect = context.Frame.Module.Types[Y]; + var funcType = ftExpect.Expansion as FunctionType; + context.Assert(funcType, + $"Instruction {Op.GetMnemonic()} failed. Not a function type."); + + int stack = context.LinkOpStackHeight; + context.LinkOpStackHeight -= funcType.ParameterTypes.Arity; + context.LinkOpStackHeight += funcType.ResultType.Arity; + //For recordkeeping + StackDiff = context.LinkOpStackHeight - stack; + return this; + } + // @Spec 4.4.8.11. call_indirect public override void Execute(ExecContext context) { diff --git a/Wacs.Core/Instructions/Exceptions.cs b/Wacs.Core/Instructions/Exceptions.cs index e2daf9b1..a7d2fb38 100644 --- a/Wacs.Core/Instructions/Exceptions.cs +++ b/Wacs.Core/Instructions/Exceptions.cs @@ -30,17 +30,18 @@ namespace Wacs.Core.Instructions public class InstTryTable : BlockTarget, IBlockInstruction, IExnHandler { private static readonly ByteCode TryTableOp = OpCode.TryTable; + + private static readonly ByteCode CatchOp = WacsCode.Catch; private Block Block; public CatchType[] Catches; - + public BlockTarget?[] CatchTargets; + public override ByteCode Op => TryTableOp; public ValType BlockType => Block.BlockType; public int Count => 1; - public int Size => 1 + Block.Size; + public int BlockSize => 1 + Block.Size; public Block GetBlock(int idx) => Block; - - private static readonly ByteCode CatchOp = WacsCode.Catch; - + public override void Validate(IWasmValidationContext context) { try @@ -101,11 +102,20 @@ public override void Validate(IWasmValidationContext context) } } + public override InstructionBase Link(ExecContext context, int pointer) + { + base.Link(context, pointer); + CatchTargets = Catches.Select(catchType => InstBranch.PrecomputeStack(context, catchType.L + 1)).ToArray(); + + PointerAdvance = 1; + return this; + } + public override void Execute(ExecContext context) { - context.EnterBlock(this, Block); + // context.Frame.PushLabel(this); } - + public override InstructionBase Parse(BinaryReader reader) { var blockType = ValTypeParser.Parse(reader, parseBlockIndex: true, parseStorageType: false); @@ -122,6 +132,7 @@ public class InstThrow : InstructionBase { private TagIdx X; public override ByteCode Op => OpCode.Throw; + public override void Validate(IWasmValidationContext context) { context.Assert(context.Tags.Contains(X), @@ -139,6 +150,24 @@ public override void Validate(IWasmValidationContext context) context.SetUnreachable(); } + public override InstructionBase Link(ExecContext context, int pointer) + { + var ta = context.Frame.Module.TagAddrs[X]; + var ti = context.Store[ta]; + var tagType = ti.Type; + var compType = tagType.Expansion; + var funcType = compType as FunctionType; + + int stack = context.LinkOpStackHeight; + context.LinkOpStackHeight -= funcType!.ParameterTypes.Arity; + context.LinkOpStackHeight += 1; + //For recordkeeping + StackDiff = context.LinkOpStackHeight - stack; + + context.LinkUnreachable = true; + return this; + } + public override void Execute(ExecContext context) { //2. @@ -170,7 +199,7 @@ public override void Execute(ExecContext context) InstThrowRef.ExecuteInstruction(context); } - + public override InstructionBase Parse(BinaryReader reader) { X = (TagIdx)reader.ReadLeb128_u32(); @@ -181,17 +210,26 @@ public override InstructionBase Parse(BinaryReader reader) public class InstThrowRef : InstructionBase { public override ByteCode Op => OpCode.ThrowRef; + public override void Validate(IWasmValidationContext context) { context.OpStack.PopType(ValType.Exn); context.SetUnreachable(); } + public override int StackDiff => -1; + public override InstructionBase Link(ExecContext context, int pointer) + { + base.Link(context, pointer); + context.LinkUnreachable = true; + return this; + } + public override void Execute(ExecContext context) { ExecuteInstruction(context); } - + public static void ExecuteInstruction(ExecContext context) { //1. @@ -212,14 +250,13 @@ public static void ExecuteInstruction(ExecContext context) //Traverse the control stack while (context.StackHeight > 0) { + var blockTarget = context.FindLabel(0); //Enumerate all the blocks to find catch clauses - while (context.Frame.LabelCount > 1) + while ((blockTarget?.LabelHeight??0) > 1) { - var blockTarget = context.Frame.TopLabel; - context.ExitBlock(); if (blockTarget is InstTryTable tryTable) { - foreach (var handler in tryTable.Catches) + foreach (var (handler,idx) in tryTable.Catches.Select((c,i)=>(c,i))) { switch (handler.Mode) { @@ -227,7 +264,7 @@ public static void ExecuteInstruction(ExecContext context) if (a.Equals(context.Frame.Module.TagAddrs[handler.X])) { context.OpStack.PushResults(exn.Fields); - InstBranch.ExecuteInstruction(context, handler.L); + InstBranch.ExecuteInstruction(context, tryTable.CatchTargets[idx]); return; } break; @@ -236,20 +273,21 @@ public static void ExecuteInstruction(ExecContext context) { context.OpStack.PushResults(exn.Fields); context.OpStack.PushValue(exnref); - InstBranch.ExecuteInstruction(context, handler.L); + InstBranch.ExecuteInstruction(context, tryTable.CatchTargets[idx]); return; } break; case CatchFlags.CatchAll: - InstBranch.ExecuteInstruction(context, handler.L); + InstBranch.ExecuteInstruction(context, tryTable.CatchTargets[idx]); return; case CatchFlags.CatchAllRef: context.OpStack.PushValue(exnref); - InstBranch.ExecuteInstruction(context, handler.L); + InstBranch.ExecuteInstruction(context, tryTable.CatchTargets[idx]); return; } } } + blockTarget = blockTarget.EnclosingBlock; } context.FunctionReturn(); } diff --git a/Wacs.Core/Instructions/GC/Array.cs b/Wacs.Core/Instructions/GC/Array.cs index 0d940eb9..d80b71ab 100644 --- a/Wacs.Core/Instructions/GC/Array.cs +++ b/Wacs.Core/Instructions/GC/Array.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Collections.Generic; @@ -32,6 +30,8 @@ public class InstArrayNew : InstructionBase, IConstInstruction { private TypeIdx X; public override ByteCode Op => GcCode.ArrayNew; + public override int StackDiff => -1; + public override void Validate(IWasmValidationContext context) { context.Assert(context.Types.Contains(X), @@ -45,11 +45,11 @@ public override void Validate(IWasmValidationContext context) var t = arrayType.ElementType.UnpackType(); - context.OpStack.PopI32(); - context.OpStack.PopType(t); + context.OpStack.PopI32(); // -1 + context.OpStack.PopType(t); // -2 var resultType = ValType.Ref | (ValType)X; - context.OpStack.PushType(resultType); + context.OpStack.PushType(resultType); // -1 } public override void Execute(ExecContext context) @@ -89,7 +89,7 @@ public override void Execute(ExecContext context) var refArray = new Value(ValType.Ref | (ValType)X, ai); context.OpStack.PushValue(refArray); } - + public override InstructionBase Parse(BinaryReader reader) { X = (TypeIdx)reader.ReadLeb128_u32(); @@ -101,6 +101,7 @@ public class InstArrayNewDefault : InstructionBase, IConstInstruction { private TypeIdx X; public override ByteCode Op => GcCode.ArrayNewDefault; + public override void Validate(IWasmValidationContext context) { context.Assert(context.Types.Contains(X), @@ -117,9 +118,9 @@ public override void Validate(IWasmValidationContext context) context.Assert(ft.StorageType.IsDefaultable(), "Instruction {0} was invalid. FieldType was not defaultable:{1}",Op.GetMnemonic(),ft); - context.OpStack.PopI32(); + context.OpStack.PopI32(); // -1 var resultType = ValType.Ref | (ValType)X; - context.OpStack.PushType(resultType); + context.OpStack.PushType(resultType); // +0 } public override void Execute(ExecContext context) @@ -146,7 +147,7 @@ public override void Execute(ExecContext context) var refArray = new Value(ValType.Ref | (ValType)X, ai); context.OpStack.PushValue(refArray); } - + public override InstructionBase Parse(BinaryReader reader) { X = (TypeIdx)reader.ReadLeb128_u32(); @@ -156,9 +157,11 @@ public override InstructionBase Parse(BinaryReader reader) public class InstArrayNewFixed : InstructionBase, IConstInstruction { - private TypeIdx X; private uint N; + private TypeIdx X; public override ByteCode Op => GcCode.ArrayNewFixed; + public override int StackDiff => -((int)N-1); + public override void Validate(IWasmValidationContext context) { context.Assert(context.Types.Contains(X), @@ -174,11 +177,11 @@ public override void Validate(IWasmValidationContext context) for (int i = 0; i < N; ++i) { - context.OpStack.PopType(t); + context.OpStack.PopType(t); // -N } var resultType = ValType.Ref | (ValType)X; - context.OpStack.PushType(resultType); + context.OpStack.PushType(resultType); // -(N-1) } public override void Execute(ExecContext context) @@ -208,7 +211,7 @@ public override void Execute(ExecContext context) var refArray = new Value(ValType.Ref | (ValType)X, ai); context.OpStack.PushValue(refArray); } - + public override InstructionBase Parse(BinaryReader reader) { X = (TypeIdx)reader.ReadLeb128_u32(); @@ -221,8 +224,10 @@ public class InstArrayNewData : InstructionBase { private TypeIdx X; private DataIdx Y; - + public override ByteCode Op => GcCode.ArrayNewData; + public override int StackDiff => -1; + public override void Validate(IWasmValidationContext context) { context.Assert(context.Types.Contains(X), @@ -245,11 +250,11 @@ public override void Validate(IWasmValidationContext context) context.Assert(context.Datas.Contains(Y), "Instruction {0} was invalid. Data {1} was not in the Context.",Op.GetMnemonic(), Y); - context.OpStack.PopI32(); - context.OpStack.PopI32(); + context.OpStack.PopI32(); // -1 + context.OpStack.PopI32(); // -2 var resultType = ValType.Ref | (ValType)X; - context.OpStack.PushType(resultType); + context.OpStack.PushType(resultType); // -1 } public override void Execute(ExecContext context) @@ -331,8 +336,10 @@ public class InstArrayNewElem : InstructionBase { private TypeIdx X; private ElemIdx Y; - + public override ByteCode Op => GcCode.ArrayNewElem; + public override int StackDiff => -1; + public override void Validate(IWasmValidationContext context) { context.Assert(context.Types.Contains(X), @@ -356,11 +363,11 @@ public override void Validate(IWasmValidationContext context) context.Assert(rtp.Matches(rt, context.Types), "Instruction {0} was invalid. ElementType {1} does not match FieldType {2}",Op.GetMnemonic(), rtp, rt); - context.OpStack.PopI32(); - context.OpStack.PopI32(); + context.OpStack.PopI32(); // -1 + context.OpStack.PopI32(); // -2 var resultType = ValType.Ref | (ValType)X; - context.OpStack.PushType(resultType); + context.OpStack.PushType(resultType); // -1 } public override void Execute(ExecContext context) @@ -414,9 +421,14 @@ public override InstructionBase Parse(BinaryReader reader) public class InstArrayGet : InstructionBase { - private PackedExt Sx; + private readonly PackedExt Sx; private TypeIdx X; + public InstArrayGet(PackedExt sx) + { + Sx = sx; + } + public override ByteCode Op => Sx switch { PackedExt.Signed => GcCode.ArrayGetS, @@ -425,11 +437,8 @@ public class InstArrayGet : InstructionBase _ => throw new InvalidDataException($"Undefined packedtype: {Sx}") }; - public InstArrayGet(PackedExt sx) - { - Sx = sx; - } - + public override int StackDiff => -1; + /// /// https://webassembly.github.io/gc/core/bikeshed/index.html#-hrefsyntax-instr-structmathsfstructgetmathsf_hrefsyntax-sxmathitsxxy /// @@ -451,10 +460,10 @@ public override void Validate(IWasmValidationContext context) context.Assert(fieldType.ValidExtension(Sx), "Instruction {0} was invalid. Bad packing extension:{1}",Op.GetMnemonic(), Sx); - context.OpStack.PopI32(); + context.OpStack.PopI32(); // -1 var refType = ValType.NullableRef | (ValType)X; - context.OpStack.PopType(refType); - context.OpStack.PushType(t); + context.OpStack.PopType(refType); // -2 + context.OpStack.PushType(t); // -1 } public override void Execute(ExecContext context) @@ -513,7 +522,7 @@ public override void Execute(ExecContext context) //17 context.OpStack.PushValue(fieldVal); } - + public override InstructionBase Parse(BinaryReader reader) { X = (TypeIdx)reader.ReadLeb128_u32(); @@ -524,8 +533,10 @@ public override InstructionBase Parse(BinaryReader reader) public class InstArraySet : InstructionBase { private TypeIdx X; - + public override ByteCode Op => GcCode.ArraySet; + public override int StackDiff => -3; + public override void Validate(IWasmValidationContext context) { context.Assert(context.Types.Contains(X), @@ -544,9 +555,9 @@ public override void Validate(IWasmValidationContext context) var t = fieldType.UnpackType(); var refType = ValType.NullableRef | (ValType)X; - context.OpStack.PopType(t); - context.OpStack.PopI32(); - context.OpStack.PopType(refType); + context.OpStack.PopType(t); // -1 + context.OpStack.PopI32(); // -2 + context.OpStack.PopType(refType); // -3 } public override void Execute(ExecContext context) @@ -596,7 +607,7 @@ public override void Execute(ExecContext context) //18 a[i] = val; } - + public override InstructionBase Parse(BinaryReader reader) { X = (TypeIdx)reader.ReadLeb128_u32(); @@ -607,12 +618,13 @@ public override InstructionBase Parse(BinaryReader reader) public class InstArrayLen : InstructionBase { public override ByteCode Op => GcCode.ArrayLen; + public override void Validate(IWasmValidationContext context) { - var rt = context.OpStack.PopRefType(); + var rt = context.OpStack.PopRefType(); // -1 context.Assert(rt.Type.Matches(ValType.Array, context.Types), "Instruction {0} was invalid. Wrong operand type at top of stack:{1}", Op.GetMnemonic(), rt.Type); - context.OpStack.PushI32(); + context.OpStack.PushI32(); // +0 } public override void Execute(ExecContext context) @@ -643,6 +655,8 @@ public class InstArrayFill : InstructionBase { private TypeIdx X; public override ByteCode Op => GcCode.ArrayFill; + public override int StackDiff => -4; + public override void Validate(IWasmValidationContext context) { context.Assert(context.Types.Contains(X), @@ -661,10 +675,10 @@ public override void Validate(IWasmValidationContext context) var t = fieldType.UnpackType(); var refType = ValType.NullableRef | (ValType)X; - context.OpStack.PopI32(); - context.OpStack.PopType(t); - context.OpStack.PopI32(); - context.OpStack.PopType(refType); + context.OpStack.PopI32(); // -1 + context.OpStack.PopType(t); // -2 + context.OpStack.PopI32(); // -3 + context.OpStack.PopType(refType); // -4 } @@ -723,6 +737,8 @@ public class InstArrayCopy : InstructionBase private TypeIdx X; //dest private TypeIdx Y; //src public override ByteCode Op => GcCode.ArrayCopy; + public override int StackDiff => -5; + public override void Validate(IWasmValidationContext context) { context.Assert(context.Types.Contains(X), @@ -754,11 +770,11 @@ public override void Validate(IWasmValidationContext context) var refTypeX = ValType.NullableRef | (ValType)X; var refTypeY = ValType.NullableRef | (ValType)Y; - context.OpStack.PopI32(); - context.OpStack.PopI32(); - context.OpStack.PopType(refTypeY); - context.OpStack.PopI32(); - context.OpStack.PopType(refTypeX); + context.OpStack.PopI32(); // -1 + context.OpStack.PopI32(); // -2 + context.OpStack.PopType(refTypeY); // -3 + context.OpStack.PopI32(); // -4 + context.OpStack.PopType(refTypeX); // -5 } public override void Execute(ExecContext context) @@ -848,8 +864,10 @@ public class InstArrayInitData : InstructionBase { private TypeIdx X; private DataIdx Y; - + public override ByteCode Op => GcCode.ArrayInitData; + public override int StackDiff => -4; + /// /// https://webassembly.github.io/gc/core/bikeshed/index.html#-hrefsyntax-instr-arraymathsfarrayinit_dataxy /// @@ -876,11 +894,11 @@ public override void Validate(IWasmValidationContext context) context.Assert(context.Datas.Contains(Y), "Instruction {0} was invalid. Data {1} was not in the Context.",Op.GetMnemonic(), Y); - context.OpStack.PopI32(); - context.OpStack.PopI32(); - context.OpStack.PopI32(); + context.OpStack.PopI32(); // -1 + context.OpStack.PopI32(); // -2 + context.OpStack.PopI32(); // -3 var resultType = ValType.NullableRef | (ValType)X; - context.OpStack.PopType(resultType); + context.OpStack.PopType(resultType); // -4 } /// @@ -977,8 +995,10 @@ public class InstArrayInitElem : InstructionBase { private TypeIdx X; private ElemIdx Y; - + public override ByteCode Op => GcCode.ArrayInitElem; + public override int StackDiff => -4; + /// /// https://webassembly.github.io/gc/core/bikeshed/index.html#-hrefsyntax-instr-arraymathsfarrayinit_elemxy /// @@ -1010,12 +1030,12 @@ public override void Validate(IWasmValidationContext context) context.Assert(rtp.Matches(rt, context.Types), "Instruction {0} was invalid. ElementType {1} does not match FieldType {2}",Op.GetMnemonic(), rtp, rt); - context.OpStack.PopI32(); - context.OpStack.PopI32(); - context.OpStack.PopI32(); + context.OpStack.PopI32(); // -1 + context.OpStack.PopI32(); // -2 + context.OpStack.PopI32(); // -3 var resultType = ValType.NullableRef | (ValType)X; - context.OpStack.PopType(resultType); + context.OpStack.PopType(resultType); // -4 } /// diff --git a/Wacs.Core/Instructions/GC/Control.cs b/Wacs.Core/Instructions/GC/Control.cs index e86ca075..280a0665 100644 --- a/Wacs.Core/Instructions/GC/Control.cs +++ b/Wacs.Core/Instructions/GC/Control.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System.IO; using Wacs.Core.OpCodes; @@ -28,10 +26,13 @@ public class InstBrOnCast : InstructionBase { public CastFlags Flags; public LabelIdx L; + private BlockTarget? LinkedLabel; + private ValType Rt1; private ValType Rt2; - + public override ByteCode Op => GcCode.BrOnCast; + public override void Validate(IWasmValidationContext context) { context.Assert(context.ContainsLabel(L.Value), @@ -50,18 +51,24 @@ public override void Validate(IWasmValidationContext context) "Instruction {0} invalid. Cast type {1} did not match {2}.",Op.GetMnemonic(), Rt2, Rt1); context.Assert(Rt2.Matches(rtp, context.Types), "Instruction {0} invalid. Cast type {1} did not match {2}.",Op.GetMnemonic(), Rt2, rtp); - context.OpStack.PopType(Rt1); - context.OpStack.PushType(Rt2); + context.OpStack.PopType(Rt1); // -1 + context.OpStack.PushType(Rt2); // +0 //Pop values like we branch - context.OpStack.DiscardValues(nthFrame.LabelTypes); + context.OpStack.DiscardValues(nthFrame.LabelTypes); // -N //But actually, we don't, so push them back on. - context.OpStack.PushResult(nthFrame.LabelTypes); + context.OpStack.PushResult(nthFrame.LabelTypes); // +0 - var rt2 = context.OpStack.PopAny(); + var rt2 = context.OpStack.PopAny(); // -1 var diffType = rt2.Type.AsDiff(Rt1, context.Types); - context.OpStack.PushType(diffType); + context.OpStack.PushType(diffType); // +0 + } + + public override InstructionBase Link(ExecContext context, int pointer) + { + LinkedLabel = InstBranch.PrecomputeStack(context, L); + return base.Link(context, pointer); } public override void Execute(ExecContext context) @@ -73,7 +80,7 @@ public override void Execute(ExecContext context) context.OpStack.PushRef(refVal); if (Rt2.Matches(refVal, context.Frame.Module.Types)) - InstBranch.ExecuteInstruction(context, L); + InstBranch.ExecuteInstruction(context, LinkedLabel); } public override InstructionBase Parse(BinaryReader reader) @@ -90,10 +97,13 @@ public class InstBrOnCastFail : InstructionBase { public CastFlags Flags; public LabelIdx L; + private BlockTarget? LinkedLabel; + private ValType Rt1; private ValType Rt2; - + public override ByteCode Op => GcCode.BrOnCastFail; + public override void Validate(IWasmValidationContext context) { context.Assert(context.ContainsLabel(L.Value), @@ -112,18 +122,24 @@ public override void Validate(IWasmValidationContext context) "Instruction {0} invalid. Cast type {1} did not match {2}.",Op.GetMnemonic(), Rt2, Rt1); context.Assert(Rt2.Matches(rtp, context.Types), "Instruction {0} invalid. Cast type {1} did not match {2}.",Op.GetMnemonic(), Rt2, rtp); - context.OpStack.PopType(Rt1); + context.OpStack.PopType(Rt1); // -1 var diffType = Rt2.AsDiff(Rt1, context.Types); - context.OpStack.PushType(diffType); + context.OpStack.PushType(diffType); // +0 //Pop values like we branch - context.OpStack.DiscardValues(nthFrame.LabelTypes); + context.OpStack.DiscardValues(nthFrame.LabelTypes); // -N //But actually, we don't, so push them back on. - context.OpStack.PushResult(nthFrame.LabelTypes); + context.OpStack.PushResult(nthFrame.LabelTypes); // +0 - context.OpStack.PopAny(); - context.OpStack.PushType(Rt2); + context.OpStack.PopAny(); // -1 + context.OpStack.PushType(Rt2); // +0 + } + + public override InstructionBase Link(ExecContext context, int pointer) + { + LinkedLabel = InstBranch.PrecomputeStack(context, L); + return base.Link(context, pointer); } public override void Execute(ExecContext context) @@ -133,7 +149,7 @@ public override void Execute(ExecContext context) var refVal = context.OpStack.PopRefType(); context.OpStack.PushRef(refVal); if (!Rt2.Matches(refVal, context.Frame.Module.Types)) - InstBranch.ExecuteInstruction(context, L); + InstBranch.ExecuteInstruction(context, LinkedLabel); } public override InstructionBase Parse(BinaryReader reader) diff --git a/Wacs.Core/Instructions/GC/ConvertExtern.cs b/Wacs.Core/Instructions/GC/ConvertExtern.cs index dc385f0c..65cad262 100644 --- a/Wacs.Core/Instructions/GC/ConvertExtern.cs +++ b/Wacs.Core/Instructions/GC/ConvertExtern.cs @@ -1,20 +1,17 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. -using FluentValidation; using Wacs.Core.OpCodes; using Wacs.Core.Runtime; using Wacs.Core.Runtime.GC; @@ -26,6 +23,7 @@ namespace Wacs.Core.Instructions.GC public class InstAnyConvertExtern : InstructionBase, IConstInstruction { public override ByteCode Op => GcCode.AnyConvertExtern; + /// /// https://webassembly.github.io/gc/core/bikeshed/index.html#-hrefsyntax-instr-externmathsfanyconvert_extern /// @@ -65,6 +63,7 @@ public override void Execute(ExecContext context) public class InstExternConvertAny : InstructionBase, IConstInstruction { public override ByteCode Op => GcCode.AnyConvertExtern; + /// /// https://webassembly.github.io/gc/core/bikeshed/index.html#-hrefsyntax-instr-externmathsfexternconvert_any /// diff --git a/Wacs.Core/Instructions/GC/I31.cs b/Wacs.Core/Instructions/GC/I31.cs index 5ff6ce70..24ee0d9d 100644 --- a/Wacs.Core/Instructions/GC/I31.cs +++ b/Wacs.Core/Instructions/GC/I31.cs @@ -1,20 +1,17 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. -using System.Transactions; using Wacs.Core.OpCodes; using Wacs.Core.Runtime; using Wacs.Core.Runtime.GC; @@ -26,22 +23,21 @@ namespace Wacs.Core.Instructions.GC { public class InstRefI31 : InstructionBase, IConstInstruction { + private const int SignBit31 = 0x4000_0000; + private const int UnsignedMask = 0x3FFF_FFFF; + private const ulong SignExtendBits = 0xFFFF_FFFF_C000_0000; public override ByteCode Op => GcCode.RefI31; - + /// /// https://webassembly.github.io/gc/core/bikeshed/index.html#-hrefsyntax-instr-i31mathsfrefi31 /// /// public override void Validate(IWasmValidationContext context) { - context.OpStack.PopI32(); - context.OpStack.PushType(ValType.I31NN); + context.OpStack.PopI32(); // -1 + context.OpStack.PushType(ValType.I31NN); // +0 } - - private const int SignBit31 = 0x4000_0000; - private const int UnsignedMask = 0x3FFF_FFFF; - private const ulong SignExtendBits = 0xFFFF_FFFF_C000_0000; - + /// /// https://webassembly.github.io/gc/core/bikeshed/index.html#-hrefsyntax-instr-i31mathsfrefi31① /// @@ -70,10 +66,11 @@ public class InstI32GetS : InstructionBase private const int SignBit31 = 0x4000_0000; private const int UnsignedMask = 0x3FFF_FFFF; public override ByteCode Op => GcCode.I31GetS; + public override void Validate(IWasmValidationContext context) { - context.OpStack.PopType(ValType.I31); - context.OpStack.PushI32(); + context.OpStack.PopType(ValType.I31); // -1 + context.OpStack.PushI32(); // +0 } public override void Execute(ExecContext context) @@ -103,10 +100,11 @@ public class InstI32GetU : InstructionBase { private const uint BitMask31 = 0x7FFF_FFFF; public override ByteCode Op => GcCode.I31GetU; + public override void Validate(IWasmValidationContext context) { - context.OpStack.PopType(ValType.I31); - context.OpStack.PushI32(); + context.OpStack.PopType(ValType.I31); // -1 + context.OpStack.PushI32(); // +0 } public override void Execute(ExecContext context) diff --git a/Wacs.Core/Instructions/GC/Reference.cs b/Wacs.Core/Instructions/GC/Reference.cs index caf97e29..00661951 100644 --- a/Wacs.Core/Instructions/GC/Reference.cs +++ b/Wacs.Core/Instructions/GC/Reference.cs @@ -48,8 +48,8 @@ public override void Validate(IWasmValidationContext context) context.Assert(Ht.Matches(rtp, context.Types), "Instruction {0} is invalid. {1} did not match top type {2}", Op.GetMnemonic(), Ht, rtp); - context.OpStack.PopType(rtp); - context.OpStack.PushType(Ht); + context.OpStack.PopType(rtp); // -1 + context.OpStack.PushType(Ht); // +0 } /// @@ -100,8 +100,8 @@ public override void Validate(IWasmValidationContext context) context.Assert(Ht.Matches(rtp, context.Types), "Instruction {0} is invalid. {1} did not match top type {2}", Op.GetMnemonic(), Ht, rtp); - context.OpStack.PopType(rtp); - context.OpStack.PushI32(); + context.OpStack.PopType(rtp); // -1 + context.OpStack.PushI32(); // +0 } /// diff --git a/Wacs.Core/Instructions/GC/Struct.cs b/Wacs.Core/Instructions/GC/Struct.cs index 5caa6ec5..be1bb938 100644 --- a/Wacs.Core/Instructions/GC/Struct.cs +++ b/Wacs.Core/Instructions/GC/Struct.cs @@ -1,20 +1,17 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. -using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -51,11 +48,22 @@ public override void Validate(IWasmValidationContext context) foreach (var ft in structType.FieldTypes.Reverse()) { - context.OpStack.PopType(ft.UnpackType()); + context.OpStack.PopType(ft.UnpackType()); // -N } var resultType = ValType.Ref | (ValType)X; - context.OpStack.PushType(resultType); + context.OpStack.PushType(resultType); // -(N-1) + } + + public override InstructionBase Link(ExecContext context, int pointer) + { + //calculate N + var defType = context.Frame.Module.Types[X]; + var compositeType = defType.Expansion; + var structType = compositeType as StructType; + + context.LinkOpStackHeight -= (structType.FieldTypes.Length-1); + return this; } public override void Execute(ExecContext context) @@ -101,6 +109,7 @@ public class InstStructNewDefault : InstructionBase, IConstInstruction { private TypeIdx X; public override ByteCode Op => GcCode.StructNewDefault; + public override int StackDiff => +1; /// /// https://webassembly.github.io/gc/core/bikeshed/index.html#-hrefsyntax-instr-structmathsfstructnewx @@ -123,7 +132,7 @@ public override void Validate(IWasmValidationContext context) "Instruction {0} was invalid. FieldType was not defaultable:{1}",Op.GetMnemonic(),ft); } var resultType = ValType.Ref | (ValType)X; - context.OpStack.PushType(resultType); + context.OpStack.PushType(resultType); // +1 } public override void Execute(ExecContext context) @@ -160,10 +169,15 @@ public override InstructionBase Parse(BinaryReader reader) public class InstStructGet : InstructionBase { - private PackedExt Sx; + private readonly PackedExt Sx; private TypeIdx X; private FieldIdx Y; + public InstStructGet(PackedExt sx) + { + Sx = sx; + } + public override ByteCode Op => Sx switch { PackedExt.Signed => GcCode.StructGetS, @@ -172,11 +186,6 @@ public class InstStructGet : InstructionBase _ => throw new InvalidDataException($"Undefined packedtype: {Sx}") }; - public InstStructGet(PackedExt sx) - { - Sx = sx; - } - /// /// https://webassembly.github.io/gc/core/bikeshed/index.html#-hrefsyntax-instr-structmathsfstructgetmathsf_hrefsyntax-sxmathitsxxy /// @@ -201,8 +210,8 @@ public override void Validate(IWasmValidationContext context) "Instruction {0} was invalid. Bad packing extension:{1}",Op.GetMnemonic(), Sx); var refType = ValType.NullableRef | (ValType)X; - context.OpStack.PopType(refType); - context.OpStack.PushType(t); + context.OpStack.PopType(refType); // -1 + context.OpStack.PushType(t); // +0 } public override void Execute(ExecContext context) @@ -256,7 +265,7 @@ public override void Execute(ExecContext context) //15 context.OpStack.PushValue(fieldVal); } - + public override InstructionBase Parse(BinaryReader reader) { X = (TypeIdx)reader.ReadLeb128_u32(); @@ -269,8 +278,10 @@ public class InstStructSet : InstructionBase { private TypeIdx X; private FieldIdx Y; - + public override ByteCode Op => GcCode.StructSet; + public override int StackDiff => -2; + public override void Validate(IWasmValidationContext context) { context.Assert(context.Types.Contains(X), @@ -291,8 +302,8 @@ public override void Validate(IWasmValidationContext context) var t = fieldtype.UnpackType(); var refType = ValType.NullableRef | (ValType)X; - context.OpStack.PopType(t); - context.OpStack.PopType(refType); + context.OpStack.PopType(t); // -1 + context.OpStack.PopType(refType); // -2 } public override void Execute(ExecContext context) @@ -337,7 +348,7 @@ public override void Execute(ExecContext context) //16 refStruct[Y] = val; } - + public override InstructionBase Parse(BinaryReader reader) { X = (TypeIdx)reader.ReadLeb128_u32(); diff --git a/Wacs.Core/Instructions/GlobalVariable.cs b/Wacs.Core/Instructions/GlobalVariable.cs index 2dd88861..a87d66a8 100644 --- a/Wacs.Core/Instructions/GlobalVariable.cs +++ b/Wacs.Core/Instructions/GlobalVariable.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.IO; @@ -30,6 +28,7 @@ public class InstGlobalGet : InstructionBase, IContextConstInstruction, IVarInst { private GlobalIdx Index; public override ByteCode Op => OpCode.GlobalGet; + public override int StackDiff => +1; public bool IsConstant(IWasmValidationContext? context) { @@ -93,7 +92,7 @@ public override void Validate(IWasmValidationContext context) context.Assert(context.Globals.Contains(Index), "Instruction global.get was invalid. Context Globals did not contain {0}",Index); var globalType = context.Globals[Index].Type; - context.OpStack.PushType(globalType.ContentType); + context.OpStack.PushType(globalType.ContentType); // +1 } // @Spec 4.4.5.4. global.get @@ -127,6 +126,7 @@ public class InstGlobalSet : InstructionBase, IContextConstInstruction, IVarInst private GlobalIdx Index; public override ByteCode Op => OpCode.GlobalSet; + public override int StackDiff => -1; public bool IsConstant(IWasmValidationContext? context) => context == null || context.Globals.Contains(Index) && context.Globals[Index].IsImport && context.Globals[Index].Type.Mutability == Mutability.Immutable; @@ -165,8 +165,7 @@ public override void Validate(IWasmValidationContext context) var mut = global.Type.Mutability; context.Assert(mut == Mutability.Mutable, "Instruction global.set was invalid. Trying to set immutable global {0}",Index); - context.OpStack.PopType(global.Type.ContentType); - + context.OpStack.PopType(global.Type.ContentType); // -1 } // @Spec 4.4.5.5. global.set diff --git a/Wacs.Core/Instructions/Humanize.cs b/Wacs.Core/Instructions/Humanize.cs index 322ad235..a5b6fdca 100644 --- a/Wacs.Core/Instructions/Humanize.cs +++ b/Wacs.Core/Instructions/Humanize.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; diff --git a/Wacs.Core/Instructions/IBlockInstruction.cs b/Wacs.Core/Instructions/IBlockInstruction.cs index a07eaa06..9180d608 100644 --- a/Wacs.Core/Instructions/IBlockInstruction.cs +++ b/Wacs.Core/Instructions/IBlockInstruction.cs @@ -1,22 +1,24 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +using System; +using System.IO; using Wacs.Core.Runtime; +using Wacs.Core.Runtime.Exceptions; using Wacs.Core.Types; using Wacs.Core.Types.Defs; +using InstructionPointer = System.Int32; namespace Wacs.Core.Instructions { @@ -25,7 +27,7 @@ namespace Wacs.Core.Instructions /// public interface IBlockInstruction { - public int Size { get; } + public int BlockSize { get; } public ValType BlockType { get; } @@ -33,11 +35,63 @@ public interface IBlockInstruction public Block GetBlock(int idx); } - + + public interface IIfInstruction {} public abstract class BlockTarget : InstructionBase { + public InstructionPointer Else = -1; public BlockTarget EnclosingBlock; + public InstructionPointer End; + public InstructionPointer Head; public Label Label; + public int LabelHeight; + + //Elses + public BlockTarget? Suboridinate; + + public override InstructionBase Link(ExecContext context, InstructionPointer pointer) + { + base.Link(context, pointer); + + Head = pointer; + EnclosingBlock = context.PeekLabel(); + + var blockInst = this as IBlockInstruction; + var block = blockInst!.GetBlock(0); + + if (!context.LinkUnreachable && context.LinkOpStackHeight < 0) + throw new WasmRuntimeException($"bad stack calculation:{context.LinkOpStackHeight} at {this}[0x{pointer:x8}]"); + + var label = new Label + { + ContinuationAddress = pointer, + Instruction = Op, + StackHeight = context.LinkOpStackHeight + }; + + try + { + var funcType = context.Frame.Module.Types.ResolveBlockType(block.BlockType); + if (funcType == null) + throw new IndexOutOfRangeException($"Could not resolve type for block instruction {this}"); + + label.Arity = this is InstLoop ? funcType.ParameterTypes.Arity : funcType.ResultType.Arity; + label.Parameters = funcType.ParameterTypes.Arity; + label.Results = funcType.ResultType.Arity; + } + catch (IndexOutOfRangeException) + { + throw new InvalidDataException($"Failure computing Labels. BlockType:{block.BlockType} did not exist in the Module"); + } + + Label = label; + + //Push this onto a stack in the context so we can address the End instructions + context.PushLabel(this); + LabelHeight = context.LabelHeight; + + return this; + } } } \ No newline at end of file diff --git a/Wacs.Core/Instructions/IBranchInstruction.cs b/Wacs.Core/Instructions/IBranchInstruction.cs index 4525e119..3dc8088b 100644 --- a/Wacs.Core/Instructions/IBranchInstruction.cs +++ b/Wacs.Core/Instructions/IBranchInstruction.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. namespace Wacs.Core.Instructions { diff --git a/Wacs.Core/Instructions/ICallInstruction.cs b/Wacs.Core/Instructions/ICallInstruction.cs index 29a1db5c..65ae23ca 100644 --- a/Wacs.Core/Instructions/ICallInstruction.cs +++ b/Wacs.Core/Instructions/ICallInstruction.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using Wacs.Core.Runtime; diff --git a/Wacs.Core/Instructions/IComplexLinkBehavior.cs b/Wacs.Core/Instructions/IComplexLinkBehavior.cs new file mode 100644 index 00000000..050df650 --- /dev/null +++ b/Wacs.Core/Instructions/IComplexLinkBehavior.cs @@ -0,0 +1,21 @@ +// Copyright 2025 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Wacs.Core.Instructions +{ + //Indicate that the instruction must get linked as an aggregated element + public interface IComplexLinkBehavior + { + } +} \ No newline at end of file diff --git a/Wacs.Core/Instructions/IConstInstruction.cs b/Wacs.Core/Instructions/IConstInstruction.cs index 5aa1113e..05ae6970 100644 --- a/Wacs.Core/Instructions/IConstInstruction.cs +++ b/Wacs.Core/Instructions/IConstInstruction.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using Wacs.Core.Validation; diff --git a/Wacs.Core/Instructions/IExnHandler.cs b/Wacs.Core/Instructions/IExnHandler.cs index 1d3c6547..0aa81728 100644 --- a/Wacs.Core/Instructions/IExnHandler.cs +++ b/Wacs.Core/Instructions/IExnHandler.cs @@ -14,5 +14,5 @@ namespace Wacs.Core.Instructions { - public interface IExnHandler { } + public interface IExnHandler {} } \ No newline at end of file diff --git a/Wacs.Core/Instructions/IInstructionFactory.cs b/Wacs.Core/Instructions/IInstructionFactory.cs index f0ddb4bb..a6be484d 100644 --- a/Wacs.Core/Instructions/IInstructionFactory.cs +++ b/Wacs.Core/Instructions/IInstructionFactory.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using Wacs.Core.OpCodes; diff --git a/Wacs.Core/Instructions/IVarInstruction.cs b/Wacs.Core/Instructions/IVarInstruction.cs index dd68e359..aa1338d1 100644 --- a/Wacs.Core/Instructions/IVarInstruction.cs +++ b/Wacs.Core/Instructions/IVarInstruction.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. namespace Wacs.Core.Instructions { diff --git a/Wacs.Core/Instructions/InstExpressionProxy.cs b/Wacs.Core/Instructions/InstExpressionProxy.cs index 279b6853..4c8000e7 100644 --- a/Wacs.Core/Instructions/InstExpressionProxy.cs +++ b/Wacs.Core/Instructions/InstExpressionProxy.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using Wacs.Core.OpCodes; using Wacs.Core.Runtime; @@ -28,6 +26,8 @@ public InstExpressionProxy(Label label) { EnclosingBlock = this; Label = label; + //Ensure that we jump out of invocations + End = -1; } public override ByteCode Op => _op; diff --git a/Wacs.Core/Instructions/InstructionBase.cs b/Wacs.Core/Instructions/InstructionBase.cs index bf9d5237..f8fe8526 100644 --- a/Wacs.Core/Instructions/InstructionBase.cs +++ b/Wacs.Core/Instructions/InstructionBase.cs @@ -1,20 +1,17 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ - -using System; +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using System.IO; using System.Threading.Tasks; using Wacs.Core.Instructions.Numeric; @@ -22,6 +19,7 @@ using Wacs.Core.Runtime; using Wacs.Core.Runtime.Exceptions; using Wacs.Core.Validation; +using InstructionPointer = System.Int32; namespace Wacs.Core.Instructions { @@ -30,10 +28,13 @@ namespace Wacs.Core.Instructions /// public abstract class InstructionBase { - public readonly Action Executor; public bool IsAsync = false; + public int PointerAdvance = 0; + public int Size = 1; + public virtual int StackDiff { get; set; } + /// /// Gets the opcode associated with the instruction. /// @@ -41,6 +42,12 @@ public abstract class InstructionBase public abstract void Validate(IWasmValidationContext context); + public virtual InstructionBase Link(ExecContext context, InstructionPointer pointer) + { + context.LinkOpStackHeight += StackDiff; + return this; + } + /// /// Synchronously executes the instruction within the given execution context. /// @@ -76,7 +83,7 @@ public virtual async ValueTask ExecuteAsync(ExecContext context) public static bool IsEnd(InstructionBase inst) => inst.Op.x00 == OpCode.End; - public static bool IsElseOrEnd(InstructionBase inst) => inst is InstEnd; + public static bool IsElseOrEnd(InstructionBase inst) => inst is InstEnd or InstElse; public static bool IsBranch(InstructionBase? inst) => inst is IBranchInstruction; diff --git a/Wacs.Core/Instructions/LocalVariable.cs b/Wacs.Core/Instructions/LocalVariable.cs index a0720b5f..3fea676f 100644 --- a/Wacs.Core/Instructions/LocalVariable.cs +++ b/Wacs.Core/Instructions/LocalVariable.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.IO; @@ -30,6 +28,7 @@ public class InstLocalGet : InstructionBase, IVarInstruction, ITypedValueProduce { private LocalIdx Index; public override ByteCode Op => OpCode.LocalGet; + public override int StackDiff => +1; public Func GetFunc => FetchFromLocals; @@ -74,7 +73,7 @@ public override void Validate(IWasmValidationContext context) context.Assert(value.Data.Set, "Instruction local.get was invalid. The non-defaultable local variable at index {0} was unset", Index.Value); - context.OpStack.PushType(value.Type); + context.OpStack.PushType(value.Type); // +1 } public override void Execute(ExecContext context) @@ -98,6 +97,7 @@ public class InstLocalSet : InstructionBase, IVarInstruction, INodeConsumer OpCode.LocalSet; + public override int StackDiff => -1; public Action GetFunc => SetLocal; @@ -130,7 +130,7 @@ public override void Validate(IWasmValidationContext context) "Instruction local.set was invalid. Context Locals did not contain {0}",Index); context.Locals.Data[Index.Value].Data.Set = true; var value = context.Locals.Get(Index); - context.OpStack.PopType(value.Type); + context.OpStack.PopType(value.Type); // -1 } // @Spec 4.4.5.2. local.set @@ -199,10 +199,10 @@ public override void Validate(IWasmValidationContext context) "Instruction local.tee was invalid. Context Locals did not contain {0}",Index); context.Locals.Data[Index.Value].Data.Set = true; var value = context.Locals.Get(Index); - context.OpStack.PopType(value.Type); - context.OpStack.PushType(value.Type); - context.OpStack.PushType(value.Type); - context.OpStack.PopType(value.Type); + context.OpStack.PopType(value.Type); // -1 + context.OpStack.PushType(value.Type); // +0 + context.OpStack.PushType(value.Type); // +1 + context.OpStack.PopType(value.Type); // +0 } // @Spec 4.4.5.3. local.tee diff --git a/Wacs.Core/Instructions/Memory.cs b/Wacs.Core/Instructions/Memory.cs index e4d09377..1bf71dca 100644 --- a/Wacs.Core/Instructions/Memory.cs +++ b/Wacs.Core/Instructions/Memory.cs @@ -1,21 +1,18 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System.IO; -using System.Runtime.InteropServices; using Wacs.Core.OpCodes; using Wacs.Core.Runtime; using Wacs.Core.Types; @@ -54,8 +51,8 @@ public override void Validate(IWasmValidationContext context) context.Assert(M.Align.LinearSize() <= WidthTByteSize, "Instruction {0} failed with invalid alignment {1} <= {2}/8",Op.GetMnemonic(),M.Align.LinearSize(),WidthT); - context.OpStack.PopInt(); - context.OpStack.PushType(Type); + context.OpStack.PopInt(); // -1 + context.OpStack.PushType(Type); // +0 } public override InstructionBase Parse(BinaryReader reader) @@ -102,6 +99,7 @@ public InstMemoryStore(ValType type, BitWidth widthT, ByteCode opcode) } public override ByteCode Op { get; } + public override int StackDiff => -2; /// /// @Spec 3.3.7.3. t.store @@ -115,8 +113,8 @@ public override void Validate(IWasmValidationContext context) "Instruction {0} failed with invalid alignment {1} <= {2}/8",Op.GetMnemonic(),M.Align.LinearSize(),WidthT); //Pop parameters from right to left - context.OpStack.PopType(Type); - context.OpStack.PopInt(); + context.OpStack.PopType(Type); // -1 + context.OpStack.PopInt(); // -2 } public override InstructionBase Parse(BinaryReader reader) diff --git a/Wacs.Core/Instructions/Memory/FMemoryLoad.cs b/Wacs.Core/Instructions/Memory/FMemoryLoad.cs index 68d9206e..69721282 100644 --- a/Wacs.Core/Instructions/Memory/FMemoryLoad.cs +++ b/Wacs.Core/Instructions/Memory/FMemoryLoad.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Runtime.InteropServices; diff --git a/Wacs.Core/Instructions/Memory/FMemoryStore.cs b/Wacs.Core/Instructions/Memory/FMemoryStore.cs index 2871d100..430bfe7d 100644 --- a/Wacs.Core/Instructions/Memory/FMemoryStore.cs +++ b/Wacs.Core/Instructions/Memory/FMemoryStore.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Runtime.InteropServices; diff --git a/Wacs.Core/Instructions/Memory/I32MemoryLoad.cs b/Wacs.Core/Instructions/Memory/I32MemoryLoad.cs index 4670342d..4dd5797d 100644 --- a/Wacs.Core/Instructions/Memory/I32MemoryLoad.cs +++ b/Wacs.Core/Instructions/Memory/I32MemoryLoad.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Runtime.InteropServices; diff --git a/Wacs.Core/Instructions/Memory/I64MemoryLoad.cs b/Wacs.Core/Instructions/Memory/I64MemoryLoad.cs index 80df3bbb..f64e9251 100644 --- a/Wacs.Core/Instructions/Memory/I64MemoryLoad.cs +++ b/Wacs.Core/Instructions/Memory/I64MemoryLoad.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Runtime.InteropServices; diff --git a/Wacs.Core/Instructions/Memory/InstI32Store.cs b/Wacs.Core/Instructions/Memory/InstI32Store.cs index 50d49380..fab1f87d 100644 --- a/Wacs.Core/Instructions/Memory/InstI32Store.cs +++ b/Wacs.Core/Instructions/Memory/InstI32Store.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Runtime.InteropServices; diff --git a/Wacs.Core/Instructions/Memory/InstI64Store.cs b/Wacs.Core/Instructions/Memory/InstI64Store.cs index fb0384a5..dabac57a 100644 --- a/Wacs.Core/Instructions/Memory/InstI64Store.cs +++ b/Wacs.Core/Instructions/Memory/InstI64Store.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Runtime.InteropServices; diff --git a/Wacs.Core/Instructions/MemoryBulk.cs b/Wacs.Core/Instructions/MemoryBulk.cs index c423669b..367c29f0 100644 --- a/Wacs.Core/Instructions/MemoryBulk.cs +++ b/Wacs.Core/Instructions/MemoryBulk.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System.IO; using Wacs.Core.OpCodes; @@ -31,6 +29,7 @@ public class InstMemorySize : InstructionBase { private MemIdx M; public override ByteCode Op => OpCode.MemorySize; + public override int StackDiff => +1; /// /// @Spec 3.3.7.10. memory.size @@ -41,7 +40,7 @@ public override void Validate(IWasmValidationContext context) "Instruction {0} failed with invalid context memory {1}.",Op.GetMnemonic(),M); var mem = context.Mems[M]; var at = mem.Limits.AddressType; - context.OpStack.PushType(at.ToValType()); + context.OpStack.PushType(at.ToValType()); // +1 } // @Spec 4.4.7.8. memory.size @@ -84,8 +83,8 @@ public override void Validate(IWasmValidationContext context) "Instruction {0} failed with invalid context memory {1}.",Op.GetMnemonic(),M); var mem = context.Mems[M]; var at = mem.Limits.AddressType.ToValType(); - context.OpStack.PopType(at);; - context.OpStack.PushType(at); + context.OpStack.PopType(at); // -1 + context.OpStack.PushType(at); // +0 } // @Spec 4.4.7.9. memory.grow @@ -151,8 +150,11 @@ public class InstMemoryInit : InstructionBase { private DataIdx X; private MemIdx Y; + public override ByteCode Op => ExtCode.MemoryInit; + public override int StackDiff => -3; + /// /// @Spec 3.3.7.14. memory.init /// @@ -167,9 +169,9 @@ public override void Validate(IWasmValidationContext context) var mem = context.Mems[Y]; var at = mem.Limits.AddressType.ToValType(); - context.OpStack.PopI32(); - context.OpStack.PopI32(); - context.OpStack.PopType(at); + context.OpStack.PopI32(); // -1 + context.OpStack.PopI32(); // -2 + context.OpStack.PopType(at); // -3 } // @Spec 4.4.7.12. memory.init x @@ -177,7 +179,6 @@ public override void Execute(ExecContext context) { //2. context.Assert( context.Frame.Module.MemAddrs.Contains(Y), - $"Instruction {Op.GetMnemonic()} failed. Address for Memory {Y} did not exist in the context."); //3. var ma = context.Frame.Module.MemAddrs[Y]; @@ -190,7 +191,6 @@ public override void Execute(ExecContext context) //6. context.Assert( context.Frame.Module.DataAddrs.Contains(X), - $"Instruction {Op.GetMnemonic()} failed. Address for Data {X} did not exist in the context."); //7. var da = context.Frame.Module.DataAddrs[X]; @@ -199,55 +199,41 @@ public override void Execute(ExecContext context) $"Instruction {Op.GetMnemonic()} failed. Address for Data {X} was not in the Store."); //9. var data = context.Store[da]; + + //10. + context.Assert( context.OpStack.Peek().IsI32, + $"Instruction {Op.GetMnemonic()} failed. Wrong type on stack."); + //11. + long n = (uint)context.OpStack.PopI32(); + //12. + context.Assert( context.OpStack.Peek().IsI32, + $"Instruction {Op.GetMnemonic()} failed. Wrong type on stack."); + //13. + long s = (uint)context.OpStack.PopI32(); + //14. + context.Assert( context.OpStack.Peek().IsInt, + $"Instruction {Op.GetMnemonic()} failed. Wrong type on stack."); + //15. + long d = context.OpStack.PopAddr(); - //Tail recursive call alternative loop + if (s + n > data.Data.Length) + throw new TrapException($"Instruction {Op.GetMnemonic()} failed. Data underflow."); + + if (d + n > mem.Data.Length) + throw new TrapException($"Instruction {Op.GetMnemonic()} failed. Memory overflow."); + + //Tail recursive call alternative loop, inline direct memory set while (true) { - //10. - context.Assert( context.OpStack.Peek().IsI32, - $"Instruction {Op.GetMnemonic()} failed. Wrong type on stack."); - //11. - long n = (uint)context.OpStack.PopI32(); - //12. - context.Assert( context.OpStack.Peek().IsI32, - $"Instruction {Op.GetMnemonic()} failed. Wrong type on stack."); - //13. - long s = (uint)context.OpStack.PopI32(); - //14. - context.Assert( context.OpStack.Peek().IsInt, - $"Instruction {Op.GetMnemonic()} failed. Wrong type on stack."); - //15. - long d = context.OpStack.PopAddr(); - //16. - if (s + n > data.Data.Length) - throw new TrapException($"Instruction {Op.GetMnemonic()} failed. Data underflow."); - if (d + n > mem.Data.Length) - throw new TrapException($"Instruction {Op.GetMnemonic()} failed. Memory overflow."); - //17. if (n == 0) return; - //18. - byte b = data.Data[s]; - //19. - context.OpStack.PushValue(new Value(at, d)); - //20. - context.OpStack.PushI32(b); - //21. - context.InstructionFactory.CreateInstruction(OpCode.I32Store8).Immediate(new MemArg(0, 0, Y)) - .Execute(context); - //22. - long check = d + 1L; - context.Assert( check < Constants.TwoTo32, - $"Instruction {Op.GetMnemonic()} failed. Memory overflow."); - //23. - context.OpStack.PushValue(new Value(at, d + 1L)); - //24. - check = s + 1L; - context.Assert( check < Constants.TwoTo32, - $"Instruction {Op.GetMnemonic()} failed. Data overflow."); - //25. - context.OpStack.PushU32((uint)(s + 1L)); - context.OpStack.PushU32((uint)(n - 1L)); + + //Set memory direct + mem.Data[(int)d] = (byte)(0xFF & data.Data[s]); + + d += 1L; + s += 1L; + n -= 1L; } } @@ -255,7 +241,6 @@ public override InstructionBase Parse(BinaryReader reader) { X = (DataIdx)reader.ReadLeb128_u32(); Y = (MemIdx)reader.ReadByte(); - return this; } @@ -317,137 +302,102 @@ public InstructionBase Immediate(DataIdx x) //0xFC_0A public class InstMemoryCopy : InstructionBase { - private MemIdx SrcY; private MemIdx DstX; + private MemIdx SrcY; public override ByteCode Op => ExtCode.MemoryCopy; + public override int StackDiff => -3; /// /// @Spec 3.3.7.13. memory.copy /// public override void Validate(IWasmValidationContext context) { - context.Assert(context.Mems.Contains(DstX), - "Instruction {0} failed with invalid context memory {1}.",Op.GetMnemonic(),DstX); context.Assert(context.Mems.Contains(SrcY), - "Instruction {0} failed with invalid context memory {1}.",Op.GetMnemonic(), SrcY); + "Instruction {0} failed with invalid context memory {1}.",Op.GetMnemonic(),SrcY); + context.Assert(context.Mems.Contains(DstX), + "Instruction {0} failed with invalid context memory {1}.",Op.GetMnemonic(), DstX); - var memX = context.Mems[DstX]; - var memY = context.Mems[SrcY]; - var atS = memX.Limits.AddressType; - var atD = memY.Limits.AddressType; + var memSrcY = context.Mems[SrcY]; + var memDstX = context.Mems[DstX]; + var atS = memSrcY.Limits.AddressType; + var atD = memDstX.Limits.AddressType; var atN = atS.Min(atD); - context.OpStack.PopType(atN.ToValType()); - context.OpStack.PopType(atD.ToValType()); - context.OpStack.PopType(atS.ToValType()); + context.OpStack.PopType(atN.ToValType()); // -1 + context.OpStack.PopType(atD.ToValType()); // -2 + context.OpStack.PopType(atS.ToValType()); // -3 } // @Spec 4.4.7.11. memory.copy public override void Execute(ExecContext context) { //2. - context.Assert( context.Frame.Module.MemAddrs.Contains(DstX), - - $"Instruction {Op.GetMnemonic()} failed. Address for Memory {DstX} did not exist in the context."); - //3. context.Assert( context.Frame.Module.MemAddrs.Contains(SrcY), $"Instruction {Op.GetMnemonic()} failed. Address for Memory {SrcY} did not exist in the context."); + //3. + context.Assert( context.Frame.Module.MemAddrs.Contains(DstX), + + $"Instruction {Op.GetMnemonic()} failed. Address for Memory {DstX} did not exist in the context."); //4. - var da = context.Frame.Module.MemAddrs[DstX]; - //5. var sa = context.Frame.Module.MemAddrs[SrcY]; + //5. + var da = context.Frame.Module.MemAddrs[DstX]; //6. context.Assert( context.Store.Contains(da), - $"Instruction {Op.GetMnemonic()} failed. Address for Memory {DstX} was not in the Store."); - //7. - context.Assert( context.Store.Contains(sa), $"Instruction {Op.GetMnemonic()} failed. Address for Memory {SrcY} was not in the Store."); + //7. + context.Assert( context.Store.Contains(da), + $"Instruction {Op.GetMnemonic()} failed. Address for Memory {DstX} was not in the Store."); //8. - var memD = context.Store[da]; + var memSrc = context.Store[sa]; //9. - var memS = context.Store[sa]; + var memDst = context.Store[da]; - var atD = memD.Type.Limits.AddressType; - var atS = memS.Type.Limits.AddressType; - var atN = atD.Min(atS); - - //Tail recursive call alternative loop + //10. + context.Assert( context.OpStack.Peek().IsInt, + $"Instruction {Op.GetMnemonic()} failed. Wrong type on stack."); + //11. + long n = context.OpStack.PopAddr(); + //12. + context.Assert( context.OpStack.Peek().IsInt, + $"Instruction {Op.GetMnemonic()} failed. Wrong type on stack."); + //13. + long s = context.OpStack.PopAddr(); + //14. + context.Assert( context.OpStack.Peek().IsInt, + $"Instruction {Op.GetMnemonic()} failed. Wrong type on stack."); + //15. + long d = context.OpStack.PopAddr(); + //16. + if (s+n > memSrc.Data.Length) + throw new TrapException($"Instruction {Op.GetMnemonic()} failed. Source memory overflow."); + if (d+n > memDst.Data.Length) + throw new TrapException($"Instruction {Op.GetMnemonic()} failed. Destination memory overflow."); + + //Tail recursive call alternative loop, inline load/store while (true) { - //10. - context.Assert( context.OpStack.Peek().IsInt, - $"Instruction {Op.GetMnemonic()} failed. Wrong type on stack."); - //11. - long n = context.OpStack.PopAddr(); - //12. - context.Assert( context.OpStack.Peek().IsInt, - $"Instruction {Op.GetMnemonic()} failed. Wrong type on stack."); - //13. - long s = context.OpStack.PopAddr(); - //14. - context.Assert( context.OpStack.Peek().IsInt, - $"Instruction {Op.GetMnemonic()} failed. Wrong type on stack."); - //15. - long d = context.OpStack.PopAddr(); - //16. - long check = s + n; - if (check > memD.Data.Length) - throw new TrapException($"Instruction {Op.GetMnemonic()} failed. Source memory overflow."); - check = d + n; - if (check > memS.Data.Length) - throw new TrapException( - $"Instruction {Op.GetMnemonic()} failed. Destination memory overflow."); - //17. if (n == 0) return; - //18. if (d <= s) { - context.OpStack.PushValue(new Value(atD, d)); - context.OpStack.PushValue(new Value(atS, s)); - context.InstructionFactory.CreateInstruction(OpCode.I32Load8U).Immediate(new MemArg(0, 0, DstX)) - .Execute(context); - context.InstructionFactory.CreateInstruction(OpCode.I32Store8).Immediate(new MemArg(0, 0, SrcY)) - .Execute(context); - check = d + 1L; - context.Assert( check < Constants.TwoTo32, - $"Instruction {Op.GetMnemonic()} failed. Destination memory overflow."); - context.OpStack.PushValue(new Value(atD, d + 1L)); - check = s + 1L; - context.Assert( check < Constants.TwoTo32, - $"Instruction {Op.GetMnemonic()} failed. Source memory overflow."); - context.OpStack.PushValue(new Value(atS, s + 1L)); + memDst.Data[(int)d] = memSrc.Data[(int)s]; + d += 1L; + s += 1L; } - //19. else { - check = d + n - 1L; - context.Assert( check < Constants.TwoTo32, - $"Instruction {Op.GetMnemonic()} failed. Destination memory overflow."); - context.OpStack.PushValue(new Value(atD, d + n - 1)); - check = s + n - 1L; - context.Assert( check < Constants.TwoTo32, - $"Instruction {Op.GetMnemonic()} failed. Source memory overflow."); - context.OpStack.PushValue(new Value(atS, s + n - 1)); - context.InstructionFactory.CreateInstruction(OpCode.I32Load8U).Immediate(new MemArg(0, 0, DstX)) - .Execute(context); - context.InstructionFactory.CreateInstruction(OpCode.I32Store8).Immediate(new MemArg(0, 0, SrcY)) - .Execute(context); - context.OpStack.PushValue(new Value(atD, d)); - context.OpStack.PushValue(new Value(atS, s)); + memDst.Data[(int)(d+n-1L)] = memSrc.Data[(int)(s+n-1L)]; } - - //20. - context.OpStack.PushValue(new Value(atN, n - 1)); - //21. + n -= 1L; } } public override InstructionBase Parse(BinaryReader reader) { - SrcY = (MemIdx)reader.ReadByte(); DstX = (MemIdx)reader.ReadByte(); + SrcY = (MemIdx)reader.ReadByte(); return this; } } @@ -458,6 +408,8 @@ public class InstMemoryFill : InstructionBase private MemIdx X; public override ByteCode Op => ExtCode.MemoryFill; + public override int StackDiff => -3; + /// /// @Spec 3.3.7.12. memory.fill /// @@ -468,9 +420,9 @@ public override void Validate(IWasmValidationContext context) var mem = context.Mems[X]; var at = mem.Limits.AddressType; - context.OpStack.PopType(at.ToValType()); - context.OpStack.PopI32(); - context.OpStack.PopType(at.ToValType()); + context.OpStack.PopType(at.ToValType()); // -1 + context.OpStack.PopI32(); // -2 + context.OpStack.PopType(at.ToValType()); // -3 } // @Spec 4.4.7.10. memory.fill @@ -489,46 +441,32 @@ public override void Execute(ExecContext context) var mem = context.Store[a]; var at = mem.Type.Limits.AddressType; - //Tail recursive call alternative loop + //6. + context.Assert( context.OpStack.Peek().IsI32, + $"Instruction {Op.GetMnemonic()} failed. Wrong type on stack."); + //7. + long n = (uint)context.OpStack.PopI32(); + //8,9. YOLO + var val = context.OpStack.PopAny(); + uint cU32 = val; + //10. + context.Assert( context.OpStack.Peek().IsInt, + $"Instruction {Op.GetMnemonic()} failed. Wrong type on stack."); + //11. + long d = context.OpStack.PopAddr(); + //12. + if (d + n > mem.Data.Length) + throw new TrapException("Instruction memory.fill failed. Buffer overflow"); + + //Tail recursive call alternative loop, inline store while (true) { - //6. - context.Assert( context.OpStack.Peek().IsI32, - $"Instruction {Op.GetMnemonic()} failed. Wrong type on stack."); - //7. - long n = (uint)context.OpStack.PopI32(); - //8,9. YOLO - var val = context.OpStack.PopAny(); - //10. - context.Assert( context.OpStack.Peek().IsInt, - $"Instruction {Op.GetMnemonic()} failed. Wrong type on stack."); - //11. - long d = context.OpStack.PopAddr(); - //12. - if (d + n > mem.Data.Length) - throw new TrapException("Instruction memory.fill failed. Buffer overflow"); - //13. if (n == 0) return; - //14. - context.OpStack.PushValue(new Value(at, d)); - //15. - context.OpStack.PushValue(val); - //16. - context.InstructionFactory.CreateInstruction(OpCode.I32Store8).Immediate(new MemArg(0, 0, X)) - .Execute(context); - //17. - long check = d + 1L; - context.Assert( check < Constants.TwoTo32, - $"Instruction {Op.GetMnemonic()} failed. Buffer overflow"); - //18. - context.OpStack.PushValue(new Value(at, d + 1)); - //19. - context.OpStack.PushValue(val); - //20. - context.OpStack.PushU32((uint)(n - 1)); - //21. + mem.Data[(int)d] = (byte)(0xFF & cU32); + d += 1L; + n -= 1L; } } diff --git a/Wacs.Core/Instructions/Numeric/Const.cs b/Wacs.Core/Instructions/Numeric/Const.cs index 30348001..1e12973f 100644 --- a/Wacs.Core/Instructions/Numeric/Const.cs +++ b/Wacs.Core/Instructions/Numeric/Const.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Globalization; @@ -30,6 +28,7 @@ public sealed class InstI32Const : InstructionBase, IConstInstruction, ITypedVal { public int Value; public override ByteCode Op => OpCode.I32Const; + public override int StackDiff => +1; public Func GetFunc => FetchImmediate; public int CalculateSize() => 1; @@ -68,6 +67,7 @@ public sealed class InstI64Const : InstructionBase, IConstInstruction, ITypedVal { private long Value; public override ByteCode Op => OpCode.I64Const; + public override int StackDiff => +1; public Func GetFunc => FetchImmediate; public int CalculateSize() => 1; @@ -101,6 +101,7 @@ public sealed class InstF32Const : InstructionBase, IConstInstruction, ITypedVal { private float Value; public override ByteCode Op => OpCode.F32Const; + public override int StackDiff => +1; public Func GetFunc => FetchImmediate; public int CalculateSize() => 1; @@ -142,6 +143,7 @@ public sealed class InstF64Const : InstructionBase, IConstInstruction, ITypedVal { private double Value; public override ByteCode Op => OpCode.F64Const; + public override int StackDiff => +1; public Func GetFunc => FetchImmediate; public int CalculateSize() => 1; diff --git a/Wacs.Core/Instructions/Numeric/Conversion.cs b/Wacs.Core/Instructions/Numeric/Conversion.cs index 409e401f..8fae92df 100644 --- a/Wacs.Core/Instructions/Numeric/Conversion.cs +++ b/Wacs.Core/Instructions/Numeric/Conversion.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.IO; @@ -70,7 +68,7 @@ private InstConvert(ByteCode op, Delegate execute, NumericInst.ValidationDelegat public override ByteCode Op { get; } - public override void Validate(IWasmValidationContext context) => _validate(context); + public override void Validate(IWasmValidationContext context) => _validate(context); // +0 public override void Execute(ExecContext context) { diff --git a/Wacs.Core/Instructions/Numeric/F32BinOp.cs b/Wacs.Core/Instructions/Numeric/F32BinOp.cs index 35538808..fb8c50da 100644 --- a/Wacs.Core/Instructions/Numeric/F32BinOp.cs +++ b/Wacs.Core/Instructions/Numeric/F32BinOp.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Runtime.InteropServices; @@ -64,13 +62,14 @@ private InstF32BinOp(ByteCode op, Func execute, NumericInst.V IsConstant = isConst; } - public bool IsConstant { get; } - public override ByteCode Op { get; } + public override int StackDiff => -1; + + public bool IsConstant { get; } public Func GetFunc => (_, i1, i2) => _execute(i1, i2); - public override void Validate(IWasmValidationContext context) => _validate(context); + public override void Validate(IWasmValidationContext context) => _validate(context); //-1 public override void Execute(ExecContext context) { diff --git a/Wacs.Core/Instructions/Numeric/F32RelOp.cs b/Wacs.Core/Instructions/Numeric/F32RelOp.cs index 651c005c..8426ce40 100644 --- a/Wacs.Core/Instructions/Numeric/F32RelOp.cs +++ b/Wacs.Core/Instructions/Numeric/F32RelOp.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using Wacs.Core.Instructions.Transpiler; @@ -55,10 +53,11 @@ private InstF32RelOp(ByteCode op, Func execute, NumericInst.Val } public override ByteCode Op { get; } + public override int StackDiff => -1; public Func GetFunc => (_, i1, i2) => _execute(i1, i2); - public override void Validate(IWasmValidationContext context) => _validate(context); + public override void Validate(IWasmValidationContext context) => _validate(context); // -1 public override void Execute(ExecContext context) { diff --git a/Wacs.Core/Instructions/Numeric/F32UnOp.cs b/Wacs.Core/Instructions/Numeric/F32UnOp.cs index ff39b2c8..de5ecd4f 100644 --- a/Wacs.Core/Instructions/Numeric/F32UnOp.cs +++ b/Wacs.Core/Instructions/Numeric/F32UnOp.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using Wacs.Core.Instructions.Transpiler; @@ -44,14 +42,14 @@ private InstF32UnOp(ByteCode op, Func execute, NumericInst.Validati _validate = validate; IsConstant = isConst; } - - public bool IsConstant { get; } public override ByteCode Op { get; } + public bool IsConstant { get; } + public Func GetFunc => (_, i1) => _execute(i1); - public override void Validate(IWasmValidationContext context) => _validate(context); + public override void Validate(IWasmValidationContext context) => _validate(context); // +0 public override void Execute(ExecContext context) { diff --git a/Wacs.Core/Instructions/Numeric/F64BinOp.cs b/Wacs.Core/Instructions/Numeric/F64BinOp.cs index 8431288c..6ba13b51 100644 --- a/Wacs.Core/Instructions/Numeric/F64BinOp.cs +++ b/Wacs.Core/Instructions/Numeric/F64BinOp.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Runtime.InteropServices; @@ -66,10 +64,11 @@ private InstF64BinOp(ByteCode op, Func execute, NumericIns public override ByteCode Op { get; } + public override int StackDiff => -1; public Func GetFunc => (_, i1, i2) => _execute(i1, i2); - public override void Validate(IWasmValidationContext context) => _validate(context); + public override void Validate(IWasmValidationContext context) => _validate(context); // -1 public override void Execute(ExecContext context) { diff --git a/Wacs.Core/Instructions/Numeric/F64RelOp.cs b/Wacs.Core/Instructions/Numeric/F64RelOp.cs index e45a40fe..fa421dde 100644 --- a/Wacs.Core/Instructions/Numeric/F64RelOp.cs +++ b/Wacs.Core/Instructions/Numeric/F64RelOp.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using Wacs.Core.Instructions.Transpiler; @@ -56,10 +54,11 @@ private InstF64RelOp(ByteCode op, Func execute, NumericInst.V public override ByteCode Op { get; } + public override int StackDiff => -1; public Func GetFunc => (_, i1, i2) => _execute(i1, i2); - public override void Validate(IWasmValidationContext context) => _validate(context); + public override void Validate(IWasmValidationContext context) => _validate(context); // -1 public override void Execute(ExecContext context) { diff --git a/Wacs.Core/Instructions/Numeric/F64UnOp.cs b/Wacs.Core/Instructions/Numeric/F64UnOp.cs index 38b8d756..fab2771a 100644 --- a/Wacs.Core/Instructions/Numeric/F64UnOp.cs +++ b/Wacs.Core/Instructions/Numeric/F64UnOp.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using Wacs.Core.Instructions.Transpiler; @@ -48,7 +46,7 @@ private InstF64UnOp(ByteCode op, Func execute, NumericInst.Valida public Func GetFunc => (_, i1) => _execute(i1); - public override void Validate(IWasmValidationContext context) => _validate(context); + public override void Validate(IWasmValidationContext context) => _validate(context); // +0 public override void Execute(ExecContext context) { diff --git a/Wacs.Core/Instructions/Numeric/I32BinOp.cs b/Wacs.Core/Instructions/Numeric/I32BinOp.cs index 21c966e2..56a11b4d 100644 --- a/Wacs.Core/Instructions/Numeric/I32BinOp.cs +++ b/Wacs.Core/Instructions/Numeric/I32BinOp.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using Wacs.Core.Instructions.Transpiler; @@ -83,9 +81,10 @@ private InstI32BinOp(ByteCode op, NumericInst.ValidationDelegate validate, bool } public override ByteCode Op { get; } + public override int StackDiff => -1; public bool IsConstant { get; } - public override void Validate(IWasmValidationContext context) => _validate(context); + public override void Validate(IWasmValidationContext context) => _validate(context); // -1 // @Spec 4.3.2.3. iadd private static int ExecuteI32Add(int i1, int i2) => i1 + i2; diff --git a/Wacs.Core/Instructions/Numeric/I32RelOp.cs b/Wacs.Core/Instructions/Numeric/I32RelOp.cs index 27e70a91..1437d0b4 100644 --- a/Wacs.Core/Instructions/Numeric/I32RelOp.cs +++ b/Wacs.Core/Instructions/Numeric/I32RelOp.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using Wacs.Core.Instructions.Transpiler; @@ -65,8 +63,9 @@ private InstI32RelOp(ByteCode op, NumericInst.ValidationDelegate validate) } public override ByteCode Op { get; } + public override int StackDiff => -1; - public override void Validate(IWasmValidationContext context) => _validate(context); + public override void Validate(IWasmValidationContext context) => _validate(context); // -1 private static int ExecuteI32Eq(int i1, int i2) => i1 == i2 ? 1 : 0; private static int ExecuteI32Ne(int i1, int i2) => i1 != i2 ? 1 : 0; diff --git a/Wacs.Core/Instructions/Numeric/I32SignExtension.cs b/Wacs.Core/Instructions/Numeric/I32SignExtension.cs index 0ac8d477..a3faa3e9 100644 --- a/Wacs.Core/Instructions/Numeric/I32SignExtension.cs +++ b/Wacs.Core/Instructions/Numeric/I32SignExtension.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using Wacs.Core.Instructions.Transpiler; diff --git a/Wacs.Core/Instructions/Numeric/I32UnOp.cs b/Wacs.Core/Instructions/Numeric/I32UnOp.cs index ad288579..770da7a2 100644 --- a/Wacs.Core/Instructions/Numeric/I32UnOp.cs +++ b/Wacs.Core/Instructions/Numeric/I32UnOp.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using Wacs.Core.Instructions.Transpiler; @@ -44,7 +42,7 @@ private InstI32UnOp(ByteCode op, Func execute, NumericInst.Validatio public Func GetFunc => (_, i1) => _execute(i1); - public override void Validate(IWasmValidationContext context) => _validate(context); + public override void Validate(IWasmValidationContext context) => _validate(context); // +0 public override void Execute(ExecContext context) { diff --git a/Wacs.Core/Instructions/Numeric/I64BinOp.cs b/Wacs.Core/Instructions/Numeric/I64BinOp.cs index 0c042393..3a0a8541 100644 --- a/Wacs.Core/Instructions/Numeric/I64BinOp.cs +++ b/Wacs.Core/Instructions/Numeric/I64BinOp.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using Wacs.Core.Instructions.Transpiler; @@ -82,9 +80,10 @@ private InstI64BinOp(ByteCode op, NumericInst.ValidationDelegate validate, bool } public override ByteCode Op { get; } + public override int StackDiff => -1; public bool IsConstant { get; } - public override void Validate(IWasmValidationContext context) => _validate(context); + public override void Validate(IWasmValidationContext context) => _validate(context); // -1 private static long ExecuteI64Add(long i1, long i2) => i1 + i2; diff --git a/Wacs.Core/Instructions/Numeric/I64RelOp.cs b/Wacs.Core/Instructions/Numeric/I64RelOp.cs index 0291f9e4..6d78432b 100644 --- a/Wacs.Core/Instructions/Numeric/I64RelOp.cs +++ b/Wacs.Core/Instructions/Numeric/I64RelOp.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using Wacs.Core.Instructions.Transpiler; @@ -65,8 +63,9 @@ private InstI64RelOp(ByteCode op, NumericInst.ValidationDelegate validate) } public override ByteCode Op { get; } + public override int StackDiff => -1; - public override void Validate(IWasmValidationContext context) => _validate(context); + public override void Validate(IWasmValidationContext context) => _validate(context); // -1 private static int ExecuteI64Eq(long i1, long i2) => i1 == i2 ? 1 : 0; diff --git a/Wacs.Core/Instructions/Numeric/I64SignExtension.cs b/Wacs.Core/Instructions/Numeric/I64SignExtension.cs index 615932c7..fcddf587 100644 --- a/Wacs.Core/Instructions/Numeric/I64SignExtension.cs +++ b/Wacs.Core/Instructions/Numeric/I64SignExtension.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using Wacs.Core.Instructions.Transpiler; @@ -62,7 +60,7 @@ private InstI64SignExtend(ByteCode op, Func execute, NumericInst.Va public Func GetFunc => (_, i1) => _execute(i1); - public override void Validate(IWasmValidationContext context) => _validate(context); + public override void Validate(IWasmValidationContext context) => _validate(context); // +0 public override void Execute(ExecContext context) { diff --git a/Wacs.Core/Instructions/Numeric/I64UnOp.cs b/Wacs.Core/Instructions/Numeric/I64UnOp.cs index 4e6b0c71..e49111a5 100644 --- a/Wacs.Core/Instructions/Numeric/I64UnOp.cs +++ b/Wacs.Core/Instructions/Numeric/I64UnOp.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using Wacs.Core.Instructions.Transpiler; @@ -44,7 +42,7 @@ private InstI64UnOp(ByteCode op, Func execute, NumericInst.Validat public Func GetFunc => (_, i1) => _execute(i1); - public override void Validate(IWasmValidationContext context) => _validate(context); + public override void Validate(IWasmValidationContext context) => _validate(context); // +0 public override void Execute(ExecContext context) { diff --git a/Wacs.Core/Instructions/Numeric/ITestOp.cs b/Wacs.Core/Instructions/Numeric/ITestOp.cs index f6b3606d..27709d30 100644 --- a/Wacs.Core/Instructions/Numeric/ITestOp.cs +++ b/Wacs.Core/Instructions/Numeric/ITestOp.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using Wacs.Core.Instructions.Transpiler; @@ -41,7 +39,7 @@ private InstI32TestOp(ByteCode op, Func execute, NumericInst.Validatio public Func GetFunc => (_, i1) => _execute(i1); - public override void Validate(IWasmValidationContext context) => _validate(context); + public override void Validate(IWasmValidationContext context) => _validate(context); // +0 public override void Execute(ExecContext context) { @@ -72,7 +70,7 @@ private InstI64TestOp(ByteCode op, Func execute, NumericInst.Validati public Func GetFunc => (_, i1) => _execute(i1); - public override void Validate(IWasmValidationContext context) => _validate(context); + public override void Validate(IWasmValidationContext context) => _validate(context); // +0 public override void Execute(ExecContext context) { diff --git a/Wacs.Core/Instructions/Numeric/NumericInst.cs b/Wacs.Core/Instructions/Numeric/NumericInst.cs index 1b2e7e94..d69857a7 100644 --- a/Wacs.Core/Instructions/Numeric/NumericInst.cs +++ b/Wacs.Core/Instructions/Numeric/NumericInst.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using Wacs.Core.OpCodes; using Wacs.Core.Runtime; @@ -31,8 +29,8 @@ public partial class NumericInst : InstructionBase, IConstOpInstruction private readonly ValidationDelegate _validate; - private NumericInst(ByteCode op, ExecuteDelegate execute, ValidationDelegate validate, bool isConst = false) => - (Op, _execute, _validate, IsConstant) = (op, execute, validate, isConst); + private NumericInst(ByteCode op, ExecuteDelegate execute, ValidationDelegate validate, int stackDiff, bool isConst = false) => + (Op, _execute, _validate, StackDiff, IsConstant) = (op, execute, validate, stackDiff, isConst); public override ByteCode Op { get; } diff --git a/Wacs.Core/Instructions/Numeric/SatConversion.cs b/Wacs.Core/Instructions/Numeric/SatConversion.cs index 0ace9cb5..f992912d 100644 --- a/Wacs.Core/Instructions/Numeric/SatConversion.cs +++ b/Wacs.Core/Instructions/Numeric/SatConversion.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using Wacs.Core.OpCodes; @@ -24,28 +22,28 @@ namespace Wacs.Core.Instructions.Numeric public partial class NumericInst { public static readonly NumericInst I32TruncSatF32S = new(ExtCode.I32TruncSatF32S, ExecuteI32TruncSatF32S, - ValidateOperands(pop: ValType.F32, push: ValType.I32)); + ValidateOperands(pop: ValType.F32, push: ValType.I32), 0); public static readonly NumericInst I32TruncSatF32U = new(ExtCode.I32TruncSatF32U, ExecuteI32TruncSatF32U, - ValidateOperands(pop: ValType.F32, push: ValType.I32)); + ValidateOperands(pop: ValType.F32, push: ValType.I32), 0); public static readonly NumericInst I32TruncSatF64S = new(ExtCode.I32TruncSatF64S, ExecuteI32TruncSatF64S, - ValidateOperands(pop: ValType.F64, push: ValType.I32)); + ValidateOperands(pop: ValType.F64, push: ValType.I32), 0); public static readonly NumericInst I32TruncSatF64U = new(ExtCode.I32TruncSatF64U, ExecuteI32TruncSatF64U, - ValidateOperands(pop: ValType.F64, push: ValType.I32)); + ValidateOperands(pop: ValType.F64, push: ValType.I32), 0); public static readonly NumericInst I64TruncSatF32S = new(ExtCode.I64TruncSatF32S, ExecuteI64TruncSatF32S, - ValidateOperands(pop: ValType.F32, push: ValType.I64)); + ValidateOperands(pop: ValType.F32, push: ValType.I64), 0); public static readonly NumericInst I64TruncSatF32U = new(ExtCode.I64TruncSatF32U, ExecuteI64TruncSatF32U, - ValidateOperands(pop: ValType.F32, push: ValType.I64)); + ValidateOperands(pop: ValType.F32, push: ValType.I64), 0); public static readonly NumericInst I64TruncSatF64S = new(ExtCode.I64TruncSatF64S, ExecuteI64TruncSatF64S, - ValidateOperands(pop: ValType.F64, push: ValType.I64)); + ValidateOperands(pop: ValType.F64, push: ValType.I64), 0); public static readonly NumericInst I64TruncSatF64U = new(ExtCode.I64TruncSatF64U, ExecuteI64TruncSatF64U, - ValidateOperands(pop: ValType.F64, push: ValType.I64)); + ValidateOperands(pop: ValType.F64, push: ValType.I64), 0); // https://github.com/WebAssembly/spec/blob/master/proposals/nontrapping-float-to-int-conversion/Overview.md private static void ExecuteI32TruncSatF32S(ExecContext context) diff --git a/Wacs.Core/Instructions/Parametric.cs b/Wacs.Core/Instructions/Parametric.cs index b7ad5efc..58ecd3dc 100644 --- a/Wacs.Core/Instructions/Parametric.cs +++ b/Wacs.Core/Instructions/Parametric.cs @@ -1,22 +1,19 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.IO; -using FluentValidation; using Wacs.Core.Instructions.Transpiler; using Wacs.Core.OpCodes; using Wacs.Core.Runtime; @@ -33,6 +30,7 @@ public class InstDrop : InstructionBase, INodeConsumer { public static readonly InstDrop Inst = new(); public override ByteCode Op => OpCode.Drop; + public override int StackDiff => -1; public Action GetFunc => (_, _) => { }; @@ -42,7 +40,7 @@ public class InstDrop : InstructionBase, INodeConsumer public override void Validate(IWasmValidationContext context) { //* Value Polymorphic ignores type - context.OpStack.PopAny(); + context.OpStack.PopAny(); // -1 } /// @@ -64,6 +62,7 @@ public class InstSelect : InstructionBase, INodeComputer WithTypes = withTypes; public override ByteCode Op => OpCode.Select; + public override int StackDiff => -2; public Func GetFunc => Select; @@ -80,20 +79,20 @@ public override void Validate(IWasmValidationContext context) context.Assert(type.Validate(context.Types), "Select instruction had invalid type:{0}", type); - context.OpStack.PopI32(); - context.OpStack.PopType(type); - context.OpStack.PopType(type); - context.OpStack.PushType(type); + context.OpStack.PopI32(); // -1 + context.OpStack.PopType(type); // -2 + context.OpStack.PopType(type); // -3 + context.OpStack.PushType(type); // -2 } else { - context.OpStack.PopI32(); - Value val2 = context.OpStack.PopAny(); - Value val1 = context.OpStack.PopAny(); + context.OpStack.PopI32(); // -1 + Value val2 = context.OpStack.PopAny(); // -2 + Value val1 = context.OpStack.PopAny(); // -3 context.Assert(val1.Type.Matches(val2.Type, context.Types) && val1.Type.IsVal() && val2.Type.IsVal(), "Select instruction expected matching non-ref types on the stack: {0} == {1}",val1.Type,val2.Type); - context.OpStack.PushType(val1.Type == ValType.Bot ? val2.Type : val1.Type); + context.OpStack.PushType(val1.Type == ValType.Bot ? val2.Type : val1.Type); // -2 } } diff --git a/Wacs.Core/Instructions/Reference/Control.cs b/Wacs.Core/Instructions/Reference/Control.cs index 1f8661eb..f11b8d27 100644 --- a/Wacs.Core/Instructions/Reference/Control.cs +++ b/Wacs.Core/Instructions/Reference/Control.cs @@ -1,23 +1,18 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ - -using System; -using System.Collections.Generic; +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using System.IO; -using System.Text; using System.Threading.Tasks; using Wacs.Core.OpCodes; using Wacs.Core.Runtime; @@ -32,22 +27,31 @@ namespace Wacs.Core.Instructions.Reference public class InstBrOnNull : InstructionBase { private LabelIdx L; + private BlockTarget? LinkedLabel; + public override ByteCode Op => OpCode.BrOnNull; + public override void Validate(IWasmValidationContext context) { context.Assert(context.ContainsLabel(L.Value), "Instruction {0} invalid. Could not branch to label {1}",Op.GetMnemonic(), L); - var refType = context.OpStack.PopRefType(); + var refType = context.OpStack.PopRefType(); // -1 var nthFrame = context.ControlStack.PeekAt((int)L.Value); //Pop values like we branch - context.OpStack.DiscardValues(nthFrame.LabelTypes); + context.OpStack.DiscardValues(nthFrame.LabelTypes); // -(N+1) //But actually, we don't, so push them back on. - context.OpStack.PushResult(nthFrame.LabelTypes); + context.OpStack.PushResult(nthFrame.LabelTypes); // -1 //Push the non-null ref back for the else case. - context.OpStack.PushRef(refType.ToConcrete()); + context.OpStack.PushRef(refType.ToConcrete()); // +0 + } + + public override InstructionBase Link(ExecContext context, int pointer) + { + LinkedLabel = InstBranch.PrecomputeStack(context, L); + return base.Link(context, pointer); } /// @@ -59,14 +63,14 @@ public override void Execute(ExecContext context) var refVal = context.OpStack.PopRefType(); if (refVal.IsNullRef) { - InstBranch.ExecuteInstruction(context, L); + InstBranch.ExecuteInstruction(context, LinkedLabel); } else { context.OpStack.PushRef(refVal); } } - + public override InstructionBase Parse(BinaryReader reader) { L = (LabelIdx)reader.ReadLeb128_u32(); @@ -77,24 +81,34 @@ public override InstructionBase Parse(BinaryReader reader) public class InstBrOnNonNull : InstructionBase { private LabelIdx L; + private BlockTarget? LinkedLabel; + public override ByteCode Op => OpCode.BrOnNonNull; + public override int StackDiff => -1; + public override void Validate(IWasmValidationContext context) { context.Assert(context.ContainsLabel(L.Value), "Instruction {0} invalid. Could not branch to label {1}",Op.GetMnemonic(), L); - var refType = context.OpStack.PopRefType(); + var refType = context.OpStack.PopRefType(); // -1 //Push the ref for the branch case. - context.OpStack.PushRef(refType.ToConcrete()); + context.OpStack.PushRef(refType.ToConcrete()); // +0 var nthFrame = context.ControlStack.PeekAt((int)L.Value); //Pop values like we branch - context.OpStack.DiscardValues(nthFrame.LabelTypes); + context.OpStack.DiscardValues(nthFrame.LabelTypes); // -N //But actually, we don't, so push them back on. - context.OpStack.PushResult(nthFrame.LabelTypes); + context.OpStack.PushResult(nthFrame.LabelTypes); // +0 //Unpush the ref we pushed for the branch - context.OpStack.PopRefType(); + context.OpStack.PopRefType(); // -1 + } + + public override InstructionBase Link(ExecContext context, int pointer) + { + LinkedLabel = InstBranch.PrecomputeStack(context, L); + return base.Link(context, pointer); } /// @@ -107,10 +121,10 @@ public override void Execute(ExecContext context) if (!refVal.IsNullRef) { context.OpStack.PushRef(refVal); - InstBranch.ExecuteInstruction(context, L); + InstBranch.ExecuteInstruction(context, LinkedLabel); } } - + public override InstructionBase Parse(BinaryReader reader) { L = (LabelIdx)reader.ReadLeb128_u32(); @@ -143,13 +157,22 @@ public override void Validate(IWasmValidationContext context) context.Assert(funcType, "Instruction call_ref was invalid. Not a FuncType. {0}", type); - var refVal = context.OpStack.PopRefType(); + var refVal = context.OpStack.PopRefType(); // -1 context.Assert(refVal.IsRefType, "Instruction call_ref was invalid. Not a RefType. {0}", refVal); context.Assert(refVal.Type.IsNull() || refVal.Type.Index() == X, "Instruction call_ref was invalid. type mismatch: expected (ref null {0}), found {1}", X.Value, refVal.Type); - context.OpStack.DiscardValues(funcType.ParameterTypes); - context.OpStack.PushResult(funcType.ResultType); + context.OpStack.DiscardValues(funcType.ParameterTypes); // -(N+1) + context.OpStack.PushResult(funcType.ResultType); // -N + } + + public override InstructionBase Link(ExecContext context, int pointer) + { + var funcType = context.Frame.Module.Types[X].Expansion as FunctionType; + context.LinkOpStackHeight -= 1; + context.LinkOpStackHeight -= funcType!.ParameterTypes.Arity; + context.LinkOpStackHeight += funcType.ResultType.Arity; + return this; } public override void Execute(ExecContext context) diff --git a/Wacs.Core/Instructions/Reference/Reference.cs b/Wacs.Core/Instructions/Reference/Reference.cs index fe9722a0..31ac7c70 100644 --- a/Wacs.Core/Instructions/Reference/Reference.cs +++ b/Wacs.Core/Instructions/Reference/Reference.cs @@ -23,9 +23,11 @@ public class InstRefNull : InstructionBase, IConstInstruction public override void Validate(IWasmValidationContext context) { context.Assert(Type.IsRefType(), $"Type was not a RefType:{Type}"); - context.OpStack.PushRef(Value.Null(Type)); + context.OpStack.PushRef(Value.Null(Type)); // +1 } + public override int StackDiff => +1; + // @Spec 4.4.2.1. ref.null t public override void Execute(ExecContext context) { context.OpStack.PushRef(Value.Null(Type)); @@ -54,8 +56,8 @@ public class InstRefIsNull : InstructionBase // @Spec 3.3.2.2. ref.is_null public override void Validate(IWasmValidationContext context) { - context.OpStack.PopRefType(); - context.OpStack.PushI32(); + context.OpStack.PopRefType(); // -1 + context.OpStack.PushI32(); // +0 } // @Spec 4.4.2.2. ref.is_null @@ -91,9 +93,11 @@ public override void Validate(IWasmValidationContext context) context.Assert(func.IsFullyDeclared(context), "Instruction ref.func is invalid. (func {0}) is not fully declared in the module.",FunctionIndex); var val = new Value(ValType.Ref | (ValType)func.TypeIndex); - context.OpStack.PushFuncref(val); + context.OpStack.PushFuncref(val); // +1 } + public override int StackDiff => +1; + // @Spec 4.4.2.3. ref.func x public override void Execute(ExecContext context) { @@ -127,11 +131,13 @@ public class InstRefEq : InstructionBase public override ByteCode Op => OpCode.RefEq; public override void Validate(IWasmValidationContext context) { - context.OpStack.PopType(ValType.Eq); - context.OpStack.PopType(ValType.Eq); - context.OpStack.PushI32(); + context.OpStack.PopType(ValType.Eq); // -1 + context.OpStack.PopType(ValType.Eq); // -2 + context.OpStack.PushI32(); // -1 } + public override int StackDiff => -1; + public override void Execute(ExecContext context) { context.Assert( context.OpStack.Peek().IsRefType, @@ -156,8 +162,8 @@ public class InstRefAsNonNull : InstructionBase public override ByteCode Op => OpCode.RefAsNonNull; public override void Validate(IWasmValidationContext context) { - var vRef = context.OpStack.PopRefType(); - context.OpStack.PushType(vRef.Type); + var vRef = context.OpStack.PopRefType(); // -1 + context.OpStack.PushType(vRef.Type); // +0 } public override void Execute(ExecContext context) diff --git a/Wacs.Core/Instructions/Runtime.cs b/Wacs.Core/Instructions/Runtime.cs index dc746774..d70add69 100644 --- a/Wacs.Core/Instructions/Runtime.cs +++ b/Wacs.Core/Instructions/Runtime.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using FluentValidation; using Wacs.Core.OpCodes; @@ -33,7 +31,7 @@ public override void Validate(IWasmValidationContext context) public override void Execute(ExecContext context) { //Notify the runtime? - context.RewindSequence(); + // context.ResumeSequence(context.Frame.TopLabel.Head); } } } \ No newline at end of file diff --git a/Wacs.Core/Instructions/SIMD/RelaxedBinOp.cs b/Wacs.Core/Instructions/SIMD/RelaxedBinOp.cs index 38acead7..b998f3f2 100644 --- a/Wacs.Core/Instructions/SIMD/RelaxedBinOp.cs +++ b/Wacs.Core/Instructions/SIMD/RelaxedBinOp.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using Wacs.Core.OpCodes; @@ -25,13 +23,13 @@ namespace Wacs.Core.Instructions.Numeric // @Spec https://github.com/WebAssembly/relaxed-simd/blob/main/proposals/relaxed-simd/Overview.md public partial class NumericInst { - public static readonly NumericInst I8x16RelaxedSwizzle = new(SimdCode.I8x16RelaxedSwizzle, ExecuteI8x16RelaxedSwizzle, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst F32x4RelaxedMin = new(SimdCode.F32x4RelaxedMin, ExecuteF32x4RelaxedMin, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst F32x4RelaxedMax = new(SimdCode.F32x4RelaxedMax, ExecuteF32x4RelaxedMax, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst F64x2RelaxedMin = new(SimdCode.F64x2RelaxedMin, ExecuteF64x2RelaxedMin, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst F64x2RelaxedMax = new(SimdCode.F64x2RelaxedMax, ExecuteF64x2RelaxedMax, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I16x8RelaxedQ15MulrS = new(SimdCode.I16x8RelaxedQ15MulrS, ExecuteI16x8RelaxedQ15MulrS, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I16x8RelaxedDotI8x16I7x16S = new (SimdCode.I16x8RelaxedDotI8x16I7x16S, ExecuteI16x8RelaxedDotI8x16I7x16S, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + public static readonly NumericInst I8x16RelaxedSwizzle = new(SimdCode.I8x16RelaxedSwizzle, ExecuteI8x16RelaxedSwizzle, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst F32x4RelaxedMin = new(SimdCode.F32x4RelaxedMin, ExecuteF32x4RelaxedMin, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst F32x4RelaxedMax = new(SimdCode.F32x4RelaxedMax, ExecuteF32x4RelaxedMax, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst F64x2RelaxedMin = new(SimdCode.F64x2RelaxedMin, ExecuteF64x2RelaxedMin, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst F64x2RelaxedMax = new(SimdCode.F64x2RelaxedMax, ExecuteF64x2RelaxedMax, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst I16x8RelaxedQ15MulrS = new(SimdCode.I16x8RelaxedQ15MulrS, ExecuteI16x8RelaxedQ15MulrS, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst I16x8RelaxedDotI8x16I7x16S = new (SimdCode.I16x8RelaxedDotI8x16I7x16S, ExecuteI16x8RelaxedDotI8x16I7x16S, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); private static void ExecuteI8x16RelaxedSwizzle(ExecContext context) { diff --git a/Wacs.Core/Instructions/SIMD/RelaxedTernOp.cs b/Wacs.Core/Instructions/SIMD/RelaxedTernOp.cs index f5afadc0..55a2030b 100644 --- a/Wacs.Core/Instructions/SIMD/RelaxedTernOp.cs +++ b/Wacs.Core/Instructions/SIMD/RelaxedTernOp.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using Wacs.Core.OpCodes; using Wacs.Core.Runtime; @@ -22,17 +20,17 @@ namespace Wacs.Core.Instructions.Numeric { public partial class NumericInst { - public static readonly NumericInst I8x16RelaxedLaneselect = new(SimdCode.I8x16RelaxedLaneselect, ExecuteI8x16RelaxedLaneselect, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, pop3: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I16x8RelaxedLaneselect = new(SimdCode.I16x8RelaxedLaneselect, ExecuteI16x8RelaxedLaneselect, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, pop3: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I32x4RelaxedLaneselect = new(SimdCode.I32x4RelaxedLaneselect, ExecuteI32x4RelaxedLaneselect, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, pop3: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I64x2RelaxedLaneselect = new(SimdCode.I64x2RelaxedLaneselect, ExecuteI64x2RelaxedLaneselect, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, pop3: ValType.V128, push: ValType.V128)); + public static readonly NumericInst I8x16RelaxedLaneselect = new(SimdCode.I8x16RelaxedLaneselect, ExecuteI8x16RelaxedLaneselect, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, pop3: ValType.V128, push: ValType.V128), -2); + public static readonly NumericInst I16x8RelaxedLaneselect = new(SimdCode.I16x8RelaxedLaneselect, ExecuteI16x8RelaxedLaneselect, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, pop3: ValType.V128, push: ValType.V128), -2); + public static readonly NumericInst I32x4RelaxedLaneselect = new(SimdCode.I32x4RelaxedLaneselect, ExecuteI32x4RelaxedLaneselect, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, pop3: ValType.V128, push: ValType.V128), -2); + public static readonly NumericInst I64x2RelaxedLaneselect = new(SimdCode.I64x2RelaxedLaneselect, ExecuteI64x2RelaxedLaneselect, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, pop3: ValType.V128, push: ValType.V128), -2); - public static readonly NumericInst F32x4RelaxedMAdd = new(SimdCode.F32x4RelaxedMAdd , ExecuteF32x4RelaxedMAdd , ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, pop3: ValType.V128, push: ValType.V128)); - public static readonly NumericInst F32x4RelaxedNMAdd = new(SimdCode.F32x4RelaxedNMAdd, ExecuteF32x4RelaxedNMAdd, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, pop3: ValType.V128, push: ValType.V128)); - public static readonly NumericInst F64x2RelaxedMAdd = new(SimdCode.F64x2RelaxedMAdd , ExecuteF64x2RelaxedMAdd , ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, pop3: ValType.V128, push: ValType.V128)); - public static readonly NumericInst F64x2RelaxedNMAdd = new(SimdCode.F64x2RelaxedNMAdd, ExecuteF64x2RelaxedNMAdd, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, pop3: ValType.V128, push: ValType.V128)); + public static readonly NumericInst F32x4RelaxedMAdd = new(SimdCode.F32x4RelaxedMAdd , ExecuteF32x4RelaxedMAdd , ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, pop3: ValType.V128, push: ValType.V128), -2); + public static readonly NumericInst F32x4RelaxedNMAdd = new(SimdCode.F32x4RelaxedNMAdd, ExecuteF32x4RelaxedNMAdd, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, pop3: ValType.V128, push: ValType.V128), -2); + public static readonly NumericInst F64x2RelaxedMAdd = new(SimdCode.F64x2RelaxedMAdd , ExecuteF64x2RelaxedMAdd , ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, pop3: ValType.V128, push: ValType.V128), -2); + public static readonly NumericInst F64x2RelaxedNMAdd = new(SimdCode.F64x2RelaxedNMAdd, ExecuteF64x2RelaxedNMAdd, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, pop3: ValType.V128, push: ValType.V128), -2); - public static readonly NumericInst I32x4RelaxedDotI8x16I7x16AddS = new (SimdCode.I32x4RelaxedDotI8x16I7x16AddS, ExecuteI32x4RelaxedDotI8x16I7x16AddS, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, pop3: ValType.V128, push: ValType.V128)); + public static readonly NumericInst I32x4RelaxedDotI8x16I7x16AddS = new (SimdCode.I32x4RelaxedDotI8x16I7x16AddS, ExecuteI32x4RelaxedDotI8x16I7x16AddS, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, pop3: ValType.V128, push: ValType.V128), -2); private static byte BitSelect(byte i1, byte i2, byte i3) { diff --git a/Wacs.Core/Instructions/SIMD/RelaxedUnOp.cs b/Wacs.Core/Instructions/SIMD/RelaxedUnOp.cs index af425ce7..d4838345 100644 --- a/Wacs.Core/Instructions/SIMD/RelaxedUnOp.cs +++ b/Wacs.Core/Instructions/SIMD/RelaxedUnOp.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using Wacs.Core.OpCodes; @@ -23,10 +21,10 @@ namespace Wacs.Core.Instructions.Numeric { public partial class NumericInst { - public static readonly NumericInst I32x4RelaxedTruncF32x4S = new(SimdCode.I32x4RelaxedTruncF32x4S, ExecuteI32x4RelaxedTruncF32x4S, ValidateOperands(pop: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I32x4RelaxedTruncF32x4U = new(SimdCode.I32x4RelaxedTruncF32x4U, ExecuteI32x4RelaxedTruncF32x4S, ValidateOperands(pop: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I32x4RelaxedTruncF64x2SZero = new (SimdCode.I32x4RelaxedTruncF64x2SZero, ExecuteI32x4RelaxedTruncF64x2SZero, ValidateOperands(pop: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I32x4RelaxedTruncF64x2UZero = new (SimdCode.I32x4RelaxedTruncF64x2UZero, ExecuteI32x4RelaxedTruncF64x2UZero, ValidateOperands(pop: ValType.V128, push: ValType.V128)); + public static readonly NumericInst I32x4RelaxedTruncF32x4S = new(SimdCode.I32x4RelaxedTruncF32x4S, ExecuteI32x4RelaxedTruncF32x4S, ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); + public static readonly NumericInst I32x4RelaxedTruncF32x4U = new(SimdCode.I32x4RelaxedTruncF32x4U, ExecuteI32x4RelaxedTruncF32x4S, ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); + public static readonly NumericInst I32x4RelaxedTruncF64x2SZero = new (SimdCode.I32x4RelaxedTruncF64x2SZero, ExecuteI32x4RelaxedTruncF64x2SZero, ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); + public static readonly NumericInst I32x4RelaxedTruncF64x2UZero = new (SimdCode.I32x4RelaxedTruncF64x2UZero, ExecuteI32x4RelaxedTruncF64x2UZero, ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); private static void ExecuteI32x4RelaxedTruncF32x4S(ExecContext context) { diff --git a/Wacs.Core/Instructions/SIMD/VConst.cs b/Wacs.Core/Instructions/SIMD/VConst.cs index 538ad543..fc48a7ba 100644 --- a/Wacs.Core/Instructions/SIMD/VConst.cs +++ b/Wacs.Core/Instructions/SIMD/VConst.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System.IO; using Wacs.Core.OpCodes; @@ -26,6 +24,7 @@ public class InstV128Const : InstructionBase, IConstInstruction { private V128 V128; public override ByteCode Op => SimdCode.V128Const; + public override int StackDiff => +1; /// /// @Spec 3.3.1.1 t.const diff --git a/Wacs.Core/Instructions/SIMD/VLaneOp.cs b/Wacs.Core/Instructions/SIMD/VLaneOp.cs index 286121c5..ce11f373 100644 --- a/Wacs.Core/Instructions/SIMD/VLaneOp.cs +++ b/Wacs.Core/Instructions/SIMD/VLaneOp.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.IO; @@ -31,25 +29,25 @@ public class InstLaneOp : InstructionBase private readonly ValidationDelegate _validate; private LaneIdx X; - private InstLaneOp(ByteCode op, ExecuteDelegate execute, ValidationDelegate validate) => - (Op, _execute, _validate) = (op, execute, validate); + private InstLaneOp(ByteCode op, ExecuteDelegate execute, ValidationDelegate validate, int stackDiff) => + (Op, _execute, _validate, StackDiff) = (op, execute, validate, stackDiff); public override ByteCode Op { get; } - public static InstLaneOp I8x16ExtractLaneS() => new(SimdCode.I8x16ExtractLaneS, ExecuteI8x16ExtractLaneS, ValidateFromLane(V128Shape.I8x16)); - public static InstLaneOp I8x16ExtractLaneU() => new(SimdCode.I8x16ExtractLaneU, ExecuteI8x16ExtractLaneU, ValidateFromLane(V128Shape.I8x16)); - public static InstLaneOp I16x8ExtractLaneS() => new(SimdCode.I16x8ExtractLaneS, ExecuteI16x8ExtractLaneS, ValidateFromLane(V128Shape.I16x8)); - public static InstLaneOp I16x8ExtractLaneU() => new(SimdCode.I16x8ExtractLaneU, ExecuteI16x8ExtractLaneU, ValidateFromLane(V128Shape.I16x8)); - public static InstLaneOp I32x4ExtractLane() => new(SimdCode.I32x4ExtractLane, ExecuteI32x4ExtractLane, ValidateFromLane(V128Shape.I32x4)); - public static InstLaneOp I64x2ExtractLane() => new(SimdCode.I64x2ExtractLane, ExecuteI64x2ExtractLane, ValidateFromLane(V128Shape.I64x2)); - public static InstLaneOp F32x4ExtractLane() => new(SimdCode.F32x4ExtractLane, ExecuteF32x4ExtractLane, ValidateFromLane(V128Shape.F32x4)); - public static InstLaneOp F64x2ExtractLane() => new(SimdCode.F64x2ExtractLane, ExecuteF64x2ExtractLane, ValidateFromLane(V128Shape.F64x2)); - - public static InstLaneOp I8x16ReplaceLane() => new(SimdCode.I8x16ReplaceLane, ExecuteI8x16ReplaceLane, ValidateToLane(V128Shape.I8x16)); - public static InstLaneOp I16x8ReplaceLane() => new(SimdCode.I16x8ReplaceLane, ExecuteI16x8ReplaceLane, ValidateToLane(V128Shape.I16x8)); - public static InstLaneOp I32x4ReplaceLane() => new(SimdCode.I32x4ReplaceLane, ExecuteI32x4ReplaceLane, ValidateToLane(V128Shape.I32x4)); - public static InstLaneOp I64x2ReplaceLane() => new(SimdCode.I64x2ReplaceLane, ExecuteI64x2ReplaceLane, ValidateToLane(V128Shape.I64x2)); - public static InstLaneOp F32x4ReplaceLane() => new(SimdCode.F32x4ReplaceLane, ExecuteF32x4ReplaceLane, ValidateToLane(V128Shape.F32x4)); - public static InstLaneOp F64x2ReplaceLane() => new(SimdCode.F64x2ReplaceLane, ExecuteF64x2ReplaceLane, ValidateToLane(V128Shape.F64x2)); + public static InstLaneOp I8x16ExtractLaneS() => new(SimdCode.I8x16ExtractLaneS, ExecuteI8x16ExtractLaneS, ValidateFromLane(V128Shape.I8x16), 0); + public static InstLaneOp I8x16ExtractLaneU() => new(SimdCode.I8x16ExtractLaneU, ExecuteI8x16ExtractLaneU, ValidateFromLane(V128Shape.I8x16), 0); + public static InstLaneOp I16x8ExtractLaneS() => new(SimdCode.I16x8ExtractLaneS, ExecuteI16x8ExtractLaneS, ValidateFromLane(V128Shape.I16x8), 0); + public static InstLaneOp I16x8ExtractLaneU() => new(SimdCode.I16x8ExtractLaneU, ExecuteI16x8ExtractLaneU, ValidateFromLane(V128Shape.I16x8), 0); + public static InstLaneOp I32x4ExtractLane() => new(SimdCode.I32x4ExtractLane, ExecuteI32x4ExtractLane, ValidateFromLane(V128Shape.I32x4), 0); + public static InstLaneOp I64x2ExtractLane() => new(SimdCode.I64x2ExtractLane, ExecuteI64x2ExtractLane, ValidateFromLane(V128Shape.I64x2), 0); + public static InstLaneOp F32x4ExtractLane() => new(SimdCode.F32x4ExtractLane, ExecuteF32x4ExtractLane, ValidateFromLane(V128Shape.F32x4), 0); + public static InstLaneOp F64x2ExtractLane() => new(SimdCode.F64x2ExtractLane, ExecuteF64x2ExtractLane, ValidateFromLane(V128Shape.F64x2), 0); + + public static InstLaneOp I8x16ReplaceLane() => new(SimdCode.I8x16ReplaceLane, ExecuteI8x16ReplaceLane, ValidateToLane(V128Shape.I8x16), -1); + public static InstLaneOp I16x8ReplaceLane() => new(SimdCode.I16x8ReplaceLane, ExecuteI16x8ReplaceLane, ValidateToLane(V128Shape.I16x8), -1); + public static InstLaneOp I32x4ReplaceLane() => new(SimdCode.I32x4ReplaceLane, ExecuteI32x4ReplaceLane, ValidateToLane(V128Shape.I32x4), -1); + public static InstLaneOp I64x2ReplaceLane() => new(SimdCode.I64x2ReplaceLane, ExecuteI64x2ReplaceLane, ValidateToLane(V128Shape.I64x2), -1); + public static InstLaneOp F32x4ReplaceLane() => new(SimdCode.F32x4ReplaceLane, ExecuteF32x4ReplaceLane, ValidateToLane(V128Shape.F32x4), -1); + public static InstLaneOp F64x2ReplaceLane() => new(SimdCode.F64x2ReplaceLane, ExecuteF64x2ReplaceLane, ValidateToLane(V128Shape.F64x2), -1); public static void ExecuteI8x16ExtractLaneS(ExecContext context, LaneIdx laneidx) { diff --git a/Wacs.Core/Instructions/SIMD/VMemory.cs b/Wacs.Core/Instructions/SIMD/VMemory.cs index 7a23a2c3..aa5bdc7f 100644 --- a/Wacs.Core/Instructions/SIMD/VMemory.cs +++ b/Wacs.Core/Instructions/SIMD/VMemory.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.IO; @@ -161,8 +159,8 @@ public override void Validate(IWasmValidationContext context) context.Assert(M.Align.LinearSize() <= WidthTByteSize * CountN, "Instruction {0} failed with invalid alignment {1} <= {2}/8",Op.GetMnemonic(),M.Align.LinearSize(),WidthT); - context.OpStack.PopInt(); - context.OpStack.PushV128(); + context.OpStack.PopInt(); // -1 + context.OpStack.PushV128(); // +0 } // @Spec 4.4.7.2. v128.loadMxN_sx memarg @@ -267,8 +265,8 @@ public override void Validate(IWasmValidationContext context) context.Assert(M.Align.LinearSize() <= WidthN.ByteSize(), "Instruction {0} failed with invalid alignment {1} <= {2}/8",Op.GetMnemonic(),M.Align,BitWidth.V128); - context.OpStack.PopInt(); - context.OpStack.PushV128(); + context.OpStack.PopInt(); // -1 + context.OpStack.PushV128(); // +0 } // @Spec 4.4.7.3. v128.loadN_splat @@ -373,8 +371,8 @@ public override void Validate(IWasmValidationContext context) context.Assert(M.Align.LinearSize() <= BitWidth.V128.ByteSize(), "Instruction {0} failed with invalid alignment {1} <= {2}/8",Op.GetMnemonic(),M.Align.LinearSize(),BitWidth.V128); - context.OpStack.PopInt(); - context.OpStack.PushV128(); + context.OpStack.PopInt(); // -1 + context.OpStack.PushV128(); // +0 } // @Spec 4.4.7.7. v128.loadN_zero memarg @@ -463,6 +461,8 @@ public class InstMemoryLoadLane : InstructionBase _ => throw new InvalidDataException($"InstMemoryLoad instruction is malformed: {WidthN}"), }; + public override int StackDiff => -1; + /// /// @Spec 3.3.7.8. v128.loadN_lane memarge laneidx /// @@ -475,9 +475,9 @@ public override void Validate(IWasmValidationContext context) context.Assert(M.Align.LinearSize() <= WidthN.ByteSize(), "Instruction {0} failed with invalid alignment {1} <= {2}/8", Op.GetMnemonic(), M.Align.LinearSize(), WidthN); - context.OpStack.PopV128(); - context.OpStack.PopInt(); - context.OpStack.PushV128(); + context.OpStack.PopV128(); // -1 + context.OpStack.PopInt(); // -2 + context.OpStack.PushV128(); // -1 } // @Spec 4.4.7.5. v128.loadN_lane memarg x @@ -571,6 +571,8 @@ public class InstMemoryStoreLane : InstructionBase _ => throw new InvalidDataException($"InstMemoryLoad instruction is malformed: {WidthN}"), }; + public override int StackDiff => -2; + public InstructionBase Immediate(MemArg m) { M = m; @@ -588,8 +590,8 @@ public override void Validate(IWasmValidationContext context) "Instruction {0} failed with invalid context memory {1}.", Op.GetMnemonic(), M.M.Value); context.Assert(M.Align.LinearSize() <= WidthN.ByteSize(), "Instruction {0} failed with invalid alignment {1} <= {2}/8", Op.GetMnemonic(), M.Align.LinearSize(), WidthN); - context.OpStack.PopV128(); - context.OpStack.PopInt(); + context.OpStack.PopV128(); // -1 + context.OpStack.PopInt(); // -2 } // @Spec 4.4.7.7. v128.storeN_lane memarg x diff --git a/Wacs.Core/Instructions/SIMD/VfBinOp.cs b/Wacs.Core/Instructions/SIMD/VfBinOp.cs index db0497d3..341b06c5 100644 --- a/Wacs.Core/Instructions/SIMD/VfBinOp.cs +++ b/Wacs.Core/Instructions/SIMD/VfBinOp.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using Wacs.Core.OpCodes; @@ -23,23 +21,23 @@ namespace Wacs.Core.Instructions.Numeric { public partial class NumericInst { - public static readonly NumericInst F32x4Add = new (SimdCode.F32x4Add, ExecuteF32x4Add, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst F32x4Sub = new (SimdCode.F32x4Sub, ExecuteF32x4Sub, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst F32x4Mul = new (SimdCode.F32x4Mul, ExecuteF32x4Mul, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst F32x4Div = new (SimdCode.F32x4Div, ExecuteF32x4Div, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst F32x4Min = new (SimdCode.F32x4Min, ExecuteF32x4Min, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst F32x4Max = new (SimdCode.F32x4Max, ExecuteF32x4Max, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst F32x4PMin = new (SimdCode.F32x4PMin, ExecuteF32x4PMin, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst F32x4PMax = new (SimdCode.F32x4PMax, ExecuteF32x4PMax, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + public static readonly NumericInst F32x4Add = new (SimdCode.F32x4Add, ExecuteF32x4Add, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst F32x4Sub = new (SimdCode.F32x4Sub, ExecuteF32x4Sub, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst F32x4Mul = new (SimdCode.F32x4Mul, ExecuteF32x4Mul, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst F32x4Div = new (SimdCode.F32x4Div, ExecuteF32x4Div, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst F32x4Min = new (SimdCode.F32x4Min, ExecuteF32x4Min, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst F32x4Max = new (SimdCode.F32x4Max, ExecuteF32x4Max, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst F32x4PMin = new (SimdCode.F32x4PMin, ExecuteF32x4PMin, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst F32x4PMax = new (SimdCode.F32x4PMax, ExecuteF32x4PMax, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); - public static readonly NumericInst F64x2Add = new (SimdCode.F64x2Add, ExecuteF64x2Add, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst F64x2Sub = new (SimdCode.F64x2Sub, ExecuteF64x2Sub, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst F64x2Mul = new (SimdCode.F64x2Mul, ExecuteF64x2Mul, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst F64x2Div = new (SimdCode.F64x2Div, ExecuteF64x2Div, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst F64x2Min = new (SimdCode.F64x2Min, ExecuteF64x2Min, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst F64x2Max = new (SimdCode.F64x2Max, ExecuteF64x2Max, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst F64x2PMin = new (SimdCode.F64x2PMin, ExecuteF64x2PMin, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst F64x2PMax = new (SimdCode.F64x2PMax, ExecuteF64x2PMax, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + public static readonly NumericInst F64x2Add = new (SimdCode.F64x2Add, ExecuteF64x2Add, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst F64x2Sub = new (SimdCode.F64x2Sub, ExecuteF64x2Sub, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst F64x2Mul = new (SimdCode.F64x2Mul, ExecuteF64x2Mul, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst F64x2Div = new (SimdCode.F64x2Div, ExecuteF64x2Div, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst F64x2Min = new (SimdCode.F64x2Min, ExecuteF64x2Min, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst F64x2Max = new (SimdCode.F64x2Max, ExecuteF64x2Max, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst F64x2PMin = new (SimdCode.F64x2PMin, ExecuteF64x2PMin, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst F64x2PMax = new (SimdCode.F64x2PMax, ExecuteF64x2PMax, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); private static void ExecuteF32x4Add(ExecContext context) { diff --git a/Wacs.Core/Instructions/SIMD/VfConvert.cs b/Wacs.Core/Instructions/SIMD/VfConvert.cs index d7ff32bf..2311a98e 100644 --- a/Wacs.Core/Instructions/SIMD/VfConvert.cs +++ b/Wacs.Core/Instructions/SIMD/VfConvert.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using Wacs.Core.OpCodes; using Wacs.Core.Runtime; @@ -22,12 +20,12 @@ namespace Wacs.Core.Instructions.Numeric { public partial class NumericInst { - public static readonly NumericInst F32x4ConvertI32x4S = new(SimdCode.F32x4ConvertI32x4S, ExecuteF32x4ConvertI32x4S, ValidateOperands(pop: ValType.V128, push: ValType.V128)); - public static readonly NumericInst F32x4ConvertI32x4U = new(SimdCode.F32x4ConvertI32x4U, ExecuteF32x4ConvertI32x4U, ValidateOperands(pop: ValType.V128, push: ValType.V128)); - public static readonly NumericInst F64x2ConvertLowI32x4S = new(SimdCode.F64x2ConvertLowI32x4S, ExecuteF64x2ConvertLowI32x4S, ValidateOperands(pop: ValType.V128, push: ValType.V128)); - public static readonly NumericInst F64x2ConvertLowI32x4U = new(SimdCode.F64x2ConvertLowI32x4U, ExecuteF64x2ConvertLowI32x4U, ValidateOperands(pop: ValType.V128, push: ValType.V128)); - public static readonly NumericInst F32x4DemoteF64x2Zero = new(SimdCode.F32x4DemoteF64x2Zero, ExecuteF32x4DemoteF64x2Zero, ValidateOperands(pop: ValType.V128, push: ValType.V128)); - public static readonly NumericInst F64x2PromoteLowF32x4 = new(SimdCode.F64x2PromoteLowF32x4, ExecuteF64x2PromoteLowF32x4, ValidateOperands(pop: ValType.V128, push: ValType.V128)); + public static readonly NumericInst F32x4ConvertI32x4S = new(SimdCode.F32x4ConvertI32x4S, ExecuteF32x4ConvertI32x4S, ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); + public static readonly NumericInst F32x4ConvertI32x4U = new(SimdCode.F32x4ConvertI32x4U, ExecuteF32x4ConvertI32x4U, ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); + public static readonly NumericInst F64x2ConvertLowI32x4S = new(SimdCode.F64x2ConvertLowI32x4S, ExecuteF64x2ConvertLowI32x4S, ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); + public static readonly NumericInst F64x2ConvertLowI32x4U = new(SimdCode.F64x2ConvertLowI32x4U, ExecuteF64x2ConvertLowI32x4U, ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); + public static readonly NumericInst F32x4DemoteF64x2Zero = new(SimdCode.F32x4DemoteF64x2Zero, ExecuteF32x4DemoteF64x2Zero, ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); + public static readonly NumericInst F64x2PromoteLowF32x4 = new(SimdCode.F64x2PromoteLowF32x4, ExecuteF64x2PromoteLowF32x4, ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); private static void ExecuteF32x4ConvertI32x4S(ExecContext context) { diff --git a/Wacs.Core/Instructions/SIMD/VfInjectOp.cs b/Wacs.Core/Instructions/SIMD/VfInjectOp.cs index 3e573ea9..91da7b67 100644 --- a/Wacs.Core/Instructions/SIMD/VfInjectOp.cs +++ b/Wacs.Core/Instructions/SIMD/VfInjectOp.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using Wacs.Core.OpCodes; using Wacs.Core.Runtime; @@ -23,8 +21,8 @@ namespace Wacs.Core.Instructions.Numeric // VvBinOps - Bit-wise Logical Operators public partial class NumericInst { - public static readonly NumericInst F32x4Splat = new(SimdCode.F32x4Splat, ExecuteF32x4Splat, ValidateOperands(pop: ValType.F32, push: ValType.V128)); - public static readonly NumericInst F64x2Splat = new(SimdCode.F64x2Splat, ExecuteF64x2Splat, ValidateOperands(pop: ValType.F64, push: ValType.V128)); + public static readonly NumericInst F32x4Splat = new(SimdCode.F32x4Splat, ExecuteF32x4Splat, ValidateOperands(pop: ValType.F32, push: ValType.V128), 0); + public static readonly NumericInst F64x2Splat = new(SimdCode.F64x2Splat, ExecuteF64x2Splat, ValidateOperands(pop: ValType.F64, push: ValType.V128), 0); private static void ExecuteF32x4Splat(ExecContext context) { diff --git a/Wacs.Core/Instructions/SIMD/VfRelOp.cs b/Wacs.Core/Instructions/SIMD/VfRelOp.cs index 69f5dd78..0a5868a7 100644 --- a/Wacs.Core/Instructions/SIMD/VfRelOp.cs +++ b/Wacs.Core/Instructions/SIMD/VfRelOp.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using Wacs.Core.OpCodes; using Wacs.Core.Runtime; @@ -24,18 +22,18 @@ namespace Wacs.Core.Instructions.Numeric { public partial class NumericInst { - public static readonly NumericInst F32x4Eq = new(SimdCode.F32x4Eq, ExecuteF32x4Eq, ValidateOperands(pop1:ValType.V128, pop2:ValType.V128, push: ValType.V128)); - public static readonly NumericInst F32x4Ne = new(SimdCode.F32x4Ne, ExecuteF32x4Ne, ValidateOperands(pop1:ValType.V128, pop2:ValType.V128, push: ValType.V128)); - public static readonly NumericInst F32x4Lt = new(SimdCode.F32x4Lt, ExecuteF32x4Lt, ValidateOperands(pop1:ValType.V128, pop2:ValType.V128, push: ValType.V128)); - public static readonly NumericInst F32x4Gt = new(SimdCode.F32x4Gt, ExecuteF32x4Gt, ValidateOperands(pop1:ValType.V128, pop2:ValType.V128, push: ValType.V128)); - public static readonly NumericInst F32x4Le = new(SimdCode.F32x4Le, ExecuteF32x4Le, ValidateOperands(pop1:ValType.V128, pop2:ValType.V128, push: ValType.V128)); - public static readonly NumericInst F32x4Ge = new(SimdCode.F32x4Ge, ExecuteF32x4Ge, ValidateOperands(pop1:ValType.V128, pop2:ValType.V128, push: ValType.V128)); - public static readonly NumericInst F64x2Eq = new(SimdCode.F64x2Eq, ExecuteF64x2Eq, ValidateOperands(pop1:ValType.V128, pop2:ValType.V128, push: ValType.V128)); - public static readonly NumericInst F64x2Ne = new(SimdCode.F64x2Ne, ExecuteF64x2Ne, ValidateOperands(pop1:ValType.V128, pop2:ValType.V128, push: ValType.V128)); - public static readonly NumericInst F64x2Lt = new(SimdCode.F64x2Lt, ExecuteF64x2Lt, ValidateOperands(pop1:ValType.V128, pop2:ValType.V128, push: ValType.V128)); - public static readonly NumericInst F64x2Gt = new(SimdCode.F64x2Gt, ExecuteF64x2Gt, ValidateOperands(pop1:ValType.V128, pop2:ValType.V128, push: ValType.V128)); - public static readonly NumericInst F64x2Le = new(SimdCode.F64x2Le, ExecuteF64x2Le, ValidateOperands(pop1:ValType.V128, pop2:ValType.V128, push: ValType.V128)); - public static readonly NumericInst F64x2Ge = new(SimdCode.F64x2Ge, ExecuteF64x2Ge, ValidateOperands(pop1:ValType.V128, pop2:ValType.V128, push: ValType.V128)); + public static readonly NumericInst F32x4Eq = new(SimdCode.F32x4Eq, ExecuteF32x4Eq, ValidateOperands(pop1:ValType.V128, pop2:ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst F32x4Ne = new(SimdCode.F32x4Ne, ExecuteF32x4Ne, ValidateOperands(pop1:ValType.V128, pop2:ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst F32x4Lt = new(SimdCode.F32x4Lt, ExecuteF32x4Lt, ValidateOperands(pop1:ValType.V128, pop2:ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst F32x4Gt = new(SimdCode.F32x4Gt, ExecuteF32x4Gt, ValidateOperands(pop1:ValType.V128, pop2:ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst F32x4Le = new(SimdCode.F32x4Le, ExecuteF32x4Le, ValidateOperands(pop1:ValType.V128, pop2:ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst F32x4Ge = new(SimdCode.F32x4Ge, ExecuteF32x4Ge, ValidateOperands(pop1:ValType.V128, pop2:ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst F64x2Eq = new(SimdCode.F64x2Eq, ExecuteF64x2Eq, ValidateOperands(pop1:ValType.V128, pop2:ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst F64x2Ne = new(SimdCode.F64x2Ne, ExecuteF64x2Ne, ValidateOperands(pop1:ValType.V128, pop2:ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst F64x2Lt = new(SimdCode.F64x2Lt, ExecuteF64x2Lt, ValidateOperands(pop1:ValType.V128, pop2:ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst F64x2Gt = new(SimdCode.F64x2Gt, ExecuteF64x2Gt, ValidateOperands(pop1:ValType.V128, pop2:ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst F64x2Le = new(SimdCode.F64x2Le, ExecuteF64x2Le, ValidateOperands(pop1:ValType.V128, pop2:ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst F64x2Ge = new(SimdCode.F64x2Ge, ExecuteF64x2Ge, ValidateOperands(pop1:ValType.V128, pop2:ValType.V128, push: ValType.V128), -1); private static void ExecuteF32x4Eq(ExecContext context) { diff --git a/Wacs.Core/Instructions/SIMD/VfUnOp.cs b/Wacs.Core/Instructions/SIMD/VfUnOp.cs index d793bf0c..130b4c20 100644 --- a/Wacs.Core/Instructions/SIMD/VfUnOp.cs +++ b/Wacs.Core/Instructions/SIMD/VfUnOp.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using Wacs.Core.OpCodes; @@ -23,26 +21,26 @@ namespace Wacs.Core.Instructions.Numeric { public partial class NumericInst { - public static readonly NumericInst F32x4Abs = new (SimdCode.F32x4Abs , ExecuteF32x4Abs , ValidateOperands(pop: ValType.V128, push: ValType.V128)); - public static readonly NumericInst F64x2Abs = new (SimdCode.F64x2Abs , ExecuteF64x2Abs , ValidateOperands(pop: ValType.V128, push: ValType.V128)); + public static readonly NumericInst F32x4Abs = new (SimdCode.F32x4Abs , ExecuteF32x4Abs , ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); + public static readonly NumericInst F64x2Abs = new (SimdCode.F64x2Abs , ExecuteF64x2Abs , ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); - public static readonly NumericInst F32x4Neg = new (SimdCode.F32x4Neg , ExecuteF32x4Neg , ValidateOperands(pop: ValType.V128, push: ValType.V128)); - public static readonly NumericInst F64x2Neg = new (SimdCode.F64x2Neg , ExecuteF64x2Neg , ValidateOperands(pop: ValType.V128, push: ValType.V128)); + public static readonly NumericInst F32x4Neg = new (SimdCode.F32x4Neg , ExecuteF32x4Neg , ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); + public static readonly NumericInst F64x2Neg = new (SimdCode.F64x2Neg , ExecuteF64x2Neg , ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); - public static readonly NumericInst F32x4Sqrt = new (SimdCode.F32x4Sqrt , ExecuteF32x4Sqrt , ValidateOperands(pop: ValType.V128, push: ValType.V128)); - public static readonly NumericInst F64x2Sqrt = new (SimdCode.F64x2Sqrt , ExecuteF64x2Sqrt , ValidateOperands(pop: ValType.V128, push: ValType.V128)); + public static readonly NumericInst F32x4Sqrt = new (SimdCode.F32x4Sqrt , ExecuteF32x4Sqrt , ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); + public static readonly NumericInst F64x2Sqrt = new (SimdCode.F64x2Sqrt , ExecuteF64x2Sqrt , ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); - public static readonly NumericInst F32x4Ceil = new (SimdCode.F32x4Ceil , ExecuteF32x4Ceil , ValidateOperands(pop: ValType.V128, push: ValType.V128)); - public static readonly NumericInst F64x2Ceil = new (SimdCode.F64x2Ceil , ExecuteF64x2Ceil , ValidateOperands(pop: ValType.V128, push: ValType.V128)); + public static readonly NumericInst F32x4Ceil = new (SimdCode.F32x4Ceil , ExecuteF32x4Ceil , ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); + public static readonly NumericInst F64x2Ceil = new (SimdCode.F64x2Ceil , ExecuteF64x2Ceil , ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); - public static readonly NumericInst F32x4Floor = new (SimdCode.F32x4Floor , ExecuteF32x4Floor , ValidateOperands(pop: ValType.V128, push: ValType.V128)); - public static readonly NumericInst F64x2Floor = new (SimdCode.F64x2Floor , ExecuteF64x2Floor , ValidateOperands(pop: ValType.V128, push: ValType.V128)); + public static readonly NumericInst F32x4Floor = new (SimdCode.F32x4Floor , ExecuteF32x4Floor , ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); + public static readonly NumericInst F64x2Floor = new (SimdCode.F64x2Floor , ExecuteF64x2Floor , ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); - public static readonly NumericInst F32x4Trunc = new (SimdCode.F32x4Trunc , ExecuteF32x4Trunc , ValidateOperands(pop: ValType.V128, push: ValType.V128)); - public static readonly NumericInst F64x2Trunc = new (SimdCode.F64x2Trunc , ExecuteF64x2Trunc , ValidateOperands(pop: ValType.V128, push: ValType.V128)); + public static readonly NumericInst F32x4Trunc = new (SimdCode.F32x4Trunc , ExecuteF32x4Trunc , ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); + public static readonly NumericInst F64x2Trunc = new (SimdCode.F64x2Trunc , ExecuteF64x2Trunc , ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); - public static readonly NumericInst F32x4Nearest = new (SimdCode.F32x4Nearest , ExecuteF32x4Nearest, ValidateOperands(pop: ValType.V128, push: ValType.V128)); - public static readonly NumericInst F64x2Nearest = new (SimdCode.F64x2Nearest , ExecuteF64x2Nearest, ValidateOperands(pop: ValType.V128, push: ValType.V128)); + public static readonly NumericInst F32x4Nearest = new (SimdCode.F32x4Nearest , ExecuteF32x4Nearest, ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); + public static readonly NumericInst F64x2Nearest = new (SimdCode.F64x2Nearest , ExecuteF64x2Nearest, ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); private static void ExecuteF32x4Abs(ExecContext context) diff --git a/Wacs.Core/Instructions/SIMD/ViBinOp.cs b/Wacs.Core/Instructions/SIMD/ViBinOp.cs index cd35718b..a879ac32 100644 --- a/Wacs.Core/Instructions/SIMD/ViBinOp.cs +++ b/Wacs.Core/Instructions/SIMD/ViBinOp.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using Wacs.Core.OpCodes; @@ -24,49 +22,49 @@ namespace Wacs.Core.Instructions.Numeric { public partial class NumericInst { - public static readonly NumericInst I8x16Add = new(SimdCode.I8x16Add, ExecuteI8x16Add, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I8x16Sub = new(SimdCode.I8x16Sub, ExecuteI8x16Sub, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + public static readonly NumericInst I8x16Add = new(SimdCode.I8x16Add, ExecuteI8x16Add, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst I8x16Sub = new(SimdCode.I8x16Sub, ExecuteI8x16Sub, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); - public static readonly NumericInst I16x8Add = new(SimdCode.I16x8Add, ExecuteI16x8Add, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I16x8Sub = new(SimdCode.I16x8Sub, ExecuteI16x8Sub, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + public static readonly NumericInst I16x8Add = new(SimdCode.I16x8Add, ExecuteI16x8Add, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst I16x8Sub = new(SimdCode.I16x8Sub, ExecuteI16x8Sub, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); - public static readonly NumericInst I32x4Add = new(SimdCode.I32x4Add, ExecuteI32x4Add, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I32x4Sub = new(SimdCode.I32x4Sub, ExecuteI32x4Sub, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + public static readonly NumericInst I32x4Add = new(SimdCode.I32x4Add, ExecuteI32x4Add, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst I32x4Sub = new(SimdCode.I32x4Sub, ExecuteI32x4Sub, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); - public static readonly NumericInst I64x2Add = new(SimdCode.I64x2Add, ExecuteI64x2Add, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I64x2Sub = new(SimdCode.I64x2Sub, ExecuteI64x2Sub, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + public static readonly NumericInst I64x2Add = new(SimdCode.I64x2Add, ExecuteI64x2Add, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst I64x2Sub = new(SimdCode.I64x2Sub, ExecuteI64x2Sub, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); - public static readonly NumericInst I16x8Mul = new(SimdCode.I16x8Mul, ExecuteI16x8Mul, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I32x4Mul = new(SimdCode.I32x4Mul, ExecuteI32x4Mul, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I64x2Mul = new(SimdCode.I64x2Mul, ExecuteI64x2Mul, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + public static readonly NumericInst I16x8Mul = new(SimdCode.I16x8Mul, ExecuteI16x8Mul, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst I32x4Mul = new(SimdCode.I32x4Mul, ExecuteI32x4Mul, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst I64x2Mul = new(SimdCode.I64x2Mul, ExecuteI64x2Mul, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); - public static readonly NumericInst I8x16AvgrU = new(SimdCode.I8x16AvgrU, ExecuteI8x16AvgrU, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I16x8AvgrU = new(SimdCode.I16x8AvgrU, ExecuteI16x8AvgrU, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + public static readonly NumericInst I8x16AvgrU = new(SimdCode.I8x16AvgrU, ExecuteI8x16AvgrU, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst I16x8AvgrU = new(SimdCode.I16x8AvgrU, ExecuteI16x8AvgrU, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); - public static readonly NumericInst I16x8ExtAddPairwiseI8x16S = new (SimdCode.I16x8ExtAddPairwiseI8x16S, ExecuteI16x8ExtAddPairwiseI8x16S, ValidateOperands(pop: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I16x8ExtAddPairwiseI8x16U = new (SimdCode.I16x8ExtAddPairwiseI8x16U, ExecuteI16x8ExtAddPairwiseI8x16U, ValidateOperands(pop: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I32x4ExtAddPairwiseI16x8S = new (SimdCode.I32x4ExtAddPairwiseI16x8S, ExecuteI32x4ExtAddPairwiseI16x8S, ValidateOperands(pop: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I32x4ExtAddPairwiseI16x8U = new (SimdCode.I32x4ExtAddPairwiseI16x8U, ExecuteI32x4ExtAddPairwiseI16x8U, ValidateOperands(pop: ValType.V128, push: ValType.V128)); + public static readonly NumericInst I16x8ExtAddPairwiseI8x16S = new (SimdCode.I16x8ExtAddPairwiseI8x16S, ExecuteI16x8ExtAddPairwiseI8x16S, ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); + public static readonly NumericInst I16x8ExtAddPairwiseI8x16U = new (SimdCode.I16x8ExtAddPairwiseI8x16U, ExecuteI16x8ExtAddPairwiseI8x16U, ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); + public static readonly NumericInst I32x4ExtAddPairwiseI16x8S = new (SimdCode.I32x4ExtAddPairwiseI16x8S, ExecuteI32x4ExtAddPairwiseI16x8S, ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); + public static readonly NumericInst I32x4ExtAddPairwiseI16x8U = new (SimdCode.I32x4ExtAddPairwiseI16x8U, ExecuteI32x4ExtAddPairwiseI16x8U, ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); - public static readonly NumericInst I16x8ExtMulLowI8x16S = new (SimdCode.I16x8ExtMulLowI8x16S , ExecuteI16x8ExtMulLowI8x16S , ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I16x8ExtMulHighI8x16S = new (SimdCode.I16x8ExtMulHighI8x16S, ExecuteI16x8ExtMulHighI8x16S, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I16x8ExtMulLowI8x16U = new (SimdCode.I16x8ExtMulLowI8x16U , ExecuteI16x8ExtMulLowI8x16U , ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I16x8ExtMulHighI8x16U = new (SimdCode.I16x8ExtMulHighI8x16U, ExecuteI16x8ExtMulHighI8x16U, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + public static readonly NumericInst I16x8ExtMulLowI8x16S = new (SimdCode.I16x8ExtMulLowI8x16S , ExecuteI16x8ExtMulLowI8x16S , ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst I16x8ExtMulHighI8x16S = new (SimdCode.I16x8ExtMulHighI8x16S, ExecuteI16x8ExtMulHighI8x16S, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst I16x8ExtMulLowI8x16U = new (SimdCode.I16x8ExtMulLowI8x16U , ExecuteI16x8ExtMulLowI8x16U , ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst I16x8ExtMulHighI8x16U = new (SimdCode.I16x8ExtMulHighI8x16U, ExecuteI16x8ExtMulHighI8x16U, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); - public static readonly NumericInst I32x4ExtMulLowI16x8S = new (SimdCode.I32x4ExtMulLowI16x8S , ExecuteI32x4ExtMulLowI16x8S , ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I32x4ExtMulHighI16x8S = new (SimdCode.I32x4ExtMulHighI16x8S, ExecuteI32x4ExtMulHighI16x8S, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I32x4ExtMulLowI16x8U = new (SimdCode.I32x4ExtMulLowI16x8U , ExecuteI32x4ExtMulLowI16x8U , ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I32x4ExtMulHighI16x8U = new (SimdCode.I32x4ExtMulHighI16x8U, ExecuteI32x4ExtMulHighI16x8U, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + public static readonly NumericInst I32x4ExtMulLowI16x8S = new (SimdCode.I32x4ExtMulLowI16x8S , ExecuteI32x4ExtMulLowI16x8S , ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst I32x4ExtMulHighI16x8S = new (SimdCode.I32x4ExtMulHighI16x8S, ExecuteI32x4ExtMulHighI16x8S, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst I32x4ExtMulLowI16x8U = new (SimdCode.I32x4ExtMulLowI16x8U , ExecuteI32x4ExtMulLowI16x8U , ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst I32x4ExtMulHighI16x8U = new (SimdCode.I32x4ExtMulHighI16x8U, ExecuteI32x4ExtMulHighI16x8U, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); - public static readonly NumericInst I64x2ExtMulLowI32x4S = new (SimdCode. I64x2ExtMulLowI32x4S , ExecuteI64x2ExtMulLowI32x4S , ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I64x2ExtMulHighI32x4S = new (SimdCode. I64x2ExtMulHighI32x4S, ExecuteI64x2ExtMulHighI32x4S, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I64x2ExtMulLowI32x4U = new (SimdCode. I64x2ExtMulLowI32x4U , ExecuteI64x2ExtMulLowI32x4U , ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I64x2ExtMulHighI32x4U = new (SimdCode. I64x2ExtMulHighI32x4U, ExecuteI64x2ExtMulHighI32x4U, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + public static readonly NumericInst I64x2ExtMulLowI32x4S = new (SimdCode. I64x2ExtMulLowI32x4S , ExecuteI64x2ExtMulLowI32x4S , ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst I64x2ExtMulHighI32x4S = new (SimdCode. I64x2ExtMulHighI32x4S, ExecuteI64x2ExtMulHighI32x4S, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst I64x2ExtMulLowI32x4U = new (SimdCode. I64x2ExtMulLowI32x4U , ExecuteI64x2ExtMulLowI32x4U , ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst I64x2ExtMulHighI32x4U = new (SimdCode. I64x2ExtMulHighI32x4U, ExecuteI64x2ExtMulHighI32x4U, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); - public static readonly NumericInst I32x4DotI16x8S = new (SimdCode.I32x4DotI16x8S, ExecuteI32x4DotI16x8S, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + public static readonly NumericInst I32x4DotI16x8S = new (SimdCode.I32x4DotI16x8S, ExecuteI32x4DotI16x8S, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); - public static readonly NumericInst I16x8Q15MulRSatS = new(SimdCode.I16x8Q15MulRSatS, ExecuteI16x8Q15MulRSatS, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I8x16Swizzle = new(SimdCode.I8x16Swizzle, ExecuteI8x16Swizzle, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + public static readonly NumericInst I16x8Q15MulRSatS = new(SimdCode.I16x8Q15MulRSatS, ExecuteI16x8Q15MulRSatS, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst I8x16Swizzle = new(SimdCode.I8x16Swizzle, ExecuteI8x16Swizzle, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); //extadd_pairwise 8/16 diff --git a/Wacs.Core/Instructions/SIMD/ViConvert.cs b/Wacs.Core/Instructions/SIMD/ViConvert.cs index ddaffaca..44b7b8de 100644 --- a/Wacs.Core/Instructions/SIMD/ViConvert.cs +++ b/Wacs.Core/Instructions/SIMD/ViConvert.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using Wacs.Core.OpCodes; @@ -23,29 +21,29 @@ namespace Wacs.Core.Instructions.Numeric { public partial class NumericInst { - public static readonly NumericInst I32x4TruncSatF32x4S = new(SimdCode.I32x4TruncSatF32x4S, ExecuteI32x4TruncSatF32x4S, ValidateOperands(pop: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I32x4TruncSatF32x4U = new(SimdCode.I32x4TruncSatF32x4U, ExecuteI32x4TruncSatF32x4U, ValidateOperands(pop: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I32x4TruncSatF64x2SZero = new(SimdCode.I32x4TruncSatF64x2SZero, ExecuteI32x4TruncSatF64x2SZero, ValidateOperands(pop: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I32x4TruncSatF64x2UZero = new(SimdCode.I32x4TruncSatF64x2UZero, ExecuteI32x4TruncSatF64x2UZero, ValidateOperands(pop: ValType.V128, push: ValType.V128)); + public static readonly NumericInst I32x4TruncSatF32x4S = new(SimdCode.I32x4TruncSatF32x4S, ExecuteI32x4TruncSatF32x4S, ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); + public static readonly NumericInst I32x4TruncSatF32x4U = new(SimdCode.I32x4TruncSatF32x4U, ExecuteI32x4TruncSatF32x4U, ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); + public static readonly NumericInst I32x4TruncSatF64x2SZero = new(SimdCode.I32x4TruncSatF64x2SZero, ExecuteI32x4TruncSatF64x2SZero, ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); + public static readonly NumericInst I32x4TruncSatF64x2UZero = new(SimdCode.I32x4TruncSatF64x2UZero, ExecuteI32x4TruncSatF64x2UZero, ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); - public static readonly NumericInst I8x16NarrowI16x8S = new(SimdCode.I8x16NarrowI16x8S, ExecuteI8x16NarrowI16x8S, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I8x16NarrowI16x8U = new(SimdCode.I8x16NarrowI16x8U, ExecuteI8x16NarrowI16x8U, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I16x8NarrowI32x4S = new(SimdCode.I16x8NarrowI32x4S, ExecuteI16x8NarrowI32x4S, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I16x8NarrowI32x4U = new(SimdCode.I16x8NarrowI32x4U, ExecuteI16x8NarrowI32x4U, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + public static readonly NumericInst I8x16NarrowI16x8S = new(SimdCode.I8x16NarrowI16x8S, ExecuteI8x16NarrowI16x8S, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst I8x16NarrowI16x8U = new(SimdCode.I8x16NarrowI16x8U, ExecuteI8x16NarrowI16x8U, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst I16x8NarrowI32x4S = new(SimdCode.I16x8NarrowI32x4S, ExecuteI16x8NarrowI32x4S, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst I16x8NarrowI32x4U = new(SimdCode.I16x8NarrowI32x4U, ExecuteI16x8NarrowI32x4U, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); - public static readonly NumericInst I16x8ExtendLowI8x16S = new (SimdCode.I16x8ExtendLowI8x16S , ExecuteI16x8ExtendLowI8x16S , ValidateOperands(pop: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I16x8ExtendHighI8x16S = new (SimdCode.I16x8ExtendHighI8x16S, ExecuteI16x8ExtendHighI8x16S, ValidateOperands(pop: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I16x8ExtendLowI8x16U = new (SimdCode.I16x8ExtendLowI8x16U , ExecuteI16x8ExtendLowI8x16U , ValidateOperands(pop: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I16x8ExtendHighI8x16U = new (SimdCode.I16x8ExtendHighI8x16U, ExecuteI16x8ExtendHighI8x16U, ValidateOperands(pop: ValType.V128, push: ValType.V128)); + public static readonly NumericInst I16x8ExtendLowI8x16S = new (SimdCode.I16x8ExtendLowI8x16S , ExecuteI16x8ExtendLowI8x16S , ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); + public static readonly NumericInst I16x8ExtendHighI8x16S = new (SimdCode.I16x8ExtendHighI8x16S, ExecuteI16x8ExtendHighI8x16S, ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); + public static readonly NumericInst I16x8ExtendLowI8x16U = new (SimdCode.I16x8ExtendLowI8x16U , ExecuteI16x8ExtendLowI8x16U , ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); + public static readonly NumericInst I16x8ExtendHighI8x16U = new (SimdCode.I16x8ExtendHighI8x16U, ExecuteI16x8ExtendHighI8x16U, ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); - public static readonly NumericInst I32x4ExtendLowI16x8S = new(SimdCode.I32x4ExtendLowI16x8S, ExecuteI32x4ExtendLowI16x8S, ValidateOperands(pop: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I32x4ExtendHighI16x8S = new(SimdCode.I32x4ExtendHighI16x8S, ExecuteI32x4ExtendHighI16x8S, ValidateOperands(pop: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I32x4ExtendLowI16x8U = new(SimdCode.I32x4ExtendLowI16x8U, ExecuteI32x4ExtendLowI16x8U, ValidateOperands(pop: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I32x4ExtendHighI16x8U = new(SimdCode.I32x4ExtendHighI16x8U, ExecuteI32x4ExtendHighI16x8U, ValidateOperands(pop: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I64x2ExtendLowI32x4S = new(SimdCode.I64x2ExtendLowI32x4S, ExecuteI64x2ExtendLowI32x4S, ValidateOperands(pop: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I64x2ExtendHighI32x4S = new(SimdCode.I64x2ExtendHighI32x4S, ExecuteI64x2ExtendHighI32x4S, ValidateOperands(pop: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I64x2ExtendLowI32x4U = new(SimdCode.I64x2ExtendLowI32x4U, ExecuteI64x2ExtendLowI32x4U, ValidateOperands(pop: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I64x2ExtendHighI32x4U = new(SimdCode.I64x2ExtendHighI32x4U, ExecuteI64x2ExtendHighI32x4U, ValidateOperands(pop: ValType.V128, push: ValType.V128)); + public static readonly NumericInst I32x4ExtendLowI16x8S = new(SimdCode.I32x4ExtendLowI16x8S, ExecuteI32x4ExtendLowI16x8S, ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); + public static readonly NumericInst I32x4ExtendHighI16x8S = new(SimdCode.I32x4ExtendHighI16x8S, ExecuteI32x4ExtendHighI16x8S, ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); + public static readonly NumericInst I32x4ExtendLowI16x8U = new(SimdCode.I32x4ExtendLowI16x8U, ExecuteI32x4ExtendLowI16x8U, ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); + public static readonly NumericInst I32x4ExtendHighI16x8U = new(SimdCode.I32x4ExtendHighI16x8U, ExecuteI32x4ExtendHighI16x8U, ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); + public static readonly NumericInst I64x2ExtendLowI32x4S = new(SimdCode.I64x2ExtendLowI32x4S, ExecuteI64x2ExtendLowI32x4S, ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); + public static readonly NumericInst I64x2ExtendHighI32x4S = new(SimdCode.I64x2ExtendHighI32x4S, ExecuteI64x2ExtendHighI32x4S, ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); + public static readonly NumericInst I64x2ExtendLowI32x4U = new(SimdCode.I64x2ExtendLowI32x4U, ExecuteI64x2ExtendLowI32x4U, ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); + public static readonly NumericInst I64x2ExtendHighI32x4U = new(SimdCode.I64x2ExtendHighI32x4U, ExecuteI64x2ExtendHighI32x4U, ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); private static void ExecuteI32x4TruncSatF32x4S(ExecContext context) { diff --git a/Wacs.Core/Instructions/SIMD/ViInjectOp.cs b/Wacs.Core/Instructions/SIMD/ViInjectOp.cs index 90d573ca..b6325605 100644 --- a/Wacs.Core/Instructions/SIMD/ViInjectOp.cs +++ b/Wacs.Core/Instructions/SIMD/ViInjectOp.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using Wacs.Core.OpCodes; using Wacs.Core.Runtime; @@ -23,15 +21,15 @@ namespace Wacs.Core.Instructions.Numeric // VvBinOps - Bit-wise Logical Operators public partial class NumericInst { - public static readonly NumericInst I8x16Splat = new(SimdCode.I8x16Splat, ExecuteI8x16Splat, ValidateOperands(pop: ValType.I32, push: ValType.V128)); - public static readonly NumericInst I16x8Splat = new(SimdCode.I16x8Splat, ExecuteI16x8Splat, ValidateOperands(pop: ValType.I32, push: ValType.V128)); - public static readonly NumericInst I32x4Splat = new(SimdCode.I32x4Splat, ExecuteI32x4Splat, ValidateOperands(pop: ValType.I32, push: ValType.V128)); - public static readonly NumericInst I64x2Splat = new(SimdCode.I64x2Splat, ExecuteI64x2Splat, ValidateOperands(pop: ValType.I64, push: ValType.V128)); + public static readonly NumericInst I8x16Splat = new(SimdCode.I8x16Splat, ExecuteI8x16Splat, ValidateOperands(pop: ValType.I32, push: ValType.V128), 0); + public static readonly NumericInst I16x8Splat = new(SimdCode.I16x8Splat, ExecuteI16x8Splat, ValidateOperands(pop: ValType.I32, push: ValType.V128), 0); + public static readonly NumericInst I32x4Splat = new(SimdCode.I32x4Splat, ExecuteI32x4Splat, ValidateOperands(pop: ValType.I32, push: ValType.V128), 0); + public static readonly NumericInst I64x2Splat = new(SimdCode.I64x2Splat, ExecuteI64x2Splat, ValidateOperands(pop: ValType.I64, push: ValType.V128), 0); - public static readonly NumericInst I8x16Bitmask = new(SimdCode.I8x16Bitmask, ExecuteI8x16Bitmask, ValidateOperands(pop: ValType.V128, push: ValType.I32)); - public static readonly NumericInst I16x8Bitmask = new(SimdCode.I16x8Bitmask, ExecuteI16x8Bitmask, ValidateOperands(pop: ValType.V128, push: ValType.I32)); - public static readonly NumericInst I32x4Bitmask = new(SimdCode.I32x4Bitmask, ExecuteI32x4Bitmask, ValidateOperands(pop: ValType.V128, push: ValType.I32)); - public static readonly NumericInst I64x2Bitmask = new(SimdCode.I64x2Bitmask, ExecuteI64x2Bitmask, ValidateOperands(pop: ValType.V128, push: ValType.I32)); + public static readonly NumericInst I8x16Bitmask = new(SimdCode.I8x16Bitmask, ExecuteI8x16Bitmask, ValidateOperands(pop: ValType.V128, push: ValType.I32), 0); + public static readonly NumericInst I16x8Bitmask = new(SimdCode.I16x8Bitmask, ExecuteI16x8Bitmask, ValidateOperands(pop: ValType.V128, push: ValType.I32), 0); + public static readonly NumericInst I32x4Bitmask = new(SimdCode.I32x4Bitmask, ExecuteI32x4Bitmask, ValidateOperands(pop: ValType.V128, push: ValType.I32), 0); + public static readonly NumericInst I64x2Bitmask = new(SimdCode.I64x2Bitmask, ExecuteI64x2Bitmask, ValidateOperands(pop: ValType.V128, push: ValType.I32), 0); // @Spec 4.4.3.8. shape.splat private static void ExecuteI8x16Splat(ExecContext context) diff --git a/Wacs.Core/Instructions/SIMD/ViMinMaxOp.cs b/Wacs.Core/Instructions/SIMD/ViMinMaxOp.cs index f2c1a7a5..253c1a8c 100644 --- a/Wacs.Core/Instructions/SIMD/ViMinMaxOp.cs +++ b/Wacs.Core/Instructions/SIMD/ViMinMaxOp.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using Wacs.Core.OpCodes; @@ -25,40 +23,40 @@ namespace Wacs.Core.Instructions.Numeric public partial class NumericInst { public static readonly NumericInst I8x16MinS = new(SimdCode.I8x16MinS, ExecuteI8x16MinS, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I8x16MinU = new(SimdCode.I8x16MinU, ExecuteI8x16MinU, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I8x16MaxS = new(SimdCode.I8x16MaxS, ExecuteI8x16MaxS, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I8x16MaxU = new(SimdCode.I8x16MaxU, ExecuteI8x16MaxU, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I16x8MinS = new(SimdCode.I16x8MinS, ExecuteI16x8MinS, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I16x8MinU = new(SimdCode.I16x8MinU, ExecuteI16x8MinU, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I16x8MaxS = new(SimdCode.I16x8MaxS, ExecuteI16x8MaxS, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I16x8MaxU = new(SimdCode.I16x8MaxU, ExecuteI16x8MaxU, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I32x4MinS = new(SimdCode.I32x4MinS, ExecuteI32x4MinS, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I32x4MinU = new(SimdCode.I32x4MinU, ExecuteI32x4MinU, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I32x4MaxS = new(SimdCode.I32x4MaxS, ExecuteI32x4MaxS, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I32x4MaxU = new(SimdCode.I32x4MaxU, ExecuteI32x4MaxU, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); private static void ExecuteI8x16MinS(ExecContext context) { diff --git a/Wacs.Core/Instructions/SIMD/ViRelOp.cs b/Wacs.Core/Instructions/SIMD/ViRelOp.cs index 95a5f6dd..627b56e7 100644 --- a/Wacs.Core/Instructions/SIMD/ViRelOp.cs +++ b/Wacs.Core/Instructions/SIMD/ViRelOp.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using Wacs.Core.OpCodes; using Wacs.Core.Runtime; @@ -25,112 +23,112 @@ namespace Wacs.Core.Instructions.Numeric public partial class NumericInst { public static readonly NumericInst I8x16Eq = new(SimdCode.I8x16Eq, ExecuteI8x16Eq, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I8x16Ne = new(SimdCode.I8x16Ne, ExecuteI8x16Ne, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I8x16LtS = new(SimdCode.I8x16LtS, ExecuteI8x16LtS, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I8x16LtU = new(SimdCode.I8x16LtU, ExecuteI8x16LtU, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I8x16GtS = new(SimdCode.I8x16GtS, ExecuteI8x16GtS, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I8x16GtU = new(SimdCode.I8x16GtU, ExecuteI8x16GtU, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I8x16LeS = new(SimdCode.I8x16LeS, ExecuteI8x16LeS, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I8x16LeU = new(SimdCode.I8x16LeU, ExecuteI8x16LeU, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I8x16GeS = new(SimdCode.I8x16GeS, ExecuteI8x16GeS, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I8x16GeU = new(SimdCode.I8x16GeU, ExecuteI8x16GeU, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I16x8Eq = new(SimdCode.I16x8Eq, ExecuteI16x8Eq, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I16x8Ne = new(SimdCode.I16x8Ne, ExecuteI16x8Ne, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I16x8LtS = new(SimdCode.I16x8LtS, ExecuteI16x8LtS, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I16x8LtU = new(SimdCode.I16x8LtU, ExecuteI16x8LtU, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I16x8GtS = new(SimdCode.I16x8GtS, ExecuteI16x8GtS, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I16x8GtU = new(SimdCode.I16x8GtU, ExecuteI16x8GtU, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I16x8LeS = new(SimdCode.I16x8LeS, ExecuteI16x8LeS, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I16x8LeU = new(SimdCode.I16x8LeU, ExecuteI16x8LeU, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I16x8GeS = new(SimdCode.I16x8GeS, ExecuteI16x8GeS, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I16x8GeU = new(SimdCode.I16x8GeU, ExecuteI16x8GeU, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I32x4Eq = new(SimdCode.I32x4Eq, ExecuteI32x4Eq, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I32x4Ne = new(SimdCode.I32x4Ne, ExecuteI32x4Ne, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I32x4LtS = new(SimdCode.I32x4LtS, ExecuteI32x4LtS, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I32x4LtU = new(SimdCode.I32x4LtU, ExecuteI32x4LtU, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I32x4GtS = new(SimdCode.I32x4GtS, ExecuteI32x4GtS, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I32x4GtU = new(SimdCode.I32x4GtU, ExecuteI32x4GtU, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I32x4LeS = new(SimdCode.I32x4LeS, ExecuteI32x4LeS, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I32x4LeU = new(SimdCode.I32x4LeU, ExecuteI32x4LeU, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I32x4GeS = new(SimdCode.I32x4GeS, ExecuteI32x4GeS, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I32x4GeU = new(SimdCode.I32x4GeU, ExecuteI32x4GeU, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I64x2Eq = new(SimdCode.I64x2Eq, ExecuteI64x2Eq, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I64x2Ne = new(SimdCode.I64x2Ne, ExecuteI64x2Ne, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I64x2LtS = new(SimdCode.I64x2LtS, ExecuteI64x2LtS, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I64x2GtS = new(SimdCode.I64x2GtS, ExecuteI64x2GtS, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I64x2LeS = new(SimdCode.I64x2LeS, ExecuteI64x2LeS, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst I64x2GeS = new(SimdCode.I64x2GeS, ExecuteI64x2GeS, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); private static void ExecuteI8x16Eq(ExecContext context) { diff --git a/Wacs.Core/Instructions/SIMD/ViSatBinOp.cs b/Wacs.Core/Instructions/SIMD/ViSatBinOp.cs index a786314a..5d5cc970 100644 --- a/Wacs.Core/Instructions/SIMD/ViSatBinOp.cs +++ b/Wacs.Core/Instructions/SIMD/ViSatBinOp.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using Wacs.Core.OpCodes; @@ -23,15 +21,15 @@ namespace Wacs.Core.Instructions.Numeric { public partial class NumericInst { - public static readonly NumericInst I8x16AddSatS = new(SimdCode.I8x16AddSatS, ExecuteI8x16AddSatS, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I8x16AddSatU = new(SimdCode.I8x16AddSatU, ExecuteI8x16AddSatU, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I16x8AddSatS = new(SimdCode.I16x8AddSatS, ExecuteI16x8AddSatS, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I16x8AddSatU = new(SimdCode.I16x8AddSatU, ExecuteI16x8AddSatU, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + public static readonly NumericInst I8x16AddSatS = new(SimdCode.I8x16AddSatS, ExecuteI8x16AddSatS, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst I8x16AddSatU = new(SimdCode.I8x16AddSatU, ExecuteI8x16AddSatU, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst I16x8AddSatS = new(SimdCode.I16x8AddSatS, ExecuteI16x8AddSatS, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst I16x8AddSatU = new(SimdCode.I16x8AddSatU, ExecuteI16x8AddSatU, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); - public static readonly NumericInst I8x16SubSatS = new(SimdCode.I8x16SubSatS, ExecuteI8x16SubSatS, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I8x16SubSatU = new(SimdCode.I8x16SubSatU, ExecuteI8x16SubSatU, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I16x8SubSatS = new(SimdCode.I16x8SubSatS, ExecuteI16x8SubSatS, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I16x8SubSatU = new(SimdCode.I16x8SubSatU, ExecuteI16x8SubSatU, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + public static readonly NumericInst I8x16SubSatS = new(SimdCode.I8x16SubSatS, ExecuteI8x16SubSatS, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst I8x16SubSatU = new(SimdCode.I8x16SubSatU, ExecuteI8x16SubSatU, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst I16x8SubSatS = new(SimdCode.I16x8SubSatS, ExecuteI16x8SubSatS, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); + public static readonly NumericInst I16x8SubSatU = new(SimdCode.I16x8SubSatU, ExecuteI16x8SubSatU, ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); //q15mulr_sat_s diff --git a/Wacs.Core/Instructions/SIMD/ViShiftOp.cs b/Wacs.Core/Instructions/SIMD/ViShiftOp.cs index a57481a6..bf53caf7 100644 --- a/Wacs.Core/Instructions/SIMD/ViShiftOp.cs +++ b/Wacs.Core/Instructions/SIMD/ViShiftOp.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using Wacs.Core.OpCodes; using Wacs.Core.Runtime; @@ -22,21 +20,21 @@ namespace Wacs.Core.Instructions.Numeric { public partial class NumericInst { - public static readonly NumericInst I8x16Shl = new (SimdCode.I8x16Shl , ExecuteI8x16Shl , ValidateOperands(pop1: ValType.V128, pop2: ValType.I32, push: ValType.V128)); - public static readonly NumericInst I8x16ShrS = new (SimdCode.I8x16ShrS , ExecuteI8x16ShrS , ValidateOperands(pop1: ValType.V128, pop2: ValType.I32, push: ValType.V128)); - public static readonly NumericInst I8x16ShrU = new (SimdCode.I8x16ShrU , ExecuteI8x16ShrU , ValidateOperands(pop1: ValType.V128, pop2: ValType.I32, push: ValType.V128)); + public static readonly NumericInst I8x16Shl = new (SimdCode.I8x16Shl , ExecuteI8x16Shl , ValidateOperands(pop1: ValType.V128, pop2: ValType.I32, push: ValType.V128), -1); + public static readonly NumericInst I8x16ShrS = new (SimdCode.I8x16ShrS , ExecuteI8x16ShrS , ValidateOperands(pop1: ValType.V128, pop2: ValType.I32, push: ValType.V128), -1); + public static readonly NumericInst I8x16ShrU = new (SimdCode.I8x16ShrU , ExecuteI8x16ShrU , ValidateOperands(pop1: ValType.V128, pop2: ValType.I32, push: ValType.V128), -1); - public static readonly NumericInst I16x8Shl = new (SimdCode.I16x8Shl , ExecuteI16x8Shl , ValidateOperands(pop1: ValType.V128, pop2: ValType.I32, push: ValType.V128)); - public static readonly NumericInst I16x8ShrS = new (SimdCode.I16x8ShrS , ExecuteI16x8ShrS , ValidateOperands(pop1: ValType.V128, pop2: ValType.I32, push: ValType.V128)); - public static readonly NumericInst I16x8ShrU = new (SimdCode.I16x8ShrU , ExecuteI16x8ShrU , ValidateOperands(pop1: ValType.V128, pop2: ValType.I32, push: ValType.V128)); + public static readonly NumericInst I16x8Shl = new (SimdCode.I16x8Shl , ExecuteI16x8Shl , ValidateOperands(pop1: ValType.V128, pop2: ValType.I32, push: ValType.V128), -1); + public static readonly NumericInst I16x8ShrS = new (SimdCode.I16x8ShrS , ExecuteI16x8ShrS , ValidateOperands(pop1: ValType.V128, pop2: ValType.I32, push: ValType.V128), -1); + public static readonly NumericInst I16x8ShrU = new (SimdCode.I16x8ShrU , ExecuteI16x8ShrU , ValidateOperands(pop1: ValType.V128, pop2: ValType.I32, push: ValType.V128), -1); - public static readonly NumericInst I32x4Shl = new (SimdCode.I32x4Shl , ExecuteI32x4Shl , ValidateOperands(pop1: ValType.V128, pop2: ValType.I32, push: ValType.V128)); - public static readonly NumericInst I32x4ShrS = new (SimdCode.I32x4ShrS , ExecuteI32x4ShrS , ValidateOperands(pop1: ValType.V128, pop2: ValType.I32, push: ValType.V128)); - public static readonly NumericInst I32x4ShrU = new (SimdCode.I32x4ShrU , ExecuteI32x4ShrU , ValidateOperands(pop1: ValType.V128, pop2: ValType.I32, push: ValType.V128)); + public static readonly NumericInst I32x4Shl = new (SimdCode.I32x4Shl , ExecuteI32x4Shl , ValidateOperands(pop1: ValType.V128, pop2: ValType.I32, push: ValType.V128), -1); + public static readonly NumericInst I32x4ShrS = new (SimdCode.I32x4ShrS , ExecuteI32x4ShrS , ValidateOperands(pop1: ValType.V128, pop2: ValType.I32, push: ValType.V128), -1); + public static readonly NumericInst I32x4ShrU = new (SimdCode.I32x4ShrU , ExecuteI32x4ShrU , ValidateOperands(pop1: ValType.V128, pop2: ValType.I32, push: ValType.V128), -1); - public static readonly NumericInst I64x2Shl = new (SimdCode.I64x2Shl , ExecuteI64x2Shl , ValidateOperands(pop1: ValType.V128, pop2: ValType.I32, push: ValType.V128)); - public static readonly NumericInst I64x2ShrS = new (SimdCode.I64x2ShrS , ExecuteI64x2ShrS , ValidateOperands(pop1: ValType.V128, pop2: ValType.I32, push: ValType.V128)); - public static readonly NumericInst I64x2ShrU = new (SimdCode.I64x2ShrU , ExecuteI64x2ShrU , ValidateOperands(pop1: ValType.V128, pop2: ValType.I32, push: ValType.V128)); + public static readonly NumericInst I64x2Shl = new (SimdCode.I64x2Shl , ExecuteI64x2Shl , ValidateOperands(pop1: ValType.V128, pop2: ValType.I32, push: ValType.V128), -1); + public static readonly NumericInst I64x2ShrS = new (SimdCode.I64x2ShrS , ExecuteI64x2ShrS , ValidateOperands(pop1: ValType.V128, pop2: ValType.I32, push: ValType.V128), -1); + public static readonly NumericInst I64x2ShrU = new (SimdCode.I64x2ShrU , ExecuteI64x2ShrU , ValidateOperands(pop1: ValType.V128, pop2: ValType.I32, push: ValType.V128), -1); private static void ExecuteI8x16Shl(ExecContext context) { diff --git a/Wacs.Core/Instructions/SIMD/ViShuffleOp.cs b/Wacs.Core/Instructions/SIMD/ViShuffleOp.cs index 98e43ece..214c3dbf 100644 --- a/Wacs.Core/Instructions/SIMD/ViShuffleOp.cs +++ b/Wacs.Core/Instructions/SIMD/ViShuffleOp.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System.IO; using Wacs.Core.OpCodes; @@ -26,6 +24,7 @@ public class InstShuffleOp : InstructionBase private V128 X; public override ByteCode Op => SimdCode.I8x16Shuffle; + public override int StackDiff => -1; public override void Validate(IWasmValidationContext context) { @@ -35,9 +34,9 @@ public override void Validate(IWasmValidationContext context) "Instruction {0} was invalid. Lane {1} ({2}) was >= 32.",Op.GetMnemonic(),i,X[(byte)i]); } - context.OpStack.PopV128(); - context.OpStack.PopV128(); - context.OpStack.PushV128(); + context.OpStack.PopV128(); // -1 + context.OpStack.PopV128(); // -2 + context.OpStack.PushV128(); // -1 } /// diff --git a/Wacs.Core/Instructions/SIMD/ViTestOp.cs b/Wacs.Core/Instructions/SIMD/ViTestOp.cs index 5faf702c..16a0d302 100644 --- a/Wacs.Core/Instructions/SIMD/ViTestOp.cs +++ b/Wacs.Core/Instructions/SIMD/ViTestOp.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using Wacs.Core.OpCodes; using Wacs.Core.Runtime; @@ -23,16 +21,16 @@ namespace Wacs.Core.Instructions.Numeric public partial class NumericInst { public static readonly NumericInst I8x16AllTrue = new(SimdCode.I8x16AllTrue, ExecuteI8x16AllTrue, - ValidateOperands(pop: ValType.V128, push: ValType.I32)); + ValidateOperands(pop: ValType.V128, push: ValType.I32), 0); public static readonly NumericInst I16x8AllTrue = new(SimdCode.I16x8AllTrue, ExecuteI16x8AllTrue, - ValidateOperands(pop: ValType.V128, push: ValType.I32)); + ValidateOperands(pop: ValType.V128, push: ValType.I32), 0); public static readonly NumericInst I32x4AllTrue = new(SimdCode.I32x4AllTrue, ExecuteI32x4AllTrue, - ValidateOperands(pop: ValType.V128, push: ValType.I32)); + ValidateOperands(pop: ValType.V128, push: ValType.I32), 0); public static readonly NumericInst I64x2AllTrue = new(SimdCode.I64x2AllTrue, ExecuteI64x2AllTrue, - ValidateOperands(pop: ValType.V128, push: ValType.I32)); + ValidateOperands(pop: ValType.V128, push: ValType.I32), 0); private static void ExecuteI8x16AllTrue(ExecContext context) { diff --git a/Wacs.Core/Instructions/SIMD/ViUnOp.cs b/Wacs.Core/Instructions/SIMD/ViUnOp.cs index d66e0e6a..a870eb66 100644 --- a/Wacs.Core/Instructions/SIMD/ViUnOp.cs +++ b/Wacs.Core/Instructions/SIMD/ViUnOp.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using Wacs.Core.OpCodes; @@ -23,17 +21,17 @@ namespace Wacs.Core.Instructions.Numeric { public partial class NumericInst { - public static readonly NumericInst I8x16Abs = new (SimdCode.I8x16Abs , ExecuteI8x16Abs , ValidateOperands(pop: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I16x8Abs = new (SimdCode.I16x8Abs , ExecuteI16x8Abs , ValidateOperands(pop: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I32x4Abs = new (SimdCode.I32x4Abs , ExecuteI32x4Abs , ValidateOperands(pop: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I64x2Abs = new (SimdCode.I64x2Abs , ExecuteI64x2Abs , ValidateOperands(pop: ValType.V128, push: ValType.V128)); + public static readonly NumericInst I8x16Abs = new (SimdCode.I8x16Abs , ExecuteI8x16Abs , ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); + public static readonly NumericInst I16x8Abs = new (SimdCode.I16x8Abs , ExecuteI16x8Abs , ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); + public static readonly NumericInst I32x4Abs = new (SimdCode.I32x4Abs , ExecuteI32x4Abs , ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); + public static readonly NumericInst I64x2Abs = new (SimdCode.I64x2Abs , ExecuteI64x2Abs , ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); - public static readonly NumericInst I8x16Neg = new (SimdCode.I8x16Neg , ExecuteI8x16Neg , ValidateOperands(pop: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I16x8Neg = new (SimdCode.I16x8Neg , ExecuteI16x8Neg , ValidateOperands(pop: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I32x4Neg = new (SimdCode.I32x4Neg , ExecuteI32x4Neg , ValidateOperands(pop: ValType.V128, push: ValType.V128)); - public static readonly NumericInst I64x2Neg = new (SimdCode.I64x2Neg , ExecuteI64x2Neg , ValidateOperands(pop: ValType.V128, push: ValType.V128)); + public static readonly NumericInst I8x16Neg = new (SimdCode.I8x16Neg , ExecuteI8x16Neg , ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); + public static readonly NumericInst I16x8Neg = new (SimdCode.I16x8Neg , ExecuteI16x8Neg , ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); + public static readonly NumericInst I32x4Neg = new (SimdCode.I32x4Neg , ExecuteI32x4Neg , ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); + public static readonly NumericInst I64x2Neg = new (SimdCode.I64x2Neg , ExecuteI64x2Neg , ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); - public static readonly NumericInst I8x16Popcnt = new (SimdCode.I8x16Popcnt , ExecuteI8x16Popcnt , ValidateOperands(pop: ValType.V128, push: ValType.V128)); + public static readonly NumericInst I8x16Popcnt = new (SimdCode.I8x16Popcnt , ExecuteI8x16Popcnt , ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); private static void ExecuteI8x16Abs(ExecContext context) { diff --git a/Wacs.Core/Instructions/SIMD/VvBinOp.cs b/Wacs.Core/Instructions/SIMD/VvBinOp.cs index 29ddf5b2..e46e7295 100644 --- a/Wacs.Core/Instructions/SIMD/VvBinOp.cs +++ b/Wacs.Core/Instructions/SIMD/VvBinOp.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using Wacs.Core.OpCodes; using Wacs.Core.Runtime; @@ -24,16 +22,16 @@ namespace Wacs.Core.Instructions.Numeric public partial class NumericInst { public static readonly NumericInst V128And = new(SimdCode.V128And, ExecuteV128And, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst V128AndNot = new(SimdCode.V128AndNot, ExecuteV128AndNot, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst V128Or = new(SimdCode.V128Or, ExecuteV128Or, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); public static readonly NumericInst V128Xor = new(SimdCode.V128Xor, ExecuteV128Xor, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, push: ValType.V128), -1); private static void ExecuteV128And(ExecContext context) { diff --git a/Wacs.Core/Instructions/SIMD/VvTernOp.cs b/Wacs.Core/Instructions/SIMD/VvTernOp.cs index 067aeb98..5e0263ea 100644 --- a/Wacs.Core/Instructions/SIMD/VvTernOp.cs +++ b/Wacs.Core/Instructions/SIMD/VvTernOp.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using Wacs.Core.OpCodes; using Wacs.Core.Runtime; @@ -24,7 +22,7 @@ public partial class NumericInst { // New entry for the V128BitSelect operation public static readonly NumericInst V128BitSelect = new(SimdCode.V128BitSelect, ExecuteV128BitSelect, - ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, pop3: ValType.V128, push: ValType.V128)); + ValidateOperands(pop1: ValType.V128, pop2: ValType.V128, pop3: ValType.V128, push: ValType.V128), -2); /// /// @Spec 4.3.2.35. ibitselect diff --git a/Wacs.Core/Instructions/SIMD/VvTestOp.cs b/Wacs.Core/Instructions/SIMD/VvTestOp.cs index 0507d172..d8c574ff 100644 --- a/Wacs.Core/Instructions/SIMD/VvTestOp.cs +++ b/Wacs.Core/Instructions/SIMD/VvTestOp.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using Wacs.Core.OpCodes; using Wacs.Core.Runtime; @@ -23,7 +21,7 @@ namespace Wacs.Core.Instructions.Numeric public partial class NumericInst { public static readonly NumericInst V128AnyTrue = new(SimdCode.V128AnyTrue, ExecuteV128AnyTrue, - ValidateOperands(pop: ValType.V128, push: ValType.I32)); + ValidateOperands(pop: ValType.V128, push: ValType.I32), 0); private static void ExecuteV128AnyTrue(ExecContext context) { diff --git a/Wacs.Core/Instructions/SIMD/VvUnOp.cs b/Wacs.Core/Instructions/SIMD/VvUnOp.cs index a4768e51..c7725b4b 100644 --- a/Wacs.Core/Instructions/SIMD/VvUnOp.cs +++ b/Wacs.Core/Instructions/SIMD/VvUnOp.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using Wacs.Core.OpCodes; using Wacs.Core.Runtime; @@ -24,7 +22,7 @@ namespace Wacs.Core.Instructions.Numeric public partial class NumericInst { public static readonly NumericInst V128Not = new(SimdCode.V128Not, ExecuteV128Not, - ValidateOperands(pop: ValType.V128, push: ValType.V128)); + ValidateOperands(pop: ValType.V128, push: ValType.V128), 0); private static void ExecuteV128Not(ExecContext context) { diff --git a/Wacs.Core/Instructions/SpecFactory/SpecFactory.cs b/Wacs.Core/Instructions/SpecFactory/SpecFactory.cs index 2467420a..df0f7a9e 100644 --- a/Wacs.Core/Instructions/SpecFactory/SpecFactory.cs +++ b/Wacs.Core/Instructions/SpecFactory/SpecFactory.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using Wacs.Core.Instructions.Memory; @@ -43,8 +41,8 @@ public T CreateInstruction(ByteCode code) OpCode.Block => new InstBlock(), OpCode.Loop => new InstLoop(), OpCode.If => new InstIf(), - OpCode.Else => InstElse.Inst, - OpCode.End => InstEnd.Inst, + OpCode.Else => new InstElse(), + OpCode.End => new InstEnd(), OpCode.TryTable => new InstTryTable(), OpCode.Throw => new InstThrow(), @@ -54,7 +52,7 @@ public T CreateInstruction(ByteCode code) OpCode.BrIf => new InstBranchIf(), OpCode.BrTable => new InstBranchTable(), - OpCode.Return => InstReturn.Inst, + OpCode.Return => new InstReturn(), OpCode.Call => new InstCall(), OpCode.CallIndirect => new InstCallIndirect(), OpCode.CallRef => new InstCallRef(), diff --git a/Wacs.Core/Instructions/SpecFactory/SpecFactoryFB.cs b/Wacs.Core/Instructions/SpecFactory/SpecFactoryFB.cs index cc378bf2..2f32025b 100644 --- a/Wacs.Core/Instructions/SpecFactory/SpecFactoryFB.cs +++ b/Wacs.Core/Instructions/SpecFactory/SpecFactoryFB.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System.IO; using Wacs.Core.Instructions.GC; diff --git a/Wacs.Core/Instructions/SpecFactory/SpecFactoryFC.cs b/Wacs.Core/Instructions/SpecFactory/SpecFactoryFC.cs index 0dcfef1d..3c6adc16 100644 --- a/Wacs.Core/Instructions/SpecFactory/SpecFactoryFC.cs +++ b/Wacs.Core/Instructions/SpecFactory/SpecFactoryFC.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System.IO; using Wacs.Core.Instructions.Numeric; diff --git a/Wacs.Core/Instructions/SpecFactory/SpecFactoryFD.cs b/Wacs.Core/Instructions/SpecFactory/SpecFactoryFD.cs index 9bb97d26..54783081 100644 --- a/Wacs.Core/Instructions/SpecFactory/SpecFactoryFD.cs +++ b/Wacs.Core/Instructions/SpecFactory/SpecFactoryFD.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System.IO; using Wacs.Core.Instructions.Numeric; diff --git a/Wacs.Core/Instructions/SpecFactory/SpecFactoryFE.cs b/Wacs.Core/Instructions/SpecFactory/SpecFactoryFE.cs index 35533de8..e4c0f85e 100644 --- a/Wacs.Core/Instructions/SpecFactory/SpecFactoryFE.cs +++ b/Wacs.Core/Instructions/SpecFactory/SpecFactoryFE.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System.IO; using Wacs.Core.OpCodes; diff --git a/Wacs.Core/Instructions/Table.cs b/Wacs.Core/Instructions/Table.cs index 4daa4b82..0a8382f6 100644 --- a/Wacs.Core/Instructions/Table.cs +++ b/Wacs.Core/Instructions/Table.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System.IO; using Wacs.Core.OpCodes; @@ -37,11 +35,11 @@ public class InstTableGet : InstructionBase public override void Validate(IWasmValidationContext context) { context.Assert(context.Tables.Contains(X), - "Instruction table.get failed to get table {0} from context",X); + "Instruction table.get failed to get table {0} from context",X); var type = context.Tables[X]; var at = type.Limits.AddressType; - context.OpStack.PopType(at.ToValType()); - context.OpStack.PushType(type.ElementType); + context.OpStack.PopType(at.ToValType()); // -1 + context.OpStack.PushType(type.ElementType); // +0 } // @Spec 4.4.6.1. table.get @@ -51,18 +49,18 @@ public static void ExecuteInstruction(ExecContext context, TableIdx tableIndex) { //2. context.Assert( context.Frame.Module.TableAddrs.Contains(tableIndex), - $"Instruction table.get could not address table {tableIndex}"); + $"Instruction table.get could not address table {tableIndex}"); //3. var a = context.Frame.Module.TableAddrs[tableIndex]; //4. context.Assert( context.Store.Contains(a), - $"Instruction table.get failed to get table at address {a} from Store"); + $"Instruction table.get failed to get table at address {a} from Store"); //5. var tab = context.Store[a]; //6. context.Assert( context.OpStack.Peek().IsInt, - $"Instruction table.get failed. Wrong type on stack."); + $"Instruction table.get failed. Wrong type on stack."); //7. long i = context.OpStack.PopAddr(); //8. @@ -92,16 +90,17 @@ public class InstTableSet : InstructionBase { private TableIdx X; public override ByteCode Op => OpCode.TableSet; + public override int StackDiff => -2; // @Spec 3.3.6.2. table.set public override void Validate(IWasmValidationContext context) { context.Assert(context.Tables.Contains(X), - "Instruction table.set failed to get table {0} from context", X); + "Instruction table.set failed to get table {0} from context", X); var type = context.Tables[X]; var at = type.Limits.AddressType; - context.OpStack.PopType(type.ElementType); - context.OpStack.PopType(at.ToValType()); + context.OpStack.PopType(type.ElementType); // -1 + context.OpStack.PopType(at.ToValType()); // -2 } // @Spec 4.4.6.2. table.set @@ -111,23 +110,23 @@ public static void ExecuteInstruction(ExecContext context, TableIdx tableIndex) { //2. context.Assert( context.Frame.Module.TableAddrs.Contains(tableIndex), - $"Instruction table.get could not address table {tableIndex}"); + $"Instruction table.get could not address table {tableIndex}"); //3. var a = context.Frame.Module.TableAddrs[tableIndex]; //4. context.Assert( context.Store.Contains(a), - $"Instruction table.set failed to get table at address {a} from Store"); + $"Instruction table.set failed to get table at address {a} from Store"); //5. var tab = context.Store.GetMutableTable(a); //6. context.Assert( context.OpStack.Peek().IsRefType, - $"Instruction table.set found non reftype on top of the Stack"); + $"Instruction table.set found non reftype on top of the Stack"); //7. var val = context.OpStack.PopRefType(); //8. context.Assert( context.OpStack.Peek().IsInt, - $"Instruction table.set found incorrect type on top of the Stack"); + $"Instruction table.set found incorrect type on top of the Stack"); //9. long i = context.OpStack.PopAddr(); //10. @@ -156,23 +155,24 @@ public class InstTableInit : InstructionBase private TableIdx X; private ElemIdx Y; public override ByteCode Op => ExtCode.TableInit; + public override int StackDiff => -3; // @Spec 3.3.6.7. table.init x y public override void Validate(IWasmValidationContext context) { context.Assert(context.Tables.Contains(X), - "Instruction table.init is invalid. Table {0} not in the Context.", X); + "Instruction table.init is invalid. Table {0} not in the Context.", X); var t1 = context.Tables[X]; context.Assert(context.Elements.Contains(Y), - "Instruction table.init is invalid. Element {0} not in the Context.",Y); + "Instruction table.init is invalid. Element {0} not in the Context.",Y); var t2 = context.Elements[Y]; context.Assert(t2.Type.Matches(t1.ElementType, context.Types), - "Instruction table.init is invalid. Type mismatch {0} != {1}",t1.ElementType,t2.Type); - context.OpStack.PopI32(); - context.OpStack.PopI32(); + "Instruction table.init is invalid. Type mismatch {0} != {1}",t1.ElementType,t2.Type); + context.OpStack.PopI32(); // -1 + context.OpStack.PopI32(); // -2 var at = t1.Limits.AddressType; - context.OpStack.PopType(at.ToValType()); + context.OpStack.PopType(at.ToValType()); // -3 } // @Spec 4.4.6.7. table.init x y @@ -180,7 +180,7 @@ public override void Execute(ExecContext context) { //2. context.Assert( context.Frame.Module.TableAddrs.Contains(X), - $"Instruction table.init failed. Table address not found in the context."); + $"Instruction table.init failed. Table address not found in the context."); //3. var ta = context.Frame.Module.TableAddrs[X]; //4. @@ -190,7 +190,7 @@ public override void Execute(ExecContext context) var at = tab.Type.Limits.AddressType; //6. context.Assert( context.Frame.Module.ElemAddrs.Contains(Y), - $"Instruction table.init failed. Element address not found in the context."); + $"Instruction table.init failed. Element address not found in the context."); //7. var ea = context.Frame.Module.ElemAddrs[Y]; //8. @@ -198,57 +198,39 @@ public override void Execute(ExecContext context) //9. var elem = context.Store[ea]; - //Tail recursive call alternative loop + //10. + context.Assert( context.OpStack.Peek().IsI32, + $"Instruction {Op.GetMnemonic()} failed. Expected i32 on top of the stack."); + //11. + long n = (uint)context.OpStack.PopI32(); + //12. + context.Assert( context.OpStack.Peek().IsI32, + $"Instruction {Op.GetMnemonic()} failed. Expected i32 on top of the stack."); + //13. + long s = (uint)context.OpStack.PopI32(); + //14. + context.Assert( context.OpStack.Peek().IsInt, + $"Instruction {Op.GetMnemonic()} found incorrect type on top of the Stack"); + //15. + long d = context.OpStack.PopAddr(); + + if (s + n > elem.Elements.Count || d + n > tab.Elements.Count) + { + throw new OutOfBoundsTableAccessException("Trap in table.init"); + } + + //Tail recursive call alternative loop, inline tableset while (true) { - //10. - context.Assert( context.OpStack.Peek().IsI32, - $"Instruction {Op.GetMnemonic()} failed. Expected i32 on top of the stack."); - //11. - long n = (uint)context.OpStack.PopI32(); - //12. - context.Assert( context.OpStack.Peek().IsI32, - $"Instruction {Op.GetMnemonic()} failed. Expected i32 on top of the stack."); - //13. - long s = (uint)context.OpStack.PopI32(); - //14. - context.Assert( context.OpStack.Peek().IsInt, - $"Instruction {Op.GetMnemonic()} found incorrect type on top of the Stack"); - //15. - long d = context.OpStack.PopAddr(); - //16. - if (s + n > elem.Elements.Count || d + n > tab.Elements.Count) - { - throw new OutOfBoundsTableAccessException("Trap in table.init"); - } - else if (n == 0) - { + if (n == 0) return; - } - //18. - var val = elem.Elements[(int)s]; - //19. - context.OpStack.PushValue(new Value(at, d)); - //20. - context.OpStack.PushRef(val); - //21. - InstTableSet.ExecuteInstruction(context, X); - //22. - long check = d + 1L; - context.Assert( check < Constants.TwoTo32, - $"Instruction {Op.GetMnemonic()} failed. Invalid table size"); - //23. - context.OpStack.PushValue(new Value(at, d + 1L)); - //24. - check = s + 1L; - context.Assert( check < Constants.TwoTo32, - $"Instruction {Op.GetMnemonic()} failed. Invalid table size"); - //25. - context.OpStack.PushU32((uint)(s + 1L)); - //26. - context.OpStack.PushU32((uint)(n - 1L)); - //27. + //Set table element direct + tab.Elements[(int)d] = elem.Elements[(int)s]; + + d += 1L; + s += 1L; + n -= 1L; } } @@ -281,7 +263,7 @@ public class InstElemDrop : InstructionBase public override void Validate(IWasmValidationContext context) { context.Assert(context.Elements.Contains(X), - "Instruction elem.drop is invalid. Element {0} was not in the Context",X); + "Instruction elem.drop is invalid. Element {0} was not in the Context",X); } // @Spec 4.4.6.8. elem.drop x @@ -289,12 +271,12 @@ public override void Execute(ExecContext context) { //2. context.Assert( context.Frame.Module.ElemAddrs.Contains(X), - $"Instruction elem.drop failed. Element {X} was not in the context"); + $"Instruction elem.drop failed. Element {X} was not in the context"); //3. var a = context.Frame.Module.ElemAddrs[X]; //4. context.Assert( context.Store.Contains(a), - $"Instruction elem.drop failed. Element {a} was not in the Store."); + $"Instruction elem.drop failed. Element {a} was not in the Store."); //5. context.Store.DropElement(a); } @@ -321,26 +303,27 @@ public class InstTableCopy : InstructionBase private TableIdx DstX; private TableIdx SrcY; public override ByteCode Op => ExtCode.TableCopy; + public override int StackDiff => -3; // @Spec 3.3.6.6. table.copy public override void Validate(IWasmValidationContext context) { context.Assert(context.Tables.Contains(DstX), - "Instruction table.copy failed. Table index {0} does not exist in Context",DstX); + "Instruction table.copy failed. Table index {0} does not exist in Context",DstX); var t1 = context.Tables[DstX]; context.Assert(context.Tables.Contains(SrcY), - "Instruction table.copy failed. Table index {0} does not exist in Context",SrcY); + "Instruction table.copy failed. Table index {0} does not exist in Context",SrcY); var t2 = context.Tables[SrcY]; context.Assert(t2.ElementType.Matches(t1.ElementType, context.Types), - "Instruction table.copy failed. Table type mismatch {0} != {1}",t1.ElementType,t2.ElementType); + "Instruction table.copy failed. Table type mismatch {0} != {1}",t1.ElementType,t2.ElementType); var at1 = t1.Limits.AddressType; var at2 = t2.Limits.AddressType; var at = at1.Min(at2); - context.OpStack.PopType(at.ToValType()); - context.OpStack.PopType(at2.ToValType()); - context.OpStack.PopType(at1.ToValType()); + context.OpStack.PopType(at.ToValType()); // -1 + context.OpStack.PopType(at2.ToValType()); // -2 + context.OpStack.PopType(at1.ToValType()); // -3 } // @Spec 4.4.6.6. table.copy @@ -348,23 +331,23 @@ public override void Execute(ExecContext context) { //2. context.Assert( context.Frame.Module.TableAddrs.Contains(DstX), - $"Instruction table.copy did not find source table {DstX} in the Context"); + $"Instruction table.copy did not find source table {DstX} in the Context"); //3. var taX = context.Frame.Module.TableAddrs[DstX]; //4. context.Assert( context.Store.Contains(taX), - $"Instruction table.copy failed. Address was not present in the Store."); + $"Instruction table.copy failed. Address was not present in the Store."); //5. var tabX = context.Store.GetMutableTable(taX); var atD = tabX.Type.Limits.AddressType; //6. context.Assert( context.Frame.Module.TableAddrs.Contains(SrcY), - $"Instruction table.copy did not find destination table {SrcY} in the Context"); + $"Instruction table.copy did not find destination table {SrcY} in the Context"); //7. var taY = context.Frame.Module.TableAddrs[SrcY]; //8. context.Assert( context.Store.Contains(taY), - $"Instruction table.copy failed. Address was not present in the Store."); + $"Instruction table.copy failed. Address was not present in the Store."); //9. var tabY = context.Store[taY]; var atS = tabY.Type.Limits.AddressType; @@ -409,11 +392,11 @@ public override void Execute(ExecContext context) InstTableSet.ExecuteInstruction(context, DstX); long check = d + 1L; context.Assert( check < Constants.TwoTo32, - "Instruction table.copy failed. Table size overflow"); + "Instruction table.copy failed. Table size overflow"); context.OpStack.PushValue(new Value(atD, d + 1L)); check = s + 1L; context.Assert( check < Constants.TwoTo32, - "Instruction table.copy failed. Table size overflow"); + "Instruction table.copy failed. Table size overflow"); context.OpStack.PushValue(new Value(atS, s + 1L)); } //19. @@ -421,11 +404,11 @@ public override void Execute(ExecContext context) { long check = d + n - 1L; context.Assert( check < Constants.TwoTo32, - "Intruction table.copy failed. Table size overflow"); + "Intruction table.copy failed. Table size overflow"); context.OpStack.PushValue(new Value(atD, d + n - 1L)); check = (long)s + n - 1; context.Assert( check < Constants.TwoTo32, - "Intruction table.copy failed. Table size overflow"); + "Intruction table.copy failed. Table size overflow"); context.OpStack.PushValue(new Value(atS, s + n - 1L)); InstTableGet.ExecuteInstruction(context, SrcY); InstTableSet.ExecuteInstruction(context, DstX); @@ -455,18 +438,19 @@ public class InstTableGrow : InstructionBase { private TableIdx X; public override ByteCode Op => ExtCode.TableGrow; + public override int StackDiff => -1; // @Spec 3.3.6.4. table.grow x public override void Validate(IWasmValidationContext context) { context.Assert(context.Tables.Contains(X), - "Instruction table.grow failed to get table {0} from context",X); + "Instruction table.grow failed to get table {0} from context",X); var type = context.Tables[X]; var at = type.Limits.AddressType; - context.OpStack.PopType(at.ToValType()); - context.OpStack.PopType(type.ElementType); - context.OpStack.PushType(at.ToValType()); + context.OpStack.PopType(at.ToValType()); // -1 + context.OpStack.PopType(type.ElementType); // -2 + context.OpStack.PushType(at.ToValType()); // -1 } // @Spec 4.4.6.4. table.grow x @@ -474,13 +458,13 @@ public override void Execute(ExecContext context) { //2. context.Assert( context.Frame.Module.TableAddrs.Contains(X), - $"Instruction table.get could not address table {X}"); + $"Instruction table.get could not address table {X}"); //3. var addr = context.Frame.Module.TableAddrs[X]; //4. context.Assert( context.Store.Contains(addr), - $"Instruction table.set failed to get table at address {addr} from Store"); + $"Instruction table.set failed to get table at address {addr} from Store"); //5. var tab = context.Store.GetMutableTable(addr); var at = tab.Type.Limits.AddressType; @@ -488,12 +472,12 @@ public override void Execute(ExecContext context) long sz = tab.Elements.Count; //7. context.Assert( context.OpStack.Peek().IsInt, - $"Instruction {Op.GetMnemonic()} found incorrect type on top of the Stack"); + $"Instruction {Op.GetMnemonic()} found incorrect type on top of the Stack"); //8. long n = context.OpStack.PopAddr(); //9. context.Assert( context.OpStack.Peek().IsRefType, - $"Instruction {Op.GetMnemonic()} found incorrect type on top of the Stack"); + $"Instruction {Op.GetMnemonic()} found incorrect type on top of the Stack"); //10. var val = context.OpStack.PopRefType(); //12, 13. TODO: implement optional constraints on table.grow @@ -524,15 +508,16 @@ public class InstTableSize : InstructionBase { private TableIdx X; public override ByteCode Op => ExtCode.TableSize; + public override int StackDiff => +1; // @Spec 3.3.6.3. table.size x public override void Validate(IWasmValidationContext context) { context.Assert(context.Tables.Contains(X), - "Instruction table.set failed to get table {0} from context",X); + "Instruction table.set failed to get table {0} from context",X); var table = context.Tables[X]; var at = table.Limits.AddressType; - context.OpStack.PushType(at.ToValType()); + context.OpStack.PushType(at.ToValType()); // +1 } // @Spec 4.4.6.3. table.size x @@ -540,13 +525,13 @@ public override void Execute(ExecContext context) { //2. context.Assert( context.Frame.Module.TableAddrs.Contains(X), - $"Instruction table.get could not address table {X}"); + $"Instruction table.get could not address table {X}"); //3. var addr = context.Frame.Module.TableAddrs[X]; //4. context.Assert( context.Store.Contains(addr), - $"Instruction table.set failed to get table at address {addr} from Store"); + $"Instruction table.set failed to get table at address {addr} from Store"); //5. var tab = context.Store[addr]; var at = tab.Type.Limits.AddressType; @@ -571,17 +556,18 @@ public class InstTableFill : InstructionBase { private TableIdx X; public override ByteCode Op => ExtCode.TableFill; + public override int StackDiff => -3; // @Spec 3.3.6.5. table.fill public override void Validate(IWasmValidationContext context) { context.Assert(context.Tables.Contains(X), - "Instruction table.set failed to get table {0} from context",X); + "Instruction table.set failed to get table {0} from context",X); var type = context.Tables[X]; var at = type.Limits.AddressType; - context.OpStack.PopType(at.ToValType()); - context.OpStack.PopType(type.ElementType); - context.OpStack.PopType(at.ToValType()); + context.OpStack.PopType(at.ToValType()); // -1 + context.OpStack.PopType(type.ElementType); // -2 + context.OpStack.PopType(at.ToValType()); // -3 } // @Spec 4.4.6.5. table.fill @@ -589,13 +575,13 @@ public override void Execute(ExecContext context) { //2. context.Assert( context.Frame.Module.TableAddrs.Contains(X), - $"Instruction table.get could not address table {X}"); + $"Instruction table.get could not address table {X}"); //3. var addr = context.Frame.Module.TableAddrs[X]; //4. context.Assert( context.Store.Contains(addr), - $"Instruction table.set failed to get table at address {addr} from Store"); + $"Instruction table.set failed to get table at address {addr} from Store"); //5. var tab = context.Store.GetMutableTable(addr); var at = tab.Type.Limits.AddressType; @@ -605,17 +591,17 @@ public override void Execute(ExecContext context) { //6. context.Assert( context.OpStack.Peek().IsInt, - $"Instruction {Op.GetMnemonic()} found incorrect type on top of the Stack"); + $"Instruction {Op.GetMnemonic()} found incorrect type on top of the Stack"); //7. long n = context.OpStack.PopAddr(); //8. context.Assert( context.OpStack.Peek().IsRefType, - $"Instruction {Op.GetMnemonic()} found incorrect type on top of the Stack"); + $"Instruction {Op.GetMnemonic()} found incorrect type on top of the Stack"); //9. var val = context.OpStack.PopRefType(); //10. context.Assert( context.OpStack.Peek().IsInt, - $"Instruction {Op.GetMnemonic()} found incorrect type on top of the Stack"); + $"Instruction {Op.GetMnemonic()} found incorrect type on top of the Stack"); //11. long i = context.OpStack.PopAddr(); //12. diff --git a/Wacs.Core/Instructions/TailCall.cs b/Wacs.Core/Instructions/TailCall.cs index 2c3b99b6..3ace4ee5 100644 --- a/Wacs.Core/Instructions/TailCall.cs +++ b/Wacs.Core/Instructions/TailCall.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System.Collections.Generic; using System.IO; @@ -74,6 +72,30 @@ public override void Validate(IWasmValidationContext context) context.SetUnreachable(); } + public override InstructionBase Link(ExecContext context, int pointer) + { + context.Assert( context.Frame.Module.FuncAddrs.Contains(X), + $"Instruction call failed. Function address for {X} was not in the Context."); + var linkedX = context.Frame.Module.FuncAddrs[X]; + var inst = context.Store[linkedX]; + IsAsync = inst switch + { + FunctionInstance => false, + HostFunction hostFunction => hostFunction.IsAsync, + _ => IsAsync + }; + + var funcType = inst.Type; + int stack = context.LinkOpStackHeight; + context.LinkOpStackHeight -= funcType.ParameterTypes.Arity; + context.LinkOpStackHeight += funcType.ResultType.Arity; + //For recordkeeping + StackDiff = context.LinkOpStackHeight - stack; + + context.LinkUnreachable = true; + return this; + } + // @Spec 4.4.8.10. call public override void Execute(ExecContext context) { @@ -241,6 +263,31 @@ public override void Validate(IWasmValidationContext context) context.SetUnreachable(); } + public override InstructionBase Link(ExecContext context, int pointer) + { + context.Assert( context.Frame.Module.TableAddrs.Contains(X), + $"Instruction call_indirect failed. Table {X} was not in the Context."); + var ta = context.Frame.Module.TableAddrs[X]; + context.Assert( context.Store.Contains(ta), + $"Instruction call_indirect failed. TableInstance {ta} was not in the Store."); + var tab = context.Store[ta]; + context.Assert( context.Frame.Module.Types.Contains(Y), + $"Instruction call_indirect failed. Function Type {Y} was not in the Context."); + var ftExpect = context.Frame.Module.Types[Y]; + var funcType = ftExpect.Expansion as FunctionType; + context.Assert(funcType, + $"Instruction {Op.GetMnemonic()} failed. Not a function type."); + + int stack = context.LinkOpStackHeight; + context.LinkOpStackHeight -= funcType.ParameterTypes.Arity; + context.LinkOpStackHeight += funcType.ResultType.Arity; + + //For recordkeeping + StackDiff = context.LinkOpStackHeight - stack; + + return this; + } + // @Spec 4.4.8.11. call_indirect public override void Execute(ExecContext context) { @@ -492,6 +539,20 @@ public override void Validate(IWasmValidationContext context) context.SetUnreachable(); } + public override InstructionBase Link(ExecContext context, int pointer) + { + var funcType = context.Frame.Module.Types[X].Expansion as FunctionType; + int stack = context.LinkOpStackHeight; + context.LinkOpStackHeight -= 1; + context.LinkOpStackHeight -= funcType!.ParameterTypes.Arity; + context.LinkOpStackHeight += funcType.ResultType.Arity; + + //For recordkeeping + StackDiff = context.LinkOpStackHeight - stack; + + return this; + } + public override void Execute(ExecContext context) { context.Assert(context.StackTopTopType() == ValType.FuncRef, diff --git a/Wacs.Core/Instructions/Transpiler/AggregateTypeCast.cs b/Wacs.Core/Instructions/Transpiler/AggregateTypeCast.cs index f6607596..1ab2873a 100644 --- a/Wacs.Core/Instructions/Transpiler/AggregateTypeCast.cs +++ b/Wacs.Core/Instructions/Transpiler/AggregateTypeCast.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using Wacs.Core.Runtime; @@ -49,10 +47,12 @@ public abstract class WrapValue : ITypedValueProducer private readonly ITypedValueProducer _inA; protected Func _func = null!; - + public int StackDiff { get; set; } + protected WrapValue(ITypedValueProducer inA) { _inA = inA; + StackDiff = Math.Min(0, inA.StackDiff); } public int CalculateSize() => _inA.CalculateSize(); @@ -134,10 +134,11 @@ public WrapValueV128(ITypedValueProducer inA) : base(inA) public abstract class UnwrapValue : ITypedValueProducer { protected ITypedValueProducer InA; - + public int StackDiff { get; set; } protected UnwrapValue(ITypedValueProducer inA) { InA = inA; + StackDiff = Math.Min(0, inA.StackDiff); } public int CalculateSize() => InA.CalculateSize(); @@ -231,10 +232,12 @@ public class CastToI32 : ITypedValueProducer where T : struct { private readonly ITypedValueProducer _inA; + public int StackDiff { get; set; } public CastToI32(ITypedValueProducer inA) { _inA = inA; + StackDiff = Math.Min(0, inA.StackDiff); if (typeof(T) == typeof(int)) { GetFunc = ((ITypedValueProducer)_inA).GetFunc; @@ -258,10 +261,12 @@ public class CastToU32 : ITypedValueProducer where T : struct { private readonly ITypedValueProducer _inA; + public int StackDiff { get; set; } public CastToU32(ITypedValueProducer inA) { _inA = inA; + StackDiff = Math.Min(0, inA.StackDiff); if (typeof(T) == typeof(uint)) { GetFunc = ((ITypedValueProducer)_inA).GetFunc; @@ -285,10 +290,12 @@ public class CastToI64 : ITypedValueProducer where T : struct { private readonly ITypedValueProducer _inA; + public int StackDiff { get; set; } public CastToI64(ITypedValueProducer inA) { _inA = inA; + StackDiff = Math.Min(0, inA.StackDiff); if (typeof(T) == typeof(long)) { GetFunc = ((ITypedValueProducer)_inA).GetFunc; @@ -312,10 +319,12 @@ public class CastToU64 : ITypedValueProducer where T : struct { private readonly ITypedValueProducer _inA; + public int StackDiff { get; set; } public CastToU64(ITypedValueProducer inA) { _inA = inA; + StackDiff = Math.Min(0, inA.StackDiff); if (typeof(T) == typeof(ulong)) { GetFunc = ((ITypedValueProducer)_inA).GetFunc; diff --git a/Wacs.Core/Instructions/Transpiler/InstAggregate1_0.cs b/Wacs.Core/Instructions/Transpiler/InstAggregate1_0.cs index 1eff34b4..9aada0a2 100644 --- a/Wacs.Core/Instructions/Transpiler/InstAggregate1_0.cs +++ b/Wacs.Core/Instructions/Transpiler/InstAggregate1_0.cs @@ -1,20 +1,19 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; +using System.Collections.Generic; using Wacs.Core.OpCodes; using Wacs.Core.Runtime; using Wacs.Core.Validation; @@ -25,10 +24,18 @@ public class InstAggregate1_0 : InstructionBase { private readonly Action _compute; private readonly Func _inA; + public sealed override int StackDiff { get; set; } + private List linkDependents = new(); + public InstAggregate1_0(ITypedValueProducer inA, INodeConsumer consumer) { _inA = inA.GetFunc; + StackDiff = Math.Min(0, inA.StackDiff); + + if (consumer is IComplexLinkBehavior) + linkDependents.Add((consumer as InstructionBase)!); + _compute = consumer.GetFunc; Size = inA.CalculateSize() + 1; @@ -41,6 +48,18 @@ public override void Validate(IWasmValidationContext context) context.Assert(false, "Validation of transpiled instructions not supported."); } + public override InstructionBase Link(ExecContext context, int pointer) + { + base.Link(context, pointer); + int stack = context.LinkOpStackHeight; + + foreach (var dependent in linkDependents) + dependent.Link(context, pointer); + + context.LinkOpStackHeight = stack; + return this; + } + public override void Execute(ExecContext context) { _compute(context, _inA(context)); diff --git a/Wacs.Core/Instructions/Transpiler/InstAggregate1_1.cs b/Wacs.Core/Instructions/Transpiler/InstAggregate1_1.cs index 6c31017c..d02f5120 100644 --- a/Wacs.Core/Instructions/Transpiler/InstAggregate1_1.cs +++ b/Wacs.Core/Instructions/Transpiler/InstAggregate1_1.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.IO; @@ -28,10 +26,12 @@ public class InstAggregate1_1 : InstructionBase, ITypedValueProducer _compute; private readonly Func _in1; private readonly Func _wrap; - + public sealed override int StackDiff { get; set; } + public InstAggregate1_1(ITypedValueProducer in1, INodeComputer compute) { _in1 = in1.GetFunc; + StackDiff = Math.Min(0, in1.StackDiff); _compute = compute.GetFunc; Size = in1.CalculateSize() + 1; @@ -59,6 +59,13 @@ public override void Validate(IWasmValidationContext context) context.Assert(false, "Validation of transpiled instructions not supported."); } + public override InstructionBase Link(ExecContext context, int pointer) + { + //Account for our own push to the stack if we're not subordinated + context.LinkOpStackHeight += StackDiff + 1; + return this; + } + public override void Execute(ExecContext context) { context.OpStack.PushValue(_wrap(context)); diff --git a/Wacs.Core/Instructions/Transpiler/InstAggregate2_0.cs b/Wacs.Core/Instructions/Transpiler/InstAggregate2_0.cs index ae1f8f26..a752be3a 100644 --- a/Wacs.Core/Instructions/Transpiler/InstAggregate2_0.cs +++ b/Wacs.Core/Instructions/Transpiler/InstAggregate2_0.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using Wacs.Core.OpCodes; @@ -26,11 +24,14 @@ public class InstAggregate2_0 : InstructionBase private readonly Action _compute; private readonly Func _in1; private readonly Func _in2; + public sealed override int StackDiff { get; set; } public InstAggregate2_0(ITypedValueProducer in1, ITypedValueProducer in2, INodeConsumer compute) { _in1 = in1.GetFunc; _in2 = in2.GetFunc; + + StackDiff = Math.Min(0, in1.StackDiff) + Math.Min(0, in2.StackDiff); _compute = compute.GetFunc; Size = in1.CalculateSize() + in2.CalculateSize() + 1; diff --git a/Wacs.Core/Instructions/Transpiler/InstAggregate2_1.cs b/Wacs.Core/Instructions/Transpiler/InstAggregate2_1.cs index 8b1ed6a0..8f4b1ce3 100644 --- a/Wacs.Core/Instructions/Transpiler/InstAggregate2_1.cs +++ b/Wacs.Core/Instructions/Transpiler/InstAggregate2_1.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.IO; @@ -29,11 +27,13 @@ public class InstAggregate2_1 : InstructionBase, ITypedValueProd private readonly Func _in1; private readonly Func _in2; private readonly Func _wrap; + public sealed override int StackDiff { get; set; } public InstAggregate2_1(ITypedValueProducer in1, ITypedValueProducer in2, INodeComputer compute) { _in1 = in1.GetFunc; _in2 = in2.GetFunc; + StackDiff = Math.Min(0, in1.StackDiff) + Math.Min(0, in2.StackDiff); _compute = compute.GetFunc; Size = in1.CalculateSize() + in2.CalculateSize() + 1; @@ -60,6 +60,12 @@ public override void Validate(IWasmValidationContext context) { context.Assert(false, "Validation of transpiled instructions not supported."); } + public override InstructionBase Link(ExecContext context, int pointer) + { + //Account for our own push to the stack if we're not subordinated + context.LinkOpStackHeight += StackDiff + 1; + return this; + } public override void Execute(ExecContext context) { diff --git a/Wacs.Core/Instructions/Transpiler/InstAggregate3_1.cs b/Wacs.Core/Instructions/Transpiler/InstAggregate3_1.cs index 77a3f9fb..e23433ba 100644 --- a/Wacs.Core/Instructions/Transpiler/InstAggregate3_1.cs +++ b/Wacs.Core/Instructions/Transpiler/InstAggregate3_1.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.IO; @@ -30,6 +28,7 @@ public class InstAggregate3_1 : InstructionBase, ITypedValu private readonly Func _in2; private readonly Func _in3; private readonly Func _wrap; + public sealed override int StackDiff { get; set; } public InstAggregate3_1( ITypedValueProducer in1, @@ -40,6 +39,7 @@ public InstAggregate3_1( _in1 = in1.GetFunc; _in2 = in2.GetFunc; _in3 = in3.GetFunc; + StackDiff = Math.Min(0, in1.StackDiff) + Math.Min(0, in2.StackDiff) + Math.Min(0, in3.StackDiff); _compute = compute.GetFunc; Size = in1.CalculateSize() + in2.CalculateSize() + 1; @@ -66,7 +66,12 @@ public override void Validate(IWasmValidationContext context) { context.Assert(false, "Validation of transpiled instructions not supported."); } - + public override InstructionBase Link(ExecContext context, int pointer) + { + //Account for our own push to the stack if we're not subordinated + context.LinkOpStackHeight += StackDiff + 1; + return this; + } public override void Execute(ExecContext context) { context.OpStack.PushValue(_wrap(context)); diff --git a/Wacs.Core/Instructions/Transpiler/InstCompoundIf.cs b/Wacs.Core/Instructions/Transpiler/InstCompoundIf.cs index dbb8156c..d7ca8de8 100644 --- a/Wacs.Core/Instructions/Transpiler/InstCompoundIf.cs +++ b/Wacs.Core/Instructions/Transpiler/InstCompoundIf.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using FluentValidation; @@ -24,14 +22,13 @@ namespace Wacs.Core.Instructions.Transpiler { - public class InstCompoundIf : BlockTarget, IBlockInstruction + public class InstCompoundIf : BlockTarget, IBlockInstruction, IIfInstruction { private static readonly ByteCode IfOp = OpCode.If; - private static readonly ByteCode ElseOp = OpCode.Else; private readonly Block ElseBlock = Block.Empty; - private readonly int ElseCount; private readonly Block IfBlock = Block.Empty; - + public sealed override int StackDiff { get; set; } + private readonly Func valueFunc; public InstCompoundIf( @@ -40,6 +37,7 @@ public InstCompoundIf( InstructionSequence elseSeq, ITypedValueProducer valueProducer) { + StackDiff = valueProducer.StackDiff; IfBlock = new Block( blockType: blockType, seq: ifSeq @@ -48,8 +46,6 @@ public InstCompoundIf( blockType: blockType, seq: elseSeq ); - ElseCount = ElseBlock.Instructions.Count; - valueFunc = valueProducer.GetFunc; } @@ -59,7 +55,7 @@ public InstCompoundIf( public int Count => ElseBlock.Length == 0 ? 1 : 2; - public int Size => 1 + IfBlock.Size + ElseBlock.Size; + public int BlockSize => 1 + IfBlock.Size + ElseBlock.Size; public Block GetBlock(int idx) => idx == 0 ? IfBlock : ElseBlock; // @Spec 3.3.8.5 if @@ -107,15 +103,11 @@ public override void Validate(IWasmValidationContext context) // @Spec 4.4.8.5. if public override void Execute(ExecContext context) { + // context.Frame.PushLabel(this); int c = valueFunc(context); - if (c != 0) - { - context.EnterBlock(this, IfBlock); - } - else + if (c == 0) { - if (ElseCount != 0) - context.EnterBlock(this, ElseBlock); + context.InstructionPointer = Else - 1; } } } diff --git a/Wacs.Core/Instructions/Transpiler/InstFusedLocalSet.cs b/Wacs.Core/Instructions/Transpiler/InstFusedLocalSet.cs index cce083ca..10d1609b 100644 --- a/Wacs.Core/Instructions/Transpiler/InstFusedLocalSet.cs +++ b/Wacs.Core/Instructions/Transpiler/InstFusedLocalSet.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using Wacs.Core.OpCodes; using Wacs.Core.Runtime; diff --git a/Wacs.Core/Instructions/Transpiler/InstI32Fused.cs b/Wacs.Core/Instructions/Transpiler/InstI32Fused.cs index 7d70cba9..d8610fe4 100644 --- a/Wacs.Core/Instructions/Transpiler/InstI32Fused.cs +++ b/Wacs.Core/Instructions/Transpiler/InstI32Fused.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using Wacs.Core.Instructions.Transpiler; @@ -30,6 +28,7 @@ public abstract class InstFusedI32Const : InstructionBase, ITypedValueProducer _execute = null!; + protected InstFusedI32Const(ITypedValueProducer prev, int constant) { _previous = prev.GetFunc; @@ -41,6 +40,7 @@ protected InstFusedI32Const(ITypedValueProducer prev, int constant) public Func GetFunc => _execute; public override void Validate(IWasmValidationContext context) => _validate(context); + public sealed override int StackDiff => +1; public override void Execute(ExecContext context) { @@ -90,7 +90,8 @@ protected InstFusedU32Const(ITypedValueProducer prev, uint constant) public Func GetFunc => _execute; public override void Validate(IWasmValidationContext context) => _validate(context); - + public sealed override int StackDiff => +1; + public override void Execute(ExecContext context) { context.OpStack.PushU32(_execute(context)); diff --git a/Wacs.Core/Instructions/Transpiler/InstI64Fused.cs b/Wacs.Core/Instructions/Transpiler/InstI64Fused.cs index 23d857cf..05488c2b 100644 --- a/Wacs.Core/Instructions/Transpiler/InstI64Fused.cs +++ b/Wacs.Core/Instructions/Transpiler/InstI64Fused.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using Wacs.Core.Instructions.Transpiler; @@ -41,6 +39,7 @@ protected InstFusedI64Const(ITypedValueProducer prev, long constant) public Func GetFunc => _execute; public override void Validate(IWasmValidationContext context) => _validate(context); + public sealed override int StackDiff => +1; public override void Execute(ExecContext context) { @@ -90,6 +89,7 @@ protected InstFusedU64Const(ITypedValueProducer prev, ulong constant) public Func GetFunc => _execute; public override void Validate(IWasmValidationContext context) => _validate(context); + public sealed override int StackDiff => +1; public override void Execute(ExecContext context) { diff --git a/Wacs.Core/Instructions/Transpiler/InstStackProducer.cs b/Wacs.Core/Instructions/Transpiler/InstStackProducer.cs index 415e1c8f..8db1bd76 100644 --- a/Wacs.Core/Instructions/Transpiler/InstStackProducer.cs +++ b/Wacs.Core/Instructions/Transpiler/InstStackProducer.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using Wacs.Core.OpCodes; @@ -44,6 +42,7 @@ public override void Validate(IWasmValidationContext context) { context.OpStack.PopAny(); } + public override int StackDiff => -1; public override void Execute(ExecContext context) {} } @@ -70,6 +69,7 @@ public override void Validate(IWasmValidationContext context) { context.OpStack.PopI32(); } + public override int StackDiff => -1; public override void Execute(ExecContext context) {} } @@ -96,6 +96,7 @@ public override void Validate(IWasmValidationContext context) { context.OpStack.PopI32(); } + public override int StackDiff => -1; public override void Execute(ExecContext context) {} } diff --git a/Wacs.Core/Instructions/Transpiler/Interfaces.cs b/Wacs.Core/Instructions/Transpiler/Interfaces.cs index 4e691e01..c9af21a3 100644 --- a/Wacs.Core/Instructions/Transpiler/Interfaces.cs +++ b/Wacs.Core/Instructions/Transpiler/Interfaces.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using Wacs.Core.Runtime; @@ -22,6 +20,7 @@ namespace Wacs.Core.Instructions.Transpiler public interface InstructionBaseAnalog { public int CalculateSize(); + public int StackDiff { get; } } @@ -31,8 +30,11 @@ public interface ITypedValueProducer : InstructionBaseAnalog, IConvertabl { public Func GetFunc { get; } } - - public interface IOptimizationTarget {} + + public interface IOptimizationTarget + { + public int StackDiff { get; } + } public interface IValueConsumer {} public interface IValueConsumer {} diff --git a/Wacs.Core/Modules/IRenderable.cs b/Wacs.Core/Modules/IRenderable.cs index de3f228e..57ce042d 100644 --- a/Wacs.Core/Modules/IRenderable.cs +++ b/Wacs.Core/Modules/IRenderable.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System.IO; diff --git a/Wacs.Core/Modules/InstructionSequence.cs b/Wacs.Core/Modules/InstructionSequence.cs index c96d79e6..1ca2b1d3 100644 --- a/Wacs.Core/Modules/InstructionSequence.cs +++ b/Wacs.Core/Modules/InstructionSequence.cs @@ -1,21 +1,20 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System.Collections; using System.Collections.Generic; +using System.IO; using System.Linq; using Wacs.Core.Instructions; using Wacs.Core.OpCodes; @@ -33,14 +32,28 @@ public class InstructionSequence : IEnumerable public static readonly InstructionSequence Empty = new(new List()); //public for direct array access on critical path - public readonly InstructionBase[] _instructions; + public readonly List _instructions; - public readonly int Count; + public int Count; - public InstructionSequence(IList list) + public InstructionSequence() { - _instructions = list.Cast().ToArray(); - Count = _instructions.Length; + _instructions = new(); + } + + public InstructionSequence(IList list, bool functionEnd = false) + { + _instructions = list.ToList(); + + if (functionEnd) + { + var last = _instructions.Last(); + if (last is not InstEnd instEnd) + throw new InvalidDataException("Instuction Sequence expected an end instruction"); + instEnd.FunctionEnd = true; + } + + Count = _instructions.Count; } public InstructionBase? this[int index] @@ -67,7 +80,7 @@ public int Size for (int index = 0; index < Count; index++) { var inst = _instructions[index]; - sum += inst is IBlockInstruction blockInst ? blockInst.Size : 1; + sum += inst is IBlockInstruction blockInst ? blockInst.BlockSize : 1; } return sum; } @@ -106,5 +119,11 @@ public bool ContainsInstruction(HashSet opcodes) return false; } + + public void Append(IEnumerable seq) + { + _instructions.AddRange(seq); + Count = _instructions.Count; + } } } \ No newline at end of file diff --git a/Wacs.Core/Modules/Module.cs b/Wacs.Core/Modules/Module.cs index d0b4941b..09ab367a 100644 --- a/Wacs.Core/Modules/Module.cs +++ b/Wacs.Core/Modules/Module.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Collections.Generic; @@ -346,14 +344,14 @@ private static void FinalizeModule(Module module) .SelectMany(global => global.Initializer.Instructions) .OfType(); foreach (var refFunc in globalIni) fullyDeclared.Add(refFunc.FunctionIndex); - + + bool lacksMemoryInit = module.DataCount == uint.MaxValue; foreach (var func in module.Funcs) { - if (func.Body.ContainsInstructions(MemoryInstructions)) - { - if (module.DataCount == uint.MaxValue) + if (lacksMemoryInit) + if (func.Body.ContainsInstructions(MemoryInstructions)) throw new FormatException($"memory.init instruction requires Data Count section"); - } + if (fullyDeclared.Contains(func.Index)) func.ElementDeclared = true; } diff --git a/Wacs.Core/Modules/ModuleRenderer.cs b/Wacs.Core/Modules/ModuleRenderer.cs index b8176be8..ed7bd465 100644 --- a/Wacs.Core/Modules/ModuleRenderer.cs +++ b/Wacs.Core/Modules/ModuleRenderer.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Collections.Generic; @@ -21,7 +19,6 @@ using System.Text; using System.Text.RegularExpressions; using Wacs.Core.Instructions; -using Wacs.Core.Instructions.Reference; using Wacs.Core.OpCodes; using Wacs.Core.Types; @@ -118,7 +115,7 @@ public void RenderText(StreamWriter writer, Module module, string indent) var inst = seq[i]; if (inst is IBlockInstruction blockInstruction) { - line += blockInstruction.Size; + line += blockInstruction.BlockSize; } else { diff --git a/Wacs.Core/Modules/Sections/CodeSection.cs b/Wacs.Core/Modules/Sections/CodeSection.cs index 92ad04a5..e3e8ef21 100644 --- a/Wacs.Core/Modules/Sections/CodeSection.cs +++ b/Wacs.Core/Modules/Sections/CodeSection.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.IO; @@ -53,7 +51,7 @@ private static (uint Number, ValType Type) ParseCompressedLocal(BinaryReader rea } public static FuncLocalsBody Parse(BinaryReader reader) => - new(reader.ParseVector(ParseCompressedLocal), Expression.Parse(reader)); + new(reader.ParseVector(ParseCompressedLocal), Expression.ParseFunc(reader)); } public class CodeDesc diff --git a/Wacs.Core/Modules/Sections/DataSection.cs b/Wacs.Core/Modules/Sections/DataSection.cs index 52399c38..d400ded6 100644 --- a/Wacs.Core/Modules/Sections/DataSection.cs +++ b/Wacs.Core/Modules/Sections/DataSection.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.IO; diff --git a/Wacs.Core/Modules/Sections/ElementSection.cs b/Wacs.Core/Modules/Sections/ElementSection.cs index 2276c402..2f6cf6e4 100644 --- a/Wacs.Core/Modules/Sections/ElementSection.cs +++ b/Wacs.Core/Modules/Sections/ElementSection.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.IO; diff --git a/Wacs.Core/Modules/Sections/ExportSection.cs b/Wacs.Core/Modules/Sections/ExportSection.cs index 13855713..705a760b 100644 --- a/Wacs.Core/Modules/Sections/ExportSection.cs +++ b/Wacs.Core/Modules/Sections/ExportSection.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.IO; @@ -147,10 +145,11 @@ public Validator() } } } - + public class TagDesc : ExportDesc { public TagIdx TagIndex { get; internal set; } + public class Validator : AbstractValidator { public Validator() diff --git a/Wacs.Core/Modules/Sections/FunctionSection.cs b/Wacs.Core/Modules/Sections/FunctionSection.cs index 0e62ae6f..91ae58c9 100644 --- a/Wacs.Core/Modules/Sections/FunctionSection.cs +++ b/Wacs.Core/Modules/Sections/FunctionSection.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System.Collections.Generic; using System.IO; @@ -39,12 +37,8 @@ public partial class Module /// public class Function : IRenderable { - public FuncIdx Index; - public bool ElementDeclared = false; - - public bool IsFullyDeclared(IWasmValidationContext ctx) => - ElementDeclared || Index.Value < ctx.FunctionIndex.Value; + public FuncIdx Index; public bool IsImport = false; public string Id { get; set; } = ""; @@ -92,6 +86,9 @@ public void RenderText(StreamWriter writer, Module module, string indent) writer.WriteLine(")"); } + public bool IsFullyDeclared(IWasmValidationContext ctx) => + ElementDeclared || Index.Value < ctx.FunctionIndex.Value; + private void RenderInstructions(StreamWriter writer, string indent, int depth, Module module, InstructionSequence seq, StackRenderer stackRenderer) { foreach (var inst in seq) diff --git a/Wacs.Core/Modules/Sections/GlobalSection.cs b/Wacs.Core/Modules/Sections/GlobalSection.cs index fcc67308..dbbd82ff 100644 --- a/Wacs.Core/Modules/Sections/GlobalSection.cs +++ b/Wacs.Core/Modules/Sections/GlobalSection.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Collections.Generic; diff --git a/Wacs.Core/Modules/Sections/ImportSection.cs b/Wacs.Core/Modules/Sections/ImportSection.cs index 116eaa1d..692d306e 100644 --- a/Wacs.Core/Modules/Sections/ImportSection.cs +++ b/Wacs.Core/Modules/Sections/ImportSection.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Collections.ObjectModel; @@ -68,7 +66,7 @@ public partial class Module .OfType() .Select(tagDesc => tagDesc.TagDef) .ToList().AsReadOnly(); - + /// /// @Spec 2.5.11. Imports /// @@ -190,7 +188,7 @@ public Validator() { public class TagDesc : ImportDesc { public TagType TagDef { get; internal set; } = null!; - + public class Validator : AbstractValidator { public Validator() diff --git a/Wacs.Core/Modules/Sections/MemorySection.cs b/Wacs.Core/Modules/Sections/MemorySection.cs index 690a723b..055f3323 100644 --- a/Wacs.Core/Modules/Sections/MemorySection.cs +++ b/Wacs.Core/Modules/Sections/MemorySection.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System.Collections.Generic; using System.IO; diff --git a/Wacs.Core/Modules/Sections/NameSubsection.cs b/Wacs.Core/Modules/Sections/NameSubsection.cs index 4a2f5d47..7e7bdd5a 100644 --- a/Wacs.Core/Modules/Sections/NameSubsection.cs +++ b/Wacs.Core/Modules/Sections/NameSubsection.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Collections.Generic; diff --git a/Wacs.Core/Modules/Sections/SectionId.cs b/Wacs.Core/Modules/Sections/SectionId.cs index ba5f1815..3f4112b5 100644 --- a/Wacs.Core/Modules/Sections/SectionId.cs +++ b/Wacs.Core/Modules/Sections/SectionId.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. namespace Wacs.Core { diff --git a/Wacs.Core/Modules/Sections/StackCalculator.cs b/Wacs.Core/Modules/Sections/StackCalculator.cs index 1a799b98..4a10fbd8 100644 --- a/Wacs.Core/Modules/Sections/StackCalculator.cs +++ b/Wacs.Core/Modules/Sections/StackCalculator.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; @@ -67,7 +65,7 @@ public void DiscardValues(ResultType types) { public Value PopI32() => _context.Pop(ValType.I32); public Value PopI64() => _context.Pop(ValType.I64); public Value PopInt() => _context.Pop(ValType.I64); - + public Value PopF32() => _context.Pop(ValType.F32); public Value PopF64() => _context.Pop(ValType.F64); public Value PopV128() => _context.Pop(ValType.V128); @@ -125,7 +123,7 @@ public class StackCalculator: IWasmValidationContext internal int stackHeight = 0; - public StackCalculator(ModuleInstance moduleInst, Module.Function func) + public StackCalculator(ModuleInstance moduleInst) { Types = new TypesSpace(moduleInst.Repr); @@ -143,22 +141,15 @@ public StackCalculator(ModuleInstance moduleInst, Module.Function func) OpStack = new CalculatorOpStack(this); - var funcType = Types[func.TypeIndex].Expansion as FunctionType; - var fakeType = new FunctionType(ResultType.Empty, funcType.ResultType); - - int capacity = funcType.ParameterTypes.Types.Length + func.Locals.Length; - var localData = new Value[capacity]; - Locals = new LocalsSpace(localData, funcType.ParameterTypes.Types, func.Locals); + Dehydrate(); - ReturnType = funcType.ResultType; - PushControlFrame(OpCode.Block, fakeType); Attributes = new RuntimeAttributes(); } public RuntimeAttributes Attributes { get; } public IValidationOpStack OpStack { get; } public FuncIdx FunctionIndex => FuncIdx.Default; - public ResultType ReturnType { get; } + public ResultType ReturnType { get; set; } public bool Unreachable { get; set; } public TypesSpace Types { get; } public FunctionsSpace Funcs { get; } @@ -166,7 +157,7 @@ public StackCalculator(ModuleInstance moduleInst, Module.Function func) public MemSpace Mems { get; } public GlobalValidationSpace Globals { get; } public TagsSpace Tags { get; } - public LocalsSpace Locals { get; } + public LocalsSpace Locals { get; set; } public ElementsSpace Elements { get; set; } public DataValidationSpace Datas { get; set; } @@ -218,6 +209,31 @@ public void Assert(bool factIsTrue, string formatString, params object[] args) { public void ValidateBlock(Block instructionBlock, int index = 0) {} public void ValidateCatches(CatchType[] catches) { } + public StackCalculator HydrateFunction(Module.Function func) + { + var funcType = Types[func.TypeIndex].Expansion as FunctionType; + var fakeType = new FunctionType(ResultType.Empty, funcType.ResultType); + + int capacity = funcType.ParameterTypes.Types.Length + func.Locals.Length; + var localData = new Value[capacity]; + Locals = new LocalsSpace(localData, funcType.ParameterTypes.Types, func.Locals); + + ReturnType = funcType.ResultType; + PushControlFrame(OpCode.Block, fakeType); + + return this; + } + + public void Dehydrate() + { + while (ControlStack.Count != 0) + ControlStack.Pop(); + stackHeight = 0; + OpStack.Clear(); + Locals = LocalsSpace.Empty; + ReturnType = ResultType.Empty; + } + public void Clear() { stackHeight = 0; diff --git a/Wacs.Core/Modules/Sections/StackRenderer.cs b/Wacs.Core/Modules/Sections/StackRenderer.cs index f80454dc..aa2e2330 100644 --- a/Wacs.Core/Modules/Sections/StackRenderer.cs +++ b/Wacs.Core/Modules/Sections/StackRenderer.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Collections.Generic; @@ -171,7 +169,7 @@ public FakeContext(Module module, Module.Function func) public void Assert(bool factIsTrue, string formatString, params object[] args) { } public void Assert([NotNull] object? objIsNotNull, string formatString, params object[] args) { objIsNotNull = NonNull; } - + public FuncIdx FunctionIndex => FuncIdx.Default; public Stack ControlStack { get; } = new(); @@ -234,7 +232,7 @@ public void SetUnreachable() public DataValidationSpace Datas { get; set; } public TagsSpace Tags { get; } - + private ExecContext BuildDummyContext(Module module, ModuleInstance moduleInst, Module.Function modFunc) { var store = new Store(); diff --git a/Wacs.Core/Modules/Sections/StartSection.cs b/Wacs.Core/Modules/Sections/StartSection.cs index ca610b04..fdb62a39 100644 --- a/Wacs.Core/Modules/Sections/StartSection.cs +++ b/Wacs.Core/Modules/Sections/StartSection.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System.IO; using Wacs.Core.Types; diff --git a/Wacs.Core/Modules/Sections/TableSection.cs b/Wacs.Core/Modules/Sections/TableSection.cs index 31532a3d..2c81e531 100644 --- a/Wacs.Core/Modules/Sections/TableSection.cs +++ b/Wacs.Core/Modules/Sections/TableSection.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System.Collections.Generic; using System.IO; diff --git a/Wacs.Core/Modules/Sections/TypeSection.cs b/Wacs.Core/Modules/Sections/TypeSection.cs index 17bfdc44..531523ab 100644 --- a/Wacs.Core/Modules/Sections/TypeSection.cs +++ b/Wacs.Core/Modules/Sections/TypeSection.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System.Collections.Generic; using System.IO; diff --git a/Wacs.Core/OpCodes/Admin.cs b/Wacs.Core/OpCodes/Admin.cs index f07bac1c..da71030c 100644 --- a/Wacs.Core/OpCodes/Admin.cs +++ b/Wacs.Core/OpCodes/Admin.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using Wacs.Core.Attributes; diff --git a/Wacs.Core/OpCodes/ByteCode.cs b/Wacs.Core/OpCodes/ByteCode.cs index 709a2a9d..868f2e9e 100644 --- a/Wacs.Core/OpCodes/ByteCode.cs +++ b/Wacs.Core/OpCodes/ByteCode.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Runtime.InteropServices; diff --git a/Wacs.Core/OpCodes/Ext.cs b/Wacs.Core/OpCodes/Ext.cs index c69fb654..7eb437d0 100644 --- a/Wacs.Core/OpCodes/Ext.cs +++ b/Wacs.Core/OpCodes/Ext.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using Wacs.Core.Attributes; diff --git a/Wacs.Core/OpCodes/Gc.cs b/Wacs.Core/OpCodes/Gc.cs index 9298b6f9..005a8094 100644 --- a/Wacs.Core/OpCodes/Gc.cs +++ b/Wacs.Core/OpCodes/Gc.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using Wacs.Core.Attributes; diff --git a/Wacs.Core/OpCodes/OpCode.cs b/Wacs.Core/OpCodes/OpCode.cs index 1c43b183..9c26e928 100644 --- a/Wacs.Core/OpCodes/OpCode.cs +++ b/Wacs.Core/OpCodes/OpCode.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using Wacs.Core.Attributes; diff --git a/Wacs.Core/OpCodes/OpCodeExtensions.cs b/Wacs.Core/OpCodes/OpCodeExtensions.cs index 63e997d9..a03feffb 100644 --- a/Wacs.Core/OpCodes/OpCodeExtensions.cs +++ b/Wacs.Core/OpCodes/OpCodeExtensions.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Collections.Concurrent; diff --git a/Wacs.Core/OpCodes/Simd.cs b/Wacs.Core/OpCodes/Simd.cs index 7f85f9e7..84f934ca 100644 --- a/Wacs.Core/OpCodes/Simd.cs +++ b/Wacs.Core/OpCodes/Simd.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using Wacs.Core.Attributes; diff --git a/Wacs.Core/OpCodes/Threads.cs b/Wacs.Core/OpCodes/Threads.cs index f96d7180..ff6e74f1 100644 --- a/Wacs.Core/OpCodes/Threads.cs +++ b/Wacs.Core/OpCodes/Threads.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using Wacs.Core.Attributes; diff --git a/Wacs.Core/Runtime/Address.cs b/Wacs.Core/Runtime/Address.cs index fd3a2fad..b61e5557 100644 --- a/Wacs.Core/Runtime/Address.cs +++ b/Wacs.Core/Runtime/Address.cs @@ -1,21 +1,18 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; -using Wacs.Core.Types.Defs; namespace Wacs.Core.Runtime { diff --git a/Wacs.Core/Runtime/Delegates.cs b/Wacs.Core/Runtime/Delegates.cs index ae0d6e26..98a30e5e 100644 --- a/Wacs.Core/Runtime/Delegates.cs +++ b/Wacs.Core/Runtime/Delegates.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Linq; @@ -32,7 +30,7 @@ public static class Delegates public delegate Task GenericFuncsAsync(params Value[] args); public delegate Value[] StackFunc(Value[] parameters); - + public static Delegate AnonymousFunctionFromType(FunctionType functionType, GenericFuncs func) { var paramTypes = functionType.ParameterTypes.Types; @@ -70,8 +68,8 @@ public static Delegate AnonymousFunctionFromType(FunctionType functionType, Gene _ => throw new NotSupportedException($"Cannot auto-bind function signature: ({string.Join(", ", paramTypes)}) -> ({string.Join(", ", resultTypes)})") }; } - - + + public static void ValidateFunctionTypeCompatibility(FunctionType functionType, Type delegateType) { if (!typeof(Delegate).IsAssignableFrom(delegateType)) @@ -175,7 +173,5 @@ public static Type ConvertValTypeToSystemType(ValType valType) _ => throw new ArgumentException($"Unsupported ValType: {valType}") }; } - - } } \ No newline at end of file diff --git a/Wacs.Core/Runtime/Exceptions/InstantiationException.cs b/Wacs.Core/Runtime/Exceptions/InstantiationException.cs index 8067df77..8f85b5c2 100644 --- a/Wacs.Core/Runtime/Exceptions/InstantiationException.cs +++ b/Wacs.Core/Runtime/Exceptions/InstantiationException.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. namespace Wacs.Core.Runtime.Exceptions { diff --git a/Wacs.Core/Runtime/Exceptions/InsufficientGasException.cs b/Wacs.Core/Runtime/Exceptions/InsufficientGasException.cs index 2f20e69f..701ce2b0 100644 --- a/Wacs.Core/Runtime/Exceptions/InsufficientGasException.cs +++ b/Wacs.Core/Runtime/Exceptions/InsufficientGasException.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using Wacs.Core.Runtime.Types; diff --git a/Wacs.Core/Runtime/Exceptions/TrapException.cs b/Wacs.Core/Runtime/Exceptions/TrapException.cs index 38109800..c2fb3c10 100644 --- a/Wacs.Core/Runtime/Exceptions/TrapException.cs +++ b/Wacs.Core/Runtime/Exceptions/TrapException.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; diff --git a/Wacs.Core/Runtime/Exceptions/UnboundEntityException.cs b/Wacs.Core/Runtime/Exceptions/UnboundEntityException.cs index 065a4dbe..605c6fd9 100644 --- a/Wacs.Core/Runtime/Exceptions/UnboundEntityException.cs +++ b/Wacs.Core/Runtime/Exceptions/UnboundEntityException.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; diff --git a/Wacs.Core/Runtime/Exceptions/WasmRuntimeException.cs b/Wacs.Core/Runtime/Exceptions/WasmRuntimeException.cs index 36d74adc..e2d45b52 100644 --- a/Wacs.Core/Runtime/Exceptions/WasmRuntimeException.cs +++ b/Wacs.Core/Runtime/Exceptions/WasmRuntimeException.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; diff --git a/Wacs.Core/Runtime/ExecContext.cs b/Wacs.Core/Runtime/ExecContext.cs index 35e3da35..7bb10bcb 100644 --- a/Wacs.Core/Runtime/ExecContext.cs +++ b/Wacs.Core/Runtime/ExecContext.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Buffers; @@ -20,7 +18,6 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Linq; -using System.Runtime.CompilerServices; using System.Threading.Tasks; using Microsoft.Extensions.ObjectPool; using Wacs.Core.Instructions; @@ -30,6 +27,7 @@ using Wacs.Core.Types; using Wacs.Core.Types.Defs; using Wacs.Core.Utilities; +using InstructionPointer = System.Int32; namespace Wacs.Core.Runtime { @@ -41,29 +39,37 @@ public struct ExecStat public class ExecContext { + // public int _sequenceCount; + + public const int AbortSequence = -2; public static readonly Frame NullFrame = new(); private static readonly ValType[] EmptyLocals = Array.Empty(); private readonly Stack _callStack; private readonly ObjectPool _framePool; - private readonly InstructionSequence _hostReturnSequence; + + private readonly Stack _linkLabelStack = new(); + // private readonly InstructionSequence _hostReturnSequence; private readonly ArrayPool _localsDataPool; public readonly RuntimeAttributes Attributes; public readonly Stopwatch InstructionTimer = new(); + + private readonly InstructionSequence linkedInstructions = new(); public readonly OpStack OpStack; public readonly Stopwatch ProcessTimer = new(); public readonly Store Store; - private InstructionSequence _currentSequence; - public int _sequenceCount; - public int _sequenceIndex; - public InstructionBase[] _sequenceInstructions; + public InstructionBase[] _currentSequence; + // public List _sequenceInstructions; + public Frame Frame = NullFrame; - public int StackHeight => _callStack.Count; + public int InstructionPointer; + public int LinkOpStackHeight; + public bool LinkUnreachable; public Dictionary Stats = new(); public long steps; @@ -80,20 +86,51 @@ public ExecContext(Store store, RuntimeAttributes? attributes = default) _callStack = new (Attributes.InitialCallStack); - _hostReturnSequence = InstructionSequence.Empty; + // _hostReturnSequence = InstructionSequence.Empty; - _currentSequence = _hostReturnSequence; - _sequenceCount = _currentSequence.Count; - _sequenceInstructions = _currentSequence._instructions; - _sequenceIndex = -1; + // _currentSequence = _hostReturnSequence; + + // _sequenceCount = _currentSequence.Count; + // _sequenceInstructions = _currentSequence._instructions; + InstructionPointer = -1; OpStack = new(Attributes.MaxOpStack); } + public int StackHeight => _callStack.Count; + public InstructionBaseFactory InstructionFactory => Attributes.InstructionFactory; public MemoryInstance DefaultMemory => Store[Frame.Module.MemAddrs[default]]; - public InstructionPointer GetPointer() => new(_currentSequence, _sequenceIndex); + + public int LabelHeight => _linkLabelStack.Count; + + public void CacheInstructions() + { + _currentSequence = linkedInstructions._instructions.ToArray(); + } + + public void PrintInstruction(int i) + { + var inst = linkedInstructions[i]; + if (inst is BlockTarget label) + { + Console.Error.WriteLine($"[0x{i:x8}] {label.Label.StackHeight} ({inst.StackDiff:+####;-####;0}) {inst}"); + } + else if (inst is InstEnd) + { + Console.Error.WriteLine($"[0x{i:x8}] {inst.StackDiff:+####;-####;0} {inst}"); + } + else + { + Console.Error.WriteLine($"[0x{i:x8}] {inst.StackDiff:+####;-####;0} {inst}"); + } + } + + public InstructionPointer GetPointer() + { + return InstructionPointer; + } [Conditional("STRICT_EXECUTION")] public void Assert([NotNull] object? objIsNotNull, string message) @@ -125,7 +162,7 @@ public Frame ReserveFrame( frame.Type = type; // frame.Labels = _labelStack.GetSubStack(); frame.Index = index; - frame.ContinuationAddress = new InstructionPointer(_currentSequence, _sequenceIndex); + frame.ContinuationAddress = InstructionPointer; frame.ClearLabels(); int capacity = type.ParameterTypes.Types.Length + locals.Length; @@ -159,12 +196,39 @@ public InstructionPointer PopFrame() return address; } + public BlockTarget? FindLabel(int depth) + { + var instructions = _currentSequence; + int ptr = InstructionPointer; + BlockTarget? label = null; + + while (ptr > Frame.Head && label == null) + { + var inst = instructions[--ptr]; + switch (inst) + { + case BlockTarget target: + label = target; + break; + case InstEnd: + depth += 1; + break; + } + } + + if (label is null && ptr == Frame.Head) + return null; + + for (int i = 0; i < depth && label != null; i++) + { + label = label?.EnclosingBlock ?? null; + } + + return label; + } + public void ResetStack(Label label) { - // for (int c = OpStack.Count, h = label.StackHeight + Frame.StackHeight; c > h; --c) - // { - // OpStack.PopAny(); - // } OpStack.PopTo(label.StackHeight + Frame.StackHeight); } @@ -176,77 +240,18 @@ public void FlushCallStack() OpStack.Clear(); Frame = NullFrame; - _currentSequence = _hostReturnSequence; - _sequenceCount = _currentSequence.Count; - _sequenceInstructions = _currentSequence._instructions; - _sequenceIndex = -1; + InstructionPointer = -1; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void EnterSequence(InstructionSequence seq) - { - _currentSequence = seq; - _sequenceCount = _currentSequence.Count; - _sequenceInstructions = _currentSequence._instructions; - _sequenceIndex = -1; - } + public void ClearLinkLabels() => _linkLabelStack.Clear(); - public void ResumeSequence(InstructionPointer pointer) - { - _currentSequence = pointer.Sequence; - _sequenceCount = _currentSequence.Count; - _sequenceInstructions = _currentSequence._instructions; - _sequenceIndex = pointer.Index; - } + public void PushLabel(BlockTarget inst) => _linkLabelStack.Push(inst); - public void FastForwardSequence() - { - //Go to penultimate instruction since we pre-increment on pointer advance. - _sequenceIndex = _sequenceCount - 2; - } + public BlockTarget PopLabel() => _linkLabelStack.Pop(); - public void RewindSequence() - { - //Go back to the first instruction in the sequence - _sequenceIndex = -1; - } + public BlockTarget PeekLabel() => _linkLabelStack.Peek(); - // @Spec 4.4.9.1. Enter Block - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void EnterBlock(BlockTarget target, Block block) - { - //HACK: Labels are a linked list with each node residing on its respective block instruction. - Frame.PushLabel(target); - //Manually inline PushLabel - // Frame.TopLabel = target; - // Frame.LabelCount++; - // Frame.Label = target.Label; - - //Sets the Pointer to the start of the block sequence - EnterSequence(block.Instructions); - //Manually inline EnterSequence - // _currentSequence = block.Instructions; - // _sequenceCount = _currentSequence.Count; - // _sequenceInstructions = _currentSequence._instructions; - // _sequenceIndex = -1; - } - // @Spec 4.4.9.2. Exit Block - public void ExitBlock() - { - var addr = Frame.PopLabels(0); - // We manage separate stacks, so we don't need to relocate the operands - // var vals = OpStack.PopResults(label.Type); - - // ResumeSequence(addr); - - //Manually inline ResumeSequence - _currentSequence = addr.Sequence; - _sequenceCount = _currentSequence.Count; - _sequenceInstructions = _currentSequence._instructions; - _sequenceIndex = addr.Index; - } - // @Spec 4.4.10.1 Function Invocation public async Task InvokeAsync(FuncAddr addr) { @@ -332,35 +337,26 @@ public void FunctionReturn() //7. split stack, values left in place //8. - //ResumeSequence(address); - - //Manually inline ResumeSequence - _currentSequence = address.Sequence; - _sequenceCount = _currentSequence.Count; - _sequenceInstructions = _currentSequence._instructions; - _sequenceIndex = address.Index; + // ResumeSequence(address); + InstructionPointer = address; } - + public InstructionBase? Next() { - //Advance to the next instruction first. - return (++_sequenceIndex < _sequenceCount) - //Critical path, using direct array access - ? _sequenceInstructions[_sequenceIndex] - : null; + return InstructionPointer > AbortSequence ? _currentSequence[++InstructionPointer] : null; } public List<(string, int)> ComputePointerPath() { Stack<(string, int)> ascent = new(); - int idx = _sequenceIndex; + int idx = InstructionPointer; foreach (var label in Frame.EnumerateLabels().Select(target => target.Label)) { var pointer = (label.Instruction.GetMnemonic(), idx); ascent.Push(pointer); - idx = label.ContinuationAddress.Index; + idx = label.ContinuationAddress; switch ((OpCode)label.Instruction) { @@ -410,12 +406,8 @@ public void ResetStats() } } - public OpCode GetEndFor() - { - if (Frame.LabelCount == 1 && Frame.Label.Instruction.x00 == OpCode.Func) - return OpCode.Func; - return OpCode.Block; - } + public OpCode GetEndFor() => + FindLabel(0) is { } label ? label.Op : OpCode.Func; public ModuleInstance? GetModule(FuncAddr funcAddr) { @@ -424,10 +416,33 @@ public OpCode GetEndFor() { case FunctionInstance wasmFunc: return wasmFunc.Module; case HostFunction hostFunc: - //TODO: maybe implement ref binding for host functions + //TODO: maybe implement ref binding for host functions default: return null; } } + + public void LinkFunction(FunctionInstance instance) + { + InstructionPointer offset = linkedInstructions.Count; + instance.LinkedOffset = offset; + + LinkOpStackHeight = 0; + LinkUnreachable = false; + ClearLinkLabels(); + PushLabel(new InstExpressionProxy(new Label + { + Instruction = OpCode.Func, + StackHeight = 0, + Arity = instance.Type.ResultType.Arity + })); + + linkedInstructions.Append( + instance.Body + .Flatten() + .Select((inst, idx) => inst.Link(this, offset + idx)) + ); + instance.Length = linkedInstructions.Count - instance.LinkedOffset; + } } } \ No newline at end of file diff --git a/Wacs.Core/Runtime/Frame.cs b/Wacs.Core/Runtime/Frame.cs index bc965ba4..ed8d398f 100644 --- a/Wacs.Core/Runtime/Frame.cs +++ b/Wacs.Core/Runtime/Frame.cs @@ -1,54 +1,63 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System.Buffers; using System.Collections.Generic; -using System.IO; -using System.Runtime.CompilerServices; using Wacs.Core.Instructions; using Wacs.Core.OpCodes; using Wacs.Core.Runtime.Types; using Wacs.Core.Types; using Wacs.Core.Utilities; +using InstructionPointer = System.Int32; namespace Wacs.Core.Runtime { public sealed class Frame : IPoolable { - public InstructionPointer ContinuationAddress = InstructionPointer.Nil; + public InstructionPointer ContinuationAddress = -1; public string FuncId = ""; + public int Head; public FuncIdx Index; - - public Label Label; - public int LabelCount = 0; public LocalsSpace Locals; public ModuleInstance Module = null!; public Label ReturnLabel = new(); public int StackHeight; - public BlockTarget TopLabel; + public BlockTarget? TopLabel; + public FunctionType Type = null!; + public Label Label + { + get + { + if (LabelCount > 1) + return TopLabel!.Label; + else + return ReturnLabel; + } + } + + private int LabelCount => TopLabel?.LabelHeight ?? 0; + public int Arity => Type.ResultType.Arity; public void Clear() { - TopLabel = default!; + // TopLabel = default!; Module = default!; Locals = default; ContinuationAddress = default; @@ -78,7 +87,7 @@ public void ForceLabels(int depth) var fakeLabel = new InstExpressionProxy(new Label { Arity = 0, - ContinuationAddress = InstructionPointer.Nil, + ContinuationAddress = -1, Instruction = OpCode.Nop, StackHeight = 0 }); @@ -93,44 +102,31 @@ public void ForceLabels(int depth) public void ClearLabels() { - TopLabel = default!; - LabelCount = 0; + // TopLabel = null; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] public void SetLabel(BlockTarget baselabel) { - TopLabel = baselabel; - LabelCount = 1; - Label = ReturnLabel; + // TopLabel = baselabel; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PushLabel(BlockTarget target) { - TopLabel = target; - LabelCount++; - Label = TopLabel.Label; + // TopLabel = target; } - public InstructionPointer PopLabels(int idx) + public void PopLabels(int idx) { - if (LabelCount <= idx + 1) - throw new InvalidDataException("Label Stack underflow"); - - idx = LabelCount - (idx + 1); - BlockTarget oldLabel; - do - { - oldLabel = TopLabel; - TopLabel = TopLabel.EnclosingBlock; - } while (--LabelCount > idx); - - Label = LabelCount > 1 - ? TopLabel.Label - : ReturnLabel; - - return oldLabel.Label.ContinuationAddress; + // if ((TopLabel?.LabelHeight ?? 0) <= idx + 1) + // throw new InvalidDataException("Label Stack underflow"); + + // var Label = TopLabel; + // for (int i = 0; i <= idx && Label != null; i++) + // { + // Label = Label?.EnclosingBlock ?? null; + // } + // + // Context.InstructionPointer = (Label?.Head ?? 0) + 1; } public IEnumerable EnumerateLabels() diff --git a/Wacs.Core/Runtime/GC/ExnInstance.cs b/Wacs.Core/Runtime/GC/ExnInstance.cs index 42b5b06c..2e5e3b9a 100644 --- a/Wacs.Core/Runtime/GC/ExnInstance.cs +++ b/Wacs.Core/Runtime/GC/ExnInstance.cs @@ -19,12 +19,11 @@ namespace Wacs.Core.Runtime.Types { public class ExnInstance : IGcRef { + public Stack Fields; public ExnIdx Index; - public RefIdx StoreIndex => Index; - + public TagAddr Tag; - public Stack Fields; - + public ExnInstance(uint idx, TagAddr tag, Stack fields) { Index = new ExnIdx(idx); @@ -32,5 +31,6 @@ public ExnInstance(uint idx, TagAddr tag, Stack fields) Fields = fields; } + public RefIdx StoreIndex => Index; } } \ No newline at end of file diff --git a/Wacs.Core/Runtime/GC/I31Ref.cs b/Wacs.Core/Runtime/GC/I31Ref.cs index eb0e37fb..d4b82102 100644 --- a/Wacs.Core/Runtime/GC/I31Ref.cs +++ b/Wacs.Core/Runtime/GC/I31Ref.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using Wacs.Core.Types; @@ -21,7 +19,6 @@ namespace Wacs.Core.Runtime.GC public class I31Ref : IGcRef { public PtrIdx _index; - public RefIdx StoreIndex => _index; public I31Ref(long i) { @@ -29,5 +26,6 @@ public I31Ref(long i) } public int Value => (int)_index.Value; + public RefIdx StoreIndex => _index; } } \ No newline at end of file diff --git a/Wacs.Core/Runtime/GC/IGcRef.cs b/Wacs.Core/Runtime/GC/IGcRef.cs index 6eda7ec3..a5083e9b 100644 --- a/Wacs.Core/Runtime/GC/IGcRef.cs +++ b/Wacs.Core/Runtime/GC/IGcRef.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using Wacs.Core.Types; diff --git a/Wacs.Core/Runtime/GC/StoreArray.cs b/Wacs.Core/Runtime/GC/StoreArray.cs index 487d5b16..e0afb688 100644 --- a/Wacs.Core/Runtime/GC/StoreArray.cs +++ b/Wacs.Core/Runtime/GC/StoreArray.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Collections.Generic; @@ -22,26 +20,14 @@ namespace Wacs.Core.Runtime { public class StoreArray : IGcRef { + private readonly Value[] _data; - private ArrayType _definition; - private Value[] _data; - - private ArrayIdx _index; - public RefIdx StoreIndex => _index; - public ArrayIdx ArrayIndex => _index; - - public int Length => _data.Length; - - public Value this[int index] - { - get => _data[index]; - set => _data[index] = value; - } + private readonly ArrayType _definition; //Fill values public StoreArray(ArrayIdx storeIndex, ArrayType def, Value elementVals, int n) { - _index = storeIndex; + ArrayIndex = storeIndex; _definition = def; _data = new Value[n]; Array.Fill(_data, elementVals); @@ -50,11 +36,11 @@ public StoreArray(ArrayIdx storeIndex, ArrayType def, Value elementVals, int n) // _data[i] = elementVals; // } } - + //Default values public StoreArray(ArrayIdx storeIndex, ArrayType def, int n) { - _index = storeIndex; + ArrayIndex = storeIndex; _definition = def; _data = new Value[n]; var fieldType = _definition.ElementType; @@ -65,11 +51,11 @@ public StoreArray(ArrayIdx storeIndex, ArrayType def, int n) // _data[i] = new Value(fieldType.UnpackType()); // } } - + //Fixed values public StoreArray(ArrayIdx storeIndex, ArrayType def, ref Stack values) { - _index = storeIndex; + ArrayIndex = storeIndex; _definition = def; int n = values.Count; _data = new Value[n]; @@ -84,7 +70,7 @@ public StoreArray(ArrayIdx storeIndex, ArrayType def, ref Stack values) //Data values public StoreArray(ArrayIdx storeIndex, ArrayType def, ReadOnlySpan data, int n, int stride) { - _index = storeIndex; + ArrayIndex = storeIndex; _definition = def; var ft = def.ElementType; @@ -97,11 +83,11 @@ public StoreArray(ArrayIdx storeIndex, ArrayType def, ReadOnlySpan data, i _data[i] = ft.UnpackValue(source); } } - + //Element values public StoreArray(ArrayIdx storeIndex, ArrayType def, List values) { - _index = storeIndex; + ArrayIndex = storeIndex; _definition = def; int n = values.Count; _data = new Value[n]; @@ -113,6 +99,18 @@ public StoreArray(ArrayIdx storeIndex, ArrayType def, List values) // } } + public ArrayIdx ArrayIndex { get; } + + public int Length => _data.Length; + + public Value this[int index] + { + get => _data[index]; + set => _data[index] = value; + } + + public RefIdx StoreIndex => ArrayIndex; + public void Fill(Value val, int offset, int count) { Array.Fill(_data, val,offset, count); @@ -166,7 +164,7 @@ public void Init(int offset, ReadOnlySpan data, int n, int stride) dest[i] = ft.UnpackValue(source); } } - + public void Init(int offset, List elems, int n) { var src = elems.ToArray(); diff --git a/Wacs.Core/Runtime/GC/StoreStruct.cs b/Wacs.Core/Runtime/GC/StoreStruct.cs index 769f2553..a9789000 100644 --- a/Wacs.Core/Runtime/GC/StoreStruct.cs +++ b/Wacs.Core/Runtime/GC/StoreStruct.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System.Collections.Generic; using Wacs.Core.Types; @@ -21,16 +19,12 @@ namespace Wacs.Core.Runtime.GC { public class StoreStruct : IGcRef { - private StructType _definition; - private Value[] _data; - - private StructIdx _index; - public RefIdx StoreIndex => _index; - public StructIdx StructIndex => _index; + private readonly Value[] _data; + private readonly StructType _definition; public StoreStruct(StructIdx storeIndex, StructType def, Stack fieldVals) { - _index = storeIndex; + StructIndex = storeIndex; _definition = def; _data = new Value[fieldVals.Count]; @@ -39,11 +33,11 @@ public StoreStruct(StructIdx storeIndex, StructType def, Stack fieldVals) _data[i] = fieldVals.Pop(); } } - + //Defaults public StoreStruct(StructIdx storeIndex, StructType def) { - _index = storeIndex; + StructIndex = storeIndex; _definition = def; var fieldTypes = _definition.FieldTypes; @@ -54,10 +48,14 @@ public StoreStruct(StructIdx storeIndex, StructType def) } } + public StructIdx StructIndex { get; } + public Value this[FieldIdx y] { get => _data[y.Value]; set => _data[y.Value] = value; } + + public RefIdx StoreIndex => StructIndex; } } \ No newline at end of file diff --git a/Wacs.Core/Runtime/IBindable.cs b/Wacs.Core/Runtime/IBindable.cs index 5531ec9a..7946f6f2 100644 --- a/Wacs.Core/Runtime/IBindable.cs +++ b/Wacs.Core/Runtime/IBindable.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. namespace Wacs.Core.Runtime { diff --git a/Wacs.Core/Runtime/ITypeConvertable.cs b/Wacs.Core/Runtime/ITypeConvertable.cs index e3067cff..cec36a9e 100644 --- a/Wacs.Core/Runtime/ITypeConvertable.cs +++ b/Wacs.Core/Runtime/ITypeConvertable.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. namespace Wacs.Core.Runtime { diff --git a/Wacs.Core/Runtime/InstructionPointer.cs b/Wacs.Core/Runtime/InstructionPointer.cs deleted file mode 100644 index 56333d30..00000000 --- a/Wacs.Core/Runtime/InstructionPointer.cs +++ /dev/null @@ -1,51 +0,0 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ - -using System; - -namespace Wacs.Core.Runtime -{ - public readonly struct InstructionPointer : IEquatable - { - public readonly InstructionSequence Sequence; - public readonly int Index; - - public InstructionPointer(InstructionSequence seq, int index) - { - Sequence = seq; - Index = index; - } - - public static InstructionPointer Nil = new(InstructionSequence.Empty, 0); - - public InstructionPointer Previous => new(Sequence, Index - 1); - - public bool Equals(InstructionPointer other) - { - return ReferenceEquals(Sequence, other.Sequence) && Index == other.Index; - } - - public override bool Equals(object? obj) - { - return obj is InstructionPointer other && Equals(other); - } - - public override int GetHashCode() - { - return HashCode.Combine(Sequence, Index); - } - } -} \ No newline at end of file diff --git a/Wacs.Core/Runtime/InvokerOptions.cs b/Wacs.Core/Runtime/InvokerOptions.cs index 18165951..6d530862 100644 --- a/Wacs.Core/Runtime/InvokerOptions.cs +++ b/Wacs.Core/Runtime/InvokerOptions.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; @@ -49,6 +47,7 @@ public class InvokerOptions public InstructionLogging LogInstructionExecution = InstructionLogging.None; public long LogProgressEvery = -1; public bool ShowPath = false; + public bool SynchronousExecution = false; public bool UseFastPath() { diff --git a/Wacs.Core/Runtime/Label.cs b/Wacs.Core/Runtime/Label.cs index f594fcc8..046ad737 100644 --- a/Wacs.Core/Runtime/Label.cs +++ b/Wacs.Core/Runtime/Label.cs @@ -1,20 +1,20 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using Wacs.Core.OpCodes; +using InstructionPointer = System.Int32; + namespace Wacs.Core.Runtime { @@ -23,6 +23,8 @@ public class Label public int Arity; public InstructionPointer ContinuationAddress; public ByteCode Instruction; + public int Parameters; + public int Results; public int StackHeight; public Label() diff --git a/Wacs.Core/Runtime/OpStack.cs b/Wacs.Core/Runtime/OpStack.cs index 15412cfd..f4f58de9 100644 --- a/Wacs.Core/Runtime/OpStack.cs +++ b/Wacs.Core/Runtime/OpStack.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Collections.Generic; @@ -147,7 +145,7 @@ public ulong PopU64() --Count; return _registers[Count].Data.UInt64; } - + public long PopAddr() { --Count; diff --git a/Wacs.Core/Runtime/RuntimeAttributes.cs b/Wacs.Core/Runtime/RuntimeAttributes.cs index 4d5657ae..48725e01 100644 --- a/Wacs.Core/Runtime/RuntimeAttributes.cs +++ b/Wacs.Core/Runtime/RuntimeAttributes.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using Wacs.Core.Instructions; diff --git a/Wacs.Core/Runtime/RuntimeOptions.cs b/Wacs.Core/Runtime/RuntimeOptions.cs index ff9acef1..010ab868 100644 --- a/Wacs.Core/Runtime/RuntimeOptions.cs +++ b/Wacs.Core/Runtime/RuntimeOptions.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. namespace Wacs.Core.Runtime { @@ -20,5 +18,6 @@ public class RuntimeOptions { public bool SkipModuleValidation = false; public bool SkipStartFunction = false; + public bool TimeInstantiation = false; } } \ No newline at end of file diff --git a/Wacs.Core/Runtime/Store.cs b/Wacs.Core/Runtime/Store.cs index 57ddb8a1..be17721d 100644 --- a/Wacs.Core/Runtime/Store.cs +++ b/Wacs.Core/Runtime/Store.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Collections.Generic; @@ -28,21 +26,21 @@ public class Store { private readonly List Datas = new(); private readonly List Elems = new(); + private readonly List Exns = new(); private readonly List Funcs = new(); private readonly List Globals = new(); - private readonly List Tags = new(); - private readonly List Exns = new(); private readonly List Tables = new(); - private StoreTransaction? CurrentTransaction = null; - - private long Structs = 0; + private readonly List Tags = new(); private long Arrays = 0; + private StoreTransaction? CurrentTransaction = null; private MemoryInstance?[] Mems = new MemoryInstance[32]; private int MemsCount = 0; + private long Structs = 0; + public IFunctionInstance this[FuncAddr addr] => CurrentTransaction?.Funcs.GetValueOrDefault(addr)??Funcs[addr.Value]; @@ -54,10 +52,10 @@ public class Store public GlobalInstance this[GlobalAddr addr] => CurrentTransaction?.Globals.GetValueOrDefault(addr)??Globals[addr.Value]; - + public TagInstance this[TagAddr addr] => CurrentTransaction?.Tags.GetValueOrDefault(addr)??Tags[addr.Value]; - + public ExnInstance this[ExnAddr addr] => Exns[addr.Value]; @@ -78,8 +76,8 @@ public class Store public bool Contains(StructIdx heapIdx) => Structs > heapIdx.Value && heapIdx.Value >= 0; public bool Contains(ArrayIdx heapIdx) => Arrays > heapIdx.Value && heapIdx.Value >= 0; - - + + public void OpenTransaction() { if (CurrentTransaction != null) @@ -207,7 +205,7 @@ public GlobalAddr AddGlobal(GlobalInstance global) return addr; } - + public TagAddr AddTag(TagInstance tag) { var addr = new TagAddr(Tags.Count); @@ -217,7 +215,7 @@ public TagAddr AddTag(TagInstance tag) CurrentTransaction.Tags.Add(addr, tag); return addr; } - + public ExnAddr AllocateExn(TagAddr ta, Stack fields) { var exnAddr = new ExnAddr(Exns.Count); diff --git a/Wacs.Core/Runtime/StoreTransaction.cs b/Wacs.Core/Runtime/StoreTransaction.cs index c21c4fbd..a70b54f2 100644 --- a/Wacs.Core/Runtime/StoreTransaction.cs +++ b/Wacs.Core/Runtime/StoreTransaction.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System.Collections.Generic; using Wacs.Core.Runtime.Types; diff --git a/Wacs.Core/Runtime/Transpiler/FunctionTranspiler.cs b/Wacs.Core/Runtime/Transpiler/FunctionTranspiler.cs index 230d626d..83351ed6 100644 --- a/Wacs.Core/Runtime/Transpiler/FunctionTranspiler.cs +++ b/Wacs.Core/Runtime/Transpiler/FunctionTranspiler.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System.Collections.Generic; using System.Linq; @@ -68,17 +66,11 @@ private static InstructionSequence OptimizeSequence(InstructionSequence seq) case InstBlock instBlock: var newBlockSeq = OptimizeSequence(instBlock.GetBlock(0).Instructions); var newBlock = new InstBlock().Immediate(instBlock.BlockType, newBlockSeq); - //HACK: We're copying the StackHeight here. Ideally we would recalculate, - //but InstAggregates would need to report correct stack consumption to Validate - newBlock.Label = new Label(instBlock.Label); - stack.Push(newBlock); break; case InstLoop instLoop: var newLoopSeq = OptimizeSequence(instLoop.GetBlock(0).Instructions); var newLoop = new InstLoop().Immediate(instLoop.BlockType, newLoopSeq); - //copy stackheight - newLoop.Label = new Label(instLoop.Label); stack.Push(newLoop); break; case InstIf instIf: @@ -106,9 +98,6 @@ private static InstructionSequence OptimizeSequence(InstructionSequence seq) } if (newIf == null) newIf = new InstIf().Immediate(instIf.BlockType, newIfSeq, newElseSeq); - - //copy stackheight - newIf.Label = new Label(instIf.Label); stack.Push(newIf); break; diff --git a/Wacs.Core/Runtime/Types/DataInstance.cs b/Wacs.Core/Runtime/Types/DataInstance.cs index 2bfce6f4..e72818e3 100644 --- a/Wacs.Core/Runtime/Types/DataInstance.cs +++ b/Wacs.Core/Runtime/Types/DataInstance.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; diff --git a/Wacs.Core/Runtime/Types/ElementInstance.cs b/Wacs.Core/Runtime/Types/ElementInstance.cs index c079c7d7..c01f0f74 100644 --- a/Wacs.Core/Runtime/Types/ElementInstance.cs +++ b/Wacs.Core/Runtime/Types/ElementInstance.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System.Collections.Generic; using System.Linq; diff --git a/Wacs.Core/Runtime/Types/ExportInstance.cs b/Wacs.Core/Runtime/Types/ExportInstance.cs index 959185dd..86cd76a0 100644 --- a/Wacs.Core/Runtime/Types/ExportInstance.cs +++ b/Wacs.Core/Runtime/Types/ExportInstance.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. namespace Wacs.Core.Runtime.Types { diff --git a/Wacs.Core/Runtime/Types/ExternalValue.cs b/Wacs.Core/Runtime/Types/ExternalValue.cs index 9d14c60c..719a25f0 100644 --- a/Wacs.Core/Runtime/Types/ExternalValue.cs +++ b/Wacs.Core/Runtime/Types/ExternalValue.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using Wacs.Core.Types.Defs; @@ -52,7 +50,7 @@ public class Global : ExternalValue public override ExternalKind Type => ExternalKind.Global; public GlobalAddr Address { get; } } - + public class Tag : ExternalValue { public Tag(TagAddr address) => Address = address; diff --git a/Wacs.Core/Runtime/Types/FunctionInstance.cs b/Wacs.Core/Runtime/Types/FunctionInstance.cs index 099a9bd5..e6d7d560 100644 --- a/Wacs.Core/Runtime/Types/FunctionInstance.cs +++ b/Wacs.Core/Runtime/Types/FunctionInstance.cs @@ -1,25 +1,23 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Collections.Generic; -using System.Linq; using Wacs.Core.OpCodes; using Wacs.Core.Types; using Wacs.Core.Types.Defs; +using InstructionPointer = System.Int32; namespace Wacs.Core.Runtime.Types { @@ -38,6 +36,8 @@ public class FunctionInstance : IFunctionInstance /// public readonly Module.Function Definition; + public readonly DefType DefType; + public readonly FuncIdx Index; public readonly ModuleInstance Module; @@ -45,6 +45,9 @@ public class FunctionInstance : IFunctionInstance //Copied from the static Definition //Can be processed with optimization passes public Expression Body; + public int Length; + + public InstructionPointer LinkedOffset; //Copied from the static Definition public ValType[] Locals; @@ -63,8 +66,8 @@ public FunctionInstance(ModuleInstance module, Module.Function definition) Module = module; DefType = type; Definition = definition; - SetBody(definition.Body); - + Body = definition.Body; + Body.LabelTarget.Label.Arity = Type.ResultType.Arity; Locals = definition.Locals; Index = definition.Index; @@ -72,8 +75,6 @@ public FunctionInstance(ModuleInstance module, Module.Function definition) Name = Definition.Id; } - public readonly DefType DefType; - public string ModuleName => Module.Name; public string Name { get; set; } = ""; public FunctionType Type { get; } @@ -91,9 +92,6 @@ public void SetBody(Expression body) { Body = body; Body.LabelTarget.Label.Arity = Type.ResultType.Arity; - - var vContext = new StackCalculator(Module, Definition); - Body.PrecomputeLabels(vContext); } public void Invoke(ExecContext context) @@ -133,10 +131,11 @@ public void Invoke(ExecContext context) frame.ReturnLabel.Arity = funcType.ResultType.Arity; frame.ReturnLabel.Instruction = LabelInst; frame.ReturnLabel.ContinuationAddress = context.GetPointer(); + frame.Head = LinkedOffset; - frame.SetLabel(Body.LabelTarget); + // frame.SetLabel(Body.LabelTarget); - context.EnterSequence(Body.Instructions); + context.InstructionPointer = LinkedOffset - 1; } public override string ToString() => $"FunctionInstance[{Id}] (Type: {Type}, IsExport: {IsExport})"; diff --git a/Wacs.Core/Runtime/Types/GlobalInstance.cs b/Wacs.Core/Runtime/Types/GlobalInstance.cs index 228a5c9c..39343500 100644 --- a/Wacs.Core/Runtime/Types/GlobalInstance.cs +++ b/Wacs.Core/Runtime/Types/GlobalInstance.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using Wacs.Core.Types; diff --git a/Wacs.Core/Runtime/Types/HostFunction.cs b/Wacs.Core/Runtime/Types/HostFunction.cs index b0cd4879..d2a4e89f 100644 --- a/Wacs.Core/Runtime/Types/HostFunction.cs +++ b/Wacs.Core/Runtime/Types/HostFunction.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Reflection; diff --git a/Wacs.Core/Runtime/Types/IFunctionInstance.cs b/Wacs.Core/Runtime/Types/IFunctionInstance.cs index 0991260d..a64c488c 100644 --- a/Wacs.Core/Runtime/Types/IFunctionInstance.cs +++ b/Wacs.Core/Runtime/Types/IFunctionInstance.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using Wacs.Core.Types; diff --git a/Wacs.Core/Runtime/Types/MemoryInstance.cs b/Wacs.Core/Runtime/Types/MemoryInstance.cs index 43a7364b..762dee2d 100644 --- a/Wacs.Core/Runtime/Types/MemoryInstance.cs +++ b/Wacs.Core/Runtime/Types/MemoryInstance.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Diagnostics.CodeAnalysis; diff --git a/Wacs.Core/Runtime/Types/ModuleInstance.cs b/Wacs.Core/Runtime/Types/ModuleInstance.cs index 4ffae590..7a80b970 100644 --- a/Wacs.Core/Runtime/Types/ModuleInstance.cs +++ b/Wacs.Core/Runtime/Types/ModuleInstance.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Collections.Generic; @@ -29,16 +27,18 @@ public class ModuleInstance { public readonly DataAddrs DataAddrs = new(); public readonly ElemAddrs ElemAddrs = new(); + public readonly ExnAddrs ExnAddrs = new(); public readonly List Exports = new(); public readonly FuncAddrs FuncAddrs = new(); public readonly GlobalAddrs GlobalAddrs = new(); - public readonly TagAddrs TagAddrs = new(); - public readonly ExnAddrs ExnAddrs = new(); public readonly MemAddrs MemAddrs = new(); public readonly Module Repr; + public readonly StackCalculator StackCalculator; + public readonly TableAddrs TableAddrs = new(); + public readonly TagAddrs TagAddrs = new(); public readonly TypesSpace Types; @@ -46,6 +46,7 @@ public ModuleInstance(Module module) { Types = new TypesSpace(module); Repr = module; + StackCalculator = new StackCalculator(this); } public string Name { get; set; } = "_"; diff --git a/Wacs.Core/Runtime/Types/TableInstance.cs b/Wacs.Core/Runtime/Types/TableInstance.cs index 9a82a0da..740cf5f5 100644 --- a/Wacs.Core/Runtime/Types/TableInstance.cs +++ b/Wacs.Core/Runtime/Types/TableInstance.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System.Collections.Generic; using System.Linq; diff --git a/Wacs.Core/Runtime/Types/TagInstance.cs b/Wacs.Core/Runtime/Types/TagInstance.cs index eb32563b..409e5056 100644 --- a/Wacs.Core/Runtime/Types/TagInstance.cs +++ b/Wacs.Core/Runtime/Types/TagInstance.cs @@ -18,8 +18,8 @@ namespace Wacs.Core.Runtime.Types { public class TagInstance { - public readonly DefType Type; - + public readonly DefType Type; + public TagInstance(DefType type) { Type = type; diff --git a/Wacs.Core/Runtime/V128.cs b/Wacs.Core/Runtime/V128.cs index 0dfc68f0..c1899610 100644 --- a/Wacs.Core/Runtime/V128.cs +++ b/Wacs.Core/Runtime/V128.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.IO; diff --git a/Wacs.Core/Runtime/Value.cs b/Wacs.Core/Runtime/Value.cs index 4e50df07..5057693c 100644 --- a/Wacs.Core/Runtime/Value.cs +++ b/Wacs.Core/Runtime/Value.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Globalization; @@ -20,8 +18,6 @@ using System.Numerics; using System.Runtime.InteropServices; using Wacs.Core.Attributes; -using Wacs.Core.Runtime.Exceptions; -using Wacs.Core.Runtime.Types; using Wacs.Core.Types; using Wacs.Core.Types.Defs; using Wacs.Core.Utilities; diff --git a/Wacs.Core/Runtime/VecRef.cs b/Wacs.Core/Runtime/VecRef.cs index 46a1cf44..909e3887 100644 --- a/Wacs.Core/Runtime/VecRef.cs +++ b/Wacs.Core/Runtime/VecRef.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using Wacs.Core.Types; @@ -20,8 +18,9 @@ namespace Wacs.Core.Runtime { public class VecRef : IGcRef { - private static VecIdx _index = (VecIdx)0; - public RefIdx StoreIndex => _index; + private static readonly VecIdx _index = (VecIdx)0; + + public MV128 V128; public VecRef(V128 val) { @@ -32,7 +31,7 @@ public VecRef(VecRef other) { V128 = other.V128; } - - public MV128 V128; + + public RefIdx StoreIndex => _index; } } \ No newline at end of file diff --git a/Wacs.Core/Runtime/WasmRuntimeBinding.cs b/Wacs.Core/Runtime/WasmRuntimeBinding.cs index b156c59a..e5eaf54d 100644 --- a/Wacs.Core/Runtime/WasmRuntimeBinding.cs +++ b/Wacs.Core/Runtime/WasmRuntimeBinding.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Collections.Generic; @@ -220,7 +218,7 @@ public GlobalInstance BindHostGlobal((string module, string entity) id, GlobalTy Store.CommitTransaction(); return Store[globAddr]; } - + public TagInstance BindHostTag((string module, string entity) id, DefType tagType) { Store.OpenTransaction(); diff --git a/Wacs.Core/Runtime/WasmRuntimeExecution.cs b/Wacs.Core/Runtime/WasmRuntimeExecution.cs index 73dc2775..812d0b96 100644 --- a/Wacs.Core/Runtime/WasmRuntimeExecution.cs +++ b/Wacs.Core/Runtime/WasmRuntimeExecution.cs @@ -1,30 +1,26 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Diagnostics; using System.Linq; -using System.Reflection; using System.Runtime.ExceptionServices; using System.Threading.Tasks; using Wacs.Core.Instructions; using Wacs.Core.OpCodes; using Wacs.Core.Runtime.Exceptions; using Wacs.Core.Runtime.Types; -using Wacs.Core.Types; using Wacs.Core.Utilities; using Wacs.Core.WASIp1; @@ -33,6 +29,7 @@ namespace Wacs.Core.Runtime public partial class WasmRuntime { private InstructionBase? lastInstruction = null; + public bool TraceExecution = false; private Delegate CreateInvokerInternal(FuncAddr funcAddr, Type delegateType, bool returnsResult, InvokerOptions? options = default) { @@ -58,50 +55,73 @@ private Delegate CreateInvokerInternal(FuncAddr funcAddr, Type delegateType, boo var invoker = CreateInvoker(funcAddr, options); return Delegates.AnonymousFunctionFromType(funcInst.Type, invoker); } - + /// /// Bind a wasm Func to C# via dynamic invocation (AOT compatible) /// public Func CreateInvokerFunc(FuncAddr funcAddr, InvokerOptions? options = default) => () => (TResult)CreateInvokerInternal(funcAddr, typeof(Func), true, options).DynamicInvoke()!; + public Func CreateInvokerFunc(FuncAddr funcAddr, InvokerOptions? options = default) => (arg1) => (TResult)CreateInvokerInternal(funcAddr, typeof(Func), true, options).DynamicInvoke(arg1)!; + public Func CreateInvokerFunc(FuncAddr funcAddr, InvokerOptions? options = default) => (arg1, arg2) => (TResult)CreateInvokerInternal(funcAddr, typeof(Func), true, options).DynamicInvoke(arg1, arg2)!; + public Func CreateInvokerFunc(FuncAddr funcAddr, InvokerOptions? options = default) => (arg1, arg2, arg3) => (TResult)CreateInvokerInternal(funcAddr, typeof(Func), true, options).DynamicInvoke(arg1, arg2, arg3)!; + public Func CreateInvokerFunc(FuncAddr funcAddr, InvokerOptions? options = default) => (arg1, arg2, arg3, arg4) => (TResult)CreateInvokerInternal(funcAddr, typeof(Func), true, options).DynamicInvoke(arg1, arg2, arg3, arg4)!; + public Func CreateInvokerFunc(FuncAddr funcAddr, InvokerOptions? options = default) => (arg1, arg2, arg3, arg4, arg5) => (TResult)CreateInvokerInternal(funcAddr, typeof(Func), true, options).DynamicInvoke(arg1, arg2, arg3, arg4, arg5)!; + public Func CreateInvokerFunc(FuncAddr funcAddr, InvokerOptions? options = default) => (arg1, arg2, arg3, arg4, arg5, arg6) => (TResult)CreateInvokerInternal(funcAddr, typeof(Func), true, options).DynamicInvoke(arg1, arg2, arg3, arg4, arg5, arg6)!; + public Func CreateInvokerFunc(FuncAddr funcAddr, InvokerOptions? options = default) => (arg1, arg2, arg3, arg4, arg5, arg6, arg7) => (TResult)CreateInvokerInternal(funcAddr, typeof(Func), true, options).DynamicInvoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7)!; + public Func CreateInvokerFunc(FuncAddr funcAddr, InvokerOptions? options = default) => (arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) => (TResult)CreateInvokerInternal(funcAddr, typeof(Func), true, options).DynamicInvoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)!; + public Func CreateInvokerFunc(FuncAddr funcAddr, InvokerOptions? options = default) => (arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) => (TResult)CreateInvokerInternal(funcAddr, typeof(Func), true, options).DynamicInvoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)!; - - + + public Action CreateInvokerAction(FuncAddr funcAddr, InvokerOptions? options = default) => - () => { CreateInvokerInternal(funcAddr, typeof(Action), false, options).DynamicInvoke(); }; + () => + { + var funcInst = Context.Store[funcAddr]; + var invoker = CreateInvokerInternal(funcAddr, typeof(Action), false, options); + invoker.DynamicInvoke(); + }; + public Action CreateInvokerAction(FuncAddr funcAddr, InvokerOptions? options = default) => (arg1) => { CreateInvokerInternal(funcAddr, typeof(Action), false, options).DynamicInvoke(arg1); }; + public Action CreateInvokerAction(FuncAddr funcAddr, InvokerOptions? options = default) => (arg1, arg2) => { CreateInvokerInternal(funcAddr, typeof(Action), false, options).DynamicInvoke(arg1, arg2); }; + public Action CreateInvokerAction(FuncAddr funcAddr, InvokerOptions? options = default) => (arg1, arg2, arg3) => { CreateInvokerInternal(funcAddr, typeof(Action), false, options).DynamicInvoke(arg1, arg2, arg3); }; + public Action CreateInvokerAction(FuncAddr funcAddr, InvokerOptions? options = default) => (arg1, arg2, arg3, arg4) => { CreateInvokerInternal(funcAddr, typeof(Action), false, options).DynamicInvoke(arg1, arg2, arg3, arg4); }; + public Action CreateInvokerAction(FuncAddr funcAddr, InvokerOptions? options = default) => (arg1, arg2, arg3, arg4, arg5) => { CreateInvokerInternal(funcAddr, typeof(Action), false, options).DynamicInvoke(arg1, arg2, arg3, arg4, arg5); }; + public Action CreateInvokerAction(FuncAddr funcAddr, InvokerOptions? options = default) => (arg1, arg2, arg3, arg4, arg5, arg6) => { CreateInvokerInternal(funcAddr, typeof(Action), false, options).DynamicInvoke(arg1, arg2, arg3, arg4, arg5, arg6); }; + public Action CreateInvokerAction(FuncAddr funcAddr, InvokerOptions? options = default) => (arg1, arg2, arg3, arg4, arg5, arg6, arg7) => { CreateInvokerInternal(funcAddr, typeof(Action), false, options).DynamicInvoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7); }; + public Action CreateInvokerAction(FuncAddr funcAddr, InvokerOptions? options = default) => (arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) => { CreateInvokerInternal(funcAddr, typeof(Action), false, options).DynamicInvoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); }; + public Action CreateInvokerAction(FuncAddr funcAddr, InvokerOptions? options = default) => (arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) => { CreateInvokerInternal(funcAddr, typeof(Action), false, options).DynamicInvoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); }; @@ -131,6 +151,9 @@ public Delegates.GenericFuncsAsync CreateStackInvokerAsync(FuncAddr funcAddr, In private Delegates.GenericFuncsAsync CreateInvokerAsync(FuncAddr funcAddr, InvokerOptions options) { + if (options.SynchronousExecution) + throw new NotSupportedException("Synchronous execution is not supported for async invokers."); + return GenericDelegateAsync; async Task GenericDelegateAsync(params Value[] args) { @@ -147,6 +170,7 @@ async Task GenericDelegateAsync(params Value[] args) Context.ProcessTimer.Restart(); Context.InstructionTimer.Restart(); + Context.InstructionPointer = ExecContext.AbortSequence; await Context.InvokeAsync(funcAddr); @@ -280,10 +304,17 @@ Value[] GenericDelegate(params object[] args) Context.ProcessTimer.Restart(); Context.InstructionTimer.Restart(); - - var task = Context.InvokeAsync(funcAddr); - task.Wait(); - + Context.InstructionPointer = ExecContext.AbortSequence; + + if (options.SynchronousExecution) + { + Context.Invoke(funcAddr); + } + else + { + var task = Context.InvokeAsync(funcAddr); + task.Wait(); + } Context.steps = 0; bool fastPath = options.UseFastPath(); try @@ -407,11 +438,18 @@ public async Task ProcessThreadAsync(long gasLimit) InstructionBase inst; if (gasLimit <= 0) { - //Manually inline Next() // while (Context.Next() is { } inst) - while (++Context._sequenceIndex < Context._sequenceCount) + //Manually inline Next() + while (++Context.InstructionPointer >= 0) { - inst = Context._sequenceInstructions[Context._sequenceIndex]; + inst = Context._currentSequence[Context.InstructionPointer]; + if (inst.PointerAdvance > 0) + { + if (inst.PointerAdvance > 1) + Context.InstructionPointer += inst.PointerAdvance - 1; + continue; + } + if (inst.IsAsync) { await inst.ExecuteAsync(Context); @@ -424,11 +462,21 @@ public async Task ProcessThreadAsync(long gasLimit) } else { - //Manually inline Next() // while (Context.Next() is { } inst) - while (++Context._sequenceIndex < Context._sequenceCount) + //Manually inline Next() + while (++Context.InstructionPointer >= 0) { - inst = Context._sequenceInstructions[Context._sequenceIndex]; + inst = Context._currentSequence[Context.InstructionPointer]; + //Counting gas costs about 18% throughput! + Context.steps += inst.Size; + + if (inst.PointerAdvance > 0) + { + if (inst.PointerAdvance > 1) + Context.InstructionPointer += inst.PointerAdvance - 1; + continue; + } + if (inst.IsAsync) { await inst.ExecuteAsync(Context); @@ -437,8 +485,7 @@ public async Task ProcessThreadAsync(long gasLimit) { inst.Execute(Context); } - //Counting gas costs about 18% throughput! - Context.steps += inst.Size; + if (Context.steps >= gasLimit) { throw new InsufficientGasException($"Invocation ran out of gas (limit:{gasLimit})."); @@ -463,8 +510,14 @@ public async Task ProcessThreadWithOptions(InvokerOptions options) if (options.CollectStats == StatsDetail.Instruction) { Context.InstructionTimer.Restart(); - - if (inst.IsAsync) + + if (inst.PointerAdvance > 0) + { + if (inst.PointerAdvance > 1) + Context.InstructionPointer += inst.PointerAdvance - 1; + continue; + } + else if (inst.IsAsync) await inst.ExecuteAsync(Context); else inst.Execute(Context); @@ -480,7 +533,13 @@ public async Task ProcessThreadWithOptions(InvokerOptions options) else { Context.InstructionTimer.Start(); - if (inst.IsAsync) + if (inst.PointerAdvance > 0) + { + if (inst.PointerAdvance > 1) + Context.InstructionPointer += inst.PointerAdvance - 1; + continue; + } + else if (inst.IsAsync) await inst.ExecuteAsync(Context); else inst.Execute(Context); @@ -558,7 +617,7 @@ private void LogPreInstruction(InvokerOptions options, InstructionBase inst) } else { - var log = $"Instruction: {inst.RenderText(Context)}".PadRight(40, ' ') + location; + var log = $"Inst[0x{Context.InstructionPointer:x8}]: {inst.RenderText(Context)}".PadRight(40, ' ') + location; Console.Error.WriteLine(log); } break; @@ -590,7 +649,7 @@ private void LogPostInstruction(InvokerOptions options, InstructionBase inst) } else { - var log = $"Instruction: {inst.RenderText(Context)}".PadRight(40, ' ') + location; + var log = $"Inst[0x{Context.InstructionPointer:x8}]: {inst.RenderText(Context)}".PadRight(40, ' ') + location; Console.Error.WriteLine(log); } break; diff --git a/Wacs.Core/Runtime/WasmRuntimeInstantiation.cs b/Wacs.Core/Runtime/WasmRuntimeInstantiation.cs index 00b9b39f..0705123f 100644 --- a/Wacs.Core/Runtime/WasmRuntimeInstantiation.cs +++ b/Wacs.Core/Runtime/WasmRuntimeInstantiation.cs @@ -1,24 +1,22 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Linq; -using System.Reflection; using System.Runtime.ExceptionServices; using FluentValidation; using Wacs.Core.Instructions; @@ -35,8 +33,6 @@ namespace Wacs.Core.Runtime { public partial class WasmRuntime { - private static readonly MethodInfo GenericFuncsInvoke = typeof(Delegates.GenericFuncs).GetMethod("Invoke")!; - private static readonly MethodInfo GenericFuncsAsyncInvoke = typeof(Delegates.GenericFuncsAsync).GetMethod("Invoke")!; private readonly Dictionary<(string module, string entity), IAddress?> _entityBindings = new(); private readonly List _moduleInstances = new(); @@ -46,11 +42,24 @@ public partial class WasmRuntime private readonly Store Store; + //Cached instructions for module initialization + private readonly InstElemDrop _dropInst; + private readonly InstI32Const _i32ConstInst; + private readonly InstTableInit _tableInitInst; + private readonly InstMemoryInit _memoryInitInst; + private readonly InstDataDrop _dataDropInst; public WasmRuntime(RuntimeAttributes? attributes = null) { Store = new Store(); Context = new ExecContext(Store, attributes); + + //Cached instructions for module initialization + _dropInst = SpecFactory.Factory.CreateInstruction(ExtCode.ElemDrop); + _i32ConstInst = SpecFactory.Factory.CreateInstruction(OpCode.I32Const); + _tableInitInst = SpecFactory.Factory.CreateInstruction(ExtCode.TableInit); + _memoryInitInst = SpecFactory.Factory.CreateInstruction(ExtCode.MemoryInit); + _dataDropInst = SpecFactory.Factory.CreateInstruction(ExtCode.DataDrop); } /// @@ -286,6 +295,14 @@ private ModuleInstance AllocateModule(Module module) public ModuleInstance InstantiateModule(Module module, RuntimeOptions? options = default) { options ??= new RuntimeOptions(); + + Stopwatch instantiationTimer = new(); + if (options.TimeInstantiation) + { + instantiationTimer.Reset(); + instantiationTimer.Start(); + } + try { //1 @@ -312,68 +329,64 @@ public ModuleInstance InstantiateModule(Module module, RuntimeOptions? options = var auxFrame = Context.ReserveFrame(moduleInstance, FunctionType.Empty, FuncIdx.ElementInitialization); //13. Context.PushFrame(auxFrame); - - //14, 15 - for (int i = 0, l = module.Elements.Length; i < l; ++i) + try { - var elem = module.Elements[i]; - switch (elem.Mode) + //14, 15 + for (int i = 0, l = module.Elements.Length; i < l; ++i) { - case Module.ElementMode.ActiveMode activeMode: - var n = elem.Initializers.Length; - activeMode.Offset - .ExecuteInitializer(Context); - Context.InstructionFactory.CreateInstruction(OpCode.I32Const).Immediate(0) - .Execute(Context); - Context.InstructionFactory.CreateInstruction(OpCode.I32Const).Immediate(n) - .Execute(Context); - Context.InstructionFactory.CreateInstruction(ExtCode.TableInit) - .Immediate(activeMode.TableIndex, (ElemIdx)i) - .Execute(Context); - Context.InstructionFactory.CreateInstruction(ExtCode.ElemDrop) - .Immediate((ElemIdx)i) - .Execute(Context); - break; - case Module.ElementMode.DeclarativeMode declarativeMode: - _ = declarativeMode; - Context.InstructionFactory.CreateInstruction(ExtCode.ElemDrop) - .Immediate((ElemIdx)i) - .Execute(Context); - break; + var elem = module.Elements[i]; + switch (elem.Mode) + { + case Module.ElementMode.ActiveMode activeMode: + activeMode.Offset.ExecuteInitializer(Context); + _i32ConstInst.Immediate(0).Execute(Context); + _i32ConstInst.Immediate(elem.Initializers.Length).Execute(Context); + _tableInitInst.Immediate(activeMode.TableIndex, (ElemIdx)i).Execute(Context); + _dropInst.Immediate((ElemIdx)i).Execute(Context); + break; + case Module.ElementMode.DeclarativeMode declarativeMode: + _ = declarativeMode; + _dropInst.Immediate((ElemIdx)i).Execute(Context); + break; + } } - } - //16. - for (int i = 0, l = module.Datas.Length; i < l; ++i) - { - var data = module.Datas[i]; - switch (data.Mode) + //16. + for (int i = 0, l = module.Datas.Length; i < l; ++i) { - case Module.DataMode.ActiveMode activeMode: - var n = data.Init.Length; - activeMode.Offset - .ExecuteInitializer(Context); - Context.InstructionFactory.CreateInstruction(OpCode.I32Const).Immediate(0) - .Execute(Context); - Context.InstructionFactory.CreateInstruction(OpCode.I32Const).Immediate(n) - .Execute(Context); - Context.InstructionFactory.CreateInstruction(ExtCode.MemoryInit) - .Immediate((DataIdx)i, activeMode.MemoryIndex) - .Execute(Context); - Context.InstructionFactory.CreateInstruction(ExtCode.DataDrop) - .Immediate((DataIdx)i) - .Execute(Context); - break; - case Module.DataMode.PassiveMode: //Do nothing - break; + var data = module.Datas[i]; + switch (data.Mode) + { + case Module.DataMode.ActiveMode activeMode: + activeMode.Offset.ExecuteInitializer(Context); + _i32ConstInst.Immediate(0).Execute(Context); + _i32ConstInst.Immediate(data.Init.Length).Execute(Context); + _memoryInitInst.Immediate((DataIdx)i, activeMode.MemoryIndex).Execute(Context); + _dataDropInst.Immediate((DataIdx)i).Execute(Context); + break; + case Module.DataMode.PassiveMode: //Do nothing + break; + } } } - - if (TranspileModules) - TranspileModule(moduleInstance); - - SynchronizeFunctionCalls(moduleInstance); + catch (TrapException exc) + { + //Linking may succeed, so we commit the transaction + Store.CommitTransaction(); + Store.OpenTransaction(); + Context.FlushCallStack(); + ExceptionDispatchInfo.Throw(exc); + } + finally + { + if (TranspileModules) + TranspileModule(moduleInstance); + LinkModule(moduleInstance); + + Context.CacheInstructions(); + } + //17. if (module.StartIndex != FuncIdx.Default) { @@ -450,9 +463,42 @@ public ModuleInstance InstantiateModule(Module module, RuntimeOptions? options = { Store.CommitTransaction(); } + + if (options.TimeInstantiation) + { + instantiationTimer.Stop(); + Console.Error.WriteLine($"Instantiating module took {instantiationTimer.ElapsedMilliseconds:#0.###}ms"); + } + return moduleInstance; } + /// + /// Serialize all function instructions into the context + /// + /// + private void LinkModule(ModuleInstance moduleInstance) + { + foreach (var funcAddr in moduleInstance.FuncAddrs) + { + var instance = Store[funcAddr]; + if (instance is FunctionInstance functionInstance) + { + if (functionInstance.Module != moduleInstance) + continue; + Context.LinkFunction(functionInstance); + // Console.Error.WriteLine($"===Function {functionInstance.Index.Value}"); + // int head = functionInstance.LinkedOffset; + // int end = head + functionInstance.Length; + // for (int i = head; i < end; i++) + // { + // Context.PrintInstruction(i); + // } + } + } + + } + public void SynchronizeFunctionCalls(ModuleInstance moduleInstance) { foreach (var funcAddr in moduleInstance.FuncAddrs) @@ -476,8 +522,12 @@ private void SynchronizeInstructions(ModuleInstance moduleInstance, InstructionS case InstCall instCall: var addr = moduleInstance.FuncAddrs[instCall.X]; var funcInst = Store[addr]; - if (funcInst is FunctionInstance) - instCall.IsAsync = false; + instCall.IsAsync = funcInst switch + { + FunctionInstance => false, + HostFunction hostFunction => hostFunction.IsAsync, + _ => instCall.IsAsync + }; break; case InstBlock instBlock: SynchronizeInstructions(moduleInstance, instBlock.GetBlock(0).Instructions); @@ -538,7 +588,7 @@ private static GlobalAddr AllocateGlobal(Store store, GlobalType globalType, Val var globalAddr = store.AddGlobal(globalInst); return globalAddr; } - + private static TagAddr AllocateTag(Store store, DefType tagType) { var tagInst = new TagInstance(tagType); diff --git a/Wacs.Core/Runtime/WasmRuntimeTranspiler.cs b/Wacs.Core/Runtime/WasmRuntimeTranspiler.cs index d636bbdc..8248ec3a 100644 --- a/Wacs.Core/Runtime/WasmRuntimeTranspiler.cs +++ b/Wacs.Core/Runtime/WasmRuntimeTranspiler.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using Wacs.Core.Runtime.Transpiler; using Wacs.Core.Runtime.Types; diff --git a/Wacs.Core/Types/Alignment.cs b/Wacs.Core/Types/Alignment.cs index 36898f35..58c62df6 100644 --- a/Wacs.Core/Types/Alignment.cs +++ b/Wacs.Core/Types/Alignment.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; diff --git a/Wacs.Core/Types/ArrayType.cs b/Wacs.Core/Types/ArrayType.cs index 8fbfa475..9962c9fd 100644 --- a/Wacs.Core/Types/ArrayType.cs +++ b/Wacs.Core/Types/ArrayType.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System.Collections.Generic; using System.IO; @@ -23,19 +21,20 @@ namespace Wacs.Core.Types public class ArrayType : CompositeType { public readonly FieldType ElementType; + public ArrayType(FieldType ft) { ElementType = ft; } - + public static ArrayType Parse(BinaryReader reader) => new(FieldType.Parse(reader)); - + public bool Matches(ArrayType other, TypesSpace? types) { return ElementType.Matches(other.ElementType, types); } - + public override int ComputeHash(int defIndexValue, List defs) { var hash = new StableHash(); diff --git a/Wacs.Core/Types/BitWidth.cs b/Wacs.Core/Types/BitWidth.cs index 2a3621de..046053ec 100644 --- a/Wacs.Core/Types/BitWidth.cs +++ b/Wacs.Core/Types/BitWidth.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; diff --git a/Wacs.Core/Types/Block.cs b/Wacs.Core/Types/Block.cs index 6e09376a..b9aabd5f 100644 --- a/Wacs.Core/Types/Block.cs +++ b/Wacs.Core/Types/Block.cs @@ -1,20 +1,17 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. -using System; using FluentValidation; using Wacs.Core.Types.Defs; using Wacs.Core.Validation; diff --git a/Wacs.Core/Types/CastFlags.cs b/Wacs.Core/Types/CastFlags.cs index 5e5f8f88..3309a7cb 100644 --- a/Wacs.Core/Types/CastFlags.cs +++ b/Wacs.Core/Types/CastFlags.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; diff --git a/Wacs.Core/Types/CompositeType.cs b/Wacs.Core/Types/CompositeType.cs index 8ed0213e..2222792c 100644 --- a/Wacs.Core/Types/CompositeType.cs +++ b/Wacs.Core/Types/CompositeType.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Collections.Generic; @@ -26,6 +24,15 @@ namespace Wacs.Core.Types { public abstract class CompositeType { + public ValType HeapType => + this switch + { + FunctionType ft => ValType.FuncRef, + ArrayType at => ValType.Array, + StructType st => ValType.Struct, + _ => throw new InvalidDataException($"Unknown CompType:{this}"), + }; + public static CompositeType ParseTagged(BinaryReader reader) => reader.ReadByte() switch { @@ -35,15 +42,6 @@ public static CompositeType ParseTagged(BinaryReader reader) => var form => throw new FormatException( $"Invalid comptype format {form} at offset {reader.BaseStream.Position - 1}.") }; - - public ValType HeapType => - this switch - { - FunctionType ft => ValType.FuncRef, - ArrayType at => ValType.Array, - StructType st => ValType.Struct, - _ => throw new InvalidDataException($"Unknown CompType:{this}"), - }; /// /// https://webassembly.github.io/gc/core/bikeshed/index.html#composite-types⑤ @@ -60,6 +58,8 @@ public bool Matches(CompositeType super, TypesSpace? types) => _ => false }; + public abstract int ComputeHash(int defIndexValue, List defs); + public class Validator : AbstractValidator { public Validator() @@ -113,7 +113,5 @@ public Validator() }); } } - - public abstract int ComputeHash(int defIndexValue, List defs); } } \ No newline at end of file diff --git a/Wacs.Core/Types/DefType.cs b/Wacs.Core/Types/DefType.cs index a71fdad1..3542b9a0 100644 --- a/Wacs.Core/Types/DefType.cs +++ b/Wacs.Core/Types/DefType.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System.Collections.Generic; using System.Linq; @@ -22,14 +20,16 @@ namespace Wacs.Core.Types { public class DefType { - public readonly RecursiveType RecType; public readonly TypeIdx DefIndex; - private int Projection; + private readonly int Projection; + public readonly RecursiveType RecType; - public List SuperTypes; + private int _computedHash; public CompositeType Expansion; + public List SuperTypes; + public DefType(RecursiveType recType, int proj, TypeIdx def) { RecType = recType; @@ -44,8 +44,6 @@ public DefType(RecursiveType recType, int proj, TypeIdx def) public SubType Unroll => RecType.SubTypes[Projection]; - private int _computedHash; - public void ComputeHash() { var hash = new StableHash(); diff --git a/Wacs.Core/Types/Defs/AddrType.cs b/Wacs.Core/Types/Defs/AddrType.cs index 596be1bb..7f1700a1 100644 --- a/Wacs.Core/Types/Defs/AddrType.cs +++ b/Wacs.Core/Types/Defs/AddrType.cs @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +using System; + namespace Wacs.Core.Types.Defs { public enum AddrType : byte @@ -23,12 +25,12 @@ public enum AddrType : byte public static class AddrTypeExtensions { public static AddrType Min(this AddrType type, AddrType other) => type <= other ? type : other; - + public static ValType ToValType(this AddrType type) => type switch { AddrType.I32 => ValType.I32, AddrType.I64 => ValType.I64, - _ => throw new System.NotImplementedException() + _ => throw new NotImplementedException() }; } } \ No newline at end of file diff --git a/Wacs.Core/Types/Defs/CatchType.cs b/Wacs.Core/Types/Defs/CatchType.cs index b332d490..386ac201 100644 --- a/Wacs.Core/Types/Defs/CatchType.cs +++ b/Wacs.Core/Types/Defs/CatchType.cs @@ -21,23 +21,23 @@ namespace Wacs.Core.Types.Defs { public class CatchType { + public LabelIdx L; public CatchFlags Mode; public TagIdx X; - public LabelIdx L; - + public CatchType(CatchFlags mode, TagIdx x, LabelIdx l) { Mode = mode; X = x; L = l; } - + public CatchType(CatchFlags mode, LabelIdx l) { Mode = mode; L = l; } - + public static CatchType Parse(BinaryReader reader) { return (CatchFlags)reader.ReadByte() switch @@ -49,8 +49,8 @@ public static CatchType Parse(BinaryReader reader) _ => throw new InvalidDataException($"Invalid catch type") }; } - - + + public class Validator : AbstractValidator { public Validator() diff --git a/Wacs.Core/Types/Defs/CompType.cs b/Wacs.Core/Types/Defs/CompType.cs index f354643a..44b84506 100644 --- a/Wacs.Core/Types/Defs/CompType.cs +++ b/Wacs.Core/Types/Defs/CompType.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. namespace Wacs.Core.Types.Defs { diff --git a/Wacs.Core/Types/Defs/ElementType.cs b/Wacs.Core/Types/Defs/ElementType.cs index 9f45cfce..002c7c14 100644 --- a/Wacs.Core/Types/Defs/ElementType.cs +++ b/Wacs.Core/Types/Defs/ElementType.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. namespace Wacs.Core.Types.Defs { diff --git a/Wacs.Core/Types/Defs/ExternalKind.cs b/Wacs.Core/Types/Defs/ExternalKind.cs index b02f1ab3..3b4ed4f7 100644 --- a/Wacs.Core/Types/Defs/ExternalKind.cs +++ b/Wacs.Core/Types/Defs/ExternalKind.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.IO; diff --git a/Wacs.Core/Types/Defs/HeapType.cs b/Wacs.Core/Types/Defs/HeapType.cs index 6adc0082..25317c9c 100644 --- a/Wacs.Core/Types/Defs/HeapType.cs +++ b/Wacs.Core/Types/Defs/HeapType.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using Wacs.Core.Attributes; diff --git a/Wacs.Core/Types/Defs/NumType.cs b/Wacs.Core/Types/Defs/NumType.cs index eaa7f79f..75674bc6 100644 --- a/Wacs.Core/Types/Defs/NumType.cs +++ b/Wacs.Core/Types/Defs/NumType.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using Wacs.Core.Attributes; diff --git a/Wacs.Core/Types/Defs/PackedExt.cs b/Wacs.Core/Types/Defs/PackedExt.cs index f546a8d5..f797b582 100644 --- a/Wacs.Core/Types/Defs/PackedExt.cs +++ b/Wacs.Core/Types/Defs/PackedExt.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. namespace Wacs.Core.Types.Defs { diff --git a/Wacs.Core/Types/Defs/PackedType.cs b/Wacs.Core/Types/Defs/PackedType.cs index 41e60374..e60aea08 100644 --- a/Wacs.Core/Types/Defs/PackedType.cs +++ b/Wacs.Core/Types/Defs/PackedType.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. namespace Wacs.Core.Types.Defs { diff --git a/Wacs.Core/Types/Defs/RecType.cs b/Wacs.Core/Types/Defs/RecType.cs index c69b9881..12f3d428 100644 --- a/Wacs.Core/Types/Defs/RecType.cs +++ b/Wacs.Core/Types/Defs/RecType.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. namespace Wacs.Core.Types { diff --git a/Wacs.Core/Types/Defs/TypePrefix.cs b/Wacs.Core/Types/Defs/TypePrefix.cs index 967b85f0..44dfff3b 100644 --- a/Wacs.Core/Types/Defs/TypePrefix.cs +++ b/Wacs.Core/Types/Defs/TypePrefix.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. namespace Wacs.Core.Types.Defs { diff --git a/Wacs.Core/Types/Defs/ValType.cs b/Wacs.Core/Types/Defs/ValType.cs index f1b425e9..16cd25e9 100644 --- a/Wacs.Core/Types/Defs/ValType.cs +++ b/Wacs.Core/Types/Defs/ValType.cs @@ -1,25 +1,21 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Collections.Generic; -using System.Diagnostics; using System.IO; using System.Text; -using System.Text.RegularExpressions; using Wacs.Core.Attributes; using Wacs.Core.Runtime; using Wacs.Core.Utilities; @@ -103,11 +99,10 @@ public enum ValType : int public class Wat { + private readonly ValType _type; + private Wat(ValType type) => _type = type; public static explicit operator Wat(ValType type) => new Wat(type); - private ValType _type; - private Wat(ValType type) => _type = type; - public override string ToString() { StringBuilder sb = new(); @@ -129,15 +124,14 @@ public override string ToString() public static class ValueTypeExtensions { - public static string ToString(this ValType type) => Enum.IsDefined(typeof(ValType), type) ? type.ToWat() : $"ValType({type:X})"; - + public static TypeIdx Index(this ValType type) => (TypeIdx)((int)type & (int)ValType.IndexMask); public static bool IsDefType(this ValType type) => type.Index().Value >= 0; - + public static bool IsNullable(this ValType type) => (type & ValType.Nullable) != 0; public static bool IsNull(this ValType type) => type switch @@ -225,7 +219,7 @@ public static ValType TopHeapType(this ValType heapType, TypesSpace types) => }, ValType.Bot or _ => throw new Exception($"HeapType {heapType} cannot occur in source"), }; - + public static bool Validate(this ValType type, TypesSpace? types) => type switch { @@ -466,7 +460,7 @@ public static ValType ParseRefType(BinaryReader reader) throw new FormatException($"Type is not a Reference Type:{type}"); return type; } - + //For parsing unrolled recursive (module-level) type indexes public static ValType ParseDefType(BinaryReader reader) => Parse(reader, true, false); diff --git a/Wacs.Core/Types/Defs/VecType.cs b/Wacs.Core/Types/Defs/VecType.cs index d4387ee8..830fa00e 100644 --- a/Wacs.Core/Types/Defs/VecType.cs +++ b/Wacs.Core/Types/Defs/VecType.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using Wacs.Core.Attributes; diff --git a/Wacs.Core/Types/Expression.cs b/Wacs.Core/Types/Expression.cs index 8c222715..524c4463 100644 --- a/Wacs.Core/Types/Expression.cs +++ b/Wacs.Core/Types/Expression.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Collections.Generic; @@ -44,15 +42,15 @@ public class Expression /// /// /// - private Expression(InstructionSequence seq, bool isStatic) + private Expression(InstructionSequence seq, bool isStatic, OpCode inst = OpCode.Expr) { Instructions = seq; IsStatic = isStatic; LabelTarget = new(new Label { - //Compute Arity in PrecomputeLabels - ContinuationAddress = new InstructionPointer(Instructions, 1), - Instruction = OpCode.Expr, + //Compute Arity in during link + ContinuationAddress = 1, + Instruction = inst, StackHeight = -1, }); } @@ -70,7 +68,7 @@ public Expression(int arity, InstructionSequence seq, bool isStatic) LabelTarget = new(new Label { Arity = arity, - ContinuationAddress = new InstructionPointer(Instructions, 1), + ContinuationAddress = 1, Instruction = OpCode.Expr, StackHeight = 0, }); @@ -84,7 +82,7 @@ public Expression(int arity, InstructionBase single) LabelTarget = new (new Label { Arity = arity, - ContinuationAddress = new InstructionPointer(Instructions, 1), + ContinuationAddress = 1, Instruction = OpCode.Expr, StackHeight = 0, }); @@ -102,41 +100,52 @@ private void LinkLabelTarget(IWasmValidationContext vContext, InstructionSequenc for (int i = 0; i < seq.Count; ++i) { var inst = seq._instructions[i]; + inst.Validate(vContext); - - if (inst is BlockTarget target) - { - target.EnclosingBlock = enclosingTarget; - var blockInst = target as IBlockInstruction; + int stackHeight = vContext.OpStack.Height; - var block = blockInst!.GetBlock(0); - int arity = 0; - try + switch (inst) + { + case InstElse instElse: + //The enclosingTarget is the InstIf, InstElse should have the same parent. + instElse.EnclosingBlock = enclosingTarget.EnclosingBlock; + break; + case BlockTarget target: { - var funcType = vContext.Types.ResolveBlockType(block.BlockType); - if (funcType == null) - throw new IndexOutOfRangeException(); + target.EnclosingBlock = enclosingTarget; + var blockInst = target as IBlockInstruction; - arity = inst is InstLoop ? funcType.ParameterTypes.Arity : funcType.ResultType.Arity; - } - catch (IndexOutOfRangeException) - { - throw new InvalidDataException($"Failure computing Labels. BlockType:{block.BlockType} did not exist in the Module"); - } + var block = blockInst!.GetBlock(0); + int arity = 0; + try + { + var funcType = vContext.Types.ResolveBlockType(block.BlockType); + if (funcType == null) + throw new IndexOutOfRangeException(); - var label = target.Label ?? new Label(); - label.Arity = arity; - label.ContinuationAddress = new InstructionPointer(seq, i); - label.Instruction = inst.Op; - //HACK: Use any existing precomputed StackHeight (assume optimization has not changed this value) - label.StackHeight = (target.Label?.StackHeight ?? -1) >= 0 - ? target.Label!.StackHeight - : vContext.OpStack.Height; + arity = inst is InstLoop ? funcType.ParameterTypes.Arity : funcType.ResultType.Arity; + } + catch (IndexOutOfRangeException) + { + throw new InvalidDataException($"Failure computing Labels. BlockType:{block.BlockType} did not exist in the Module"); + } + + var label = target.Label ?? new Label(); + label.Arity = arity; + label.ContinuationAddress = i; + label.Instruction = inst.Op; + // label.StackHeight = stackHeight; + //HACK: Use any existing precomputed StackHeight (assume optimization has not changed this value) + label.StackHeight = (target.Label?.StackHeight ?? -1) >= 0 + ? target.Label!.StackHeight + : vContext.OpStack.Height; - for (int b = 0; b < blockInst!.Count; ++b) - LinkLabelTarget(vContext,blockInst.GetBlock(b).Instructions, target); + for (int b = 0; b < blockInst!.Count; ++b) + LinkLabelTarget(vContext,blockInst.GetBlock(b).Instructions, target); - target.Label = label; + target.Label = label; + break; + } } } } @@ -147,6 +156,7 @@ private void LinkLabelTarget(IWasmValidationContext vContext, InstructionSequenc /// public void ExecuteInitializer(ExecContext context) { + int callStackHeight = context.StackHeight; var frame = context.ReserveFrame(context.Frame.Module, FunctionType.Empty, FuncIdx.ExpressionEvaluation); if (context.OpStack.Count != 0) throw new InvalidDataException("OpStack should be empty"); @@ -157,14 +167,20 @@ public void ExecuteInitializer(ExecContext context) { inst.Execute(context); } - context.PopFrame(); + + //Our expression may have popped the callstack for us, + // but if it hasn't we should clean up. + while (context.StackHeight > callStackHeight) + { + context.PopFrame(); + } } /// /// @Spec 5.4.9 Expressions /// - public static Expression Parse(BinaryReader reader) => - new(new InstructionSequence(reader.ParseUntil(BinaryModuleParser.ParseInstruction, InstructionBase.IsEnd)), true); + public static Expression ParseFunc(BinaryReader reader) => + new(new InstructionSequence(reader.ParseUntil(BinaryModuleParser.ParseInstruction, InstructionBase.IsEnd), true), true, OpCode.Func); public static Expression ParseInitializer(BinaryReader reader) => new(1, new InstructionSequence(reader.ParseUntil(BinaryModuleParser.ParseInstruction, InstructionBase.IsEnd)), true); @@ -183,6 +199,32 @@ public string ToWat() public bool ContainsInstructions(HashSet opcodes) => Instructions.ContainsInstruction(opcodes); + public IEnumerable Flatten() + { + Queue seq = new(); + Enqueue(seq, Instructions); + return seq; + } + + private static void Enqueue(Queue queue, IEnumerable instructions) + { + foreach (var inst in instructions) + { + queue.Enqueue(inst); + switch (inst) + { + case IBlockInstruction node: + for (int i = 0; i < node.Count; i++) + { + var block = node.GetBlock(i); + Enqueue(queue, block.Instructions); + } + break; + default: break; + } + } + } + /// /// @Spec 3.3.10. Expressions /// diff --git a/Wacs.Core/Types/FieldType.cs b/Wacs.Core/Types/FieldType.cs index 3ef8d2ca..48ed9a88 100644 --- a/Wacs.Core/Types/FieldType.cs +++ b/Wacs.Core/Types/FieldType.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Collections.Generic; @@ -37,7 +35,7 @@ public FieldType(ValType st, Mutability mut) Mut = mut; StorageType = st; } - + public static FieldType Parse(BinaryReader reader) => new( ValTypeParser.Parse(reader, parseBlockIndex: false, parseStorageType: true), @@ -100,7 +98,7 @@ public Value UnpackValue(ReadOnlySpan bytes) ValType.V128 => Types.BitWidth.V128, _ => Types.BitWidth.None, }; - + public bool ValidExtension(PackedExt pt) => pt switch { PackedExt.NotPacked => StorageType is not (ValType.I8 or ValType.I16), @@ -108,6 +106,15 @@ public Value UnpackValue(ReadOnlySpan bytes) _ => false }; + public int ComputeHash(int defIndexValue, List defs) + { + var hash = new StableHash(); + hash.Add(nameof(FieldType)); + hash.Add(Mut); + hash.Add(StorageType.ComputeHash(defIndexValue,defs)); + return hash.ToHashCode(); + } + public class Validator : AbstractValidator { public Validator() @@ -126,14 +133,5 @@ public Validator() //Spec ignores Mutability for validation } } - - public int ComputeHash(int defIndexValue, List defs) - { - var hash = new StableHash(); - hash.Add(nameof(FieldType)); - hash.Add(Mut); - hash.Add(StorageType.ComputeHash(defIndexValue,defs)); - return hash.ToHashCode(); - } } } \ No newline at end of file diff --git a/Wacs.Core/Types/FunctionType.cs b/Wacs.Core/Types/FunctionType.cs index f3de2d18..22567674 100644 --- a/Wacs.Core/Types/FunctionType.cs +++ b/Wacs.Core/Types/FunctionType.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System.Collections.Generic; using System.IO; @@ -115,7 +113,7 @@ public override int ComputeHash(int defIndexValue, List defs) hash.Add(ResultType.ComputeHash(defIndexValue,defs)); return hash.ToHashCode(); } - + /// /// 3.2.3. Function Types /// Always valid diff --git a/Wacs.Core/Types/GlobalType.cs b/Wacs.Core/Types/GlobalType.cs index 07cb7887..86177978 100644 --- a/Wacs.Core/Types/GlobalType.cs +++ b/Wacs.Core/Types/GlobalType.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.IO; @@ -70,6 +68,17 @@ public static GlobalType Parse(BinaryReader reader) => mut: MutabilityParser.Parse(reader) ); + public bool Matches(GlobalType other, TypesSpace? types) + { + if (Mutability != other.Mutability) + return false; + if (!ContentType.Matches(other.ContentType, types)) + return false; + if (Mutability == Mutability.Mutable && !other.ContentType.Matches(ContentType, types)) + return false; + return true; + } + /// /// @Spec 3.2.6. Global Types /// @@ -83,17 +92,6 @@ public Validator() { .WithMessage(gt => $"GlobalType had invalid ContentType {gt.ContentType}"); } } - - public bool Matches(GlobalType other, TypesSpace? types) - { - if (Mutability != other.Mutability) - return false; - if (!ContentType.Matches(other.ContentType, types)) - return false; - if (Mutability == Mutability.Mutable && !other.ContentType.Matches(ContentType, types)) - return false; - return true; - } } /// diff --git a/Wacs.Core/Types/IndexSpace.cs b/Wacs.Core/Types/IndexSpace.cs index 843337d4..8ba9bca0 100644 --- a/Wacs.Core/Types/IndexSpace.cs +++ b/Wacs.Core/Types/IndexSpace.cs @@ -1,25 +1,22 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; -using FluentValidation; using Wacs.Core.Runtime; using Wacs.Core.Runtime.Exceptions; using Wacs.Core.Types.Defs; @@ -106,17 +103,17 @@ public GlobalAddr this[GlobalIdx idx] public class TagAddrs { private readonly List _space = new(); - + public TagAddr this[TagIdx idx] { get => _space[(int)idx.Value]; set => _space[(int)idx.Value] = value; } - + public bool Contains(TagIdx idx) => idx.Value < _space.Count; - + public void Add(TagAddr element) => _space.Add(element); - + public IEnumerator GetEnumerator() => _space.GetEnumerator(); } @@ -266,8 +263,8 @@ public bool Contains(MemIdx idx) => public class GlobalValidationSpace : AbstractIndexSpace { - private readonly ReadOnlyCollection _imports; private readonly ReadOnlyCollection _globals; + private readonly ReadOnlyCollection _imports; public int IncrementalHighWatermark = -1; public GlobalValidationSpace(Module module) @@ -389,7 +386,7 @@ public class TagsSpace : AbstractIndexSpace { private readonly ReadOnlyCollection _imports; private readonly ReadOnlyCollection _tags; - + public TagsSpace(Module module) { _imports = module.ImportedTags; diff --git a/Wacs.Core/Types/Indices.cs b/Wacs.Core/Types/Indices.cs index 7c2156de..bc1d92c2 100644 --- a/Wacs.Core/Types/Indices.cs +++ b/Wacs.Core/Types/Indices.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using Wacs.Core.Runtime.Exceptions; @@ -189,6 +187,9 @@ private LocalIdx(int value) public static explicit operator Index(LabelIdx labelIdx) => new((int)labelIdx.Value); public static explicit operator LabelIdx(int value) => new((uint)value); public static explicit operator LabelIdx(uint value) => new(value); + + public static LabelIdx operator +(LabelIdx left, int right) => new((uint)(left.Value + right)); + public static LabelIdx operator -(LabelIdx left, int right) => new((uint)(left.Value - right)); } public readonly struct FieldIdx : IEquatable diff --git a/Wacs.Core/Types/Limits.cs b/Wacs.Core/Types/Limits.cs index ead1c314..3c08bd46 100644 --- a/Wacs.Core/Types/Limits.cs +++ b/Wacs.Core/Types/Limits.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.IO; @@ -28,6 +26,11 @@ namespace Wacs.Core.Types /// public class Limits : ICloneable { + /// + /// The address type of the memory. + /// + public AddrType AddressType; + /// /// The optional maximum number of units. If MaxValue, there is no specified maximum. /// @@ -38,11 +41,6 @@ public class Limits : ICloneable /// public long Minimum; - /// - /// The address type of the memory. - /// - public AddrType AddressType; - /// /// For threads, indicates whether the memory is shared. /// diff --git a/Wacs.Core/Types/MemArg.cs b/Wacs.Core/Types/MemArg.cs index 679f95b9..f35ab448 100644 --- a/Wacs.Core/Types/MemArg.cs +++ b/Wacs.Core/Types/MemArg.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System.IO; using Wacs.Core.Utilities; diff --git a/Wacs.Core/Types/MemoryType.cs b/Wacs.Core/Types/MemoryType.cs index 09478eff..8c3262fe 100644 --- a/Wacs.Core/Types/MemoryType.cs +++ b/Wacs.Core/Types/MemoryType.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System.IO; using FluentValidation; @@ -31,7 +29,7 @@ public class MemoryType : IRenderable /// The limits specifying the minimum and optional maximum number of memory pages. /// public readonly Limits Limits; - + /// /// Initializes a new instance of the class with the specified limits. /// diff --git a/Wacs.Core/Types/RecursiveType.cs b/Wacs.Core/Types/RecursiveType.cs index ed0ccf99..e99892eb 100644 --- a/Wacs.Core/Types/RecursiveType.cs +++ b/Wacs.Core/Types/RecursiveType.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Collections.Generic; @@ -28,6 +26,9 @@ namespace Wacs.Core.Types public class RecursiveType : IRenderable { public readonly SubType[] SubTypes; + + private int _computedHash; + //The defType index of the first subtype public TypeIdx DefIndex = TypeIdx.Default; @@ -41,8 +42,22 @@ public RecursiveType(SubType[] subTypes) SubTypes = subTypes; } - private int _computedHash; - + /// + /// For rendering/debugging + /// + public string Id { get; set; } = ""; + + public void RenderText(StreamWriter writer, Module module, string indent) + { + var symbol = string.IsNullOrWhiteSpace(Id) ? "" : $" (;{Id};)"; + // var parameters = ParameterTypes.ToParameters(); + // var results = ResultType.ToResults(); + // var func = $" (func{parameters}{results})"; + var func = ""; + + writer.WriteLine($"{indent}(type{symbol}{func})"); + } + public void ComputeHash(List defs) { var hash = new StableHash(); @@ -65,22 +80,6 @@ public static implicit operator FunctionType(RecursiveType recursiveType) throw new InvalidDataException($"RecursiveType ({recursiveType}) was not a FunctionType"); return func; } - - /// - /// For rendering/debugging - /// - public string Id { get; set; } = ""; - - public void RenderText(StreamWriter writer, Module module, string indent) - { - var symbol = string.IsNullOrWhiteSpace(Id) ? "" : $" (;{Id};)"; - // var parameters = ParameterTypes.ToParameters(); - // var results = ResultType.ToResults(); - // var func = $" (func{parameters}{results})"; - var func = ""; - - writer.WriteLine($"{indent}(type{symbol}{func})"); - } private static TypeIdx ParseTypeIndexes(BinaryReader reader) => (TypeIdx)reader.ReadLeb128_u32(); @@ -117,7 +116,7 @@ public static RecursiveType Parse(BinaryReader reader) => var form => throw new FormatException( $"Invalid type format {form} at offset {reader.BaseStream.Position-1}.") }; - + public class Validator : AbstractValidator { /// https://webassembly.github.io/gc/core/bikeshed/index.html#-hrefsyntax-rectypemathsfrechrefsyntax-subtypemathitsubtypeast @@ -144,6 +143,5 @@ public Validator() }); } } - } } \ No newline at end of file diff --git a/Wacs.Core/Types/ResultType.cs b/Wacs.Core/Types/ResultType.cs index 5b9f648c..a657f06a 100644 --- a/Wacs.Core/Types/ResultType.cs +++ b/Wacs.Core/Types/ResultType.cs @@ -1,24 +1,21 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Collections.Generic; using System.IO; using System.Linq; -using Wacs.Core.Attributes; using Wacs.Core.Types.Defs; using Wacs.Core.Utilities; @@ -68,7 +65,7 @@ private ResultType(BinaryReader reader) Types = reader.ParseVector(ValTypeParser.Parse); Arity = Types.Length; } - + public ResultType Append(ValType type) { var newTypes = new ValType[Types.Length + 1]; @@ -101,7 +98,7 @@ public bool Matches(ResultType other, TypesSpace? types) return true; } - + public bool Equals(ResultType other) { if (Types.Length != other.Types.Length) diff --git a/Wacs.Core/Types/StorageType.cs b/Wacs.Core/Types/StorageType.cs index 03e07c88..6455a775 100644 --- a/Wacs.Core/Types/StorageType.cs +++ b/Wacs.Core/Types/StorageType.cs @@ -1,23 +1,19 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. namespace Wacs.Core.Types { public class StorageType - { - - } + {} } \ No newline at end of file diff --git a/Wacs.Core/Types/StructType.cs b/Wacs.Core/Types/StructType.cs index 53eaa90d..e522a7f0 100644 --- a/Wacs.Core/Types/StructType.cs +++ b/Wacs.Core/Types/StructType.cs @@ -1,25 +1,20 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. -using System; using System.Collections.Generic; using System.IO; using System.Linq; -using FluentValidation; -using Wacs.Core.Types.Defs; using Wacs.Core.Utilities; namespace Wacs.Core.Types @@ -27,18 +22,19 @@ namespace Wacs.Core.Types public class StructType : CompositeType { public readonly FieldType[] FieldTypes; - public int Arity => FieldTypes.Length; public StructType(FieldType[] types) { FieldTypes = types; } - public static StructType Parse(BinaryReader reader) => - new(reader.ParseVector(FieldType.Parse)); + public int Arity => FieldTypes.Length; public FieldType this[FieldIdx y] => FieldTypes[y.Value]; + public static StructType Parse(BinaryReader reader) => + new(reader.ParseVector(FieldType.Parse)); + public bool Matches(StructType other, TypesSpace? types) { if (Arity < other.Arity) @@ -50,7 +46,7 @@ public bool Matches(StructType other, TypesSpace? types) } return true; } - + public override int ComputeHash(int defIndexValue, List defs) { var hash = new StableHash(); diff --git a/Wacs.Core/Types/SubType.cs b/Wacs.Core/Types/SubType.cs index 6abc70fd..52c294d9 100644 --- a/Wacs.Core/Types/SubType.cs +++ b/Wacs.Core/Types/SubType.cs @@ -1,22 +1,19 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Collections.Generic; -using System.Data; using System.IO; using FluentValidation; using Wacs.Core.Types.Defs; @@ -27,9 +24,9 @@ namespace Wacs.Core.Types { public class SubType { + public readonly CompositeType Body; public readonly bool Final; public readonly TypeIdx[] SuperTypeIndexes; - public readonly CompositeType Body; public SubType(TypeIdx[] idxs, CompositeType body, bool final) { @@ -37,7 +34,7 @@ public SubType(TypeIdx[] idxs, CompositeType body, bool final) Body = body; Final = final; } - + public SubType(CompositeType body, bool final) { SuperTypeIndexes = Array.Empty(); @@ -48,10 +45,12 @@ public SubType(CompositeType body, bool final) hash.Add(nameof(SubType)); ComputedHash = hash.ToHashCode(); } - + + private int ComputedHash { get; set; } + public static TypeIdx ParseTypeIndexes(BinaryReader reader) => (TypeIdx)reader.ReadLeb128_u32(); - + public static SubType Parse(BinaryReader reader) { return reader.ReadByte() switch @@ -75,8 +74,6 @@ public static SubType Parse(BinaryReader reader) }; } - private int ComputedHash { get; set; } - public void ComputeHash(int defIndexValue, List defs) { var hash = new StableHash(); diff --git a/Wacs.Core/Types/TableType.cs b/Wacs.Core/Types/TableType.cs index 8bbe10d9..44bcc758 100644 --- a/Wacs.Core/Types/TableType.cs +++ b/Wacs.Core/Types/TableType.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.IO; @@ -32,18 +30,21 @@ namespace Wacs.Core.Types /// public class TableType : ICloneable, IRenderable { + private const byte TableTypeExpr = 0x40; + private const byte FutureExtByte = 0x00; + /// /// The element type of the table (e.g., funcref or externref). /// public readonly ValType ElementType; + public readonly Expression Init; + /// /// The limits specifying the minimum and optional maximum number of elements. /// public Limits Limits = null!; - public readonly Expression Init; - public TableType(ValType elementType, Limits limits, Expression? init = null) { ElementType = elementType; @@ -77,9 +78,6 @@ public void RenderText(StreamWriter writer, Module module, string indent) public override string ToString() => $"TableType({ElementType}[{Limits}])"; - private const byte TableTypeExpr = 0x40; - private const byte FutureExtByte = 0x00; - private static TableType ParseTableTypeWithExpr(BinaryReader reader) { switch (reader.ReadByte()) @@ -93,7 +91,7 @@ private static TableType ParseTableTypeWithExpr(BinaryReader reader) var init = Expression.ParseInitializer(reader); return new(type, limits, init); } - + /// /// https://webassembly.github.io/gc/core/bikeshed/index.html#table-section① /// diff --git a/Wacs.Core/Types/TagType.cs b/Wacs.Core/Types/TagType.cs index a0e4e87f..2c924036 100644 --- a/Wacs.Core/Types/TagType.cs +++ b/Wacs.Core/Types/TagType.cs @@ -24,13 +24,13 @@ public class TagType { public TagTypeAttribute Attribute; public TypeIdx TypeIndex; - + public TagType(TagTypeAttribute attribute, TypeIdx typeIndex) { Attribute = attribute; TypeIndex = typeIndex; } - + public static TagType Parse(BinaryReader reader) { return new TagType( @@ -38,7 +38,7 @@ public static TagType Parse(BinaryReader reader) (TypeIdx)reader.ReadLeb128_u32() ); } - + public class Validator : AbstractValidator { public Validator() diff --git a/Wacs.Core/Utilities/BinaryReaderExtension.cs b/Wacs.Core/Utilities/BinaryReaderExtension.cs index f190eec9..47124b79 100644 --- a/Wacs.Core/Utilities/BinaryReaderExtension.cs +++ b/Wacs.Core/Utilities/BinaryReaderExtension.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Collections.Generic; @@ -48,7 +46,7 @@ public static uint ReadLeb128_u32(this BinaryReader reader) return result; } - + public static ulong ReadLeb128_u64(this BinaryReader reader) { ulong result = 0; diff --git a/Wacs.Core/Utilities/BytesEncoder.cs b/Wacs.Core/Utilities/BytesEncoder.cs index 72a38317..a4301b5c 100644 --- a/Wacs.Core/Utilities/BytesEncoder.cs +++ b/Wacs.Core/Utilities/BytesEncoder.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Text; diff --git a/Wacs.Core/Utilities/Constants.cs b/Wacs.Core/Utilities/Constants.cs index 65d05a92..bd718477 100644 --- a/Wacs.Core/Utilities/Constants.cs +++ b/Wacs.Core/Utilities/Constants.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. namespace Wacs.Core.Utilities { diff --git a/Wacs.Core/Utilities/FloatConversion.cs b/Wacs.Core/Utilities/FloatConversion.cs index 205400e5..ad8ff11b 100644 --- a/Wacs.Core/Utilities/FloatConversion.cs +++ b/Wacs.Core/Utilities/FloatConversion.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; diff --git a/Wacs.Core/Utilities/FloatFormatter.cs b/Wacs.Core/Utilities/FloatFormatter.cs index 639b2f08..76ddf869 100644 --- a/Wacs.Core/Utilities/FloatFormatter.cs +++ b/Wacs.Core/Utilities/FloatFormatter.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Text; diff --git a/Wacs.Core/Utilities/IPoolable.cs b/Wacs.Core/Utilities/IPoolable.cs index cffbfe53..35c884af 100644 --- a/Wacs.Core/Utilities/IPoolable.cs +++ b/Wacs.Core/Utilities/IPoolable.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. namespace Wacs.Core.Utilities { diff --git a/Wacs.Core/Utilities/ObjectPoolExtension.cs b/Wacs.Core/Utilities/ObjectPoolExtension.cs index 06c259b2..1c95d1ef 100644 --- a/Wacs.Core/Utilities/ObjectPoolExtension.cs +++ b/Wacs.Core/Utilities/ObjectPoolExtension.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System.Collections.Generic; using Microsoft.Extensions.ObjectPool; diff --git a/Wacs.Core/Utilities/StableHash.cs b/Wacs.Core/Utilities/StableHash.cs index 243c8d99..436f30dd 100644 --- a/Wacs.Core/Utilities/StableHash.cs +++ b/Wacs.Core/Utilities/StableHash.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Collections; @@ -209,6 +207,5 @@ public static StableHash Combine(StableHash first, StableHash second) combined._hash = combined._hash * Multiplier + second._hash; return combined; } - } } \ No newline at end of file diff --git a/Wacs.Core/Utilities/StackExtension.cs b/Wacs.Core/Utilities/StackExtension.cs index 8fdd18c6..ff8605cb 100644 --- a/Wacs.Core/Utilities/StackExtension.cs +++ b/Wacs.Core/Utilities/StackExtension.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Collections.Generic; diff --git a/Wacs.Core/Utilities/StackPoolPolicy.cs b/Wacs.Core/Utilities/StackPoolPolicy.cs index c9e68544..ff052469 100644 --- a/Wacs.Core/Utilities/StackPoolPolicy.cs +++ b/Wacs.Core/Utilities/StackPoolPolicy.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using Microsoft.Extensions.ObjectPool; diff --git a/Wacs.Core/Utilities/StringExtension.cs b/Wacs.Core/Utilities/StringExtension.cs index 3c0a32d1..f768002b 100644 --- a/Wacs.Core/Utilities/StringExtension.cs +++ b/Wacs.Core/Utilities/StringExtension.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. namespace Wacs.Core.Utilities { diff --git a/Wacs.Core/Utilities/TypeExtensions.cs b/Wacs.Core/Utilities/TypeExtensions.cs index 606606b6..65add268 100644 --- a/Wacs.Core/Utilities/TypeExtensions.cs +++ b/Wacs.Core/Utilities/TypeExtensions.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System.Linq; using System.Numerics; diff --git a/Wacs.Core/Validation/IWasmValidationContext.cs b/Wacs.Core/Validation/IWasmValidationContext.cs index d430d59e..c3f686e8 100644 --- a/Wacs.Core/Validation/IWasmValidationContext.cs +++ b/Wacs.Core/Validation/IWasmValidationContext.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; diff --git a/Wacs.Core/Validation/Validation.cs b/Wacs.Core/Validation/Validation.cs index f354598c..822196ea 100644 --- a/Wacs.Core/Validation/Validation.cs +++ b/Wacs.Core/Validation/Validation.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using FluentValidation; using Wacs.Core.Types; diff --git a/Wacs.Core/Validation/ValidationContextExtension.cs b/Wacs.Core/Validation/ValidationContextExtension.cs index 80b78cd4..204c014e 100644 --- a/Wacs.Core/Validation/ValidationContextExtension.cs +++ b/Wacs.Core/Validation/ValidationContextExtension.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using FluentValidation; diff --git a/Wacs.Core/Validation/ValidationControlStack.cs b/Wacs.Core/Validation/ValidationControlStack.cs index ba6cc8e1..0252db00 100644 --- a/Wacs.Core/Validation/ValidationControlStack.cs +++ b/Wacs.Core/Validation/ValidationControlStack.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using Wacs.Core.OpCodes; using Wacs.Core.Types; @@ -21,6 +19,7 @@ namespace Wacs.Core.Validation { public class ValidationControlFrame { + public LocalsSpace Locals; public ByteCode Opcode { get; set; } public FunctionType Types { get; set; } = null!; @@ -28,8 +27,6 @@ public class ValidationControlFrame public ResultType EndTypes => Types.ResultType; public ResultType LabelTypes => Opcode == OpCode.Loop ? StartTypes : EndTypes; public int Height { get; set; } - - public LocalsSpace Locals; public bool Unreachable { get; set; } } } \ No newline at end of file diff --git a/Wacs.Core/Validation/ValidationOpStack.cs b/Wacs.Core/Validation/ValidationOpStack.cs index 2466fdb2..35a73857 100644 --- a/Wacs.Core/Validation/ValidationOpStack.cs +++ b/Wacs.Core/Validation/ValidationOpStack.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System.Collections.Generic; using System.Linq; @@ -186,7 +184,7 @@ public Value PopI64() $"Wrong operand type {value.Type} popped from stack. Expected: {ValType.I64}"); return value; } - + public Value PopInt() { if (_stack.Count == _context.ControlFrame.Height && _context.ControlFrame.Unreachable) @@ -274,7 +272,7 @@ public Value PopType(ValType expectedType) return actual; } - + public Value PopAny() { if (_stack.Count == _context.ControlFrame.Height && _context.ControlFrame.Unreachable) @@ -308,6 +306,5 @@ public void ReturnResults(ResultType types) PushType(type); } } - } } \ No newline at end of file diff --git a/Wacs.Core/Validation/WasmValidationContext.cs b/Wacs.Core/Validation/WasmValidationContext.cs index 89959949..ecdcdd59 100644 --- a/Wacs.Core/Validation/WasmValidationContext.cs +++ b/Wacs.Core/Validation/WasmValidationContext.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; using System.Collections.Generic; @@ -84,6 +82,7 @@ public WasmValidationContext(Module module, ValidationContext rootContex public TablesSpace Tables { get; } public MemSpace Mems { get; } public GlobalValidationSpace Globals { get; } + public LocalsSpace Locals => ControlStack.Count == 0 ? ExecFrame.Locals @@ -91,7 +90,7 @@ public WasmValidationContext(Module module, ValidationContext rootContex public ElementsSpace Elements { get; set; } public DataValidationSpace Datas { get; set; } - + public TagsSpace Tags { get; } public bool Unreachable { get; set; } @@ -158,9 +157,6 @@ public void ValidateCatches(CatchType[] catches) PopValidationContext(); } } - - public bool ValidateBlockType(ValType type) => - type.Validate(Types) || type == ValType.Empty; public void PushControlFrame(ByteCode opCode, FunctionType types) { @@ -195,8 +191,10 @@ public ValidationControlFrame PopControlFrame() public bool ContainsLabel(uint label) => ControlStack.Count - 2 >= label; - - + public bool ValidateBlockType(ValType type) => + type.Validate(Types) || type == ValType.Empty; + + public void PopOperandsToHeight(int height) { if (OpStack.Height < height) diff --git a/Wacs.Core/WASIp1/ErrNo.cs b/Wacs.Core/WASIp1/ErrNo.cs index 4a92cd21..c14e377e 100644 --- a/Wacs.Core/WASIp1/ErrNo.cs +++ b/Wacs.Core/WASIp1/ErrNo.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using Wacs.Core.Attributes; using Wacs.Core.Types.Defs; diff --git a/Wacs.Core/WASIp1/SignalAttribute.cs b/Wacs.Core/WASIp1/SignalAttribute.cs index 665fd4b1..6bd24121 100644 --- a/Wacs.Core/WASIp1/SignalAttribute.cs +++ b/Wacs.Core/WASIp1/SignalAttribute.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; diff --git a/Wacs.Core/WASIp1/SignalException.cs b/Wacs.Core/WASIp1/SignalException.cs index 8b3f13ff..d4b623de 100644 --- a/Wacs.Core/WASIp1/SignalException.cs +++ b/Wacs.Core/WASIp1/SignalException.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. using System; diff --git a/Wacs.Core/WASIp1/SystemExit.cs b/Wacs.Core/WASIp1/SystemExit.cs index 9da34e35..1b62e1fb 100644 --- a/Wacs.Core/WASIp1/SystemExit.cs +++ b/Wacs.Core/WASIp1/SystemExit.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. namespace Wacs.Core.WASIp1 { diff --git a/Wacs.Core/WASIp1/SystemExitException.cs b/Wacs.Core/WASIp1/SystemExitException.cs index 8133b3ad..9395bc00 100644 --- a/Wacs.Core/WASIp1/SystemExitException.cs +++ b/Wacs.Core/WASIp1/SystemExitException.cs @@ -1,18 +1,16 @@ -// /* -// * Copyright 2024 Kelvin Nishikawa -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ +// Copyright 2024 Kelvin Nishikawa +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. namespace Wacs.Core.WASIp1 { diff --git a/unity b/unity index 1bec6f8e..b2f1b0a8 160000 --- a/unity +++ b/unity @@ -1 +1 @@ -Subproject commit 1bec6f8e256eafccf7f7a60cf3573ce4e3a7b838 +Subproject commit b2f1b0a8e1428a33f154394c67c664f4714af04f