Skip to content

Commit

Permalink
Merge pull request #20 from kelnishi/tail-calls
Browse files Browse the repository at this point in the history
Tail calls
  • Loading branch information
kelnishi authored Nov 18, 2024
2 parents e21f1cb + 2fb88fb commit 1ecd572
Show file tree
Hide file tree
Showing 8 changed files with 381 additions and 3 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ Harnessed results from [wasm-feature-detect](https://github.com/GoogleChromeLabs
|[Sign-extension operators](https://github.com/WebAssembly/sign-extension-ops)||✅|
|[Fixed-Width SIMD](https://github.com/webassembly/simd)||✅|
|[Streaming Compilation](https://webassembly.github.io/spec/web-api/index.html#streaming-modules)|streaming_compilation|<span title="Browser idioms, not directly supported">🌐</span>|
|[Tail call](https://github.com/webassembly/tail-call)|tail_call||
|[Tail call](https://github.com/webassembly/tail-call)|tail_call||
|[Threads](https://github.com/webassembly/threads)|threads|❌|
|[Type Reflection](https://github.com/WebAssembly/js-types)|type-reflection|<span title="Browser idioms, not directly supported">🌐</span>|
|[Typed function references](https://github.com/WebAssembly/function-references)|function-references|❌|
Expand Down
44 changes: 44 additions & 0 deletions Spec.Test/ExtensionTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// /*
// * Copyright 2024 Kelvin Nishikawa
// *
// * Licensed under the Apache License, Version 2.0 (the "License");
// * you may not use this file except in compliance with the License.
// * You may obtain a copy of the License at
// *
// * http://www.apache.org/licenses/LICENSE-2.0
// *
// * Unless required by applicable law or agreed to in writing, software
// * distributed under the License is distributed on an "AS IS" BASIS,
// * WITHOUT 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;
using Wacs.Core.Runtime;
using Xunit;

namespace Spec.Test
{
public class ExtensionTests
{
[Fact]
public void TailCallFactorial()
{
var runtime = new WasmRuntime();

using var fileStream = new FileStream("../../../engine/tailcalls.wasm", FileMode.Open);
var module = BinaryModuleParser.ParseWasm(fileStream);
var moduleInst = runtime.InstantiateModule(module);
runtime.RegisterModule("tailcalls", moduleInst);

var fa = runtime.GetExportedFunction(("tailcalls", "factorial"));
var invoker = runtime.CreateInvoker<Func<long, long>>(fa);

Assert.Equal(479_001_600, invoker(12));
Assert.Equal(2_432_902_008_176_640_000 , invoker(20));
}
}
}
Binary file added Spec.Test/engine/tailcalls.wasm
Binary file not shown.
19 changes: 19 additions & 0 deletions Spec.Test/engine/tailcalls.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
(module
;; Recursive factorial implementation using tail calls
(func $fac (export "factorial") (param $x i64) (result i64)
(return_call $fac-aux (local.get $x) (i64.const 1))
)
(func $fac-aux (param $x i64) (param $r i64) (result i64)
(if (result i64) (i64.eqz (local.get $x))
(then
(local.get $r)
)
(else
(return_call $fac-aux
(i64.sub (local.get $x) (i64.const 1))
(i64.mul (local.get $x) (local.get $r))
)
)
)
)
)
3 changes: 2 additions & 1 deletion Wacs.Core/Instructions/Control.cs
Original file line number Diff line number Diff line change
Expand Up @@ -722,7 +722,8 @@ public override void Execute(ExecContext context)
context.Assert( context.OpStack.Count >= context.Frame.Arity,
$"Instruction return failed. Operand stack underflow");
//We're managing separate stacks, so we won't need to shift the operands
// var vals = context.OpStack.PopResults(context.Frame.Type.ResultType);
// Stack<Value> values = new Stack<Value>();
// context.OpStack.PopResults(context.Frame.Type.ResultType, ref values);
var address = context.PopFrame();
context.ResumeSequence(address);
}
Expand Down
3 changes: 3 additions & 0 deletions Wacs.Core/Instructions/SpecFactory/SpecFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ public T CreateInstruction<T>(ByteCode code)
OpCode.Call => new InstCall(),
OpCode.CallIndirect => new InstCallIndirect(),

OpCode.ReturnCall => new InstReturnCall(),
OpCode.ReturnCallIndirect => new InstReturnCallIndirect(),

//When invoking externally
OpCode.Func => new InstFuncReturn(),

Expand Down
Loading

0 comments on commit 1ecd572

Please sign in to comment.