wardite 0.2.2 → 0.4.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.
data/lib/wardite/value.rb CHANGED
@@ -1,12 +1,15 @@
1
1
  # rbs_inline: enabled
2
2
 
3
3
  module Wardite
4
+ # @rbs!
5
+ # type wasmValue = I32 | I64 | F32 | F64
6
+
4
7
  module ValueHelper
5
8
  # @rbs value: Integer
6
9
  # @rbs return: I32
7
10
  def I32(value)
8
11
  if value < 0
9
- $stderr.puts "debug: negative i32 value #{value} is passed, convert to unsigned"
12
+ # $stderr.puts "trace: negative i32 value #{value} is passed, convert to unsigned"
10
13
  value = as_u32(value)
11
14
  end
12
15
  I32.new.tap{|i| i.value = value & I32::I32_MAX }
@@ -16,7 +19,7 @@ module Wardite
16
19
  # @rbs return: I64
17
20
  def I64(value)
18
21
  if value < 0
19
- $stderr.puts "debug: negative i64 value #{value} is passed, convert to unsigned"
22
+ # $stderr.puts "trace: negative i64 value #{value} is passed, convert to unsigned"
20
23
  value = as_u64(value)
21
24
  end
22
25
  I64.new.tap{|i| i.value = value & I64::I64_MAX }
@@ -53,7 +56,7 @@ module Wardite
53
56
  class I32
54
57
  include ValueHelper
55
58
 
56
- I32_MAX = (1<<32) - 1
59
+ I32_MAX = (1<<32) - 1 #: Integer
57
60
  # value should be stored as unsigned Integer, even in I32/I64
58
61
  # when we want to access signed value, it'd be done via #value_s
59
62
  attr_accessor :value #: Integer
@@ -107,39 +110,39 @@ module Wardite
107
110
  end
108
111
 
109
112
  # @rbs to: Symbol
110
- # @rbs return: I32|I64|F32|F64
113
+ # @rbs return: wasmValue
111
114
  def wrap(to:)
112
115
  raise EvalError, "unsupported operation"
113
116
  end
114
117
 
115
118
  # @rbs to: Symbol
116
- # @rbs return: I32|I64|F32|F64
119
+ # @rbs return: wasmValue
117
120
  def extend_s(to:)
118
121
  raise EvalError, "unsupported operation" if to != :i64
119
122
  I64(value_s)
120
123
  end
121
124
 
122
125
  # @rbs to: Symbol
123
- # @rbs return: I32|I64|F32|F64
126
+ # @rbs return: wasmValue
124
127
  def extend_u(to:)
125
128
  raise EvalError, "unsupported operation" if to != :i64
126
129
  I64(value)
127
130
  end
128
131
 
129
132
  # @rbs to: Symbol
130
- # @rbs return: I32|I64|F32|F64
133
+ # @rbs return: wasmValue
131
134
  def trunc_s(to:)
132
135
  raise EvalError, "unsupported operation"
133
136
  end
134
137
 
135
138
  # @rbs to: Symbol
136
- # @rbs return: I32|I64|F32|F64
139
+ # @rbs return: wasmValue
137
140
  def trunc_u(to:)
138
141
  raise EvalError, "unsupported operation"
139
142
  end
140
143
 
141
144
  # @rbs to: Symbol
142
- # @rbs return: I32|I64|F32|F64
145
+ # @rbs return: wasmValue
143
146
  def convert_s(to:)
144
147
  case to
145
148
  when :f32
@@ -152,7 +155,7 @@ module Wardite
152
155
  end
153
156
 
154
157
  # @rbs to: Symbol
155
- # @rbs return: I32|I64|F32|F64
158
+ # @rbs return: wasmValue
156
159
  def convert_u(to:)
157
160
  case to
158
161
  when :f32
@@ -165,21 +168,21 @@ module Wardite
165
168
  end
166
169
 
167
170
  # @rbs to: Symbol
168
- # @rbs return: I32|I64|F32|F64
171
+ # @rbs return: wasmValue
169
172
  def demote(to:)
170
173
  raise EvalError, "unsupported operation"
171
174
 
172
175
  end
173
176
 
174
177
  # @rbs to: Symbol
175
- # @rbs return: I32|I64|F32|F64
178
+ # @rbs return: wasmValue
176
179
  def promote(to:)
