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|🌐|