diff --git a/README.md b/README.md index 40e4fa8..78777bd 100644 --- a/README.md +++ b/README.md @@ -207,7 +207,7 @@ Harnessed results from [wasm-feature-detect](https://github.com/GoogleChromeLabs |[Bulk memory operations](https://github.com/webassembly/bulk-memory-operations)||✅| |[Legacy Exception Handling](https://github.com/WebAssembly/exception-handling)|exceptions|❌| |[Exception Handling with exnref](https://github.com/WebAssembly/exception-handling)|exceptions|❌| -|[Extented Const Expressesions](https://github.com/WebAssembly/extended-const)|extended_const|❌| +|[Extented Const Expressesions](https://github.com/WebAssembly/extended-const)|extended_const|✅| |[Garbage Collection](https://github.com/WebAssembly/gc)|gc|❌| |[JS String Builtins Proposal for WebAssembly](https://github.com/WebAssembly/js-string-builtins)||❌| |[JavaScript Promise Integration](https://github.com/WebAssembly/js-promise-integration)|jspi|🌐| diff --git a/Wacs.Core/Instructions/IConstInstruction.cs b/Wacs.Core/Instructions/IConstInstruction.cs index d0d4850..3bec9f9 100644 --- a/Wacs.Core/Instructions/IConstInstruction.cs +++ b/Wacs.Core/Instructions/IConstInstruction.cs @@ -18,8 +18,15 @@ namespace Wacs.Core.Instructions { - public interface IConstInstruction + public interface IConstInstruction { } + + public interface IContextConstInstruction { public bool IsConstant(IWasmValidationContext? context); } + + public interface IConstOpInstruction + { + public bool IsConstant { get; } + } } \ No newline at end of file diff --git a/Wacs.Core/Instructions/Numeric/Const.cs b/Wacs.Core/Instructions/Numeric/Const.cs index 97047fa..6079794 100644 --- a/Wacs.Core/Instructions/Numeric/Const.cs +++ b/Wacs.Core/Instructions/Numeric/Const.cs @@ -29,8 +29,6 @@ public class InstI32Const : InstructionBase, IConstInstruction public override ByteCode Op => OpCode.I32Const; private int Value { get; set; } - public bool IsConstant(IWasmValidationContext? ctx) => true; - /// /// @Spec 3.3.1.1 t.const /// @@ -64,8 +62,6 @@ public class InstI64Const : InstructionBase, IConstInstruction public override ByteCode Op => OpCode.I64Const; private long Value { get; set; } - public bool IsConstant(IWasmValidationContext? ctx) => true; - /// /// @Spec 3.3.1.1 t.const /// @@ -93,8 +89,6 @@ public class InstF32Const : InstructionBase, IConstInstruction public override ByteCode Op => OpCode.F32Const; private float Value { get; set; } - public bool IsConstant(IWasmValidationContext? ctx) => true; - /// /// @Spec 3.3.1.1 t.const /// @@ -130,8 +124,6 @@ public class InstF64Const : InstructionBase, IConstInstruction public override ByteCode Op => OpCode.F64Const; private double Value { get; set; } - public bool IsConstant(IWasmValidationContext? ctx) => true; - /// /// @Spec 3.3.1.1 t.const /// diff --git a/Wacs.Core/Instructions/Numeric/I32BinOp.cs b/Wacs.Core/Instructions/Numeric/I32BinOp.cs index e70f53d..f8c1116 100644 --- a/Wacs.Core/Instructions/Numeric/I32BinOp.cs +++ b/Wacs.Core/Instructions/Numeric/I32BinOp.cs @@ -25,13 +25,13 @@ public partial class NumericInst { // @Spec 3.3.1.3. i.binop public static readonly NumericInst I32Add = new(OpCode.I32Add, ExecuteI32Add, - ValidateOperands(pop1: ValType.I32, pop2: ValType.I32, push: ValType.I32)); + ValidateOperands(pop1: ValType.I32, pop2: ValType.I32, push: ValType.I32), isConst: true); public static readonly NumericInst I32Sub = new(OpCode.I32Sub, ExecuteI32Sub, - ValidateOperands(pop1: ValType.I32, pop2: ValType.I32, push: ValType.I32)); + ValidateOperands(pop1: ValType.I32, pop2: ValType.I32, push: ValType.I32), isConst: true); public static readonly NumericInst I32Mul = new(OpCode.I32Mul, ExecuteI32Mul, - ValidateOperands(pop1: ValType.I32, pop2: ValType.I32, push: ValType.I32)); + ValidateOperands(pop1: ValType.I32, pop2: ValType.I32, push: ValType.I32), isConst: true); public static readonly NumericInst I32DivS = new(OpCode.I32DivS, ExecuteI32DivS, ValidateOperands(pop1: ValType.I32, pop2: ValType.I32, push: ValType.I32)); diff --git a/Wacs.Core/Instructions/Numeric/I64BinOp.cs b/Wacs.Core/Instructions/Numeric/I64BinOp.cs index 99f8bfa..bfb64d1 100644 --- a/Wacs.Core/Instructions/Numeric/I64BinOp.cs +++ b/Wacs.Core/Instructions/Numeric/I64BinOp.cs @@ -25,13 +25,13 @@ public partial class NumericInst { // @Spec 3.3.1.3. i.binop public static readonly NumericInst I64Add = new(OpCode.I64Add, ExecuteI64Add, - ValidateOperands(pop1: ValType.I64, pop2: ValType.I64, push: ValType.I64)); + ValidateOperands(pop1: ValType.I64, pop2: ValType.I64, push: ValType.I64), isConst: true); public static readonly NumericInst I64Sub = new(OpCode.I64Sub, ExecuteI64Sub, - ValidateOperands(pop1: ValType.I64, pop2: ValType.I64, push: ValType.I64)); + ValidateOperands(pop1: ValType.I64, pop2: ValType.I64, push: ValType.I64), isConst: true); public static readonly NumericInst I64Mul = new(OpCode.I64Mul, ExecuteI64Mul, - ValidateOperands(pop1: ValType.I64, pop2: ValType.I64, push: ValType.I64)); + ValidateOperands(pop1: ValType.I64, pop2: ValType.I64, push: ValType.I64), isConst: true); public static readonly NumericInst I64DivS = new(OpCode.I64DivS, ExecuteI64DivS, ValidateOperands(pop1: ValType.I64, pop2: ValType.I64, push: ValType.I64)); diff --git a/Wacs.Core/Instructions/Numeric/NumericInst.cs b/Wacs.Core/Instructions/Numeric/NumericInst.cs index 12e61b9..27a176f 100644 --- a/Wacs.Core/Instructions/Numeric/NumericInst.cs +++ b/Wacs.Core/Instructions/Numeric/NumericInst.cs @@ -21,14 +21,18 @@ namespace Wacs.Core.Instructions.Numeric { - public partial class NumericInst : InstructionBase + public partial class NumericInst : InstructionBase, IConstOpInstruction { private readonly ExecuteDelegate _execute; private readonly ValidationDelegate _validate; - private NumericInst(ByteCode op, ExecuteDelegate execute, ValidationDelegate validate) => - (Op, _execute, _validate) = (op, execute, validate); + private readonly bool _isConst; + + private NumericInst(ByteCode op, ExecuteDelegate execute, ValidationDelegate validate, bool isConst = false) => + (Op, _execute, _validate, _isConst) = (op, execute, validate, isConst); + + public bool IsConstant => _isConst; public override ByteCode Op { get; } diff --git a/Wacs.Core/Instructions/Reference.cs b/Wacs.Core/Instructions/Reference.cs index 6610d4c..a77241a 100644 --- a/Wacs.Core/Instructions/Reference.cs +++ b/Wacs.Core/Instructions/Reference.cs @@ -17,7 +17,6 @@ public class InstRefNull : InstructionBase, IConstInstruction { public override ByteCode Op => OpCode.RefNull; public ReferenceType Type { get; internal set; } - public bool IsConstant(IWasmValidationContext? ctx) => true; // @Spec 3.3.2.1. ref.null t public override void Validate(IWasmValidationContext context) @@ -71,8 +70,6 @@ public class InstRefFunc : InstructionBase, IConstInstruction public override ByteCode Op => OpCode.RefFunc; public FuncIdx FunctionIndex { get; internal set; } - public bool IsConstant(IWasmValidationContext? ctx) => true; - // @Spec 3.3.2.3. ref.func x public override void Validate(IWasmValidationContext context) { diff --git a/Wacs.Core/Instructions/SIMD/VConst.cs b/Wacs.Core/Instructions/SIMD/VConst.cs index ebd56b9..3f654c3 100644 --- a/Wacs.Core/Instructions/SIMD/VConst.cs +++ b/Wacs.Core/Instructions/SIMD/VConst.cs @@ -27,8 +27,6 @@ public class InstV128Const : InstructionBase, IConstInstruction public override ByteCode Op => SimdCode.V128Const; private V128 V128 { get; set; } - public bool IsConstant(IWasmValidationContext? ctx) => true; - /// /// @Spec 3.3.1.1 t.const /// diff --git a/Wacs.Core/Instructions/Variable.cs b/Wacs.Core/Instructions/Variable.cs index 8255aa7..5a06acb 100644 --- a/Wacs.Core/Instructions/Variable.cs +++ b/Wacs.Core/Instructions/Variable.cs @@ -147,7 +147,7 @@ private static void ExecuteLocalTee(ExecContext context, LocalIdx localIndex) private delegate void ValidationDelegate(IWasmValidationContext context, LocalIdx localIndex); } - public class GlobalVariableInst : InstructionBase, IConstInstruction + public class GlobalVariableInst : InstructionBase, IContextConstInstruction { private readonly ExecuteDelegate _execute; diff --git a/Wacs.Core/Modules/InstructionSequence.cs b/Wacs.Core/Modules/InstructionSequence.cs index 8267cf8..241c6b1 100644 --- a/Wacs.Core/Modules/InstructionSequence.cs +++ b/Wacs.Core/Modules/InstructionSequence.cs @@ -90,10 +90,11 @@ public int Size IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); public bool IsConstant(IWasmValidationContext? ctx) => - _instructions.Count - (HasExplicitEnd ? 1 : 0) == 1 && !_instructions.Any(inst => inst switch { - IConstInstruction constInstruction => !constInstruction.IsConstant(ctx), + IContextConstInstruction ctxInstruction => !ctxInstruction.IsConstant(ctx), + IConstInstruction => false, + IConstOpInstruction opInst => !opInst.IsConstant, InstEnd => false, _ => true }); diff --git a/features.md b/features.md index 07a9a83..8953975 100644 --- a/features.md +++ b/features.md @@ -4,7 +4,7 @@ |[Bulk memory operations](https://github.com/webassembly/bulk-memory-operations)||✅| |[Legacy Exception Handling](https://github.com/WebAssembly/exception-handling)|exceptions|❌| |[Exception Handling with exnref](https://github.com/WebAssembly/exception-handling)|exceptions|❌| -|[Extented Const Expressesions](https://github.com/WebAssembly/extended-const)|extended_const|❌| +|[Extented Const Expressesions](https://github.com/WebAssembly/extended-const)|extended_const|✅| |[Garbage Collection](https://github.com/WebAssembly/gc)|gc|❌| |[JS String Builtins Proposal for WebAssembly](https://github.com/WebAssembly/js-string-builtins)||❌| |[JavaScript Promise Integration](https://github.com/WebAssembly/js-promise-integration)|jspi|🌐|