177
180
  raise EvalError, "unsupported operation"
178
181
 
179
182
  end
180
183
 
181
184
  # @rbs to: Symbol
182
- # @rbs return: I32|I64|F32|F64
185
+ # @rbs return: wasmValue
183
186
  def reinterpret(to:)
184
187
  raise EvalError, "unsupported operation" if to != :f32
185
188
  v = [value].pack("I!").unpack("f")[0]
@@ -187,6 +190,49 @@ module Wardite
187
190
  F32(v)
188
191
  end
189
192
 
193
+ # @rbs from: Symbol
194
+ # @rbs to: Symbol
195
+ # @rbs return: wasmValue
196
+ def extendN_s(from:, to:)
197
+ src_value = case from
198
+ when :i8
199
+ base = value & 0xff
200
+ (base >> 8).zero? ?
201
+ base :
202
+ ((-base) ^ 0xff) + 1
203
+ when :i16
204
+ base = value & 0xffff
205
+ (base >> 15).zero? ?
206
+ base :
207
+ ((-base) ^ 0xffff) + 1
208
+ when :i32
209
+ value_s
210
+ else
211
+ raise EvalError, "unsupported value size"
212
+ end
213
+
214
+ case to
215
+ when :i32
216
+ I32(src_value)
217
+ when :i64
218
+ I64(src_value)
219
+ else
220
+ raise EvalError, "unsupported value size"
221
+ end
222
+ end
223
+
224
+ # @rbs to: Symbol
225
+ # @rbs return: wasmValue
226
+ def trunc_sat_u(to:)
227
+ raise EvalError, "unsupported operation"
228
+ end
229
+
230
+ # @rbs to: Symbol
231
+ # @rbs return: wasmValue
232
+ def trunc_sat_s(to:)
233
+ raise EvalError, "unsupported operation"
234
+ end
235
+
190
236
  # I32#inspect shows signed value for convinience
191
237
  def inspect
192
238
  "I32(#{value_s})"
@@ -196,7 +242,7 @@ module Wardite
196
242
  class I64
197
243
  include ValueHelper
198
244
 
199
- I64_MAX = (1<<64) - 1
245
+ I64_MAX = (1<<64) - 1 #: Integer
200
246
 
201
247
  attr_accessor :value #: Integer
202
248
 
@@ -252,7 +298,7 @@ module Wardite
252
298
  end
253
299
 
254
300
  # @rbs to: Symbol
255
- # @rbs return: I32|I64|F32|F64
301
+ # @rbs return: wasmValue
256
302
  def wrap(to:)
257
303
  if to != :i32
258
304
  raise EvalError, "unsupported operation #{to}"
@@ -261,31 +307,31 @@ module Wardite
261
307
  end
262
308
 
263
309
  # @rbs to: Symbol
264
- # @rbs return: I32|I64|F32|F64
310
+ # @rbs return: wasmValue
265
311
  def extend_s(to:)
266
312
  raise EvalError, "unsupported operation"
267
313
  end
268
314
 
269
315
  # @rbs to: Symbol
270
- # @rbs return: I32|I64|F32|F64
316
+ # @rbs return: wasmValue
271
317
  def extend_u(to:)
272
318
  raise EvalError, "unsupported operation"
273
319
  end
274
320
 
275
321
  # @rbs to: Symbol
276
- # @rbs return: I32|I64|F32|F64
322
+ # @rbs return: wasmValue
277
323
  def trunc_s(to:)
278
324
  raise EvalError, "unsupported operation"
279
325
  end
280
326
 
281
327
  # @rbs to: Symbol
282
- # @rbs return: I32|I64|F32|F64
328
+ # @rbs return: wasmValue
283
329
  def trunc_u(to:)
284
330
  raise EvalError, "unsupported operation"
285
331
  end
286
332
 
287
333
  # @rbs to: Symbol
288
- # @rbs return: I32|I64|F32|F64
334
+ # @rbs return: wasmValue
289
335
  def convert_s(to:)
290
336
  case to
291
337
  when :f32
@@ -298,7 +344,7 @@ module Wardite
298
344
  end
299
345
 
300
346
  # @rbs to: Symbol
301
- # @rbs return: I32|I64|F32|F64
347
+ # @rbs return: wasmValue
302
348
  def convert_u(to:)
