wardite 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Rakefile +15 -0
- data/exe/wardite +7 -0
- data/lib/wardite/alu_i32.generated.rb +77 -0
- data/lib/wardite/instruction.rb +48 -30
- data/lib/wardite/leb128.rb +1 -1
- data/lib/wardite/value.rb +82 -0
- data/lib/wardite/version.rb +1 -1
- data/lib/wardite/wasi.rb +5 -3
- data/lib/wardite.rb +117 -90
- data/scripts/gen_alu.rb +124 -0
- data/scripts/templates/alu_module.rb.tmpl +18 -0
- data/sig/generated/wardite/alu_i32.generated.rbs +11 -0
- data/sig/generated/wardite/instruction.rbs +9 -6
- data/sig/generated/wardite/leb128.rbs +1 -1
- data/sig/generated/wardite/value.rbs +58 -0
- data/sig/generated/wardite/wasi.rbs +4 -2
- data/sig/generated/wardite.rbs +18 -12
- metadata +8 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 8e33fd39e5cc58e9ec6071c4a74d5cbe872d68355657dd1adfdf375d74cf03b9
         | 
| 4 | 
            +
              data.tar.gz: cee2e80f2dda3a2366450cf9b2d6656b172faa41b69eba39c03610b8a3c8d38b
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: bfabd5ef113b7ebdc5e7aa5059eed7984e5f38a8490e120b4ab4230972f503e62aff24d0bfa5cdcef49bc8dcd082c69ade651f95e5cd0101780acdd389378fda
         | 
| 7 | 
            +
              data.tar.gz: eac7e0374494969be1ea08e8fb7344e163a2c122ff3d6b958d47851bc3815104329216c9107612930209ecf0551ff677a5d9f3744792d82746b410b32fe329d4
         | 
    
        data/Rakefile
    CHANGED
    
    | @@ -15,5 +15,20 @@ task :check do | |
| 15 15 | 
             
              sh "bundle exec steep check"
         | 
| 16 16 | 
             
            end
         | 
| 17 17 |  | 
| 18 | 
            +
            desc "Generate codes"
         | 
| 19 | 
            +
            task :generate do
         | 
| 20 | 
            +
              require_relative "scripts/gen_alu"
         | 
| 21 | 
            +
              libdir = File.expand_path("../lib", __FILE__)
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              GenAlu.execute(libdir + "/wardite/alu_i32.generated.rb", prefix: "i32", defined_ops: [
         | 
| 24 | 
            +
                :lts,
         | 
| 25 | 
            +
                :leu,
         | 
| 26 | 
            +
                :add,
         | 
| 27 | 
            +
                :sub,
         | 
| 28 | 
            +
                :const,
         | 
| 29 | 
            +
                :store,
         | 
| 30 | 
            +
              ])
         | 
| 31 | 
            +
            end
         | 
| 32 | 
            +
             | 
| 18 33 | 
             
            task default: %i[test check]
         | 
| 19 34 |  | 
    
        data/exe/wardite
    CHANGED
    
    | @@ -11,6 +11,13 @@ instance = Wardite::BinaryLoader::load_from_buffer(f); | |
| 11 11 | 
             
            if !method && instance.runtime.respond_to?(:_start)
         | 
| 12 12 | 
             
              instance.runtime._start
         | 
| 13 13 | 
             
            else
         | 
| 14 | 
            +
              args = args.map do|a|
         | 
| 15 | 
            +
                if a.include? "."
         | 
| 16 | 
            +
                  a.to_f
         | 
| 17 | 
            +
                else
         | 
| 18 | 
            +
                  a.to_i
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
              end
         | 
| 14 21 | 
             
              ret = instance.runtime.call(method, args)
         | 
| 15 22 | 
             
              $stderr.puts "return value: #{ret.inspect}"
         | 
| 16 23 | 
             
            end
         | 
| @@ -0,0 +1,77 @@ | |
| 1 | 
            +
            # rbs_inline: enabled
         | 
| 2 | 
            +
            require_relative "value"
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            module Wardite
         | 
| 5 | 
            +
              module Evaluator
         | 
| 6 | 
            +
                # @rbs runtime: Runtime
         | 
| 7 | 
            +
                # @rbs frame: Frame
         | 
| 8 | 
            +
                # @rbs insn: Op
         | 
| 9 | 
            +
                # @rbs return: void 
         | 
| 10 | 
            +
                def self.i32_eval_insn(runtime, frame, insn)
         | 
| 11 | 
            +
                  case insn.code
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  when :i32_lts
         | 
| 14 | 
            +
                    right, left = runtime.stack.pop, runtime.stack.pop
         | 
| 15 | 
            +
                    if !right.is_a?(I32) || !left.is_a?(I32)
         | 
| 16 | 
            +
                      raise EvalError, "maybe empty or invalid stack"
         | 
| 17 | 
            +
                    end
         | 
| 18 | 
            +
                    value = (left.value < right.value) ? 1 : 0
         | 
| 19 | 
            +
                    runtime.stack.push(I32(value))
         | 
| 20 | 
            +
             | 
| 21 | 
            +
             | 
| 22 | 
            +
                  when :i32_leu
         | 
| 23 | 
            +
                    right, left = runtime.stack.pop, runtime.stack.pop
         | 
| 24 | 
            +
                    if !right.is_a?(I32) || !left.is_a?(I32)
         | 
| 25 | 
            +
                      raise EvalError, "maybe empty or invalid stack"
         | 
| 26 | 
            +
                    end
         | 
| 27 | 
            +
                    value = (left.value >= right.value) ? 1 : 0
         | 
| 28 | 
            +
                    runtime.stack.push(I32(value))
         | 
| 29 | 
            +
             | 
| 30 | 
            +
             | 
| 31 | 
            +
                  when :i32_add
         | 
| 32 | 
            +
                    right, left = runtime.stack.pop, runtime.stack.pop
         | 
| 33 | 
            +
                    if !right.is_a?(I32) || !left.is_a?(I32)
         | 
| 34 | 
            +
                      raise EvalError, "maybe empty or invalid stack"
         | 
| 35 | 
            +
                    end
         | 
| 36 | 
            +
                    runtime.stack.push(I32(left.value + right.value))
         | 
| 37 | 
            +
             | 
| 38 | 
            +
             | 
| 39 | 
            +
                  when :i32_sub
         | 
| 40 | 
            +
                    right, left = runtime.stack.pop, runtime.stack.pop
         | 
| 41 | 
            +
                    if !right.is_a?(I32) || !left.is_a?(I32)
         | 
| 42 | 
            +
                      raise EvalError, "maybe empty or invalid stack"
         | 
| 43 | 
            +
                    end
         | 
| 44 | 
            +
                    runtime.stack.push(I32(left.value - right.value))
         | 
| 45 | 
            +
             | 
| 46 | 
            +
             | 
| 47 | 
            +
                  when :i32_const
         | 
| 48 | 
            +
                    const = insn.operand[0]
         | 
| 49 | 
            +
                    if !const.is_a?(Integer)
         | 
| 50 | 
            +
                      raise EvalError, "invalid type of operand"
         | 
| 51 | 
            +
                    end
         | 
| 52 | 
            +
                    runtime.stack.push(I32(const))
         | 
| 53 | 
            +
             | 
| 54 | 
            +
             | 
| 55 | 
            +
                  when :i32_store
         | 
| 56 | 
            +
                    _align = insn.operand[0] # TODO: alignment support?
         | 
| 57 | 
            +
                    offset = insn.operand[1]
         | 
