flat assembler
Message board for the users of flat assembler.

Index > Programming Language Design > WebAssembly

Author
Thread Post new topic Reply to topic
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 05 Feb 2017, 20:04
Have any of you tried the WebAssembly? I think that could be another interesting area where fasmg could become useful. After I finish the AVX-512 macros I'm working on currently I might give it a try and write some WebAssembly macros. Or perhaps someone already tried it?
Post 05 Feb 2017, 20:04
View user's profile Send private message Visit poster's website Reply with quote
Jerry



Joined: 24 Dec 2016
Posts: 18
Location: Zeist, Netherlands
Jerry 08 Feb 2017, 09:12
At first i never even heard of it, but it got me curious and i have a (very simple/small) example working.
I used this page as a source : https://medium.com/@MadsSejersen/webassembly-the-missing-tutorial-95f8580b08ba
To enable it in firefox you need to go to about:config and enable "javascript.options.wasm" and then restart your browser.
I think you should remember to disable it again once you're done testing/playing, since it's still experimental.

Two ways you can use this :
1. In a html page, see test.html in attached archive
2. paste the text i output with display (test.asm) in the webconsole commandline

The single macro "section" in webasm.inc only captures the generation of the textlength/name/rest of section length, but it's a start i guess
The defined function name is 'sum' and takes two i32 parameters and returns one i32

I'm using firefox 51.0.1 btw


Description:
Download
Filename: webasm.zip
Filesize: 1.99 KB
Downloaded: 1561 Time(s)

Post 08 Feb 2017, 09:12
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 15 Feb 2017, 12:27
I believe that we can make some good macros packages for fasmg that would assemble these structures and instructions with a clean syntax. But I have to say that I am not very excited with this architecture.

I admit that I simply dislike stack-based architectures in general, including the x86 FPU. I feel that for anything more complex than the very basic snippets you need to carefully trace the contents of the stack at any point in code and you end up writing comments about what is on the stack after every instruction. But at the same time it allows to make the binary code more compact, so I understand why it is a tempting option.

However even Java byte-code, which is also stack-based, at least has some classic branching instructions (like conditional jumps). You cannot utilize their power to the full extent because of some arbitrary rules for the code structure enforced by JVM (which are perhaps the main reason why I gave up trying to write anything for JVM in an assembly-like language), but still they are there. And in WebAssembly the branching instructions look like "if", "else" and "end", structuring the code in blocks. I think that someone must have read too much into Dijkstra's pet-peeve. I am pretty convinced that this approach does not lead to more compact code - I have recently demonstrated that modern compilers are able to make a really good use of jump instructions to generate an efficient code, and hand-crafted assembly has always been full of similar tricks.