303
349
  case to
304
350
  when :f32
@@ -311,19 +357,19 @@ module Wardite
311
357
  end
312
358
 
313
359
  # @rbs to: Symbol
314
- # @rbs return: I32|I64|F32|F64
360
+ # @rbs return: wasmValue
315
361
  def demote(to:)
316
362
  raise EvalError, "unsupported operation"
317
363
  end
318
364
 
319
365
  # @rbs to: Symbol
320
- # @rbs return: I32|I64|F32|F64
366
+ # @rbs return: wasmValue
321
367
  def promote(to:)
322
368
  raise EvalError, "unsupported operation"
323
369
  end
324
370
 
325
371
  # @rbs to: Symbol
326
- # @rbs return: I32|I64|F32|F64
372
+ # @rbs return: wasmValue
327
373
  def reinterpret(to:)
328
374
  raise EvalError, "unsupported operation" if to != :f64
329
375
  v = [value].pack("L!").unpack("d")[0]
@@ -331,6 +377,25 @@ module Wardite
331
377
  F32(v)
332
378
  end
333
379
 
380
+ # @rbs from: Symbol
381
+ # @rbs to: Symbol
382
+ # @rbs return: wasmValue
383
+ def extendN_s(from:, to:)
384
+ raise EvalError, "unsupported operation"
385
+ end
386
+
387
+ # @rbs to: Symbol
388
+ # @rbs return: wasmValue
389
+ def trunc_sat_u(to:)
390
+ raise EvalError, "unsupported operation"
391
+ end
392
+
393
+ # @rbs to: Symbol
394
+ # @rbs return: wasmValue
395
+ def trunc_sat_s(to:)
396
+ raise EvalError, "unsupported operation"
397
+ end
398
+
334
399
  # I64#inspect shows signed value
335
400
  def inspect
336
401
  "I64(#{@value})"
@@ -373,47 +438,71 @@ module Wardite
373
438
  end
374
439
 
375
440
  # @rbs to: Symbol
376
- # @rbs return: I32|I64|F32|F64
441
+ # @rbs return: wasmValue
377
442
  def wrap(to:)
378
443
  raise EvalError, "unsupported operation"
379
444
  end
380
445
 
381
446
  # @rbs to: Symbol
382
- # @rbs return: I32|I64|F32|F64
447
+ # @rbs return: wasmValue
383
448
  def extend_s(to:)
384
449
  raise EvalError, "unsupported operation"
385
450
  end
386
451
 
387
452
  # @rbs to: Symbol
388
- # @rbs return: I32|I64|F32|F64
453
+ # @rbs return: wasmValue
389
454
  def extend_u(to:)
390
455
  raise EvalError, "unsupported operation"
391
456
  end
392
457
 
393
458
  # @todo need more testcase...
394
459
  # @see https://webassembly.github.io/spec/core/exec/numerics.html#xref-exec-numerics-op-trunc-s-mathrm-trunc-mathsf-s-m-n-z
460
+ # @see copy this impl to F64 when changed
395
461
  # @rbs to: Symbol
396
- # @rbs return: I32|I64|F32|F64
397
- def trunc_s(to:)
462
+ # @rbs saturating: bool
463
+ # @rbs return: wasmValue
464
+ def trunc_s(to:, saturating: false)
398
465
  v = value.to_i
399
466
  case to
400
467
  when :i32
401
468
  if v >= 0
402
- I32(v & (I32::I32_MAX >> 1))
469
+ i32_signed_max = I32::I32_MAX >> 1
470
+ if saturating
471
+ v = i32_signed_max if v > i32_signed_max
472
+ else
473
+ v = v & i32_signed_max
474
+ end
475
+ I32(v & i32_signed_max)
403
476
  else
404
- v = v & I32::I32_MAX
405
- if (v >> 31).zero?
406
- raise EvalError, "[undefined behavior] detected overflow: #{value}"
477
+ i32_signed_min = -(I32::I32_MAX >> 1) - 1
478
+ if saturating
479
+ v = i32_signed_min if v < i32_signed_min
480
+ else
481
+ v = v & I32::I32_MAX
482
+ if (v >> 31).zero?
483
+ raise EvalError, "[undefined behavior] detected overflow: #{value}"
484
+ end
407
485
  end