| 58 | 
            +
                    raise EvalError, "[BUG] invalid type of operand" if !offset.is_a?(Integer)
         | 
| 59 | 
            +
                  
         | 
| 60 | 
            +
                    value = runtime.stack.pop
         | 
| 61 | 
            +
                    addr = runtime.stack.pop
         | 
| 62 | 
            +
                    if !value.is_a?(I32) || !addr.is_a?(I32)
         | 
| 63 | 
            +
                      raise EvalError, "maybe stack too short"
         | 
| 64 | 
            +
                    end
         | 
| 65 | 
            +
                  
         | 
| 66 | 
            +
                    at = addr.value + offset
         | 
| 67 | 
            +
                    data_end = at + value.packed.size
         | 
| 68 | 
            +
                    memory = runtime.instance.store.memories[0] || raise("[BUG] no memory")
         | 
| 69 | 
            +
                    memory.data[at...data_end] = value.packed
         | 
| 70 | 
            +
             | 
| 71 | 
            +
             | 
| 72 | 
            +
                  else
         | 
| 73 | 
            +
                    raise "Unknown opcode for namespace #{insn.namespace}: #{insn.code}"
         | 
| 74 | 
            +
                  end
         | 
| 75 | 
            +
                end
         | 
| 76 | 
            +
              end
         | 
| 77 | 
            +
            end
         | 
    
        data/lib/wardite/instruction.rb
    CHANGED
    
    | @@ -1,47 +1,65 @@ | |
| 1 1 | 
             
            # rbs_inline: enabled
         | 
| 2 | 
            +
             | 
| 2 3 | 
             
            module Wardite
         | 
| 3 4 | 
             
              class Op
         | 
| 5 | 
            +
                attr_accessor :namespace #: Symbol
         | 
| 6 | 
            +
             | 
| 4 7 | 
             
                attr_accessor :code #: Symbol
         | 
| 5 8 |  | 
| 6 | 
            -
                 | 
| 9 | 
            +
                # TODO: add types of potential operands
         | 
| 10 | 
            +
                attr_accessor :operand #: Array[Integer|Float|Block]
         | 
| 7 11 |  | 
| 12 | 
            +
                # @rbs namespace: Symbol
         | 
| 8 13 | 
             
                # @rbs code: Symbol
         | 
| 9 | 
            -
                # @rbs operand: Array[ | 
| 10 | 
            -
                def initialize(code, operand)
         | 
| 14 | 
            +
                # @rbs operand: Array[Integer|Float|Block]
         | 
| 15 | 
            +
                def initialize(namespace, code, operand)
         | 
| 16 | 
            +
                  @namespace = namespace      
         | 
| 11 17 | 
             
                  @code = code
         | 
| 12 18 | 
             
                  @operand = operand
         | 
| 13 19 | 
             
                end
         | 
| 14 20 |  | 
| 15 21 | 
             
                # @rbs chr: String
         | 
| 16 | 
            -
                # @rbs return: Symbol
         | 
| 22 | 
            +
                # @rbs return: [Symbol, Symbol]
         | 
| 17 23 | 
             
                def self.to_sym(chr)
         | 
| 18 | 
            -
                  case chr
         | 
| 19 | 
            -
             | 
| 20 | 
            -
             | 
| 21 | 
            -
             | 
| 22 | 
            -
             | 
| 23 | 
            -
             | 
| 24 | 
            -
             | 
| 25 | 
            -
             | 
| 26 | 
            -
             | 
| 27 | 
            -
             | 
| 28 | 
            -
             | 
| 29 | 
            -
             | 
| 30 | 
            -
             | 
| 31 | 
            -
             | 
| 32 | 
            -
             | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 35 | 
            -
             | 
| 36 | 
            -
             | 
| 37 | 
            -
             | 
| 38 | 
            -
             | 
| 39 | 
            -
             | 
| 40 | 
            -
             | 
| 41 | 
            -
             | 
| 42 | 
            -
             | 
| 24 | 
            +
                  code = case chr
         | 
| 25 | 
            +
                    when "\u0004"
         | 
| 26 | 
            +
                      :if
         | 
| 27 | 
            +
                    when "\u000b"
         | 
| 28 | 
            +
                      :end
         | 
| 29 | 
            +
                    when "\u000f"
         | 
| 30 | 
            +
                      :return
         | 
| 31 | 
            +
                    when "\u0010"
         | 
| 32 | 
            +
                      :call
         | 
| 33 | 
            +
                    when "\u0020"
         | 
| 34 | 
            +
                      :local_get
         | 
| 35 | 
            +
                    when "\u0021"
         | 
| 36 | 
            +
                      :local_set
         | 
| 37 | 
            +
                    when "\u0036"
         | 
| 38 | 
            +
                      :i32_store
         | 
| 39 | 
            +
                    when "\u0041"
         | 
| 40 | 
            +
                      :i32_const
         | 
| 41 | 
            +
                    when "\u0048"
         | 
| 42 | 
            +
                      :i32_lts
         | 
| 43 | 
            +
                    when "\u004d"
         | 
| 44 | 
            +
                      :i32_leu
         | 
| 45 | 
            +
                    when "\u006a"
         | 
| 46 | 
            +
                      :i32_add
         | 
| 47 | 
            +
                    when "\u006b"
         | 
| 48 | 
            +
                      :i32_sub
         | 
| 49 | 
            +
                    else
         | 
| 50 | 
            +
                      raise NotImplementedError, "unimplemented: #{"%04x" % chr.ord}"
         | 
| 51 | 
            +
                    end
         | 
| 52 | 
            +
                  # opcodes equal to or larger than are "convert" ops
         | 
| 53 | 
            +
                  if chr.ord >= 0xa7
         | 
| 54 | 
            +
                    return [:convert, code]
         | 
| 55 | 
            +
                  end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                  prefix = code.to_s.split("_")[0]
         | 
| 58 | 
            +
                  case prefix
         | 
| 59 | 
            +
                  when "i32", "i64", "f32", "f64"
         | 
| 60 | 
            +
                    [prefix.to_sym, code]
         | 
| 43 61 | 
             
                  else
         | 
| 44 | 
            -
                     | 
| 62 | 
            +
                    [:default, code]
         | 
| 45 63 | 
             
                  end
         | 
| 46 64 | 
             
                end
         | 
| 47 65 |  | 
    
        data/lib/wardite/leb128.rb
    CHANGED
    
    
| @@ -0,0 +1,82 @@ | |
| 1 | 
            +
            # rbs_inline: enabled
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Wardite
         | 
| 4 | 
            +
              class I32
         | 
| 5 | 
            +
                attr_accessor :value #: Integer
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                # TODO: eliminate use of pack, to support mruby - in this file!
         | 
| 8 | 
            +
                # @rbs return: String
         | 
| 9 | 
            +
                def packed
         | 
| 10 | 
            +
                  [self.value].pack("I")
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                def inspect
         | 
| 14 | 
            +
                  "I32(#{@value})"
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
              class I64
         | 
| 19 | 
            +
                attr_accessor :value #: Integer
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                # @rbs return: String
         | 
| 22 | 
            +
                def packed
         | 
| 23 | 
            +
                  [self.value].pack("L")
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                def inspect
         | 
| 27 | 
            +
                  "I64(#{@value})"
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
              class F32
         | 
| 32 | 
            +
                attr_accessor :value #: Float    
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                # @rbs return: String
         | 
| 35 | 
            +
                def packed
         | 
| 36 | 
            +
                  [self.value].pack("f")
         | 
