flat assembler
Message board for the users of flat assembler.
Index
> Programming Language Design > WebAssembly |
Author |
|
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
|
|||||||||||
08 Feb 2017, 09:12 |
|
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. |
|||
15 Feb 2017, 12:27 |
|
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 Oh, and not all instructions are supported. I only made macros for some of them, the ones I needed for testing.
|
|||||||||||
17 Feb 2017, 22:15 |
|
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.
|
|||||||||||
18 Feb 2017, 12:50 |
|
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 ? |
|||
19 Feb 2017, 11:10 |
|
jmg 21 Feb 2017, 19:16
Tomasz Grysztar wrote:
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 ? |
|||
21 Feb 2017, 19:16 |
|
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. 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. |
|||
21 Feb 2017, 19:52 |
|
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. |
|||
21 Feb 2017, 20:19 |
|
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. |
|||
01 Mar 2017, 07:21 |
|
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 |
|||
24 Sep 2017, 12:16 |
|
jorido 24 Sep 2017, 12:18
And also, where can I get "fasmg"?
|
|||
24 Sep 2017, 12:18 |
|
Tomasz Grysztar 24 Sep 2017, 12:59
jorido wrote: And also, where can I get "fasmg"? jorido wrote: Has anyone been able to get it to work? I have 2 errors: (...) 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.
|
|||||||||||
24 Sep 2017, 12:59 |
|
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 Code: fasmg -i "_WASM_FILE_='test.wasm'" wasm2html.asm I've only tested it with a couple files thus far. _________________ ¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup |
|||
06 May 2021, 12:56 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.