408
486
  I32(v)
409
487
  end
410
488
  when :i64
411
489
  if v >= 0
412
- I64(v & (I64::I64_MAX >> 1))
490
+ i64_signed_max = I64::I64_MAX >> 1
491
+ if saturating
492
+ v = i64_signed_max if v > i64_signed_max
493
+ else
494
+ v = v & i64_signed_max
495
+ end
496
+ I64(v & i64_signed_max)
413
497
  else
414
- v = v & I64::I64_MAX
415
- if (v >> 31).zero?
416
- raise EvalError, "[undefined behavior] detected overflow: #{value}"
498
+ i64_signed_min = -(I64::I64_MAX >> 1) - 1
499
+ if saturating
500
+ v = i64_signed_min if v < i64_signed_min
501
+ else
502
+ v = v & I64::I64_MAX
503
+ if (v >> 63).zero?
504
+ raise EvalError, "[undefined behavior] detected overflow: #{value}"
505
+ end
417
506
  end
418
507
  I64(v)
419
508
  end
@@ -423,19 +512,33 @@ module Wardite
423
512
  end
424
513
 
425
514
  # @see https://webassembly.github.io/spec/core/exec/numerics.html#xref-exec-numerics-op-trunc-u-mathrm-trunc-mathsf-u-m-n-z
515
+ # @see copy this impl to F64 when changed
426
516
  # @rbs to: Symbol
427
- # @rbs return: I32|I64|F32|F64
428
- def trunc_u(to:)
517
+ # @rbs sturating: bool
518
+ # @rbs return: wasmValue
519
+ def trunc_u(to:, saturating: false)
429
520
  v = value.to_i
430
521
  if v < 0
431
- raise EvalError, "[undefined behavior] unexpected negative value"
522
+ if saturating
523
+ v = 0
524
+ else
525
+ raise EvalError, "[undefined behavior] unexpected negative value"
526
+ end
432
527
  end
433
528
  case to
434
529
  when :i32
435
- v = v & I32::I32_MAX
530
+ if saturating
531
+ v = I32::I32_MAX if v > I32::I32_MAX
532
+ else
533
+ v = v & I32::I32_MAX
534
+ end
436
535
  I32(v)
437
536
  when :i64
438
- v = v & I64::I64_MAX
537
+ if saturating
538
+ v = I64::I64_MAX if v > I64::I64_MAX
539
+ else
540
+ v = v & I64::I64_MAX
541
+ end
439
542
  I64(v)
440
543
  else
441
544
  raise EvalError, "unsupported operation to: #{to}"
@@ -443,32 +546,32 @@ module Wardite
443
546
  end
444
547
 
445
548
  # @rbs to: Symbol
446
- # @rbs return: I32|I64|F32|F64
549
+ # @rbs return: wasmValue
447
550
  def convert_s(to:)
448
551
  raise EvalError, "unsupported operation"
449
552
  end
450
553
 
451
554
  # @rbs to: Symbol
452
- # @rbs return: I32|I64|F32|F64
555
+ # @rbs return: wasmValue
453
556
  def convert_u(to:)
454
557
  raise EvalError, "unsupported operation"
455
558
  end
456
559
 
457
560
  # @rbs to: Symbol
458
- # @rbs return: I32|I64|F32|F64
561
+ # @rbs return: wasmValue
459
562
  def demote(to:)
460
563
  raise EvalError, "unsupported operation"
461
564
  end
462
565
 
463
566
  # @rbs to: Symbol
464
- # @rbs return: I32|I64|F32|F64
567
+ # @rbs return: wasmValue
465
568
  def promote(to:)
466
569
  raise EvalError, "unsupported operation" if to != :f64
467
570
  F64(value)
468
571
  end
469
572
 
470
573
  # @rbs to: Symbol
471
- # @rbs return: I32|I64|F32|F64
574
+ # @rbs return: wasmValue
472
575
  def reinterpret(to:)
473
576
  raise EvalError, "unsupported operation" if to != :i32
474
577
  v = [value].pack("f").unpack("I!")[0]
@@ -476,6 +579,25 @@ module Wardite
476
579
  I32(v)
477
580
  end
478
581
 
