Skip to content

Commit

Permalink
Compile to .wasm binary: global.set
Browse files Browse the repository at this point in the history
  • Loading branch information
RoyalIcing committed Jul 27, 2024
1 parent 93fbacc commit 802d0d2
Show file tree
Hide file tree
Showing 9 changed files with 62 additions and 16 deletions.
5 changes: 3 additions & 2 deletions lib/orb.ex
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ defmodule Orb do
I32.global(count: 0, tally: 0)
defw insert(element: I32) do
Orb.Instruction.global_set(Orb.I32, :count, I32.add(Orb.Instruction.Global.Get.new(Orb.I32, :count), 1))
Orb.Instruction.global_set(Orb.I32, :tally, I32.add(Orb.Instruction.Global.Get.new(Orb.I32, :tally), element))
Orb.Instruction.Global.Set.new(Orb.I32, :count, I32.add(Orb.Instruction.Global.Get.new(Orb.I32, :count), 1))
Orb.Instruction.Global.Set.new(Orb.I32, :tally, I32.add(Orb.Instruction.Global.Get.new(Orb.I32, :tally), element))
end
defw calculate_mean(), I32 do
Expand Down Expand Up @@ -1045,6 +1045,7 @@ defmodule Orb do
end
end

# TODO: move to Orb.Compiler
def __lookup_global_type!(global_identifier) do
Process.get({Orb, :global_types}) |> Map.fetch!(global_identifier)
end
Expand Down
4 changes: 2 additions & 2 deletions lib/orb/dsl/dsl.ex
Original file line number Diff line number Diff line change
Expand Up @@ -249,9 +249,9 @@ defmodule Orb.DSL do

# @some_global = input
{:=, _, [{:@, _, [{global, _, nil}]}, input]} when is_atom(global) ->
# quote do: Orb.Instruction.global_set(unquote(Macro.var(:wasm_global_type, nil)).(unquote(global)), unquote(global), unquote(input))
# quote do: Orb.Instruction.Global.Set.new(unquote(Macro.var(:wasm_global_type, nil)).(unquote(global)), unquote(global), unquote(input))
quote do:
Orb.Instruction.global_set(
Orb.Instruction.Global.Set.new(
Orb.__lookup_global_type!(unquote(global)),
unquote(global),
unquote(input)
Expand Down
3 changes: 3 additions & 0 deletions lib/orb/instruction.ex
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ defmodule Orb.Instruction do
])
end

# TODO: remove
def global_set(type, global_name, value) do
new(nil, {:global_set, global_name, type}, [value])
end
Expand Down Expand Up @@ -256,6 +257,7 @@ defmodule Orb.Instruction do
operand
end

# TODO: remove
defp type_check_operand!(
nil,
{:global_set, global_name, expected_type},
Expand Down Expand Up @@ -386,6 +388,7 @@ defmodule Orb.Instruction do
]
end

