wardite 0.4.3 → 0.5.1
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/examples/grayscale.rb +64 -0
- data/lib/wardite/alu_i32.generated.rb +27 -13
- data/lib/wardite/alu_i64.generated.rb +27 -13
- data/lib/wardite/errors.rb +9 -0
- data/lib/wardite/instruction.rb +3 -0
- data/lib/wardite/load.rb +6 -1
- data/lib/wardite/revisitor.rb +92 -0
- data/lib/wardite/version.rb +1 -1
- data/lib/wardite.rb +8 -65
- data/scripts/gen_alu.rb +27 -13
- data/sig/generated/wardite/errors.rbs +12 -0
- data/sig/generated/wardite/instruction.rbs +2 -0
- data/sig/generated/wardite/load.rbs +0 -1
- data/sig/generated/wardite/revisitor.rbs +25 -0
- data/sig/generated/wardite.rbs +0 -10
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 89b6c42e1a3f16c39c214eb127c5b87966c0d2933257a1da7fdc96236c6a0f9b
|
4
|
+
data.tar.gz: 321d62cdddc61c8a342b966b3e4d7b6c01ffbbcb5788a6787fd3490ba96b1430
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4b8b67989d47775828aca0908794f6b02abdea5ed653d794fa308d437f2d1735997a91dee341cdfa51aa5829aa097ca61dd262dba8479e805d1bbfd540f90ff5
|
7
|
+
data.tar.gz: 26face977ed4d76232bdee62f64208a22ec824314cb3d479979705fee327a1c9ce72ee960055a0c26db591f932c598b591651170fedf31b36533c52774f05fbe
|
@@ -0,0 +1,64 @@
|
|
1
|
+
#
|
2
|
+
# Usage:
|
3
|
+
# $ bundle exec ruby --yjit examples/grayscale.rb \
|
4
|
+
# --wasm-file path/to/grayscale.wasm \
|
5
|
+
# --source tmp/source.png \
|
6
|
+
# --dest tmp/result.png \
|
7
|
+
# --width 660 --height 495
|
8
|
+
#
|
9
|
+
require "wardite"
|
10
|
+
require "base64"
|
11
|
+
require "optparse"
|
12
|
+
require "ostruct"
|
13
|
+
|
14
|
+
$options = OpenStruct.new
|
15
|
+
|
16
|
+
opt = OptionParser.new
|
17
|
+
opt.on('--wasm-file [FILE]') {|v| $options.wasm_file = v }
|
18
|
+
opt.on('--source [IMAGE]') {|v| $options.source = v }
|
19
|
+
opt.on('--dest [IMAGE]') {|v| $options.dest = v }
|
20
|
+
opt.on('--width [W]') {|v| $options.width = v.to_i }
|
21
|
+
opt.on('--height [H]') {|v| $options.height = v.to_i }
|
22
|
+
opt.parse!
|
23
|
+
|
24
|
+
#require 'ruby-prof'
|
25
|
+
#profile = RubyProf::Profile.new
|
26
|
+
|
27
|
+
f = File.open($options.wasm_file)
|
28
|
+
data = IO.read($options.source)
|
29
|
+
orig = Base64.encode64(data).gsub(/(\r|\n)/, "")
|
30
|
+
data_url = "data:image/png;base64," + orig
|
31
|
+
instance = Wardite::BinaryLoader::load_from_buffer(f);
|
32
|
+
instance.store.memories[0].grow(data_url.size / (64*1024) + 1)
|
33
|
+
|
34
|
+
start = instance.exports.__heap_base.value.value
|
35
|
+
instance.store.memories[0].data[start...(start+data_url.size)] = data_url
|
36
|
+
|
37
|
+
offset = 0
|
38
|
+
result = nil
|
39
|
+
begin
|
40
|
+
# pub fn grayscale(width: i32, height: i32, memory_offset: i32, length: i32) -> *const u8
|
41
|
+
#profile.start
|
42
|
+
offset = instance.runtime.grayscale_blob($options.width, $options.height, start, data_url.size)
|
43
|
+
#result = profile.stop
|
44
|
+
rescue => e
|
45
|
+
raise "failed to execute grayscale() " + e.message
|
46
|
+
end
|
47
|
+
|
48
|
+
#printer = RubyProf::GraphPrinter.new(result)
|
49
|
+
#printer.print(STDOUT, {})
|
50
|
+
|
51
|
+
len = 0
|
52
|
+
until instance.store.memories[0].data[offset.value+len] == "\0"
|
53
|
+
len += 1
|
54
|
+
end
|
55
|
+
|
56
|
+
result_b64 = instance.store.memories[0].data[offset.value...(offset.value+len)]
|
57
|
+
result = Base64.decode64(result_b64)
|
58
|
+
|
59
|
+
dest = File.open($options.dest, "w")
|
60
|
+
dest.write result
|
61
|
+
dest.close
|
62
|
+
|
63
|
+
puts "created: #{$options.dest}"
|
64
|
+
|
@@ -311,7 +311,7 @@ module Wardite
|
|
311
311
|
digits = target.memsize
|
312
312
|
count = 0
|
313
313
|
digits.times do |i|
|
314
|
-
if (target.value & (1 << i)).
|
314
|
+
if (target.value & (1 << i)).nonzero?
|
315
315
|
count += 1
|
316
316
|
end
|
317
317
|
end
|
@@ -347,7 +347,13 @@ module Wardite
|
|
347
347
|
if !right.is_a?(I32) || !left.is_a?(I32)
|
348
348
|
raise EvalError, "maybe empty or invalid stack"
|
349
349
|
end
|
350
|
-
|
350
|
+
result = left.value_s / right.value_s.to_f
|
351
|
+
iresult = (result >= 0 ? result.floor : result.ceil).to_i
|
352
|
+
if iresult >= (1 << (left.memsize - 1))
|
353
|
+
raise IntegerOverflow, "integer overflow"
|
354
|
+
end
|
355
|
+
|
356
|
+
runtime.stack.push(I32(iresult))
|
351
357
|
|
352
358
|
|
353
359
|
when :i32_div_u
|
@@ -363,7 +369,13 @@ module Wardite
|
|
363
369
|
if !right.is_a?(I32) || !left.is_a?(I32)
|
364
370
|
raise EvalError, "maybe empty or invalid stack"
|
365
371
|
end
|
366
|
-
|
372
|
+
result = left.value_s % right.value_s
|
373
|
+
if result > 0 && left.value_s < 0
|
374
|
+
result = result - right.value_s
|
375
|
+
elsif result < 0 && left.value_s > 0
|
376
|
+
result = result - right.value_s
|
377
|
+
end
|
378
|
+
runtime.stack.push(I32(result))
|
367
379
|
|
368
380
|
|
369
381
|
when :i32_rem_u
|
@@ -403,8 +415,8 @@ module Wardite
|
|
403
415
|
if !right.is_a?(I32) || !left.is_a?(I32)
|
404
416
|
raise EvalError, "maybe empty or invalid stack"
|
405
417
|
end
|
406
|
-
value = left.value << right.value
|
407
|
-
value %=
|
418
|
+
value = left.value << (right.value % right.memsize)
|
419
|
+
value %= 1 << right.memsize
|
408
420
|
|
409
421
|
runtime.stack.push(I32(value))
|
410
422
|
|
@@ -414,7 +426,7 @@ module Wardite
|
|
414
426
|
if !right.is_a?(I32) || !left.is_a?(I32)
|
415
427
|
raise EvalError, "maybe empty or invalid stack"
|
416
428
|
end
|
417
|
-
value = left.value_s >> right.value
|
429
|
+
value = left.value_s >> (right.value % right.memsize)
|
418
430
|
runtime.stack.push(I32(value))
|
419
431
|
|
420
432
|
|
@@ -423,7 +435,7 @@ module Wardite
|
|
423
435
|
if !right.is_a?(I32) || !left.is_a?(I32)
|
424
436
|
raise EvalError, "maybe empty or invalid stack"
|
425
437
|
end
|
426
|
-
value = left.value >> right.value
|
438
|
+
value = left.value >> (right.value % right.memsize)
|
427
439
|
runtime.stack.push(I32(value))
|
428
440
|
|
429
441
|
|
@@ -432,9 +444,10 @@ module Wardite
|
|
432
444
|
if !right.is_a?(I32) || !left.is_a?(I32)
|
433
445
|
raise EvalError, "maybe empty or invalid stack"
|
434
446
|
end
|
435
|
-
|
436
|
-
|
437
|
-
|
447
|
+
k = (right.value % right.memsize)
|
448
|
+
rotated = left.value << k
|
449
|
+
rest = left.value & (I32::I32_MAX << (right.memsize - k))
|
450
|
+
value = rotated | (rest >> (right.memsize - k))
|
438
451
|
runtime.stack.push(I32(value))
|
439
452
|
|
440
453
|
|
@@ -443,9 +456,10 @@ module Wardite
|
|
443
456
|
if !right.is_a?(I32) || !left.is_a?(I32)
|
444
457
|
raise EvalError, "maybe empty or invalid stack"
|
445
458
|
end
|
446
|
-
|
447
|
-
|
448
|
-
|
459
|
+
k = (right.value % right.memsize)
|
460
|
+
rotated = left.value >> k
|
461
|
+
rest = left.value & (I32::I32_MAX >> (right.memsize - k))
|
462
|
+
value = rotated | (rest << (right.memsize - k))
|
449
463
|
runtime.stack.push(I32(value))
|
450
464
|
|
451
465
|
|
@@ -368,7 +368,7 @@ module Wardite
|
|
368
368
|
digits = target.memsize
|
369
369
|
count = 0
|
370
370
|
digits.times do |i|
|
371
|
-
if (target.value & (1 << i)).
|
371
|
+
if (target.value & (1 << i)).nonzero?
|
372
372
|
count += 1
|
373
373
|
end
|
374
374
|
end
|
@@ -404,7 +404,13 @@ module Wardite
|
|
404
404
|
if !right.is_a?(I64) || !left.is_a?(I64)
|
405
405
|
raise EvalError, "maybe empty or invalid stack"
|
406
406
|
end
|
407
|
-
|
407
|
+
result = left.value_s / right.value_s.to_f
|
408
|
+
iresult = (result >= 0 ? result.floor : result.ceil).to_i
|
409
|
+
if iresult >= (1 << (left.memsize - 1))
|
410
|
+
raise IntegerOverflow, "integer overflow"
|
411
|
+
end
|
412
|
+
|
413
|
+
runtime.stack.push(I64(iresult))
|
408
414
|
|
409
415
|
|
410
416
|
when :i64_div_u
|
@@ -420,7 +426,13 @@ module Wardite
|
|
420
426
|
if !right.is_a?(I64) || !left.is_a?(I64)
|
421
427
|
raise EvalError, "maybe empty or invalid stack"
|
422
428
|
end
|
423
|
-
|
429
|
+
result = left.value_s % right.value_s
|
430
|
+
if result > 0 && left.value_s < 0
|
431
|
+
result = result - right.value_s
|
432
|
+
elsif result < 0 && left.value_s > 0
|
433
|
+
result = result - right.value_s
|
434
|
+
end
|
435
|
+
runtime.stack.push(I64(result))
|
424
436
|
|
425
437
|
|
426
438
|
when :i64_rem_u
|
@@ -460,8 +472,8 @@ module Wardite
|
|
460
472
|
if !right.is_a?(I64) || !left.is_a?(I64)
|
461
473
|
raise EvalError, "maybe empty or invalid stack"
|
462
474
|
end
|
463
|
-
value = left.value << right.value
|
464
|
-
value %=
|
475
|
+
value = left.value << (right.value % right.memsize)
|
476
|
+
value %= 1 << right.memsize
|
465
477
|
|
466
478
|
runtime.stack.push(I64(value))
|
467
479
|
|
@@ -471,7 +483,7 @@ module Wardite
|
|
471
483
|
if !right.is_a?(I64) || !left.is_a?(I64)
|
472
484
|
raise EvalError, "maybe empty or invalid stack"
|
473
485
|
end
|
474
|
-
value = left.value_s >> right.value
|
486
|
+
value = left.value_s >> (right.value % right.memsize)
|
475
487
|
runtime.stack.push(I64(value))
|
476
488
|
|
477
489
|
|
@@ -480,7 +492,7 @@ module Wardite
|
|
480
492
|
if !right.is_a?(I64) || !left.is_a?(I64)
|
481
493
|
raise EvalError, "maybe empty or invalid stack"
|
482
494
|
end
|
483
|
-
value = left.value >> right.value
|
495
|
+
value = left.value >> (right.value % right.memsize)
|
484
496
|
runtime.stack.push(I64(value))
|
485
497
|
|
486
498
|
|
@@ -489,9 +501,10 @@ module Wardite
|
|
489
501
|
if !right.is_a?(I64) || !left.is_a?(I64)
|
490
502
|
raise EvalError, "maybe empty or invalid stack"
|
491
503
|
end
|
492
|
-
|
493
|
-
|
494
|
-
|
504
|
+
k = (right.value % right.memsize)
|
505
|
+
rotated = left.value << k
|
506
|
+
rest = left.value & (I64::I64_MAX << (right.memsize - k))
|
507
|
+
value = rotated | (rest >> (right.memsize - k))
|
495
508
|
runtime.stack.push(I64(value))
|
496
509
|
|
497
510
|
|
@@ -500,9 +513,10 @@ module Wardite
|
|
500
513
|
if !right.is_a?(I64) || !left.is_a?(I64)
|
501
514
|
raise EvalError, "maybe empty or invalid stack"
|
502
515
|
end
|
503
|
-
|
504
|
-
|
505
|
-
|
516
|
+
k = (right.value % right.memsize)
|
517
|
+
rotated = left.value >> k
|
518
|
+
rest = left.value & (I64::I64_MAX >> (right.memsize - k))
|
519
|
+
value = rotated | (rest << (right.memsize - k))
|
506
520
|
runtime.stack.push(I64(value))
|
507
521
|
|
508
522
|
|
data/lib/wardite/instruction.rb
CHANGED
@@ -78,6 +78,8 @@ module Wardite
|
|
78
78
|
# TODO: add types of potential operands
|
79
79
|
attr_accessor :operand #: Array[operandItem]
|
80
80
|
|
81
|
+
attr_accessor :meta #: Hash[Symbol, Integer]
|
82
|
+
|
81
83
|
# @rbs namespace: Symbol
|
82
84
|
# @rbs code: Symbol
|
83
85
|
# @rbs operand: Array[operandItem]
|
@@ -85,6 +87,7 @@ module Wardite
|
|
85
87
|
@namespace = namespace
|
86
88
|
@code = code
|
87
89
|
@operand = operand
|
90
|
+
@meta = {}
|
88
91
|
end
|
89
92
|
|
90
93
|
# @rbs chr: String
|
data/lib/wardite/load.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
# rbs_inline: enabled
|
2
|
+
require "wardite/revisitor"
|
3
|
+
|
2
4
|
module Wardite
|
3
5
|
class Section
|
4
6
|
attr_accessor :name #: String
|
@@ -593,10 +595,13 @@ module Wardite
|
|
593
595
|
locals_type << Op.i2type(value_type || -1)
|
594
596
|
end
|
595
597
|
body = code_body(cbuf)
|
598
|
+
revisitor = Revisitor.new(body)
|
599
|
+
revisitor.revisit!
|
600
|
+
|
596
601
|
dest.func_codes << CodeSection::CodeBody.new do |b|
|
597
602
|
b.locals_count = locals_count
|
598
603
|
b.locals_type = locals_type
|
599
|
-
b.body =
|
604
|
+
b.body = revisitor.ops
|
600
605
|
end
|
601
606
|
end
|
602
607
|
dest
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# rbs_inline: enabled
|
2
|
+
module Wardite
|
3
|
+
class Revisitor
|
4
|
+
attr_accessor :ops #: Array[Op]
|
5
|
+
|
6
|
+
# @rbs ops: Array[Op]
|
7
|
+
# @rbs return: void
|
8
|
+
def initialize(ops)
|
9
|
+
@ops = ops
|
10
|
+
end
|
11
|
+
|
12
|
+
# @rbs return: void
|
13
|
+
def revisit!
|
14
|
+
@ops.each_with_index do |op, idx|
|
15
|
+
case op.code
|
16
|
+
when :block
|
17
|
+
next_pc = fetch_ops_while_end(idx)
|
18
|
+
op.meta[:end_pos] = next_pc
|
19
|
+
|
20
|
+
when :loop
|
21
|
+
next_pc = fetch_ops_while_end(idx)
|
22
|
+
op.meta[:end_pos] = next_pc
|
23
|
+
|
24
|
+
when :if
|
25
|
+
next_pc = fetch_ops_while_end(idx)
|
26
|
+
else_pc = fetch_ops_while_else_or_end(idx)
|
27
|
+
op.meta[:end_pos] = next_pc
|
28
|
+
op.meta[:else_pos] = else_pc
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# @rbs pc_start: Integer
|
34
|
+
# @rbs return: Integer
|
35
|
+
# @rbs return: void
|
36
|
+
def fetch_ops_while_else_or_end(pc_start)
|
37
|
+
cursor = pc_start
|
38
|
+
depth = 0
|
39
|
+
loop {
|
40
|
+
cursor += 1
|
41
|
+
inst = @ops[cursor]
|
42
|
+
case inst&.code
|
43
|
+
when nil
|
44
|
+
raise EvalError, "end op not found"
|
45
|
+
when :if
|
46
|
+
depth += 1
|
47
|
+
when :else
|
48
|
+
if depth == 0
|
49
|
+
return cursor
|
50
|
+
end
|
51
|
+
# do not touch depth
|
52
|
+
when :end
|
53
|
+
if depth == 0
|
54
|
+
return cursor
|
55
|
+
else
|
56
|
+
depth -= 1
|
57
|
+
end
|
58
|
+
else
|
59
|
+
# nop
|
60
|
+
end
|
61
|
+
}
|
62
|
+
raise "not found corresponding end"
|
63
|
+
end
|
64
|
+
|
65
|
+
# @rbs pc_start: Integer
|
66
|
+
# @rbs return: Integer
|
67
|
+
# @rbs return: void
|
68
|
+
def fetch_ops_while_end(pc_start)
|
69
|
+
cursor = pc_start
|
70
|
+
depth = 0
|
71
|
+
loop {
|
72
|
+
cursor += 1
|
73
|
+
inst = @ops[cursor]
|
74
|
+
case inst&.code
|
75
|
+
when nil
|
76
|
+
raise EvalError, "end op not found"
|
77
|
+
when :if, :block, :loop
|
78
|
+
depth += 1
|
79
|
+
when :end
|
80
|
+
if depth == 0
|
81
|
+
return cursor
|
82
|
+
else
|
83
|
+
depth -= 1
|
84
|
+
end
|
85
|
+
else
|
86
|
+
# nop
|
87
|
+
end
|
88
|
+
}
|
89
|
+
raise "not found corresponding end"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
data/lib/wardite/version.rb
CHANGED
data/lib/wardite.rb
CHANGED
@@ -7,6 +7,7 @@ require_relative "wardite/const"
|
|
7
7
|
require_relative "wardite/instruction"
|
8
8
|
require_relative "wardite/value"
|
9
9
|
require_relative "wardite/load"
|
10
|
+
require_relative "wardite/errors"
|
10
11
|
|
11
12
|
module Wardite
|
12
13
|
module Evaluator
|
@@ -472,7 +473,7 @@ module Wardite
|
|
472
473
|
when :block
|
473
474
|
block = insn.operand[0]
|
474
475
|
raise EvalError, "block op without block" if !block.is_a?(Block)
|
475
|
-
next_pc =
|
476
|
+
next_pc = insn.meta[:end_pos]
|
476
477
|
label = Label.new(:block, next_pc, stack.size, block.result_size)
|
477
478
|
frame.labels.push(label)
|
478
479
|
|
@@ -480,19 +481,19 @@ module Wardite
|
|
480
481
|
block = insn.operand[0]
|
481
482
|
raise EvalError, "loop op without block" if !block.is_a?(Block)
|
482
483
|
start = frame.pc
|
483
|
-
|
484
|
-
label = Label.new(:loop,
|
484
|
+
next_pc = insn.meta[:end_pos]
|
485
|
+
label = Label.new(:loop, next_pc, stack.size, block.result_size, start)
|
485
486
|
frame.labels.push(label)
|
486
487
|
|
487
488
|
when :if
|
488
489
|
block = insn.operand[0]
|
489
490
|
raise EvalError, "if op without block" if !block.is_a?(Block)
|
490
|
-
cond = stack.pop
|
491
|
+
cond = stack.pop
|
491
492
|
raise EvalError, "cond not found" if !cond.is_a?(I32)
|
492
|
-
next_pc =
|
493
|
+
next_pc = insn.meta[:end_pos]
|
493
494
|
|
494
495
|
if cond.value.zero?
|
495
|
-
frame.pc =
|
496
|
+
frame.pc = insn.meta[:else_pos]
|
496
497
|
end
|
497
498
|
|
498
499
|
if frame.pc == next_pc
|
@@ -739,38 +740,6 @@ module Wardite
|
|
739
740
|
raise e
|
740
741
|
end
|
741
742
|
|
742
|
-
# @rbs ops: Array[Op]
|
743
|
-
# @rbs pc_start: Integer
|
744
|
-
# @rbs return: Integer
|
745
|
-
def fetch_ops_while_else_or_end(ops, pc_start)
|
746
|
-
cursor = pc_start
|
747
|
-
depth = 0
|
748
|
-
loop {
|
749
|
-
cursor += 1
|
750
|
-
inst = ops[cursor]
|
751
|
-
case inst&.code
|
752
|
-
when nil
|
753
|
-
raise EvalError, "end op not found"
|
754
|
-
when :if
|
755
|
-
depth += 1
|
756
|
-
when :else
|
757
|
-
if depth == 0
|
758
|
-
return cursor
|
759
|
-
end
|
760
|
-
# do not touch depth
|
761
|
-
when :end
|
762
|
-
if depth == 0
|
763
|
-
return cursor
|
764
|
-
else
|
765
|
-
depth -= 1
|
766
|
-
end
|
767
|
-
else
|
768
|
-
# nop
|
769
|
-
end
|
770
|
-
}
|
771
|
-
raise "[BUG] unreachable"
|
772
|
-
end
|
773
|
-
|
774
743
|
# @rbs labels: Array[Label]
|
775
744
|
# @rbs stack: Array[wasmValue]
|
776
745
|
# @rbs level: Integer
|
@@ -796,33 +765,6 @@ module Wardite
|
|
796
765
|
pc
|
797
766
|
end
|
798
767
|
|
799
|
-
# @rbs ops: Array[Op]
|
800
|
-
# @rbs pc_start: Integer
|
801
|
-
# @rbs return: Integer
|
802
|
-
def fetch_ops_while_end(ops, pc_start)
|
803
|
-
cursor = pc_start
|
804
|
-
depth = 0
|
805
|
-
loop {
|
806
|
-
cursor += 1
|
807
|
-
inst = ops[cursor]
|
808
|
-
case inst&.code
|
809
|
-
when nil
|
810
|
-
raise EvalError, "end op not found"
|
811
|
-
when :if, :block, :loop
|
812
|
-
depth += 1
|
813
|
-
when :end
|
814
|
-
if depth == 0
|
815
|
-
return cursor
|
816
|
-
else
|
817
|
-
depth -= 1
|
818
|
-
end
|
819
|
-
else
|
820
|
-
# nop
|
821
|
-
end
|
822
|
-
}
|
823
|
-
raise "[BUG] unreachable"
|
824
|
-
end
|
825
|
-
|
826
768
|
# unwind the stack and put return value if exists
|
827
769
|
# @rbs sp: Integer
|
828
770
|
# @rbs arity: Integer
|
@@ -1119,6 +1061,7 @@ module Wardite
|
|
1119
1061
|
end
|
1120
1062
|
|
1121
1063
|
@data += String.new("\0" * (delta * 64 * 1024))
|
1064
|
+
self.current = newsize
|
1122
1065
|
prev
|
1123
1066
|
end
|
1124
1067
|
|
data/scripts/gen_alu.rb
CHANGED
@@ -480,7 +480,7 @@ module GenAlu
|
|
480
480
|
digits = target.memsize
|
481
481
|
count = 0
|
482
482
|
digits.times do |i|
|
483
|
-
if (target.value & (1 << i)).
|
483
|
+
if (target.value & (1 << i)).nonzero?
|
484
484
|
count += 1
|
485
485
|
end
|
486
486
|
end
|
@@ -520,7 +520,13 @@ module GenAlu
|
|
520
520
|
if !right.is_a?(${CLASS}) || !left.is_a?(${CLASS})
|
521
521
|
raise EvalError, "maybe empty or invalid stack"
|
522
522
|
end
|
523
|
-
|
523
|
+
result = left.value_s / right.value_s.to_f
|
524
|
+
iresult = (result >= 0 ? result.floor : result.ceil).to_i
|
525
|
+
if iresult >= (1 << (left.memsize - 1))
|
526
|
+
raise IntegerOverflow, "integer overflow"
|
527
|
+
end
|
528
|
+
|
529
|
+
runtime.stack.push(${CLASS}(iresult))
|
524
530
|
RUBY
|
525
531
|
|
526
532
|
div_u: <<~RUBY,
|
@@ -547,7 +553,13 @@ module GenAlu
|
|
547
553
|
if !right.is_a?(${CLASS}) || !left.is_a?(${CLASS})
|
548
554
|
raise EvalError, "maybe empty or invalid stack"
|
549
555
|
end
|
550
|
-
|
556
|
+
result = left.value_s % right.value_s
|
557
|
+
if result > 0 && left.value_s < 0
|
558
|
+
result = result - right.value_s
|
559
|
+
elsif result < 0 && left.value_s > 0
|
560
|
+
result = result - right.value_s
|
561
|
+
end
|
562
|
+
runtime.stack.push(${CLASS}(result))
|
551
563
|
RUBY
|
552
564
|
|
553
565
|
rem_u: <<~RUBY,
|
@@ -592,8 +604,8 @@ module GenAlu
|
|
592
604
|
if !right.is_a?(${CLASS}) || !left.is_a?(${CLASS})
|
593
605
|
raise EvalError, "maybe empty or invalid stack"
|
594
606
|
end
|
595
|
-
value = left.value << right.value
|
596
|
-
value %=
|
607
|
+
value = left.value << (right.value % right.memsize)
|
608
|
+
value %= 1 << right.memsize
|
597
609
|
|
598
610
|
runtime.stack.push(${CLASS}(value))
|
599
611
|
RUBY
|
@@ -604,7 +616,7 @@ module GenAlu
|
|
604
616
|
if !right.is_a?(${CLASS}) || !left.is_a?(${CLASS})
|
605
617
|
raise EvalError, "maybe empty or invalid stack"
|
606
618
|
end
|
607
|
-
value = left.value_s >> right.value
|
619
|
+
value = left.value_s >> (right.value % right.memsize)
|
608
620
|
runtime.stack.push(${CLASS}(value))
|
609
621
|
RUBY
|
610
622
|
|
@@ -614,7 +626,7 @@ module GenAlu
|
|
614
626
|
if !right.is_a?(${CLASS}) || !left.is_a?(${CLASS})
|
615
627
|
raise EvalError, "maybe empty or invalid stack"
|
616
628
|
end
|
617
|
-
value = left.value >> right.value
|
629
|
+
value = left.value >> (right.value % right.memsize)
|
618
630
|
runtime.stack.push(${CLASS}(value))
|
619
631
|
RUBY
|
620
632
|
|
@@ -624,9 +636,10 @@ module GenAlu
|
|
624
636
|
if !right.is_a?(${CLASS}) || !left.is_a?(${CLASS})
|
625
637
|
raise EvalError, "maybe empty or invalid stack"
|
626
638
|
end
|
627
|
-
|
628
|
-
|
629
|
-
|
639
|
+
k = (right.value % right.memsize)
|
640
|
+
rotated = left.value << k
|
641
|
+
rest = left.value & (${CLASS}::${CLASS}_MAX << (right.memsize - k))
|
642
|
+
value = rotated | (rest >> (right.memsize - k))
|
630
643
|
runtime.stack.push(${CLASS}(value))
|
631
644
|
RUBY
|
632
645
|
|
@@ -636,9 +649,10 @@ module GenAlu
|
|
636
649
|
if !right.is_a?(${CLASS}) || !left.is_a?(${CLASS})
|
637
650
|
raise EvalError, "maybe empty or invalid stack"
|
638
651
|
end
|
639
|
-
|
640
|
-
|
641
|
-
|
652
|
+
k = (right.value % right.memsize)
|
653
|
+
rotated = left.value >> k
|
654
|
+
rest = left.value & (${CLASS}::${CLASS}_MAX >> (right.memsize - k))
|
655
|
+
value = rotated | (rest << (right.memsize - k))
|
642
656
|
runtime.stack.push(${CLASS}(value))
|
643
657
|
RUBY
|
644
658
|
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# Generated from lib/wardite/errors.rb with RBS::Inline
|
2
|
+
|
3
|
+
# frozen_string_literal: true
|
4
|
+
# rbs_inline: enabled
|
5
|
+
module Wardite
|
6
|
+
# basic error class.
|
7
|
+
class WebAssemblyError < StandardError
|
8
|
+
end
|
9
|
+
|
10
|
+
class IntegerOverflow < WebAssemblyError
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# Generated from lib/wardite/revisitor.rb with RBS::Inline
|
2
|
+
|
3
|
+
# rbs_inline: enabled
|
4
|
+
module Wardite
|
5
|
+
class Revisitor
|
6
|
+
attr_accessor ops: Array[Op]
|
7
|
+
|
8
|
+
# @rbs ops: Array[Op]
|
9
|
+
# @rbs return: void
|
10
|
+
def initialize: (Array[Op] ops) -> void
|
11
|
+
|
12
|
+
# @rbs return: void
|
13
|
+
def revisit!: () -> void
|
14
|
+
|
15
|
+
# @rbs pc_start: Integer
|
16
|
+
# @rbs return: Integer
|
17
|
+
# @rbs return: void
|
18
|
+
def fetch_ops_while_else_or_end: (Integer pc_start) -> Integer
|
19
|
+
|
20
|
+
# @rbs pc_start: Integer
|
21
|
+
# @rbs return: Integer
|
22
|
+
# @rbs return: void
|
23
|
+
def fetch_ops_while_end: (Integer pc_start) -> Integer
|
24
|
+
end
|
25
|
+
end
|
data/sig/generated/wardite.rbs
CHANGED
@@ -115,22 +115,12 @@ module Wardite
|
|
115
115
|
# @rbs return: void
|
116
116
|
def eval_insn: (Frame frame, Op insn) -> void
|
117
117
|
|
118
|
-
# @rbs ops: Array[Op]
|
119
|
-
# @rbs pc_start: Integer
|
120
|
-
# @rbs return: Integer
|
121
|
-
def fetch_ops_while_else_or_end: (Array[Op] ops, Integer pc_start) -> Integer
|
122
|
-
|
123
118
|
# @rbs labels: Array[Label]
|
124
119
|
# @rbs stack: Array[wasmValue]
|
125
120
|
# @rbs level: Integer
|
126
121
|
# @rbs return: Integer
|
127
122
|
def do_branch: (Array[Label] labels, Array[wasmValue] stack, Integer level) -> Integer
|
128
123
|
|
129
|
-
# @rbs ops: Array[Op]
|
130
|
-
# @rbs pc_start: Integer
|
131
|
-
# @rbs return: Integer
|
132
|
-
def fetch_ops_while_end: (Array[Op] ops, Integer pc_start) -> Integer
|
133
|
-
|
134
124
|
# unwind the stack and put return value if exists
|
135
125
|
# @rbs sp: Integer
|
136
126
|
# @rbs arity: 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.5.1
|
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-
|
11
|
+
date: 2024-11-24 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: A pure-ruby webassembly runtime
|
14
14
|
email:
|
@@ -31,6 +31,7 @@ files:
|
|
31
31
|
- examples/fib.wat
|
32
32
|
- examples/fib2.wat
|
33
33
|
- examples/global.wat
|
34
|
+
- examples/grayscale.rb
|
34
35
|
- examples/helloworld.wat
|
35
36
|
- examples/i32_const.wat
|
36
37
|
- examples/i32_store.wat
|
@@ -49,9 +50,11 @@ files:
|
|
49
50
|
- lib/wardite/alu_i64.generated.rb
|
50
51
|
- lib/wardite/const.rb
|
51
52
|
- lib/wardite/convert.generated.rb
|
53
|
+
- lib/wardite/errors.rb
|
52
54
|
- lib/wardite/instruction.rb
|
53
55
|
- lib/wardite/leb128.rb
|
54
56
|
- lib/wardite/load.rb
|
57
|
+
- lib/wardite/revisitor.rb
|
55
58
|
- lib/wardite/value.rb
|
56
59
|
- lib/wardite/version.rb
|
57
60
|
- lib/wardite/wasi.rb
|
@@ -66,9 +69,11 @@ files:
|
|
66
69
|
- sig/generated/wardite/alu_i64.generated.rbs
|
67
70
|
- sig/generated/wardite/const.rbs
|
68
71
|
- sig/generated/wardite/convert.generated.rbs
|
72
|
+
- sig/generated/wardite/errors.rbs
|
69
73
|
- sig/generated/wardite/instruction.rbs
|
70
74
|
- sig/generated/wardite/leb128.rbs
|
71
75
|
- sig/generated/wardite/load.rbs
|
76
|
+
- sig/generated/wardite/revisitor.rbs
|
72
77
|
- sig/generated/wardite/value.rbs
|
73
78
|
- sig/generated/wardite/version.rbs
|
74
79
|
- sig/generated/wardite/wasi.rbs
|