582
+ # @rbs from: Symbol
583
+ # @rbs to: Symbol
584
+ # @rbs return: wasmValue
585
+ def extendN_s(from:, to:)
586
+ raise EvalError, "unsupported operation"
587
+ end
588
+
589
+ # @rbs to: Symbol
590
+ # @rbs return: wasmValue
591
+ def trunc_sat_u(to:)
592
+ trunc_u(to: to, saturating: true)
593
+ end
594
+
595
+ # @rbs to: Symbol
596
+ # @rbs return: wasmValue
597
+ def trunc_sat_s(to:)
598
+ trunc_s(to: to, saturating: true)
599
+ end
600
+
479
601
  def inspect
480
602
  "F32(#{@value})"
481
603
  end
@@ -517,46 +639,69 @@ module Wardite
517
639
  end
518
640
 
519
641
  # @rbs to: Symbol
520
- # @rbs return: I32|I64|F32|F64
642
+ # @rbs return: wasmValue
521
643
  def wrap(to:)
522
644
  raise EvalError, "unsupported operation"
523
645
  end
524
646
 
525
647
  # @rbs to: Symbol
526
- # @rbs return: I32|I64|F32|F64
648
+ # @rbs return: wasmValue
527
649
  def extend_s(to:)
528
650
  raise EvalError, "unsupported operation"
529
651
  end
530
652
 
531
653
  # @rbs to: Symbol
532
- # @rbs return: I32|I64|F32|F64
654
+ # @rbs return: wasmValue
533
655
  def extend_u(to:)
534
656
  raise EvalError, "unsupported operation"
535
657
  end
536
658
 
537
659
  # @see the same as F32
538
660
  # @rbs to: Symbol
539
- # @rbs return: I32|I64|F32|F64
540
- def trunc_s(to:)
661
+ # @rbs saturating: bool
662
+ # @rbs return: wasmValue
663
+ def trunc_s(to:, saturating: false)
541
664
  v = value.to_i
542
665
  case to
543
666
  when :i32
544
667
  if v >= 0
545
- I32(v & (I32::I32_MAX >> 1))
668
+ i32_signed_max = I32::I32_MAX >> 1
669
+ if saturating
670
+ v = i32_signed_max if v > i32_signed_max
671
+ else
672
+ v = v & i32_signed_max
673
+ end
674
+ I32(v & i32_signed_max)
546
675
  else
547
- v = v & I32::I32_MAX
548
- if (v >> 31).zero?
549
- raise EvalError, "[undefined behavior] detected overflow: #{value}"
676
+ i32_signed_min = -(I32::I32_MAX >> 1) - 1
677
+ if saturating
678
+ v = i32_signed_min if v < i32_signed_min
679
+ else
680
+ v = v & I32::I32_MAX
681
+ if (v >> 31).zero?
682
+ raise EvalError, "[undefined behavior] detected overflow: #{value}"
683
+ end
550
684
  end
551
685
  I32(v)
552
686
  end
553
687
  when :i64
554
688
  if v >= 0
555
- I64(v & (I64::I64_MAX >> 1))
689
+ i64_signed_max = I64::I64_MAX >> 1
690
+ if saturating
691
+ v = i64_signed_max if v > i64_signed_max
692
+ else
693
+ v = v & i64_signed_max
694
+ end
695
+ I64(v & i64_signed_max)
556
696
  else
557
- v = v & I64::I64_MAX
558
- if (v >> 31).zero?
559
- raise EvalError, "[undefined behavior] detected overflow: #{value}"
697
+ i64_signed_min = -(I64::I64_MAX >> 1) - 1
698
+ if saturating
699
+ v = i64_signed_min if v < i64_signed_min
700
+ else
701
+ v = v & I64::I64_MAX
702
+ if (v >> 63).zero?
703
+ raise EvalError, "[undefined behavior] detected overflow: #{value}"
704
+ end
560
705
  end
561
706
  I64(v)
562
707
  end
@@ -567,18 +712,31 @@ module Wardite
567
712
 
568
713
  # @see the same as F32
569
714
  # @rbs to: Symbol
570
- # @rbs return: I32|I64|F32|F64
571
- def trunc_u(to:)
715
+ # @rbs saturating: bool
716
+ # @rbs return: wasmValue
717
+ def trunc_u(to:, saturating: false)
572
718
  v = value.to_i
573
719
  if v < 0