# TODO: remove
def to_wat(
%Orb.Instruction{
operation: {:global_set, global_name, _},
Expand Down
37 changes: 37 additions & 0 deletions lib/orb/instruction/global_set.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
defmodule Orb.Instruction.Global.Set do
@moduledoc false
defstruct push_type: nil, global_name: nil, value: nil

def new(type, global_name, value) when is_atom(type) do
%__MODULE__{
global_name: global_name,
value: Orb.Instruction.Const.wrap(type, value, "global.set $#{global_name}")
}
end

defimpl Orb.ToWat do
def to_wat(%Orb.Instruction.Global.Set{global_name: global_name, value: value}, indent) do
[
Orb.ToWat.to_wat(value, indent),
"\n",
indent,
"(global.set $",
to_string(global_name),
")"
]
end
end

defimpl Orb.ToWasm do
import Orb.Leb

def to_wasm(%Orb.Instruction.Global.Set{global_name: global_name, value: value}, context) do
global_index = Orb.ToWasm.Context.fetch_global_index!(context, global_name)

[
Orb.ToWasm.to_wasm(value, context),
[0x24, leb128_u(global_index)]
]
end
end
end
5 changes: 4 additions & 1 deletion lib/orb/module_definition.ex
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ defmodule Orb.ModuleDefinition do
for(param <- params, do: to_primitive_type(param.type))
|> List.to_tuple()

result = to_primitive_type(result)
result = if result, do: to_primitive_type(result)

{params, result}
end
Expand All @@ -294,6 +294,9 @@ defmodule Orb.ModuleDefinition do
types when is_tuple(types) ->
for type <- Tuple.to_list(types), do: Param.to_wasm_type(type)

nil ->
[]

type when is_atom(type) ->
[to_wasm_type(type)]
end
Expand Down
5 changes: 1 addition & 4 deletions lib/orb/ops.ex
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,7 @@ defmodule Orb.Ops do
def to_primitive_type(type) when is_effect(type), do: type
def to_primitive_type(type) when type in @elixir_types, do: type
# TODO: remove these as they don’t match is_primitive_type/1 above
def to_primitive_type(nil), do: :nop
# TODO: remove :nop and :trap
def to_primitive_type(:nop), do: :nop
def to_primitive_type(:trap), do: :trap
def to_primitive_type(nil), do: raise("InvalidType: nil cannot be a type")

def to_primitive_type(type) when is_tuple(type) do
for nested <- Tuple.to_list(type) do
Expand Down
5 changes: 3 additions & 2 deletions lib/orb/to_wasm.ex
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ defmodule Orb.ToWasm.Helpers do
def to_wasm_type(:f64), do: 0x7C
def to_wasm_type(:v128), do: 0x7B

def to_wasm_type(custom_type) when is_atom(custom_type),
do: Orb.Ops.to_primitive_type(custom_type) |> to_wasm_type()
def to_wasm_type(custom_type) when is_atom(custom_type) do
Orb.Ops.to_primitive_type(custom_type) |> to_wasm_type()
end
end

defmodule Orb.ToWasm.Context do
Expand Down
4 changes: 2 additions & 2 deletions test/examples/arena.exs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ defmodule Examples.Arena do
unreachable!()
end

Instruction.global_set(Orb.I32, offset_global_name, new_ptr + byte_count)
Instruction.Global.Set.new(Orb.I32, offset_global_name, new_ptr + byte_count)

new_ptr
end
Expand All @@ -27,7 +27,7 @@ defmodule Examples.Arena do
start_offset = values_mod.start_offset()

Orb.snippet Orb.S32 do
Instruction.global_set(
Instruction.Global.Set.new(
Orb.I32,
offset_global_name,
start_offset * Orb.Memory.page_byte_size()
Expand Down
10 changes: 7 additions & 3 deletions test/wasm_output_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -220,10 +220,14 @@ defmodule WasmOutputTest do
i64(0)
end

defw multiple_by_global(a: I64), I64 do
defw multiple_by_factor(a: I64), I64 do
a * @factor
end

defw set_factor(a: I64) do
@factor = a
end

# defw divide2(a: I64, b: I64), I64 do
# Control.block ByZero, I64 do
# # ByZero.break() when b === i64(0)
Expand Down Expand Up @@ -251,8 +255,8 @@ defmodule WasmOutputTest do
assert Wasm.call(wasm, :divide, {:i64, 22}, {:i64, 2}) === 11
assert Wasm.call(wasm, :divide, {:i64, 0}, {:i64, 0}) === 0

assert Wasm.call(wat, :multiple_by_global, {:i64, 7}) === 35
assert Wasm.call(wasm, :multiple_by_global, {:i64, 7}) === 35
assert Wasm.call(wat, :multiple_by_factor, {:i64, 7}) === 35
assert Wasm.call(wasm, :multiple_by_factor, {:i64, 7}) === 35
end

defp extract_wasm_sections(<<"\0asm", 0x01000000::32>> <> bytes) do

Check warning on line 262 in test/wasm_output_test.exs

View workflow job for this annotation

GitHub Actions / Build and test (1.15.2, 25.3.2)

function extract_wasm_sections/1 is unused
Expand Down

0 comments on commit 802d0d2

Please sign in to comment.