| 37 | 
            +
                end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                def inspect
         | 
| 40 | 
            +
                  "F32(#{@value})"
         | 
| 41 | 
            +
                end
         | 
| 42 | 
            +
              end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
              class F64
         | 
| 45 | 
            +
                attr_accessor :value #: Float    
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                # @rbs return: String
         | 
| 48 | 
            +
                def packed
         | 
| 49 | 
            +
                  [self.value].pack("d")
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                def inspect
         | 
| 53 | 
            +
                  "F64(#{@value})"
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
              end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
              module ValueHelper
         | 
| 58 | 
            +
                # @rbs value: Integer
         | 
| 59 | 
            +
                # @rbs return: I32
         | 
| 60 | 
            +
                def I32(value)
         | 
| 61 | 
            +
                  I32.new.tap{|i| i.value = value }
         | 
| 62 | 
            +
                end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                # @rbs value: Integer
         | 
| 65 | 
            +
                # @rbs return: I64
         | 
| 66 | 
            +
                def I64(value)
         | 
| 67 | 
            +
                  I64.new.tap{|i| i.value = value }
         | 
| 68 | 
            +
                end
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                # @rbs value: Float
         | 
| 71 | 
            +
                # @rbs return: F32
         | 
| 72 | 
            +
                def F32(value)
         | 
| 73 | 
            +
                  F32.new.tap{|i| i.value = value }
         | 
| 74 | 
            +
                end
         | 
| 75 | 
            +
             | 
| 76 | 
            +
                # @rbs value: Float
         | 
| 77 | 
            +
                # @rbs return: F64
         | 
| 78 | 
            +
                def F64(value)
         | 
| 79 | 
            +
                  F64.new.tap{|i| i.value = value }
         | 
| 80 | 
            +
                end
         | 
| 81 | 
            +
              end
         | 
| 82 | 
            +
            end
         | 
    
        data/lib/wardite/version.rb
    CHANGED
    
    
    
        data/lib/wardite/wasi.rb
    CHANGED
    
    | @@ -1,6 +1,8 @@ | |
| 1 1 | 
             
            # rbs_inline: enabled
         | 
| 2 2 | 
             
            module Wardite
         | 
| 3 3 | 
             
              class WasiSnapshotPreview1
         | 
| 4 | 
            +
                include ValueHelper
         | 
| 5 | 
            +
             | 
| 4 6 | 
             
                attr_accessor :fd_table #: Array[IO]
         | 
| 5 7 |  | 
| 6 8 | 
             
                def initialize
         | 
| @@ -12,12 +14,12 @@ module Wardite | |
| 12 14 | 
             
                end
         | 
| 13 15 |  | 
| 14 16 | 
             
                # @rbs store: Store
         | 
| 15 | 
            -
                # @rbs args: Array[ | 
| 17 | 
            +
                # @rbs args: Array[I32|I64|F32|F64]
         | 
| 16 18 | 
             
                # @rbs return: Object
         | 
| 17 19 | 
             
                def fd_write(store, args)
         | 
| 18 20 | 
             
                  iargs = args.map do |elm|
         | 
