mirror of
https://github.com/vsariola/sointu.git
synced 2025-05-27 10:50:23 -04:00
feat(compiler, wasm): do not hard code memory addresses to uninitialized sections
Rather, allocate unitialized segments as needed.
This commit is contained in:
parent
f330ccebf7
commit
f3cf4a52ce
@ -1,5 +1,5 @@
|
|||||||
{{- if not .Output16Bit }}
|
{{- if not .Output16Bit }}
|
||||||
(i64.store (global.get $outputBufPtr) (i64.load (i32.const 4128))) ;; load the sample from left & right channels as one 64bit int and store it in the address pointed by outputBufPtr
|
(i64.store (global.get $outputBufPtr) (i64.load (i32.const {{index .Labels "su_globalports"}}))) ;; load the sample from left & right channels as one 64bit int and store it in the address pointed by outputBufPtr
|
||||||
(global.set $outputBufPtr (i32.add (global.get $outputBufPtr) (i32.const 8))) ;; advance outputbufptr
|
(global.set $outputBufPtr (i32.add (global.get $outputBufPtr) (i32.const 8))) ;; advance outputbufptr
|
||||||
{{- else }}
|
{{- else }}
|
||||||
(local.set $channel (i32.const 0))
|
(local.set $channel (i32.const 0))
|
||||||
@ -7,7 +7,7 @@
|
|||||||
(i32.store16 (global.get $outputBufPtr) (i32.trunc_f32_s
|
(i32.store16 (global.get $outputBufPtr) (i32.trunc_f32_s
|
||||||
(f32.mul
|
(f32.mul
|
||||||
(call $clip
|
(call $clip
|
||||||
(f32.load offset=4128 (i32.mul (local.get $channel) (i32.const 4)))
|
(f32.load offset={{index .Labels "su_globalports"}} (i32.mul (local.get $channel) (i32.const 4)))
|
||||||
)
|
)
|
||||||
(f32.const 32767)
|
(f32.const 32767)
|
||||||
)
|
)
|
||||||
@ -16,4 +16,4 @@
|
|||||||
(br_if $channelLoop (local.tee $channel (i32.eqz (local.get $channel))))
|
(br_if $channelLoop (local.tee $channel (i32.eqz (local.get $channel))))
|
||||||
end
|
end
|
||||||
{{- end }}
|
{{- end }}
|
||||||
(i64.store (i32.const 4128) (i64.const 0)) ;; clear the left and right ports
|
(i64.store (i32.const {{index .Labels "su_globalports"}}) (i64.const 0)) ;; clear the left and right ports
|
@ -13,7 +13,7 @@
|
|||||||
{{- $addr := sub (index .Labels "su_vm_transformcounts") 1}}
|
{{- $addr := sub (index .Labels "su_vm_transformcounts") 1}}
|
||||||
(if (i32.lt_u (local.get $paramNum) (i32.load8_u offset={{$addr}} (local.get $opcode)))(then ;;(i32.ge (local.get $paramNum) (i32.load8_u (local.get $opcode))) /*TODO: offset to transformvalues
|
(if (i32.lt_u (local.get $paramNum) (i32.load8_u offset={{$addr}} (local.get $opcode)))(then ;;(i32.ge (local.get $paramNum) (i32.load8_u (local.get $opcode))) /*TODO: offset to transformvalues
|
||||||
(local.set $WRKplusparam (i32.add (global.get $WRK) (local.get $paramX4)))
|
(local.set $WRKplusparam (i32.add (global.get $WRK) (local.get $paramX4)))
|
||||||
(f32.store offset=512
|
(f32.store offset={{index .Labels "su_transformedvalues"}}
|
||||||
(local.get $paramX4)
|
(local.get $paramX4)
|
||||||
(f32.add
|
(f32.add
|
||||||
(f32.mul
|
(f32.mul
|
||||||
@ -59,7 +59,7 @@
|
|||||||
;; The transformed values start at 512 (TODO: change magic constants somehow)
|
;; The transformed values start at 512 (TODO: change magic constants somehow)
|
||||||
;;-------------------------------------------------------------------------------
|
;;-------------------------------------------------------------------------------
|
||||||
(func $input (param $inputNumber i32) (result f32)
|
(func $input (param $inputNumber i32) (result f32)
|
||||||
(f32.load offset=512 (i32.mul (local.get $inputNumber) (i32.const 4)))
|
(f32.load offset={{index .Labels "su_transformedvalues"}} (i32.mul (local.get $inputNumber) (i32.const 4)))
|
||||||
)
|
)
|
||||||
|
|
||||||
;;-------------------------------------------------------------------------------
|
;;-------------------------------------------------------------------------------
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
; Patterns
|
; Patterns
|
||||||
;-------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
*/}}
|
*/}}
|
||||||
{{- .SetLabel "su_patterns"}}
|
{{- .SetDataLabel "su_patterns"}}
|
||||||
{{- $m := .}}
|
{{- $m := .}}
|
||||||
{{- range .Patterns}}
|
{{- range .Patterns}}
|
||||||
{{- range .}}
|
{{- range .}}
|
||||||
@ -18,7 +18,7 @@
|
|||||||
; Tracks
|
; Tracks
|
||||||
;-------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
*/}}
|
*/}}
|
||||||
{{- .SetLabel "su_tracks"}}
|
{{- .SetDataLabel "su_tracks"}}
|
||||||
{{- $m := .}}
|
{{- $m := .}}
|
||||||
{{- range .Sequences}}
|
{{- range .Sequences}}
|
||||||
{{- range .}}
|
{{- range .}}
|
||||||
@ -31,7 +31,7 @@
|
|||||||
; The code for this patch, basically indices to vm jump table
|
; The code for this patch, basically indices to vm jump table
|
||||||
;-------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
*/}}
|
*/}}
|
||||||
{{- .SetLabel "su_patch_code"}}
|
{{- .SetDataLabel "su_patch_code"}}
|
||||||
{{- range .Commands}}
|
{{- range .Commands}}
|
||||||
{{- $.DataB .}}
|
{{- $.DataB .}}
|
||||||
{{- end}}
|
{{- end}}
|
||||||
@ -41,7 +41,7 @@
|
|||||||
; The parameters / inputs to each opcode
|
; The parameters / inputs to each opcode
|
||||||
;-------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
*/}}
|
*/}}
|
||||||
{{- .SetLabel "su_patch_parameters"}}
|
{{- .SetDataLabel "su_patch_parameters"}}
|
||||||
{{- range .Values}}
|
{{- range .Values}}
|
||||||
{{- $.DataB .}}
|
{{- $.DataB .}}
|
||||||
{{- end}}
|
{{- end}}
|
||||||
@ -51,7 +51,7 @@
|
|||||||
; Delay times
|
; Delay times
|
||||||
;-------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
*/}}
|
*/}}
|
||||||
{{- .SetLabel "su_delay_times"}}
|
{{- .SetDataLabel "su_delay_times"}}
|
||||||
{{- range .DelayTimes}}
|
{{- range .DelayTimes}}
|
||||||
{{- $.DataW .}}
|
{{- $.DataW .}}
|
||||||
{{- end}}
|
{{- end}}
|
||||||
@ -61,11 +61,61 @@
|
|||||||
; The number of transformed parameters each opcode takes
|
; The number of transformed parameters each opcode takes
|
||||||
;-------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
*/}}
|
*/}}
|
||||||
{{- .SetLabel "su_vm_transformcounts"}}
|
{{- .SetDataLabel "su_vm_transformcounts"}}
|
||||||
{{- range .Instructions}}
|
{{- range .Instructions}}
|
||||||
{{- $.TransformCount . | $.ToByte | $.DataB}}
|
{{- $.TransformCount . | $.ToByte | $.DataB}}
|
||||||
{{- end}}
|
{{- end}}
|
||||||
|
|
||||||
|
{{- /*
|
||||||
|
;-------------------------------------------------------------------------------
|
||||||
|
; Allocate memory for stack.
|
||||||
|
; Stack of 64 float signals is enough for everybody... right?
|
||||||
|
; Note: as the stack grows _downwards_ the label is _after_ stack
|
||||||
|
;-------------------------------------------------------------------------------
|
||||||
|
*/}}
|
||||||
|
{{- .Align}}
|
||||||
|
{{- .Block 256}}
|
||||||
|
{{- .SetBlockLabel "su_stack"}}
|
||||||
|
|
||||||
|
{{- /*
|
||||||
|
;-------------------------------------------------------------------------------
|
||||||
|
; Allocate memory for transformed values.
|
||||||
|
;-------------------------------------------------------------------------------
|
||||||
|
*/}}
|
||||||
|
{{- .Align}}
|
||||||
|
{{- .SetBlockLabel "su_transformedvalues"}}
|
||||||
|
{{- .Block 32}}
|
||||||
|
|
||||||
|
{{- /*
|
||||||
|
;-------------------------------------------------------------------------------
|
||||||
|
; Uninitialized memory for synth, delaylines & outputbuffer
|
||||||
|
;-------------------------------------------------------------------------------
|
||||||
|
*/}}
|
||||||
|
{{- .Align}}
|
||||||
|
{{- if ne .VoiceTrackBitmask 0}}
|
||||||
|
{{- .SetBlockLabel "su_trackcurrentvoice"}}
|
||||||
|
{{- .Block 32}}
|
||||||
|
{{- end}}
|
||||||
|
{{- .Align}}
|
||||||
|
{{- .SetBlockLabel "su_synth"}}
|
||||||
|
{{- .Block 32}}
|
||||||
|
{{- .SetBlockLabel "su_globalports"}}
|
||||||
|
{{- .Block 32}}
|
||||||
|
{{- .SetBlockLabel "su_voices"}}
|
||||||
|
{{- .Block 131072}}
|
||||||
|
{{- .Align}}
|
||||||
|
{{- .SetBlockLabel "su_delaylines"}}
|
||||||
|
{{- .Block (int (mul 262156 .Song.Patch.NumDelayLines))}}
|
||||||
|
{{- .Align}}
|
||||||
|
{{- .SetBlockLabel "su_outputbuffer"}}
|
||||||
|
{{- if .Output16Bit}}
|
||||||
|
{{- .Block (int (mul .PatternLength .SequenceLength .Song.SamplesPerRow 4))}}
|
||||||
|
{{- else}}
|
||||||
|
{{- .Block (int (mul .PatternLength .SequenceLength .Song.SamplesPerRow 8))}}
|
||||||
|
{{- end}}
|
||||||
|
{{- .SetBlockLabel "su_outputend"}}
|
||||||
|
|
||||||
|
|
||||||
;;------------------------------------------------------------------------------
|
;;------------------------------------------------------------------------------
|
||||||
;; Import the difficult math functions from javascript
|
;; Import the difficult math functions from javascript
|
||||||
;; (seriously now, it's 2020)
|
;; (seriously now, it's 2020)
|
||||||
@ -82,9 +132,8 @@
|
|||||||
|
|
||||||
;;------------------------------------------------------------------------------
|
;;------------------------------------------------------------------------------
|
||||||
;; The one and only memory
|
;; The one and only memory
|
||||||
;; TODO: Its size should be calculated just to fit, but not more
|
|
||||||
;;------------------------------------------------------------------------------
|
;;------------------------------------------------------------------------------
|
||||||
(memory (export "m") 256)
|
(memory (export "m") {{.MemoryPages}})
|
||||||
|
|
||||||
;;------------------------------------------------------------------------------
|
;;------------------------------------------------------------------------------
|
||||||
;; Globals. Putting all with same initialization value should compress most
|
;; Globals. Putting all with same initialization value should compress most
|
||||||
@ -106,11 +155,11 @@
|
|||||||
(global $voice (mut i32) (i32.const 0))
|
(global $voice (mut i32) (i32.const 0))
|
||||||
(global $voicesRemain (mut i32) (i32.const 0))
|
(global $voicesRemain (mut i32) (i32.const 0))
|
||||||
(global $randseed (mut i32) (i32.const 1))
|
(global $randseed (mut i32) (i32.const 1))
|
||||||
(global $sp (mut i32) (i32.const 2048))
|
(global $sp (mut i32) (i32.const {{index .Labels "su_stack"}}))
|
||||||
(global $outputBufPtr (mut i32) (i32.const 8388608))
|
(global $outputBufPtr (mut i32) (i32.const {{index .Labels "su_outputbuffer"}}))
|
||||||
;; TODO: only export start and length with certain compiler options; in demo use, they can be hard coded
|
;; TODO: only export start and length with certain compiler options; in demo use, they can be hard coded
|
||||||
;; in the intro
|
;; in the intro
|
||||||
(global $outputStart (export "s") i32 (i32.const 8388608)) ;; TODO: do not hard code, layout memory somehow intelligently
|
(global $outputStart (export "s") i32 (i32.const {{index .Labels "su_outputbuffer"}}))
|
||||||
(global $outputLength (export "l") i32 (i32.const {{if .Output16Bit}}{{mul .PatternLength .SequenceLength .Song.SamplesPerRow 4}}{{else}}{{mul .PatternLength .SequenceLength .Song.SamplesPerRow 8}}{{end}}))
|
(global $outputLength (export "l") i32 (i32.const {{if .Output16Bit}}{{mul .PatternLength .SequenceLength .Song.SamplesPerRow 4}}{{else}}{{mul .PatternLength .SequenceLength .Song.SamplesPerRow 8}}{{end}}))
|
||||||
(global $output16bit (export "t") i32 (i32.const {{if .Output16Bit}}1{{else}}0{{end}}))
|
(global $output16bit (export "t") i32 (i32.const {{if .Output16Bit}}1{{else}}0{{end}}))
|
||||||
|
|
||||||
@ -168,13 +217,11 @@
|
|||||||
(global.set $COM_instr_start (global.get $COM))
|
(global.set $COM_instr_start (global.get $COM))
|
||||||
(global.set $VAL_instr_start (global.get $VAL))
|
(global.set $VAL_instr_start (global.get $VAL))
|
||||||
{{- end}}
|
{{- end}}
|
||||||
(global.set $WRK (i32.const 4160))
|
(global.set $WRK (i32.const {{index .Labels "su_voices"}}))
|
||||||
(global.set $voice (i32.const 4160))
|
(global.set $voice (i32.const {{index .Labels "su_voices"}}))
|
||||||
(global.set $voicesRemain (i32.const {{.Song.Patch.NumVoices | printf "%v"}}))
|
(global.set $voicesRemain (i32.const {{.Song.Patch.NumVoices | printf "%v"}}))
|
||||||
{{- if .HasOp "delay"}}
|
{{- if .HasOp "delay"}}
|
||||||
(global.set $delayWRK (i32.const 262144)) ;; BAD IDEA: we are limited to something like 30 delay lines
|
(global.set $delayWRK (i32.const {{index .Labels "su_delaylines"}}))
|
||||||
;; after that, the delay lines start to overwrite the outputbuffer. Find a way to layout the memory
|
|
||||||
;; based on the song, instead of hard coding addressed.
|
|
||||||
{{- end}}
|
{{- end}}
|
||||||
(call $su_run_vm)
|
(call $su_run_vm)
|
||||||
{{- template "output_sound.wat" .}}
|
{{- template "output_sound.wat" .}}
|
||||||
@ -217,10 +264,10 @@
|
|||||||
(i32.load8_u offset={{index .Labels "su_patterns"}})
|
(i32.load8_u offset={{index .Labels "su_patterns"}})
|
||||||
(local.tee $note)
|
(local.tee $note)
|
||||||
(if (i32.ne (i32.const {{.Hold}}))(then
|
(if (i32.ne (i32.const {{.Hold}}))(then
|
||||||
(i32.store offset=4164
|
(i32.store offset={{add (index .Labels "su_voices") 4}}
|
||||||
(i32.mul
|
(i32.mul
|
||||||
(i32.add
|
(i32.add
|
||||||
(local.tee $voiceNo (i32.load8_u offset=768 (local.get $tracksRemaining)))
|
(local.tee $voiceNo (i32.load8_u offset={{index .Labels "su_trackcurrentvoice"}} (local.get $tracksRemaining)))
|
||||||
(local.get $firstVoice)
|
(local.get $firstVoice)
|
||||||
)
|
)
|
||||||
(i32.const 4096)
|
(i32.const 4096)
|
||||||
@ -239,11 +286,11 @@
|
|||||||
)
|
)
|
||||||
(i32.const 4096)
|
(i32.const 4096)
|
||||||
)
|
)
|
||||||
(i32.const 4160)
|
(i32.const {{index .Labels "su_voices"}})
|
||||||
))
|
))
|
||||||
(memory.fill (local.get $di) (i32.const 0) (i32.const 4096))
|
(memory.fill (local.get $di) (i32.const 0) (i32.const 4096))
|
||||||
(i32.store (local.get $di) (local.get $note))
|
(i32.store (local.get $di) (local.get $note))
|
||||||
(i32.store8 offset=768 (local.get $tracksRemaining) (local.get $voiceNo))
|
(i32.store8 offset={{index .Labels "su_trackcurrentvoice"}} (local.get $tracksRemaining) (local.get $voiceNo))
|
||||||
))
|
))
|
||||||
))
|
))
|
||||||
(local.set $si (i32.add (local.get $si) (i32.const {{.SequenceLength}})))
|
(local.set $si (i32.add (local.get $si) (i32.const {{.SequenceLength}})))
|
||||||
@ -256,7 +303,7 @@
|
|||||||
(func $su_update_voices (local $si i32) (local $di i32) (local $tracksRemaining i32) (local $note i32)
|
(func $su_update_voices (local $si i32) (local $di i32) (local $tracksRemaining i32) (local $note i32)
|
||||||
(local.set $tracksRemaining (i32.const {{len .Sequences}}))
|
(local.set $tracksRemaining (i32.const {{len .Sequences}}))
|
||||||
(local.set $si (global.get $pattern))
|
(local.set $si (global.get $pattern))
|
||||||
(local.set $di (i32.const 4160))
|
(local.set $di (i32.const {{index .Labels "su_voices"}}))
|
||||||
loop $track_loop
|
loop $track_loop
|
||||||
(i32.load8_u offset={{index .Labels "su_tracks"}} (local.get $si))
|
(i32.load8_u offset={{index .Labels "su_tracks"}} (local.get $si))
|
||||||
(i32.mul (i32.const {{.PatternLength}}))
|
(i32.mul (i32.const {{.PatternLength}}))
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
;; Stereo: also add outgain*ST1 to main right port and auxgain*ST1 to aux1 right
|
;; Stereo: also add outgain*ST1 to main right port and auxgain*ST1 to aux1 right
|
||||||
;;-------------------------------------------------------------------------------
|
;;-------------------------------------------------------------------------------
|
||||||
(func $su_op_outaux (param $stereo i32) (local $addr i32)
|
(func $su_op_outaux (param $stereo i32) (local $addr i32)
|
||||||
(local.set $addr (i32.const 4128))
|
(local.set $addr (i32.const {{index .Labels "su_globalports"}}))
|
||||||
{{- if .Stereo "outaux"}}
|
{{- if .Stereo "outaux"}}
|
||||||
loop $stereoLoop
|
loop $stereoLoop
|
||||||
{{- end}}
|
{{- end}}
|
||||||
@ -47,7 +47,7 @@
|
|||||||
;; Stereo: also add gain*ST1 to right port
|
;; Stereo: also add gain*ST1 to right port
|
||||||
;;-------------------------------------------------------------------------------
|
;;-------------------------------------------------------------------------------
|
||||||
(func $su_op_aux (param $stereo i32) (local $addr i32)
|
(func $su_op_aux (param $stereo i32) (local $addr i32)
|
||||||
(local.set $addr (i32.add (i32.mul (call $scanValueByte) (i32.const 4)) (i32.const 4128)))
|
(local.set $addr (i32.add (i32.mul (call $scanValueByte) (i32.const 4)) (i32.const {{index .Labels "su_globalports"}})))
|
||||||
{{- if .Stereo "aux"}}
|
{{- if .Stereo "aux"}}
|
||||||
loop $stereoLoop
|
loop $stereoLoop
|
||||||
{{- end}}
|
{{- end}}
|
||||||
@ -97,7 +97,7 @@
|
|||||||
(local.set $scaledAddress (i32.add (i32.mul (i32.and (local.get $address) (i32.const 0x7FF7)) (i32.const 4))
|
(local.set $scaledAddress (i32.add (i32.mul (i32.and (local.get $address) (i32.const 0x7FF7)) (i32.const 4))
|
||||||
{{- if .SupportsGlobalSend}}
|
{{- if .SupportsGlobalSend}}
|
||||||
(select
|
(select
|
||||||
(i32.const 4096)
|
(i32.const {{index .Labels "su_synth"}})
|
||||||
{{- end}}
|
{{- end}}
|
||||||
(global.get $voice)
|
(global.get $voice)
|
||||||
{{- if .SupportsGlobalSend}}
|
{{- if .SupportsGlobalSend}}
|
||||||
@ -137,7 +137,7 @@
|
|||||||
{{- end}}
|
{{- end}}
|
||||||
;;-------------------------------------------------------------------------------
|
;;-------------------------------------------------------------------------------
|
||||||
(func $su_op_out (param $stereo i32) (local $ptr i32)
|
(func $su_op_out (param $stereo i32) (local $ptr i32)
|
||||||
(local.set $ptr (i32.const 4128)) ;; synth.left, but should not be magic constant
|
(local.set $ptr (i32.const {{index .Labels "su_globalports"}})) ;; synth.left
|
||||||
(f32.store (local.get $ptr)
|
(f32.store (local.get $ptr)
|
||||||
(f32.add
|
(f32.add
|
||||||
(f32.mul
|
(f32.mul
|
||||||
@ -147,7 +147,7 @@
|
|||||||
(f32.load (local.get $ptr))
|
(f32.load (local.get $ptr))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(local.set $ptr (i32.const 4132)) ;; synth.right, but should not be magic constant
|
(local.set $ptr (i32.const {{add (index .Labels "su_globalports") 4}})) ;; synth.right, note that ATM does not seem to support mono ocpode at all
|
||||||
(f32.store (local.get $ptr)
|
(f32.store (local.get $ptr)
|
||||||
(f32.add
|
(f32.add
|
||||||
(f32.mul
|
(f32.mul
|
||||||
|
@ -183,7 +183,7 @@
|
|||||||
{{- if .SupportsParamValueOtherThan "oscillator" "unison" 0}}
|
{{- if .SupportsParamValueOtherThan "oscillator" "unison" 0}}
|
||||||
(call $push (f32.add (call $pop) (call $pop)))
|
(call $push (f32.add (call $pop) (call $pop)))
|
||||||
(if (local.tee $unison (i32.sub (local.get $unison) (i32.const 1)))(then
|
(if (local.tee $unison (i32.sub (local.get $unison) (i32.const 1)))(then
|
||||||
(f32.store offset={{.InputNumber "oscillator" "phase" | mul 4 | add 512}} (i32.const 0)
|
(f32.store offset={{.InputNumber "oscillator" "phase" | mul 4 | add (index .Labels "su_transformedvalues")}} (i32.const 0)
|
||||||
(f32.add
|
(f32.add
|
||||||
(call $input (i32.const {{.InputNumber "oscillator" "phase"}}))
|
(call $input (i32.const {{.InputNumber "oscillator" "phase"}}))
|
||||||
(f32.const 0.08333333) ;; 1/12, add small phase shift so all oscillators don't start in phase
|
(f32.const 0.08333333) ;; 1/12, add small phase shift so all oscillators don't start in phase
|
||||||
@ -328,7 +328,7 @@
|
|||||||
{{- if .Stereo "in"}}
|
{{- if .Stereo "in"}}
|
||||||
(i32.add (local.get $stereo)) ;; start from right channel if stereo
|
(i32.add (local.get $stereo)) ;; start from right channel if stereo
|
||||||
{{- end}}
|
{{- end}}
|
||||||
(local.set $addr (i32.add (i32.mul (i32.const 4)) (i32.const 4128)))
|
(local.set $addr (i32.add (i32.mul (i32.const 4)) (i32.const {{index .Labels "su_globalports"}})))
|
||||||
{{- if .Stereo "in"}}
|
{{- if .Stereo "in"}}
|
||||||
loop $stereoLoop
|
loop $stereoLoop
|
||||||
{{- end}}
|
{{- end}}
|
||||||
|
@ -5,39 +5,70 @@ import (
|
|||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// WasmMacros are the macros called from .wat templates
|
||||||
|
//
|
||||||
|
// NOTE! Due to the single pass nature of the compilation and the way memory is
|
||||||
|
// organized, you should initialize all initialized data in the .wat files using
|
||||||
|
// DataB, DataW and DataD macros _before_ any calls to Block. Block allocates
|
||||||
|
// uninitialized data blocks from the memory.
|
||||||
type WasmMacros struct {
|
type WasmMacros struct {
|
||||||
data *bytes.Buffer
|
data *bytes.Buffer
|
||||||
Labels map[string]int
|
blockStart int
|
||||||
|
blockAlign int
|
||||||
|
Labels map[string]int
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewWasmMacros() *WasmMacros {
|
func NewWasmMacros() *WasmMacros {
|
||||||
return &WasmMacros{
|
return &WasmMacros{
|
||||||
data: new(bytes.Buffer),
|
data: new(bytes.Buffer),
|
||||||
Labels: map[string]int{},
|
blockAlign: 128,
|
||||||
|
Labels: map[string]int{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wm *WasmMacros) SetLabel(label string) string {
|
func (wm *WasmMacros) SetDataLabel(label string) string {
|
||||||
wm.Labels[label] = wm.data.Len()
|
wm.Labels[label] = wm.data.Len()
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (wm *WasmMacros) SetBlockLabel(label string) string {
|
||||||
|
wm.Labels[label] = wm.blockStart
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *WasmMacros) Align() string {
|
||||||
|
wm.blockStart += wm.blockAlign - 1 - ((wm.blockStart + wm.blockAlign - 1) % wm.blockAlign)
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *WasmMacros) MemoryPages() int {
|
||||||
|
return (wm.blockStart + 65535) / 65536
|
||||||
|
}
|
||||||
|
|
||||||
func (wm *WasmMacros) GetLabel(label string) int {
|
func (wm *WasmMacros) GetLabel(label string) int {
|
||||||
return wm.Labels[label]
|
return wm.Labels[label]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wm *WasmMacros) DataB(value byte) string {
|
func (wm *WasmMacros) DataB(value byte) string {
|
||||||
binary.Write(wm.data, binary.LittleEndian, value)
|
binary.Write(wm.data, binary.LittleEndian, value)
|
||||||
|
wm.blockStart++
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wm *WasmMacros) DataW(value uint16) string {
|
func (wm *WasmMacros) DataW(value uint16) string {
|
||||||
binary.Write(wm.data, binary.LittleEndian, value)
|
binary.Write(wm.data, binary.LittleEndian, value)
|
||||||
|
wm.blockStart += 2
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wm *WasmMacros) DataD(value uint32) string {
|
func (wm *WasmMacros) DataD(value uint32) string {
|
||||||
binary.Write(wm.data, binary.LittleEndian, value)
|
binary.Write(wm.data, binary.LittleEndian, value)
|
||||||
|
wm.blockStart += 4
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *WasmMacros) Block(value int) string {
|
||||||
|
wm.blockStart += value
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user