Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

using two callbacks gives type mismatch #82

Closed
carllocos opened this issue Sep 5, 2022 · 1 comment
Closed

using two callbacks gives type mismatch #82

carllocos opened this issue Sep 5, 2022 · 1 comment
Labels
bug Something isn't working invalid This doesn't seem right

Comments

@carllocos
Copy link
Contributor

carllocos commented Sep 5, 2022

I wrote an example that increases or decreases the brightness of an LED when pressing two different buttons. Pressing any button for a random amount of times raises an exception call type mismatch.

The issue may come from the Wast but I could not test whether the code is correct because the raised exception prevents me to test in depth. Nevertheless, faulty source code that compiles to wasm should not break the VM.

When I register the same callback (e.g. $decrDelta) on the two different buttons then the call type mismatch does not manifest but instead I get a guru mediation error probably because the VM accesses a null pointer somewhere.

(module
  (type $i32->i32->void (func (param i32 i32)))
  (type $i32->i32->i32->void (func (param i32 i32 i32)))
  (type $void->i32 (func (result i32)))
  (type $void->void (func))

  (import "env" "chip_ledc_analog_write" (func $env.analogWrite (type $i32->i32->i32->void)))
  (import "env" "chip_ledc_setup" (func $env.ledcSetup (type $i32->i32->i32->void)))
  (import "env" "chip_ledc_attach_pin" (func $env.ledcAttachPin (type $i32->i32->void)))
  (import "env" "subscribe_interrupt" (func $env.subscribeInterrupt (type $i32->i32->i32->void)))

  (global $led i32 (i32.const 10)) ;; analog led pin
  (global $brigthness (mut i32) (i32.const 0))
  (global $maxBrigthness i32 (i32.const 255))
  (global $delta (mut i32) (i32.const 0))
  (global $upButton i32 (i32.const 37)) ;; button to increase brigthness
  (global $downButton i32 (i32.const 39)) ;; button to decrease brigthness
  (global $channel i32 (i32.const 0)) ;; channel for analog write
  
  ;; needed for subscribe_interrupt
  (memory $memory 1)
  (table 2 funcref)
  (elem (i32.const 0) func $incrDelta $decrDelta)

  (func $setupButtons (type $void->void)
    ;; register up Button
    global.get $upButton
    i32.const 0 ;; Table idx of $incrDelta
    i32.const 2 ;; trigger callback on CHANGE
    (call $env.subscribeInterrupt)

    ;; register down Button
    global.get $downButton
    i32.const 1 ;; Table idx of $decrDelta
    i32.const 2 ;; trigger callback on CHANGE
    (call $env.subscribeInterrupt))
      
  (func $initLed (type $void->void)
    (local $freq i32)
    (local $ledcTimer i32)
    (local.set $freq (i32.const 5000))
    (local.set $ledcTimer (i32.const 12))

    global.get $channel
    local.get $freq
    local.get $ledcTimer
    (call $env.ledcSetup)

    global.get $led
    global.get $channel
    (call $env.ledcAttachPin))

  (func $decrDelta  (type $void->void)
    (global.set $delta (i32.const 10)))

  (func $incrDelta  (type $void->void)
    (global.set $delta (i32.const -20)))

  (func $isDeltaNotZero (type $void->i32)
    (i32.ne
      (i32.const 0)
      (global.get $delta)))

  (func $updateBrigthness (type $void->void)

    ;; change global $brigthness
    (i32.add (global.get $brigthness)
             (global.get $delta))
    global.set $brigthness
     
    ;; if newbrightness greater than max rebase brightness
    (if (i32.gt_s
          (global.get $brigthness)
          (global.get $maxBrigthness))
        (then
          (i32.sub
            (global.get $brigthness)
            (global.get $maxBrigthness))
           global.set $brigthness)
        (else nop))

    ;; if newbrightness is less than zero rebase brightness
    (if (i32.lt_s
          (global.get $brigthness)
          (i32.const 0))
        (then
          (i32.add
            (global.get $maxBrigthness)
            (global.get $brigthness))
          global.set $brigthness)
        (else nop))

    ;; write to pin
    global.get $channel
    global.get $brigthness
    global.get $maxBrigthness
    (call $env.analogWrite)

    ;; reset delta
    i32.const 0
    global.set $delta)
  
  (func $main  (type $void->void)
    (call $initLed)
    (call $setupButtons)

    (loop $infinite
      (if (call $isDeltaNotZero)
          (then
            (call $updateBrigthness))
          (else nop))
      (br $infinite)))
  (export "main" (func $main)))


@carllocos carllocos added the bug Something isn't working label Sep 5, 2022
@tolauwae
Copy link
Member

I believe there is another cause for this bug. I cannot reproduce this with another program by just "using two callbacks". I even rewrote the above program by hand in .wat from scratch. This also didn't produce the error.

I think the real cause is that we do not typecheck callbacks (#86). This is a known issue.

Since I cannot reproduce this bug and the issue assigns an implausible cause to the bug, I'm marking this as invalid.
I think we should follow up on this in #86.

@tolauwae tolauwae added the invalid This doesn't seem right label Sep 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working invalid This doesn't seem right
Projects
None yet
Development

No branches or pull requests

2 participants