574
- raise EvalError, "[undefined behavior] unexpected negative value"
720
+ if saturating
721
+ v = 0
722
+ else
723
+ raise EvalError, "[undefined behavior] unexpected negative value"
724
+ end
575
725
  end
576
726
  case to
577
727
  when :i32
578
- v = v & I32::I32_MAX
728
+ if saturating
729
+ v = I32::I32_MAX if v > I32::I32_MAX
730
+ else
731
+ v = v & I32::I32_MAX
732
+ end
579
733
  I32(v)
580
734
  when :i64
581
- v = v & I64::I64_MAX
735
+ if saturating
736
+ v = I64::I64_MAX if v > I64::I64_MAX
737
+ else
738
+ v = v & I64::I64_MAX
739
+ end
582
740
  I64(v)
583
741
  else
584
742
  raise EvalError, "unsupported operation to: #{to}"
@@ -586,33 +744,33 @@ module Wardite
586
744
  end
587
745
 
588
746
  # @rbs to: Symbol
589
- # @rbs return: I32|I64|F32|F64
747
+ # @rbs return: wasmValue
590
748
  def convert_s(to:)
591
749
  raise EvalError, "unsupported operation"
592
750
  end
593
751
 
594
752
  # @rbs to: Symbol
595
- # @rbs return: I32|I64|F32|F64
753
+ # @rbs return: wasmValue
596
754
  def convert_u(to:)
597
755
  raise EvalError, "unsupported operation"
598
756
  end
599
757
 
600
758
  # @todo no loss of digits...
601
759
  # @rbs to: Symbol
602
- # @rbs return: I32|I64|F32|F64
760
+ # @rbs return: wasmValue
603
761
  def demote(to:)
604
762
  raise EvalError, "unsupported operation" if to != :f32
605
763
  F32(value)
606
764
  end
607
765
 
608
766
  # @rbs to: Symbol
609
- # @rbs return: I32|I64|F32|F64
767
+ # @rbs return: wasmValue
610
768
  def promote(to:)
611
769
  raise EvalError, "unsupported operation"
612
770
  end
613
771
 
614
772
  # @rbs to: Symbol
615
- # @rbs return: I32|I64|F32|F64
773
+ # @rbs return: wasmValue
616
774
  def reinterpret(to:)
617
775
  raise EvalError, "unsupported operation" if to != :i64
618
776
  v = [value].pack("d").unpack("L!")[0]
@@ -620,6 +778,25 @@ module Wardite
620
778
  I64(v)
621
779
  end
622
780
 
781
+ # @rbs from: Symbol
782
+ # @rbs to: Symbol
783
+ # @rbs return: wasmValue
784
+ def extendN_s(from:, to:)
785
+ raise EvalError, "unsupported operation"
786
+ end
787
+
788
+ # @rbs to: Symbol
789
+ # @rbs return: wasmValue
790
+ def trunc_sat_u(to:)
791
+ trunc_u(to: to, saturating: true)
792
+ end
793
+
794
+ # @rbs to: Symbol
795
+ # @rbs return: wasmValue
796
+ def trunc_sat_s(to:)
797
+ trunc_s(to: to, saturating: true)
798
+ end
799
+
623
800
  def inspect
624
801
  "F64(#{@value})"
625
802
  end
@@ -2,5 +2,5 @@
2
2
  # rbs_inline: enabled
3
3
 
4
4
  module Wardite
5
- VERSION = "0.2.2" #: String
5
+ VERSION = "0.4.0" #: String
6
6
  end
data/lib/wardite/wasi.rb CHANGED
@@ -14,7 +14,7 @@ module Wardite
14
14
  end
15
15
 
16
16
  # @rbs store: Store
17
- # @rbs args: Array[I32|I64|F32|F64]
17
+ # @rbs args: Array[wasmValue]
18
18
  # @rbs return: Object
19
19
  def fd_write(store, args)
20
20
  iargs = args.map do |elm|
@@ -45,7 +45,7 @@ module Wardite
45
45
  0
46
46
  end
47
47
 
48
- # @rbs return: Hash[Symbol, Proc]
48
+ # @rbs return: Hash[Symbol, wasmCallable]
49
49
  def to_module
50
50
  {
51
51
  fd_write: lambda{|store, args| self.fd_write(store, args) },