| 19 | 
            -
                    if elm.is_a?( | 
| 20 | 
            -
                      elm
         | 
| 21 | 
            +
                    if elm.is_a?(I32)
         | 
| 22 | 
            +
                      elm.value
         | 
| 21 23 | 
             
                    else
         | 
| 22 24 | 
             
                      raise Wardite::ArgumentError, "invalid type of args: #{args.inspect}"
         | 
| 23 25 | 
             
                    end
         | 
    
        data/lib/wardite.rb
    CHANGED
    
    | @@ -5,6 +5,15 @@ require_relative "wardite/version" | |
| 5 5 | 
             
            require_relative "wardite/leb128"
         | 
| 6 6 | 
             
            require_relative "wardite/const"
         | 
| 7 7 | 
             
            require_relative "wardite/instruction"
         | 
| 8 | 
            +
            require_relative "wardite/value"
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            module Wardite
         | 
| 11 | 
            +
              module Evaluator
         | 
| 12 | 
            +
                extend Wardite::ValueHelper
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
            end
         | 
| 15 | 
            +
            require_relative "wardite/alu_i32.generated"
         | 
| 16 | 
            +
             | 
| 8 17 | 
             
            require_relative "wardite/wasi"
         | 
| 9 18 |  | 
| 10 19 | 
             
            require "stringio"
         | 
| @@ -164,7 +173,8 @@ module Wardite | |
| 164 173 | 
             
              end
         | 
| 165 174 |  | 
| 166 175 | 
             
              module BinaryLoader
         | 
| 167 | 
            -
                extend Wardite:: | 
| 176 | 
            +
                extend Wardite::Leb128Helper
         | 
| 177 | 
            +
                extend Wardite::ValueHelper
         | 
| 168 178 |  | 
| 169 179 | 
             
                # @rbs buf: File|StringIO
         | 
| 170 180 | 
             
                # @rbs import_object: Hash[Symbol, Hash[Symbol, Proc]]
         | 
| @@ -417,9 +427,9 @@ module Wardite | |
| 417 427 | 
             
                def self.code_body(buf)
         | 
| 418 428 | 
             
                  dest = []
         | 
| 419 429 | 
             
                  while c = buf.read(1)
         | 
| 420 | 
            -
                    code = Op.to_sym(c)
         | 
| 430 | 
            +
                    namespace, code = Op.to_sym(c)
         | 
| 421 431 | 
             
                    operand_types = Op.operand_of(code)
         | 
| 422 | 
            -
                    operand = [] #: Array[ | 
| 432 | 
            +
                    operand = [] #: Array[Integer|Float|Block]
         | 
| 423 433 | 
             
                    operand_types.each do |typ|
         | 
| 424 434 | 
             
                      case typ
         | 
| 425 435 | 
             
                      when :u32
         | 
| @@ -442,7 +452,7 @@ module Wardite | |
| 442 452 | 
             
                      end         
         | 
| 443 453 | 
             
                    end
         | 
| 444 454 |  | 
| 445 | 
            -
                    dest << Op.new(code, operand)
         | 
| 455 | 
            +
                    dest << Op.new(namespace, code, operand)
         | 
| 446 456 | 
             
                  end
         | 
| 447 457 |  | 
| 448 458 | 
             
                  dest
         | 
| @@ -675,7 +685,10 @@ module Wardite | |
| 675 685 | 
             
              end
         | 
| 676 686 |  | 
| 677 687 | 
             
              class Runtime
         | 
| 678 | 
            -
                 | 
| 688 | 
            +
                include ValueHelper
         | 
| 689 | 
            +
             | 
| 690 | 
            +
                # TODO: add types of class that the stack accomodates
         | 
| 691 | 
            +
                attr_accessor :stack #: Array[I32|I64|F32|F64|Block]
         | 
| 679 692 |  | 
| 680 693 | 
             
                attr_accessor :call_stack #: Array[Frame]
         | 
| 681 694 |  | 
| @@ -708,34 +721,14 @@ module Wardite | |
| 708 721 | 
             
                  if fn.callsig.size != args.size
         | 
| 709 722 | 
             
                    raise ArgumentError, "unmatch arg size"
         | 
| 710 723 | 
             
                  end
         | 
| 711 | 
            -
                  args. | 
| 712 | 
            -
                     | 
| 713 | 
            -
             | 
| 714 | 
            -
             | 
| 715 | 
            -
             | 
| 716 | 
            -
             | 
| 717 | 
            -
             | 
| 718 | 
            -
             | 
| 719 | 
            -
                    invoke_external(fn)
         | 
| 720 | 
            -
                  else
         | 
| 721 | 
            -
                    raise GenericError, "registered pointer is not to a function"
         | 
| 722 | 
            -
                  end
         | 
| 723 | 
            -
                end
         | 
| 724 | 
            -
             | 
| 725 | 
            -
                # @rbs idx: Integer
         | 
| 726 | 
            -
                # @rbs args: Array[Object]
         | 
| 727 | 
            -
                # @rbs return: Object|nil
         | 
| 728 | 
            -
                def call_index(idx, args)
         | 
| 729 | 
            -
                  fn = self.instance.store[idx]
         | 
| 730 | 
            -
                  if !fn
         | 
| 731 | 
            -
                    # TODO: own error NoFunctionError
         | 
| 732 | 
            -
                    raise ::NoMethodError, "func #{idx} not found"
         | 
| 733 | 
            -
                  end
         | 
| 734 | 
            -
                  if fn.callsig.size != args.size
         | 
| 735 | 
            -
                    raise ArgumentError, "unmatch arg size"
         | 
| 736 | 
            -
                  end
         | 
| 737 | 
            -
                  args.each do |arg|
         | 
| 738 | 
            -
                    stack.push arg
         | 
| 724 | 
            +
                  args.each_with_index do |arg, idx|
         | 
| 725 | 
            +
                    case fn.callsig[idx]
         | 
| 726 | 
            +
                    when :i32
         | 
| 727 | 
            +
                      raise "type mismatch: i32(#{arg})" unless arg.is_a?(Integer)
         | 
| 728 | 
            +
                      stack.push I32(arg)
         | 
| 729 | 
            +
                    else
         | 
| 730 | 
            +
                      raise "TODO: add me"
         | 
| 731 | 
            +
                    end
         | 
| 739 732 | 
             
                  end
         | 
| 740 733 |  | 
| 741 734 | 
             
                  case fn
         | 
| @@ -761,11 +754,12 @@ module Wardite | |
| 761 754 | 
             
                  wasm_function.locals_type.each_with_index do |typ, i|
         | 
| 762 755 | 
             
                    case typ
         | 
| 763 756 | 
             
                    when :i32, :u32
         | 
| 764 | 
            -
                       | 
| 765 | 
            -
             | 
| 757 | 
            +
                      locals.push I32(0)
         | 
| 758 | 
            +
                    when :i64, :u64
         | 
| 759 | 
            +
                      locals.push I64(0)
         | 
| 766 760 | 
             
                    else
         | 
| 767 | 
            -
                      $stderr.puts "warning: unknown type #{typ.inspect}. default to  | 
| 768 | 
            -
                      locals.push  | 
| 761 | 
            +
                      $stderr.puts "warning: unknown type #{typ.inspect}. default to I32"
         | 
| 762 | 
            +
                      locals.push I32(0)
         | 
| 769 763 | 
             
                    end
         | 
| 770 764 | 
             
                  end
         | 
| 771 765 |  | 
| @@ -796,7 +790,7 @@ module Wardite | |
| 796 790 | 
             
                end
         | 
| 797 791 |  | 
| 798 792 | 
             
                # @rbs external_function: ExternalFunction
         | 
| 799 | 
            -
                # @rbs return:  | 
| 793 | 
            +
                # @rbs return: I32|I64|F32|F64|nil
         | 
| 800 794 | 
             
                def invoke_external(external_function)
         | 
| 801 795 | 
             
                  local_start = stack.size - external_function.callsig.size
         | 
| 802 796 | 
             
                  args = stack[local_start..]
         | 
| @@ -806,7 +800,31 @@ module Wardite | |
| 806 800 | 
             
                  self.stack = drained_stack(local_start)
         | 
| 807 801 |  | 
| 808 802 | 
             
                  proc = external_function.callable
         | 
| 809 | 
            -
                  proc[self.instance.store, args]
         | 
| 803 | 
            +
                  val = proc[self.instance.store, args]
         | 
| 804 | 
            +
                  if !val
         | 
| 805 | 
            +
                    return
         | 
| 806 | 
            +
                  end
         | 
| 807 | 
            +
             | 
| 808 | 
            +
                  case val
         | 
| 809 | 
            +
                  when I32, I64, F32, F64
         | 
| 810 | 
            +
                    return val
         | 
| 811 | 
            +
                  when Integer
         | 
| 812 | 
            +
                    case external_function.retsig[0]
         | 
| 813 | 
            +
                    when :i32
         | 
| 814 | 
            +
                      return I32(val)
         | 
| 815 | 
            +
                    when :i64
         | 
| 816 | 
            +
                      return I64(val)
         | 
| 817 | 
            +
                    end
         | 
| 818 | 
            +
                  when Float
         | 
| 819 | 
            +
                    case external_function.retsig[0]
         | 
| 820 | 
            +
                    when :f32
         | 
| 821 | 
            +
                      return F32(val)
         | 
| 822 | 
            +
                    when :f64
         | 
| 823 | 
            +
                      return F64(val)
         | 
| 824 | 
            +
                    end
         | 
| 825 | 
            +
                  end
         | 
| 826 | 
            +
             | 
| 827 | 
            +
                  raise "invalid type of value returned in proc. val: #{val.inspect}"
         | 
| 810 828 | 
             
                end
         | 
| 811 829 |  | 
| 812 830 | 
             
                # @rbs return: void
         | 
| @@ -829,14 +847,20 @@ module Wardite | |
| 829 847 | 
             
                # @rbs insn: Op
         | 
| 830 848 | 
             
                # @rbs return: void
         | 
| 831 849 | 
             
                def eval_insn(frame, insn)
         | 
| 850 | 
            +
                  case insn.namespace
         | 
| 851 | 
            +
                  when :i32
         | 
| 852 | 
            +
                    return Evaluator.i32_eval_insn(self, frame, insn)
         | 
| 853 | 
            +
                  end
         | 
| 854 | 
            +
             | 
| 855 | 
            +
                  # unmached namespace...
         | 
| 832 856 | 
             
                  case insn.code
         | 
| 833 857 | 
             
                  when :if
         | 
| 834 858 | 
             
                    block = insn.operand[0]
         | 
| 835 859 | 
             
                    raise EvalError, "if op without block" if !block.is_a?(Block)
         | 
| 836 860 | 
             
                    cond = stack.pop 
         | 
| 837 | 
            -
                    raise EvalError, "cond not found" if !cond.is_a?( | 
| 861 | 
            +
                    raise EvalError, "cond not found" if !cond.is_a?(I32)
         | 
| 838 862 | 
             
                    next_pc = fetch_ops_while_end(frame.body, frame.pc)
         | 
| 839 | 
            -
                    if cond.zero?
         | 
| 863 | 
            +
                    if cond.value.zero?
         | 
| 840 864 | 
             
                      frame.pc = next_pc
         | 
| 841 865 | 
             
                    end
         | 
| 842 866 |  | 
| @@ -862,55 +886,58 @@ module Wardite | |
| 862 886 | 
             
                    if !value
         | 
| 863 887 | 
             
                      raise EvalError, "value should be pushed"
         | 
| 864 888 | 
             
                    end
         | 
| 865 | 
            -
                     | 
| 866 | 
            -
             | 
| 867 | 
            -
                  when :i32_lts
         | 
| 868 | 
            -
                    right, left = stack.pop, stack.pop
         | 
| 869 | 
            -
                    if !right.is_a?(Integer) || !left.is_a?(Integer)
         | 
| 870 | 
            -
                      raise EvalError, "maybe empty stack"
         | 
| 871 | 
            -
                    end
         | 
| 872 | 
            -
                    value = (left < right) ? 1 : 0
         | 
| 873 | 
            -
                    stack.push(value)
         | 
| 874 | 
            -
                  when :i32_leu
         | 
| 875 | 
            -
                    right, left = stack.pop, stack.pop
         | 
| 876 | 
            -
                    if !right.is_a?(Integer) || !left.is_a?(Integer)
         | 
| 877 | 
            -
                      raise EvalError, "maybe empty stack"
         | 
| 878 | 
            -
                    end
         | 
| 879 | 
            -
                    value = (left >= right) ? 1 : 0
         | 
| 880 | 
            -
                    stack.push(value)
         | 
| 881 | 
            -
                  when :i32_add
         | 
| 882 | 
            -
                    right, left = stack.pop, stack.pop
         | 
| 883 | 
            -
                    if !right.is_a?(Integer) || !left.is_a?(Integer)
         | 
| 884 | 
            -
                      raise EvalError, "maybe empty stack"
         | 
| 885 | 
            -
                    end
         | 
| 886 | 
            -
                    stack.push(left + right)
         | 
| 887 | 
            -
                  when :i32_sub
         | 
| 888 | 
            -
                    right, left = stack.pop, stack.pop
         | 
| 889 | 
            -
                    if !right.is_a?(Integer) || !left.is_a?(Integer)
         | 
| 890 | 
            -
                      raise EvalError, "maybe empty stack"
         | 
| 891 | 
            -
                    end
         | 
| 892 | 
            -
                    stack.push(left - right)
         | 
| 893 | 
            -
                  when :i32_const
         | 
| 894 | 
            -
                    const = insn.operand[0]
         | 
| 895 | 
            -
                    if !const.is_a?(Integer)
         | 
| 896 | 
            -
                      raise EvalError, "[BUG] invalid type of operand"
         | 
| 897 | 
            -
                    end
         | 
| 898 | 
            -
                    stack.push(const)
         | 
| 899 | 
            -
                  when :i32_store
         | 
| 900 | 
            -
                    _align = insn.operand[0] # TODO: alignment support?
         | 
| 901 | 
            -
                    offset = insn.operand[1]
         | 
| 902 | 
            -
                    raise EvalError, "[BUG] invalid type of operand" if !offset.is_a?(Integer)
         | 
| 903 | 
            -
             | 
| 904 | 
            -
                    value = stack.pop
         | 
| 905 | 
            -
                    addr = stack.pop
         | 
| 906 | 
            -
                    if !value.is_a?(Integer) || !addr.is_a?(Integer)
         | 
| 907 | 
            -
                      raise EvalError, "maybe stack too short"
         | 
| 889 | 
            +
                    if value.is_a?(Block)
         | 
| 890 | 
            +
                      raise EvalError, "block value detected"
         | 
| 908 891 | 
             
                    end
         | 
| 892 | 
            +
                    frame.locals[idx] = value
         | 
| 909 893 |  | 
| 910 | 
            -
             | 
| 911 | 
            -
             | 
| 912 | 
            -
             | 
| 913 | 
            -
             | 
| 894 | 
            +
                  # when :i32_lts
         | 
| 895 | 
            +
                  #   right, left = stack.pop, stack.pop
         | 
| 896 | 
            +
                  #   if !right.is_a?(Integer) || !left.is_a?(Integer)
         | 
| 897 | 
            +
                  #     raise EvalError, "maybe empty stack"
         | 
| 898 | 
            +
                  #   end
         | 
| 899 | 
            +
                  #   value = (left < right) ? 1 : 0
         | 
| 900 | 
            +
                  #   stack.push(value)
         | 
| 901 | 
            +
                  # when :i32_leu
         | 
| 902 | 
            +
                  #   right, left = stack.pop, stack.pop
         | 
| 903 | 
            +
                  #   if !right.is_a?(Integer) || !left.is_a?(Integer)
         | 
| 904 | 
            +
                  #     raise EvalError, "maybe empty stack"
         | 
| 905 | 
            +
                  #   end
         | 
| 906 | 
            +
                  #   value = (left >= right) ? 1 : 0
         | 
| 907 | 
            +
                  #   stack.push(value)
         | 
| 908 | 
            +
                  # when :i32_add
         | 
| 909 | 
            +
                  #   right, left = stack.pop, stack.pop
         | 
| 910 | 
            +
                  #   if !right.is_a?(Integer) || !left.is_a?(Integer)
         | 
| 911 | 
            +
                  #     raise EvalError, "maybe empty stack"
         | 
| 912 | 
            +
                  #   end
         | 
| 913 | 
            +
                  #   stack.push(left + right)
         | 
| 914 | 
            +
                  # when :i32_sub
         | 
| 915 | 
            +
                  #   right, left = stack.pop, stack.pop
         | 
| 916 | 
            +
                  #   if !right.is_a?(Integer) || !left.is_a?(Integer)
         | 
| 917 | 
            +
                  #     raise EvalError, "maybe empty stack"
         | 
| 918 | 
            +
                  #   end
         | 
| 919 | 
            +
                  #   stack.push(left - right)
         | 
| 920 | 
            +
                  # when :i32_const
         | 
| 921 | 
            +
                  #   const = insn.operand[0]
         | 
| 922 | 
            +
                  #   if !const.is_a?(Integer)
         | 
| 923 | 
            +
                  #     raise EvalError, "[BUG] invalid type of operand"
         | 
| 924 | 
            +
                  #   end
         | 
| 925 | 
            +
                  #   stack.push(const)
         | 
| 926 | 
            +
                  # when :i32_store
         | 
| 927 | 
            +
                  #   _align = insn.operand[0] # TODO: alignment support?
         | 
| 928 | 
            +
                  #   offset = insn.operand[1]
         | 
| 929 | 
            +
                  #   raise EvalError, "[BUG] invalid type of operand" if !offset.is_a?(Integer)
         | 
| 930 | 
            +
             | 
| 931 | 
            +
                  #   value = stack.pop
         | 
| 932 | 
            +
                  #   addr = stack.pop
         | 
| 933 | 
            +
                  #   if !value.is_a?(Integer) || !addr.is_a?(Integer)
         | 
| 934 | 
            +
                  #     raise EvalError, "maybe stack too short"
         | 
| 935 | 
            +
                  #   end
         | 
| 936 | 
            +
             | 
| 937 | 
            +
                  #   at = addr + offset
         | 
| 938 | 
            +
                  #   data_end = at + 4 # sizeof(i32)
         | 
| 939 | 
            +
                  #   memory = self.instance.store.memories[0] || raise("[BUG] no memory")
         | 
| 940 | 
            +
                  #   memory.data[at...data_end] = [value].pack("I")
         | 
| 914 941 |  | 
| 915 942 | 
             
                  when :call
         | 
| 916 943 | 
             
                    idx = insn.operand[0]
         | 
| @@ -996,7 +1023,7 @@ module Wardite | |
| 996 1023 | 
             
                end
         | 
| 997 1024 |  | 
| 998 1025 | 
             
                # @rbs finish: Integer
         | 
| 999 | 
            -
                # @rbs return: Array[ | 
| 1026 | 
            +
                # @rbs return: Array[I32|I64|F32|F64|Block]
         | 
| 1000 1027 | 
             
                def drained_stack(finish)
         | 
| 1001 1028 | 
             
                  drained = stack[0...finish]
         | 
| 1002 1029 | 
             
                  if ! drained
         | 
| @@ -1034,7 +1061,7 @@ module Wardite | |
| 1034 1061 |  | 
| 1035 1062 | 
             
                attr_accessor :labels #: Array[Label]
         | 
| 1036 1063 |  | 
| 1037 | 
            -
                attr_accessor :locals #: Array[ | 
| 1064 | 
            +
                attr_accessor :locals #: Array[I32|I64|F32|F64]
         | 
| 1038 1065 |  | 
| 1039 1066 | 
             
                # @rbs pc: Integer
         | 
| 1040 1067 | 
             
                # @rbs sp: Integer
         | 
    
        data/scripts/gen_alu.rb
    ADDED
    
    | @@ -0,0 +1,124 @@ | |
| 1 | 
            +
            require "stringio"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module GenAlu
         | 
| 4 | 
            +
              def self.execute(path, prefix: "i32", defined_ops: [])
         | 
| 5 | 
            +
                parent_dir = File.dirname(path)
         | 
| 6 | 
            +
                system "mkdir -p #{parent_dir}"
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                basic_module = File.read(
         | 
| 9 | 
            +
                  File.expand_path("../templates/alu_module.rb.tmpl", __FILE__)
         | 
| 10 | 
            +
                )
         | 
| 11 | 
            +
                basic_module.gsub!(/\$\{PREFIX\}/, prefix)
         | 
| 12 | 
            +
                ope_defs = generate_ops(prefix: prefix, defined_ops: defined_ops)
         | 
| 13 | 
            +
                basic_module.gsub!(/\$\{DEFS\}/, ope_defs)
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                dest = File.open(path, "w")
         | 
| 16 | 
            +
                dest.puts basic_module
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                $stderr.puts "generated: #{path}"
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
              def self.generate_ops(prefix:, defined_ops:)
         | 
| 22 | 
            +
                result = StringIO.new("")
         | 
| 23 | 
            +
                defined_ops.each do |op|
         | 
| 24 | 
            +
                  code = DEFS[op.to_sym]
         | 
| 25 | 
            +
                  if ! code
         | 
| 26 | 
            +
                    raise "unsupported code specified!"
         | 
| 27 | 
            +
                  end
         | 
| 28 | 
            +
                  code.gsub!(/\$\{PREFIX\}/, prefix)
         | 
| 29 | 
            +
                  code.gsub!(/\$\{CLASS\}/, to_class(prefix.to_sym))
         | 
| 30 | 
            +
                  result << "\n"
         | 
| 31 | 
            +
                  code.each_line do |ln|
         | 
| 32 | 
            +
                    result << " " * 6 << ln
         | 
| 33 | 
            +
                  end
         | 
| 34 | 
            +
                  result << "\n"
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
                result.string
         | 
| 37 | 
            +
              end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
              def self.to_class(prefix)
         | 
| 40 | 
            +
                {
         | 
| 41 | 
            +
                  i32: "I32",
         | 
| 42 | 
            +
                  i64: "I64",
         | 
| 43 | 
            +
                  f32: "F32",
         | 
| 44 | 
            +
                  f64: "F64",
         | 
| 45 | 
            +
                }[prefix]
         | 
| 46 | 
            +
              end
         | 
| 47 | 
            +
             
         | 
| 48 | 
            +
              # ope_templates
         | 
| 49 | 
            +
              DEFS = { #: Hash[Symbol, String]
         | 
| 50 | 
            +
                lts: <<~RUBY,
         | 
| 51 | 
            +
                  when :${PREFIX}_lts
         | 
| 52 | 
            +
                    right, left = runtime.stack.pop, runtime.stack.pop
         | 
| 53 | 
            +
                    if !right.is_a?(${CLASS}) || !left.is_a?(${CLASS})
         | 
| 54 | 
            +
                      raise EvalError, "maybe empty or invalid stack"
         | 
| 55 | 
            +
                    end
         | 
| 56 | 
            +
                    value = (left.value < right.value) ? 1 : 0
         | 
| 57 | 
            +
                    runtime.stack.push(I32(value))
         | 
| 58 | 
            +
                RUBY
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                leu: <<~RUBY,
         | 
| 61 | 
            +
                  when :${PREFIX}_leu
         | 
| 62 | 
            +
                    right, left = runtime.stack.pop, runtime.stack.pop
         | 
| 63 | 
            +
                    if !right.is_a?(${CLASS}) || !left.is_a?(${CLASS})
         | 
| 64 | 
            +
                      raise EvalError, "maybe empty or invalid stack"
         | 
| 65 | 
            +
                    end
         | 
| 66 | 
            +
                    value = (left.value >= right.value) ? 1 : 0
         | 
| 67 | 
            +
                    runtime.stack.push(I32(value))
         | 
| 68 | 
            +
                RUBY
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                add: <<~RUBY,
         | 
| 71 | 
            +
                  when :${PREFIX}_add
         | 
| 72 | 
            +
                    right, left = runtime.stack.pop, runtime.stack.pop
         | 
| 73 | 
            +
                    if !right.is_a?(${CLASS}) || !left.is_a?(${CLASS})
         | 
| 74 | 
            +
                      raise EvalError, "maybe empty or invalid stack"
         | 
| 75 | 
            +
                    end
         | 
| 76 | 
            +
                    runtime.stack.push(${CLASS}(left.value + right.value))
         | 
| 77 | 
            +
                RUBY
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                sub: <<~RUBY,
         | 
| 80 | 
            +
                  when :${PREFIX}_sub
         | 
| 81 | 
            +
                    right, left = runtime.stack.pop, runtime.stack.pop
         | 
| 82 | 
            +
                    if !right.is_a?(${CLASS}) || !left.is_a?(${CLASS})
         | 
| 83 | 
            +
                      raise EvalError, "maybe empty or invalid stack"
         | 
| 84 | 
            +
                    end
         | 
| 85 | 
            +
                    runtime.stack.push(${CLASS}(left.value - right.value))
         | 
| 86 | 
            +
                RUBY
         | 
| 87 | 
            +
             | 
| 88 | 
            +
                const: <<~RUBY,
         | 
| 89 | 
            +
                  when :${PREFIX}_const
         | 
| 90 | 
            +
                    const = insn.operand[0]
         | 
| 91 | 
            +
                    if !const.is_a?(Integer)
         | 
| 92 | 
            +
                      raise EvalError, "invalid type of operand"
         | 
| 93 | 
            +
                    end
         | 
| 94 | 
            +
                    runtime.stack.push(${CLASS}(const))
         | 
| 95 | 
            +
                RUBY
         | 
| 96 | 
            +
             | 
| 97 | 
            +
                const__f: <<~RUBY,
         | 
| 98 | 
            +
                  when :${PREFIX}_const
         | 
| 99 | 
            +
                    const = insn.operand[0]
         | 
| 100 | 
            +
                    if !const.is_a?(Float)
         | 
| 101 | 
            +
                      raise EvalError, "invalid type of operand"
         | 
| 102 | 
            +
                    end
         | 
| 103 | 
            +
                    runtime.stack.push(${CLASS}(const))
         | 
| 104 | 
            +
                RUBY
         | 
| 105 | 
            +
             | 
| 106 | 
            +
                store: <<~RUBY,
         | 
| 107 | 
            +
                  when :${PREFIX}_store
         | 
| 108 | 
            +
                    _align = insn.operand[0] # TODO: alignment support?
         | 
| 109 | 
            +
                    offset = insn.operand[1]
         | 
| 110 | 
            +
                    raise EvalError, "[BUG] invalid type of operand" if !offset.is_a?(Integer)
         | 
| 111 | 
            +
             | 
| 112 | 
            +
                    value = runtime.stack.pop
         | 
| 113 | 
            +
                    addr = runtime.stack.pop
         | 
| 114 | 
            +
                    if !value.is_a?(${CLASS}) || !addr.is_a?(I32)
         | 
| 115 | 
            +
                      raise EvalError, "maybe stack too short"
         | 
| 116 | 
            +
                    end
         | 
| 117 | 
            +
             | 
| 118 | 
            +
                    at = addr.value + offset
         | 
| 119 | 
            +
                    data_end = at + value.packed.size
         | 
| 120 | 
            +
                    memory = runtime.instance.store.memories[0] || raise("[BUG] no memory")
         | 
| 121 | 
            +
                    memory.data[at...data_end] = value.packed
         | 
| 122 | 
            +
                RUBY
         | 
| 123 | 
            +
              }
         | 
| 124 | 
            +
            end
         | 
| @@ -0,0 +1,18 @@ | |
| 1 | 
            +
            # rbs_inline: enabled
         | 
| 2 | 
            +
            require_relative "value"
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            module Wardite
         | 
| 5 | 
            +
              module Evaluator
         | 
| 6 | 
            +
                # @rbs runtime: Runtime
         | 
| 7 | 
            +
                # @rbs frame: Frame
         | 
| 8 | 
            +
                # @rbs insn: Op
         | 
| 9 | 
            +
                # @rbs return: void 
         | 
| 10 | 
            +
                def self.${PREFIX}_eval_insn(runtime, frame, insn)
         | 
| 11 | 
            +
                  case insn.code
         | 
| 12 | 
            +
            ${DEFS}
         | 
| 13 | 
            +
                  else
         | 
| 14 | 
            +
                    raise "Unknown opcode for namespace #{insn.namespace}: #{insn.code}"
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
            end
         | 
| @@ -0,0 +1,11 @@ | |
| 1 | 
            +
            # Generated from lib/wardite/alu_i32.generated.rb with RBS::Inline
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Wardite
         | 
| 4 | 
            +
              module Evaluator
         | 
| 5 | 
            +
                # @rbs runtime: Runtime
         | 
| 6 | 
            +
                # @rbs frame: Frame
         | 
| 7 | 
            +
                # @rbs insn: Op
         | 
| 8 | 
            +
                # @rbs return: void 
         | 
| 9 | 
            +
                def self.i32_eval_insn: (Runtime runtime, Frame frame, Op insn) -> void
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
            end
         | 
| @@ -1,19 +1,22 @@ | |
| 1 1 | 
             
            # Generated from lib/wardite/instruction.rb with RBS::Inline
         | 
| 2 2 |  | 
| 3 | 
            -
            # rbs_inline: enabled
         | 
| 4 3 | 
             
            module Wardite
         | 
| 5 4 | 
             
              class Op
         | 
| 5 | 
            +
                attr_accessor namespace: Symbol
         | 
| 6 | 
            +
             | 
| 6 7 | 
             
                attr_accessor code: Symbol
         | 
| 7 8 |  | 
| 8 | 
            -
                 | 
| 9 | 
            +
                # TODO: add types of potential operands
         | 
| 10 | 
            +
                attr_accessor operand: Array[Integer | Float | Block]
         | 
| 9 11 |  | 
| 12 | 
            +
                # @rbs namespace: Symbol
         | 
| 10 13 | 
             
                # @rbs code: Symbol
         | 
| 11 | 
            -
                # @rbs operand: Array[ | 
| 12 | 
            -
                def initialize: (Symbol code, Array[ | 
| 14 | 
            +
                # @rbs operand: Array[Integer|Float|Block]
         | 
| 15 | 
            +
                def initialize: (Symbol namespace, Symbol code, Array[Integer | Float | Block] operand) -> untyped
         | 
| 13 16 |  | 
| 14 17 | 
             
                # @rbs chr: String
         | 
| 15 | 
            -
                # @rbs return: Symbol
         | 
| 16 | 
            -
                def self.to_sym: (String chr) -> Symbol
         | 
| 18 | 
            +
                # @rbs return: [Symbol, Symbol]
         | 
| 19 | 
            +
                def self.to_sym: (String chr) -> [ Symbol, Symbol ]
         | 
| 17 20 |  | 
| 18 21 | 
             
                # @rbs chr: Symbol
         | 
| 19 22 | 
             
                # @rbs return: Array[Symbol]
         | 
| @@ -0,0 +1,58 @@ | |
| 1 | 
            +
            # Generated from lib/wardite/value.rb with RBS::Inline
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Wardite
         | 
| 4 | 
            +
              class I32
         | 
| 5 | 
            +
                attr_accessor value: Integer
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                # TODO: eliminate use of pack, to support mruby - in this file!
         | 
| 8 | 
            +
                # @rbs return: String
         | 
| 9 | 
            +
                def packed: () -> String
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                def inspect: () -> untyped
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              class I64
         | 
| 15 | 
            +
                attr_accessor value: Integer
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                # @rbs return: String
         | 
| 18 | 
            +
                def packed: () -> String
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                def inspect: () -> untyped
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              class F32
         | 
| 24 | 
            +
                attr_accessor value: Float
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                # @rbs return: String
         | 
| 27 | 
            +
                def packed: () -> String
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                def inspect: () -> untyped
         | 
| 30 | 
            +
              end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
              class F64
         | 
| 33 | 
            +
                attr_accessor value: Float
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                # @rbs return: String
         | 
| 36 | 
            +
                def packed: () -> String
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                def inspect: () -> untyped
         | 
| 39 | 
            +
              end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
              module ValueHelper
         | 
| 42 | 
            +
                # @rbs value: Integer
         | 
| 43 | 
            +
                # @rbs return: I32
         | 
| 44 | 
            +
                def I32: (Integer value) -> I32
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                # @rbs value: Integer
         | 
| 47 | 
            +
                # @rbs return: I64
         | 
| 48 | 
            +
                def I64: (Integer value) -> I64
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                # @rbs value: Float
         | 
| 51 | 
            +
                # @rbs return: F32
         | 
| 52 | 
            +
                def F32: (Float value) -> F32
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                # @rbs value: Float
         | 
| 55 | 
            +
                # @rbs return: F64
         | 
| 56 | 
            +
                def F64: (Float value) -> F64
         | 
| 57 | 
            +
              end
         | 
| 58 | 
            +
            end
         | 
| @@ -3,14 +3,16 @@ | |
| 3 3 | 
             
            # rbs_inline: enabled
         | 
| 4 4 | 
             
            module Wardite
         | 
| 5 5 | 
             
              class WasiSnapshotPreview1
         | 
| 6 | 
            +
                include ValueHelper
         | 
| 7 | 
            +
             | 
| 6 8 | 
             
                attr_accessor fd_table: Array[IO]
         | 
| 7 9 |  | 
| 8 10 | 
             
                def initialize: () -> untyped
         | 
| 9 11 |  | 
| 10 12 | 
             
                # @rbs store: Store
         | 
| 11 | 
            -
                # @rbs args: Array[ | 
| 13 | 
            +
                # @rbs args: Array[I32|I64|F32|F64]
         | 
| 12 14 | 
             
                # @rbs return: Object
         | 
| 13 | 
            -
                def fd_write: (Store store, Array[ | 
| 15 | 
            +
                def fd_write: (Store store, Array[I32 | I64 | F32 | F64] args) -> Object
         | 
| 14 16 |  | 
| 15 17 | 
             
                # @rbs return: Hash[Symbol, Proc]
         | 
| 16 18 | 
             
                def to_module: () -> Hash[Symbol, Proc]
         | 
    
        data/sig/generated/wardite.rbs
    CHANGED
    
    | @@ -1,5 +1,11 @@ | |
| 1 1 | 
             
            # Generated from lib/wardite.rb with RBS::Inline
         | 
| 2 2 |  | 
| 3 | 
            +
            module Wardite
         | 
| 4 | 
            +
              module Evaluator
         | 
| 5 | 
            +
                extend Wardite::ValueHelper
         | 
| 6 | 
            +
              end
         | 
| 7 | 
            +
            end
         | 
| 8 | 
            +
             | 
| 3 9 | 
             
            module Wardite
         | 
| 4 10 | 
             
              class Section
         | 
| 5 11 | 
             
                attr_accessor name: String
         | 
| @@ -107,7 +113,9 @@ module Wardite | |
| 107 113 | 
             
              end
         | 
| 108 114 |  | 
| 109 115 | 
             
              module BinaryLoader
         | 
| 110 | 
            -
                extend Wardite:: | 
| 116 | 
            +
                extend Wardite::Leb128Helper
         | 
| 117 | 
            +
             | 
| 118 | 
            +
                extend Wardite::ValueHelper
         | 
| 111 119 |  | 
| 112 120 | 
             
                # @rbs buf: File|StringIO
         | 
| 113 121 | 
             
                # @rbs import_object: Hash[Symbol, Hash[Symbol, Proc]]
         | 
| @@ -204,7 +212,10 @@ module Wardite | |
| 204 212 | 
             
              end
         | 
| 205 213 |  | 
| 206 214 | 
             
              class Runtime
         | 
| 207 | 
            -
                 | 
| 215 | 
            +
                include ValueHelper
         | 
| 216 | 
            +
             | 
| 217 | 
            +
                # TODO: add types of class that the stack accomodates
         | 
| 218 | 
            +
                attr_accessor stack: Array[I32 | I64 | F32 | F64 | Block]
         | 
| 208 219 |  | 
| 209 220 | 
             
                attr_accessor call_stack: Array[Frame]
         | 
| 210 221 |  | 
| @@ -222,11 +233,6 @@ module Wardite | |
| 222 233 | 
             
                # @rbs return: Object|nil
         | 
| 223 234 | 
             
                def call: (String | Symbol name, Array[Object] args) -> (Object | nil)
         | 
| 224 235 |  | 
| 225 | 
            -
                # @rbs idx: Integer
         | 
| 226 | 
            -
                # @rbs args: Array[Object]
         | 
| 227 | 
            -
                # @rbs return: Object|nil
         | 
| 228 | 
            -
                def call_index: (Integer idx, Array[Object] args) -> (Object | nil)
         | 
| 229 | 
            -
             | 
| 230 236 | 
             
                # @rbs wasm_function: WasmFunction
         | 
| 231 237 | 
             
                # @rbs return: void
         | 
| 232 238 | 
             
                def push_frame: (WasmFunction wasm_function) -> void
         | 
| @@ -236,8 +242,8 @@ module Wardite | |
| 236 242 | 
             
                def invoke_internal: (WasmFunction wasm_function) -> (Object | nil)
         | 
| 237 243 |  | 
| 238 244 | 
             
                # @rbs external_function: ExternalFunction
         | 
| 239 | 
            -
                # @rbs return:  | 
| 240 | 
            -
                def invoke_external: (ExternalFunction external_function) -> ( | 
| 245 | 
            +
                # @rbs return: I32|I64|F32|F64|nil
         | 
| 246 | 
            +
                def invoke_external: (ExternalFunction external_function) -> (I32 | I64 | F32 | F64 | nil)
         | 
| 241 247 |  | 
| 242 248 | 
             
                # @rbs return: void
         | 
| 243 249 | 
             
                def execute!: () -> void
         | 
| @@ -259,8 +265,8 @@ module Wardite | |
| 259 265 | 
             
                def stack_unwind: (Integer sp, Integer arity) -> void
         | 
| 260 266 |  | 
| 261 267 | 
             
                # @rbs finish: Integer
         | 
| 262 | 
            -
                # @rbs return: Array[ | 
| 263 | 
            -
                def drained_stack: (Integer finish) -> Array[ | 
| 268 | 
            +
                # @rbs return: Array[I32|I64|F32|F64|Block]
         | 
| 269 | 
            +
                def drained_stack: (Integer finish) -> Array[I32 | I64 | F32 | F64 | Block]
         | 
| 264 270 |  | 
| 265 271 | 
             
                # @rbs name: Symbol
         | 
| 266 272 | 
             
                # @rbs args: Array[Object]
         | 
| @@ -283,7 +289,7 @@ module Wardite | |
| 283 289 |  | 
| 284 290 | 
             
                attr_accessor labels: Array[Label]
         | 
| 285 291 |  | 
| 286 | 
            -
                attr_accessor locals: Array[ | 
| 292 | 
            +
                attr_accessor locals: Array[I32 | I64 | F32 | F64]
         | 
| 287 293 |  | 
| 288 294 | 
             
                # @rbs pc: Integer
         | 
| 289 295 | 
             
                # @rbs sp: Integer
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: wardite
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: 0.2.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Uchio Kondo
         | 
| 8 8 | 
             
            autorequire:
         | 
| 9 9 | 
             
            bindir: exe
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2024- | 
| 11 | 
            +
            date: 2024-11-02 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies: []
         | 
| 13 13 | 
             
            description: A pure-ruby webassembly runtime
         | 
| 14 14 | 
             
            email:
         | 
| @@ -34,15 +34,21 @@ files: | |
| 34 34 | 
             
            - examples/memory.wat
         | 
| 35 35 | 
             
            - exe/wardite
         | 
| 36 36 | 
             
            - lib/wardite.rb
         | 
| 37 | 
            +
            - lib/wardite/alu_i32.generated.rb
         | 
| 37 38 | 
             
            - lib/wardite/const.rb
         | 
| 38 39 | 
             
            - lib/wardite/instruction.rb
         | 
| 39 40 | 
             
            - lib/wardite/leb128.rb
         | 
| 41 | 
            +
            - lib/wardite/value.rb
         | 
| 40 42 | 
             
            - lib/wardite/version.rb
         | 
| 41 43 | 
             
            - lib/wardite/wasi.rb
         | 
| 44 | 
            +
            - scripts/gen_alu.rb
         | 
| 45 | 
            +
            - scripts/templates/alu_module.rb.tmpl
         | 
| 42 46 | 
             
            - sig/generated/wardite.rbs
         | 
| 47 | 
            +
            - sig/generated/wardite/alu_i32.generated.rbs
         | 
| 43 48 | 
             
            - sig/generated/wardite/const.rbs
         | 
| 44 49 | 
             
            - sig/generated/wardite/instruction.rbs
         | 
| 45 50 | 
             
            - sig/generated/wardite/leb128.rbs
         | 
| 51 | 
            +
            - sig/generated/wardite/value.rbs
         | 
| 46 52 | 
             
            - sig/generated/wardite/version.rbs
         | 
| 47 53 | 
             
            - sig/generated/wardite/wasi.rbs
         | 
| 48 54 | 
             
            - sig/wardite.rbs
         |