Not that I think that instructions like "if" are necessarily a bad idea - I think we could perceive them as a tool similar to conditional predicates of ARM (or their less robust kin in x86 architecture - CMOV), with the difference that they could apply to entire blocks of instructions instead of a single one (though I'm not sure if this could be as effective in terms of efficiency). But I do believe that any assembly language without jump instructions is deeply flawed.
Post 15 Feb 2017, 12:27
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 17 Feb 2017, 22:15
In the browser I use (Vivaldi) the expected WebAssembly version was 13, so I had to convert your sample to a new format. And while I was at it, I tried to make macros that would provide a bit of automation. The rewritten sample looks simply like this:
Code:
include 'wasm.inc'

function sum:i32 (x:i32, y:i32)
        get_local x
        get_local y
        i32.add
        return
end function    
You can add more functions and the structures should be assembled correctly. It does not detect if two or more function have the same signature in order to "compress" the type section, I though it was not important enough to warrant making the macros more complex. And it does not allow to declare additional local variables, though it should be easy to add - I just did not have an idea for a syntax.

Oh, and not all instructions are supported. I only made macros for some of them, the ones I needed for testing.


Description: example for WebAssembly 13 (pre-MVP)
Download
Filename: wasm.zip
Filesize: 2.64 KB
Downloaded: 1410 Time(s)

Post 17 Feb 2017, 22:15
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 18 Feb 2017, 12:50
I have made an improved version of these macros which do not generate multiple type entries for the same function signature, because I wanted to test a simple trick that I devised for this purpose. And at the same time I added basic support for local variables (with "var" macro inside the function body) and allowed alternate syntax "i32 x" in place of "x:i32" (both variants are allowed, it does not increase the complexity of macros, choosing to use just one variant would only make them a little bit shorter).

The "var" macro outside of the function bodies could be made to generate global symbol entries and the instruction set is left only partially implemented, but I feel that my enthusiasm here burns out very quickly.


Description: revised example for WebAssembly 13 (pre-MVP)
Download
Filename: wasm.zip
Filesize: 3.16 KB
Downloaded: 1516 Time(s)

Post 18 Feb 2017, 12:50
View user's profile Send private message Visit poster's website Reply with quote
Jerry



Joined: 24 Dec 2016
Posts: 18
Location: Zeist, Netherlands
Jerry 19 Feb 2017, 11:10
Hello Tomasz,

First off, wow you got working what i could not, i was still messing around with version 11, which doesn't make much sense anymore.
These look a lot better and complete than what i have, so i'll use these as a basis.
I plan to do my best to implement as much as i can, as a learning experience, if it's anything worthy i'll post it as an example for anyone who cares.
I'm not very proficient with the complete macro language (yet), so this is a good challenge (started now with a way to import javascript functions).

Thanks again for these examples.

By the way, couple of days ago i needed to unwatch and then rewatch the topic as i did not receive any updates from it, does that happens sometimes ?
Post 19 Feb 2017, 11:10
View user's profile Send private message Reply with quote
jmg



Joined: 18 Sep 2016
Posts: 62
jmg 21 Feb 2017, 19:16
Tomasz Grysztar wrote:

Have any of you tried the WebAssembly? I think that could be another interesting area where fasmg could become useful. After I finish the AVX-512 macros I'm working on currently I might give it a try and write some WebAssembly macros. Or perhaps someone already tried it?


This is a good use for fasmg, and your quick examples are impressive.

Tomasz Grysztar wrote:
... But I do believe that any assembly language without jump instructions is deeply flawed.


Well, yes, strictly I'd agree, but WebAssembly looks to be an 'assembly language' only in the loosest sense.

In most cases the 'text "linear assembly bytecode" (Intermediate Representation)' will come from higher level tools ?
Post 21 Feb 2017, 19:16
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 21 Feb 2017, 19:52
jmg wrote:
Well, yes, strictly I'd agree, but WebAssembly looks to be an 'assembly language' only in the loosest sense.

In most cases the 'text "linear assembly bytecode" (Intermediate Representation)' will come from higher level tools ?
That's why I referred to the fact that modern compilers are able to put branches into a very good use, so even when the instruction set is only going to be used by high-level compilers, having traditional branches may still be beneficial.

But I understand that this is in fact an "intermediate" language, a half-compiled stage that is going to be further compiled when the WebAssembly module is loaded for execution. Though I think that splitting compilation in half like that may make some types of optimization less effective.
Post 21 Feb 2017, 19:52
View user's profile Send private message Visit poster's website Reply with quote
jmg



Joined: 18 Sep 2016
Posts: 62
jmg 21 Feb 2017, 20:19
Tomasz Grysztar wrote:
That's why I referred to the fact that modern compilers are able to put branches into a very good use, so even when the instruction set is only going to be used by high-level compilers, having traditional branches may still be beneficial..


Maybe they will add jump instructions in some form, tho I imagine they could be security cautious here ?

Jump instructions would be useful, on embedded controller versions of this.
Post 21 Feb 2017, 20:19
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 01 Mar 2017, 07:21
It seems that the initial format specification has been closed:
https://lists.w3.org/Archives/Public/public-webassembly/2017Feb/0002.html
The examples above may need updating to use the MVP (1) version.
Post 01 Mar 2017, 07:21
View user's profile Send private message Visit poster's website Reply with quote
jorido



Joined: 23 Jan 2017
Posts: 53
jorido 24 Sep 2017, 12:16
Has anyone been able to get it to work? I have 2 errors:


1)
test.html:7 Fetch API cannot load file:///home/me123/webasm_fasm_test/test.wasm. URL scheme must be "http" or "https" for CORS request.
(anonymous) @ test.html:7


2)
test.html:7 Uncaught (in promise) TypeError: Failed to fetch
at test.html:7
Post 24 Sep 2017, 12:16
View user's profile Send private message Reply with quote
jorido



Joined: 23 Jan 2017
Posts: 53
jorido 24 Sep 2017, 12:18
And also, where can I get "fasmg"?
Post 24 Sep 2017, 12:18
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 24 Sep 2017, 12:59
jorido wrote:
And also, where can I get "fasmg"?
You are right on the website of this assembler, please visit the Download section (the link is also available in the shortcut menu on the bottom of message board page) and look for the "flat assembler g" package.

