Skip to content

Commit

Permalink
Breaking change: Change strings constants to be {i32, i32} tuples
Browse files Browse the repository at this point in the history
  • Loading branch information
RoyalIcing committed Jun 30, 2024
1 parent b1f13e3 commit 253feb4
Show file tree
Hide file tree
Showing 14 changed files with 215 additions and 111 deletions.
6 changes: 3 additions & 3 deletions lib/orb.ex
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,12 @@ 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(Orb.I32, :count), 1))
Orb.Instruction.global_set(Orb.I32, :tally, I32.add(Orb.Instruction.global_get(Orb.I32, :tally), element))
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))
end
defw calculate_mean(), I32 do
I32.div_s(Orb.Instruction.global_get(Orb.I32, :tally), Orb.Instruction.global_get(Orb.I32, :count))
I32.div_s(Orb.Instruction.Global.Get.new(Orb.I32, :tally), Orb.Instruction.Global.Get.new(Orb.I32, :count))
end
end
```
Expand Down
49 changes: 38 additions & 11 deletions lib/orb/constants.ex
Original file line number Diff line number Diff line change
Expand Up @@ -126,12 +126,13 @@ defmodule Orb.Constants do

defmodule NulTerminatedString do
# defstruct push_type: Orb.I32.UnsafePointer, memory_offset: nil, string: nil
defstruct push_type: Orb.Memory.Slice, memory_offset: nil, string: nil
defstruct push_type: __MODULE__, memory_offset: nil, string: nil

with @behaviour Orb.CustomType do
@impl Orb.CustomType
def wasm_type, do: :i32
# def wasm_type, do: :i32
# def wasm_type, do: Orb.Memory.Slice.wasm_type()
def wasm_type, do: {:i32, :i32}
end

def empty() do
Expand All @@ -141,13 +142,14 @@ defmodule Orb.Constants do
}
end

defp len(%__MODULE__{} = constant) do
byte_size(constant.string)
end

def to_slice(%__MODULE__{} = constant) do
len = len(constant)
Orb.Memory.Slice.from(constant.memory_offset, Orb.Instruction.Const.new(:i32, len))
len = byte_size(constant.string)

if is_integer(constant.memory_offset) do
Orb.Memory.Slice.from(constant.memory_offset, len)
else
Orb.Memory.Slice.from(constant.memory_offset, Orb.Instruction.Const.new(:i32, len))
end
end

def to_slice(string) when is_binary(string) do
Expand All @@ -160,9 +162,34 @@ defmodule Orb.Constants do
end

defimpl Orb.ToWat do
def to_wat(%Orb.Constants.NulTerminatedString{memory_offset: memory_offset}, indent) do
Orb.Instruction.Const.new(:i32, memory_offset)
|> Orb.ToWat.to_wat(indent)
def to_wat(
%Orb.Constants.NulTerminatedString{memory_offset: memory_offset, string: string},
indent
) do
[
indent,
Orb.Instruction.Const.new(:i32, memory_offset)
|> Orb.ToWat.to_wat(""),
" ",
Orb.Instruction.Const.new(:i32, byte_size(string))
|> Orb.ToWat.to_wat("")
]
end
end

defmodule Slice do
defstruct push_type: __MODULE__, slice64: nil

with @behaviour Orb.CustomType do
@impl Orb.CustomType
def wasm_type, do: :i64
end

defimpl Orb.ToWat do
def to_wat(%Orb.Constants.NulTerminatedString.Slice{slice64: slice64}, indent) do
Orb.Instruction.Const.new(:i64, slice64)
|> Orb.ToWat.to_wat(indent)
end
end
end
end
Expand Down
7 changes: 6 additions & 1 deletion lib/orb/custom_type.ex
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
defmodule Orb.CustomType do
@callback wasm_type() :: :i64 | :i32 | :f64 | :f32
@type wasm_primitive() :: :i64 | :i32 | :f64 | :f32
@callback wasm_type() ::
wasm_primitive()
| {wasm_primitive(), wasm_primitive()}
| {wasm_primitive(), wasm_primitive(), wasm_primitive()}
| {wasm_primitive(), wasm_primitive(), wasm_primitive(), wasm_primitive()}
@callback load_instruction() ::
:load | :load8_s | :load8_u | :load16_s | :load16_u | :load32_s | :load32_u
# @callback store_instruction() :: :store | :store8 | :store16 | :store32
Expand Down
33 changes: 24 additions & 9 deletions lib/orb/global.ex
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
defmodule Orb.Global do
@moduledoc false

defstruct [:name, :type, :initial_value, :mutability, :exported]
defstruct [:name, :type, :initial_value, :mutability, :exported, :comment]

def new(nil, name, mutability, exported, value) when is_binary(value) do
new(Orb.Constants.NulTerminatedString, name, mutability, exported, value)
new(Orb.Constants.NulTerminatedString.Slice, name, mutability, exported, value)
# new(Orb.Memory.Slice, name, mutability, exported, value)
end

def new(nil, name, mutability, exported, value) when is_integer(value) do
Expand Down Expand Up @@ -54,6 +55,7 @@ defmodule Orb.Global do
}
end

# TODO: remove?
def new32(name, mutability, exported, value)
when is_atom(name) and
mutability in ~w[readonly mutable]a and
Expand All @@ -62,7 +64,7 @@ defmodule Orb.Global do

%__MODULE__{
name: name,
type: Orb.Constants.NulTerminatedString,
type: Orb.Constants.NulTerminatedString.Slice,
initial_value: value,
mutability: mutability,
exported: exported == :exported
Expand Down Expand Up @@ -98,19 +100,28 @@ defmodule Orb.Global do
end
end

def expand!(%Orb.Global{type: Orb.Constants.NulTerminatedString, initial_value: ""} = global) do
def expand!(
%Orb.Global{type: Orb.Constants.NulTerminatedString.Slice, initial_value: ""} = global
) do
%Orb.Global{
global
| initial_value: Orb.Constants.NulTerminatedString.empty()
| initial_value:
Orb.Constants.NulTerminatedString.empty()
|> Orb.Constants.NulTerminatedString.to_slice(),
comment: "empty string constant"
}
end

def expand!(
%Orb.Global{type: Orb.Constants.NulTerminatedString, initial_value: string} = global
%Orb.Global{type: Orb.Constants.NulTerminatedString.Slice, initial_value: string} = global
) do
%Orb.Global{
global
| initial_value: Orb.Constants.expand_if_needed(string)
| initial_value:
string
|> Orb.Constants.expand_if_needed()
|> Orb.Constants.NulTerminatedString.to_slice(),
comment: "string constant"
}
end

Expand All @@ -125,7 +136,8 @@ defmodule Orb.Global do
type: type,
initial_value: initial_value,
mutability: mutability,
exported: exported
exported: exported,
comment: comment
},
indent
) do
Expand All @@ -137,6 +149,9 @@ defmodule Orb.Global do
true -> [?$, to_string(name), ~S{ (export "}, to_string(name), ~S{")}]
end,
" ",
if comment do
["(; ", comment, " ;) "]
end || [],
case mutability do
:readonly -> do_type(type)
:mutable -> ["(mut ", do_type(type), ?)]
Expand Down Expand Up @@ -226,7 +241,7 @@ defmodule Orb.Global do

defmacro @{name, _meta, _args} do
quote do
Orb.Instruction.global_get(Orb.__lookup_global_type!(unquote(name)), unquote(name))
Orb.Instruction.Global.Get.new(Orb.__lookup_global_type!(unquote(name)), unquote(name))
end
end
end
Expand Down
12 changes: 0 additions & 12 deletions lib/orb/instruction.ex
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,6 @@ defmodule Orb.Instruction do
new(nil, {:local_set, local_name, type}, [value])
end

def global_get(type, global_name), do: new(type, {:global_get, global_name})

def global_set(type, global_name, value) do
new(nil, {:global_set, global_name, type}, [value])
end
Expand Down Expand Up @@ -389,16 +387,6 @@ defmodule Orb.Instruction do
]
end

def to_wat(
%Orb.Instruction{
operation: {:global_get, global_name},
operands: []
},
indent
) do
[indent, "(global.get $", to_string(global_name), ")"]
end

def to_wat(
%Orb.Instruction{
operation: {:global_set, global_name, _},
Expand Down
14 changes: 14 additions & 0 deletions lib/orb/instruction/global_get.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
defmodule Orb.Instruction.Global.Get do
@moduledoc false
defstruct [:push_type, :global_name]

def new(type, global_name) when is_atom(type) do
%__MODULE__{push_type: type, global_name: global_name}
end

defimpl Orb.ToWat do
def to_wat(%Orb.Instruction.Global.Get{global_name: global_name}, indent) do
[indent, "(global.get $", to_string(global_name), ")"]
end
end
end
43 changes: 40 additions & 3 deletions lib/orb/memory/slice.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ defmodule Orb.Memory.Slice do

require Orb.I64 |> alias
require Orb.I32 |> alias
# import Bitwise

with @behaviour Orb.CustomType do
@impl Orb.CustomType
Expand All @@ -14,8 +13,17 @@ defmodule Orb.Memory.Slice do

def from(byte_offset, byte_length) when is_integer(byte_offset) and is_integer(byte_length) do
# :binary.encode_unsigned(byte_offset, :little)
<<byte_offset::unsigned-little-integer-size(32),
byte_length::unsigned-little-integer-size(32)>>

<<i64::unsigned-little-integer-size(64)>> =
<<byte_offset::unsigned-little-integer-size(32),
byte_length::unsigned-little-integer-size(32)>>

import Bitwise
b = byte_offset <<< 32 ||| byte_length

IO.inspect({byte_offset, byte_length, i64, b}, label: "#{__MODULE__}.from/2")

b
end

def from(byte_offset = %{push_type: _}, byte_length = %{push_type: _}) do
Expand All @@ -27,6 +35,14 @@ defmodule Orb.Memory.Slice do
)
end

def get_byte_offset(n) when is_integer(n) do
# <<byte_offset::unsigned-little-integer-size(32), _::unsigned-little-integer-size(32)>> =
# <<n::unsigned-little-integer-size(64)>>

import Bitwise
n >>> 32
end

def get_byte_offset(
<<byte_offset::unsigned-little-integer-size(32), _::unsigned-little-integer-size(32)>>
) do
Expand All @@ -37,6 +53,16 @@ defmodule Orb.Memory.Slice do
I64.shr_u(range, 32) |> I32.wrap_i64()
end

def get_byte_length(n) when is_integer(n) do
# <<_::unsigned-little-integer-size(32), byte_length::unsigned-little-integer-size(32)>> =
# <<n::unsigned-little-integer-size(64)>>

# byte_length

import Bitwise
n &&& 0xFFFFFFFF
end

def get_byte_length(
<<_::unsigned-little-integer-size(32), byte_length::unsigned-little-integer-size(32)>>
) do
Expand All @@ -46,4 +72,15 @@ defmodule Orb.Memory.Slice do
def get_byte_length(range = %{push_type: _}) do
I32.wrap_i64(range)
end

# defimpl Orb.ToWat do
# def to_wat(
# %Orb.Memory.Slice{},
# indent
# ) do
# [
# indent,
# ]
# end
# end
end
10 changes: 9 additions & 1 deletion lib/orb/to_wat.ex
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ defmodule Orb.ToWat.Helpers do
alias Orb.CustomType

def do_type(type) do
do_type(type, 0, type)
end

defp do_type(_type, 10, original_type) do
raise "Cannot unfold deep 10+ layers of CustomType nesting. Top type is #{original_type}."
end

defp do_type(type, nesting, original_type) do
case type do
:i64 ->
"i64"
Expand All @@ -40,7 +48,7 @@ defmodule Orb.ToWat.Helpers do
|> Enum.join(" ")

type ->
CustomType.resolve!(type) |> to_string()
CustomType.resolve!(type) |> do_type(nesting + 1, original_type)
end
end
end
8 changes: 4 additions & 4 deletions test/defw_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,11 @@ defmodule DefwTest do
defmodule SharedStringConstants do
use Orb

defw foo(), I32.UnsafePointer do
defw foo(), Orb.Constants.NulTerminatedString do
~S"foo"
end

defw cdata_start(), I32.UnsafePointer do
defw cdata_start(), Orb.Constants.NulTerminatedString do
~S"<![CDATA["
end
end
Expand All @@ -94,11 +94,11 @@ defmodule DefwTest do

Memory.pages(1)

defw cdata_start2(), I32.UnsafePointer do
defw cdata_start2(), Orb.Constants.NulTerminatedString do
~S"<![CDATA["
end

defw use_other(), I32.UnsafePointer do
defw use_other(), Orb.Constants.NulTerminatedString do
cdata_start()
end
end
Expand Down
2 changes: 1 addition & 1 deletion test/examples/arena.exs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ defmodule Examples.Arena do
end_offset = values_mod.end_offset()

Orb.snippet Orb.S32, new_ptr: I32.UnsafePointer do
new_ptr = Instruction.global_get(Orb.I32, offset_global_name)
new_ptr = Orb.Instruction.Global.Get.new(Orb.I32, offset_global_name)

if new_ptr + byte_count > end_offset * Orb.Memory.page_byte_size() do
unreachable!()
Expand Down
1 change: 1 addition & 0 deletions test/global_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ defmodule GlobalTest do
"""
end

@tag skip: true
test "global do" do
defmodule GlobalDo do
use Orb
Expand Down
Loading

0 comments on commit 253feb4

Please sign in to comment.