webassemblyjs icon indicating copy to clipboard operation
webassemblyjs copied to clipboard

WIP: Transpile sign extension proposal

Open maurobringolf opened this issue 7 years ago • 14 comments

Here is what I've been working on:

  • New package that transpiles sign extension instructions back to functions with the (hopefully) same behavior.

  • The functions replacing the instructions are written in assemblyScript, compiled to wasm, parsed by wasm-parser and then injected into a given ast.

  • Only the necessary functions are inserted

The package is currently written as ast->ast transform and the tests are setup as text->text for readability. We can add another API using wasm-edit for binaries directly. I would like to have a test setup for functional correctness though and haven't really figured out how to do that yet.

maurobringolf avatar May 31 '18 08:05 maurobringolf

Nice idea :-)

The use of Assembly Script to generated the function that polyfills does feel like overkill. The generated WAT is really quite simple:

  (func $main/i32_extend16_s (export "i32_extend16_s") (type $t2) (param $p0 i32) (result i32)
    get_local $p0
    i32.const 32768
    i32.and
    if $I0 (result i32)
      get_local $p0
      i32.const -32768
      i32.or
    else
      get_local $p0
      i32.const 32767
      i32.and
    end
    return)

I'd just use the above wat directly, parsing it into AST, then 'injecting' it as part of your polyfill transform.

ColinEberhardt avatar May 31 '18 09:05 ColinEberhardt

Thanks for the feedback! It might very well be overkill and caused some extra work in the build process. It simply represents the way I arrived at these (first in C, Sven suggested migrating to AssemblyScript). There might be one advantage though: I am looking for a way to test the functional correctness of the polyfill functions. One possibility would be to test the AssemblyScript source. Do you have an alternative suggestion for this kind of testing?

We could use the interpreter, but its probably not ready yet? Also much more errorprone I imagine

maurobringolf avatar May 31 '18 11:05 maurobringolf

I am looking for a way to test the functional correctness of the polyfill functions. One possibility would be to test the AssemblyScript source. Do you have an alternative suggestion for this kind of testing?

If you write these functions in WAT, I'd just unit test that via JS - e.g. unit test the $main/i32_extend16_s function I added in the comment above

ColinEberhardt avatar May 31 '18 13:05 ColinEberhardt

We could use the interpreter, but its probably not ready yet? Also much more errorprone I imagine

How? It's not a C compiler.

Assembly Script to generated the function that polyfills does feel like overkill

I think it will be more maintainable

xtuc avatar May 31 '18 16:05 xtuc

@xtuc Its not a C compiler yet. Just kidding :smile: I meant that the interpreter could be used to run the polyfill wasm function to test functional correctness.

maurobringolf avatar May 31 '18 16:05 maurobringolf

Assembly Script to generated the function that polyfills does feel like overkill

I think it will be more maintainable

For complex polyfills I'd agree, but in this case it's a few lines of WAT. I like simple :-)

Also, how stable is AssemblyScript? If you encounter an error, can you be sure it is in your code? Or is it the AssemblyScript compiler? How optimised is the output?

Anyhow, this is not a strong objection, just my thoughts!

ColinEberhardt avatar May 31 '18 16:05 ColinEberhardt

Yeah I agree @ColinEberhardt. What do you think @maurobringolf?

Our interpreter is definitely not ready.

xtuc avatar May 31 '18 16:05 xtuc

Less things to maintain is fine with me :+1: It was a fun experiment. Would you make the wat->ast translation build-time or runtime?

maurobringolf avatar May 31 '18 17:05 maurobringolf

We could do it at publish-time but runtime seems easier for now.

xtuc avatar May 31 '18 17:05 xtuc

Yeah, I’d go runtime for simplicity. It’s a pretty simple transform and transforms aren’t really that performance critical

ColinEberhardt avatar May 31 '18 18:05 ColinEberhardt

Thanks for the feedback, I prefer text format as source for the polyfills now too. I also realized that the other approach would not work in the long run anyways: As soon as a feature becomes standard it wouldnt make sense to use a compiler anymore since it might output code that relies on the feature (instructions in this case) we're trying to polyfill in the first place.

  • Now .wast polyfills are loaded from source files and parsed with wast-parser
  • I added functional tests for both i32 polyfills by converting the wast source to wasm with wat2wasm from wabt and then running it as module in node directly.
  • Not sure what to do with i64

maurobringolf avatar Jun 01 '18 20:06 maurobringolf

Not sure what to do with i64

Sorry, what do you mean

xtuc avatar Jun 02 '18 09:06 xtuc

@xtuc There is no functional test for i64 polyfills since we cannot call functions directly from JS.

maurobringolf avatar Jun 02 '18 10:06 maurobringolf

You can deactivate the check: https://github.com/xtuc/webassemblyjs/blob/master/packages/repl/src/index.js#L299-L307

We are testing i64 in the spectest via our REPL.

xtuc avatar Jun 02 '18 11:06 xtuc