jorido wrote:
Has anyone been able to get it to work? I have 2 errors: (...)
You need to upload the files to a server to get this to work. Also note that the all the output generated by the example goes to JS console.

As for WebAssembly example, the standard has since moved from pre-MVP version numbering to a more official MVP 1.0 release. Because of that, the above example causes this error:
Console wrote:
CompileError: WasmCompile: Wasm decoding failed: expected version 01 00 00 00, found 0d 00 00 00 @+4

So I changed the version number field in the header to 1 and the sample seems to work correctly. I attach the updated example below.

Also, please keep in mind that this was quickly patched-up and I have not implemented the complete instruction set. But writing the instruction macros (placed in the WASMCODE.INC) is a very simple task. And if this generates any attention I may implement more instructions and include this in the official fasmg package.


Description: example for WebAssembly MVP 1.0
Download
Filename: wasm.zip
Filesize: 3.04 KB
Downloaded: 1416 Time(s)

Post 24 Sep 2017, 12:59
View user's profile Send private message Visit poster's website Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4060
Location: vpcmpistri
bitRAKE 06 May 2021, 12:56
Code:
; encode wasm binary to base64 string
; no need for any other http requests or server communication
format binary as 'html'

db "<!DOCTYPE HTML><html><body>",10
db "<script>",10
db "const buffer = atob('"

; base64 encoded bytes need to be output between these two strings
; (naïve implementation)

virtual at 0
BASE64:: db 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
end virtual
virtual at 0
        WASM::
        file _WASM_FILE_
        WASM_bytes := $
end virtual
offset = 0
while 1
        i = WASM_bytes - offset
        if i > 2 ; common case, three byted to four codes
                load code:3 from WASM:offset
                offset = offset + 3
                code0 = (code shr 2) and $3F
                code1 = ((code shr 12) and $F) + ((code shl 4) and $30)
                code2 = (code shr 22) + ((code shr 6) and $3C)
                code3 = (code shr 16) and $3F
                load code0:1 from BASE64:code0
                load code1:1 from BASE64:code1
                load code2:1 from BASE64:code2
                load code3:1 from BASE64:code3
                db code0,code1,code2,code3
        else if i = 2
                load code:2 from WASM:offset
                code0 = (code shr 2) and $3F
                code1 = ((code shr 12) and $F) + ((code shl 4) and $30)
                code2 = (code shr 6) and $3C
                load code0:1 from BASE64:code0
                load code1:1 from BASE64:code1
                if code2 <> 0
                        load code2:1 from BASE64:code2
                else
                        code2 = '='
                end if
                db code0,code1,code2,'='
                break
        else if i = 1
                load code:2 from WASM:offset
                code0 = (code shr 2) and $3F
                code1 = (code shl 4) and $30
                load code0:1 from BASE64:code0
                if code1 <> 0
                        load code1:1 from BASE64:code1
                else
                        code1 = '='
                end if
                db code0,code1,'=','='
                break
        else if i = 0
                break
        end if
end while

db "');",10
db "wasm_code = new Uint8Array(buffer.length);",10
db "for (var i in buffer) wasm_code[i] = buffer.charCodeAt(i);",10
db 10
db "const memory = new WebAssembly.Memory({ initial: 256, maximum: 256 })",10
db "const importObj = {",10
db "    env: {",10
db "            abortStackOverflow: () => { throw new Error('overflow'); },",10
db "            table: new WebAssembly.Table({ initial: 0, maximum: 0, element: 'anyfunc' }),",10
db "            tableBase: 0,",10
db "            memory: memory,",10
db "            memoryBase: 1024,",10
db "            STACKTOP: 0,",10
db "            STACK_MAX: memory.buffer.byteLength,",10
db "    }",10
db "}",10
db 10
db "WebAssembly.instantiate(wasm_code, importObj)",10
db "  .then(({module, instance}) => { console.log(instance.exports.sqrsum(5, 7)) })",10
db "  .catch((err) => { console.log(err.message) })",10
db "</script>",10
db "</body>",10
db "</html>",10    
It's possible to test wasm without running a server by encoding wasm binary with base64.
Code:
fasmg -i "_WASM_FILE_='test.wasm'" wasm2html.asm    
...passes the wasm to process from the commandline.

I've only tested it with a couple files thus far.

_________________
¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup
Post 06 May 2021, 12:56
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.