mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-03 02:27:48 +00:00
all: add WebAssembly backend
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
package main
|
||||
|
||||
func main() {
|
||||
}
|
||||
|
||||
//go:export add
|
||||
func add(a, b int) int {
|
||||
return a + b
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>Go WebAssembly</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<script src="wasm.js" async></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>WebAssembly</h1>
|
||||
<p>Add two numbers, using WebAssembly:</p>
|
||||
<input type="number" id="a" value="2"/> + <input type="number" id="b" value="2"/> = <input type="number" id="result" readonly/>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,55 @@
|
||||
'use strict';
|
||||
|
||||
const WASM_URL = '../../../wasm.wasm';
|
||||
|
||||
var wasm;
|
||||
var logLine = [];
|
||||
var memory8;
|
||||
|
||||
var importObject = {
|
||||
env: {
|
||||
io_get_stdout: function() {
|
||||
return 1;
|
||||
},
|
||||
resource_write: function(fd, ptr, len) {
|
||||
if (fd == 1) {
|
||||
for (let i=0; i<len; i++) {
|
||||
let c = memory8[ptr+i];
|
||||
if (c == 13) { // CR
|
||||
// ignore
|
||||
} else if (c == 10) { // LF
|
||||
// write line
|
||||
let line = new TextDecoder("utf-8").decode(new Uint8Array(logLine));
|
||||
logLine = [];
|
||||
console.log(line);
|
||||
} else {
|
||||
logLine.push(c);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.error('invalid file descriptor:', fd);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
function updateResult() {
|
||||
let a = parseInt(document.querySelector('#a').value);
|
||||
let b = parseInt(document.querySelector('#b').value);
|
||||
let result = wasm.exports.add(a, b);
|
||||
document.querySelector('#result').value = result;
|
||||
}
|
||||
|
||||
function init() {
|
||||
document.querySelector('#a').oninput = updateResult;
|
||||
document.querySelector('#b').oninput = updateResult;
|
||||
|
||||
WebAssembly.instantiateStreaming(fetch(WASM_URL), importObject).then(function(obj) {
|
||||
wasm = obj.instance;
|
||||
memory8 = new Uint8Array(wasm.exports.memory.buffer);
|
||||
wasm.exports.cwa_main();
|
||||
updateResult();
|
||||
})
|
||||
}
|
||||
|
||||
init();
|
||||
@@ -2,6 +2,10 @@
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const GOARCH = "arm"
|
||||
|
||||
// The length type used inside strings and slices.
|
||||
@@ -9,3 +13,6 @@ type lenType uint32
|
||||
|
||||
// The bitness of the CPU (e.g. 8, 32, 64).
|
||||
const TargetBits = 32
|
||||
|
||||
//go:extern _heap_start
|
||||
var heapStart unsafe.Pointer
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const GOARCH = "avr"
|
||||
|
||||
// The length type used inside strings and slices.
|
||||
@@ -9,3 +13,6 @@ type lenType uint16
|
||||
|
||||
// The bitness of the CPU (e.g. 8, 32, 64).
|
||||
const TargetBits = 8
|
||||
|
||||
//go:extern _heap_start
|
||||
var heapStart unsafe.Pointer
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const GOARCH = "wasm"
|
||||
|
||||
// The length type used inside strings and slices.
|
||||
@@ -9,3 +13,6 @@ type lenType uint32
|
||||
|
||||
// The bitness of the CPU (e.g. 8, 32, 64).
|
||||
const TargetBits = 32
|
||||
|
||||
//go:extern __heap_base
|
||||
var heapStart unsafe.Pointer
|
||||
|
||||
@@ -6,9 +6,6 @@ import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
//go:extern _heap_start
|
||||
var heapStart unsafe.Pointer
|
||||
|
||||
var heapptr = uintptr(unsafe.Pointer(&heapStart))
|
||||
|
||||
func alloc(size uintptr) unsafe.Pointer {
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
// +build wasm,!arm,!avr
|
||||
|
||||
package runtime
|
||||
|
||||
type timeUnit int64
|
||||
|
||||
const tickMicros = 1
|
||||
|
||||
var timestamp timeUnit
|
||||
|
||||
// CommonWA: io_get_stdout
|
||||
func _Cfunc_io_get_stdout() int32
|
||||
|
||||
// CommonWA: resource_write
|
||||
func _Cfunc_resource_write(id int32, ptr *uint8, len int32) int32
|
||||
|
||||
var stdout int32
|
||||
|
||||
func init() {
|
||||
stdout = _Cfunc_io_get_stdout()
|
||||
}
|
||||
|
||||
//go:export _start
|
||||
func _start() {
|
||||
initAll()
|
||||
}
|
||||
|
||||
//go:export cwa_main
|
||||
func cwa_main() {
|
||||
initAll() // _start is not called by olin/cwa so has to be called here
|
||||
mainWrapper()
|
||||
}
|
||||
|
||||
func putchar(c byte) {
|
||||
_Cfunc_resource_write(stdout, &c, 1)
|
||||
}
|
||||
|
||||
func sleepTicks(d timeUnit) {
|
||||
// TODO: actually sleep here for the given time.
|
||||
timestamp += d
|
||||
}
|
||||
|
||||
func ticks() timeUnit {
|
||||
return timestamp
|
||||
}
|
||||
|
||||
// Align on word boundary.
|
||||
func align(ptr uintptr) uintptr {
|
||||
return (ptr + 3) &^ 3
|
||||
}
|
||||
|
||||
func abort() {
|
||||
// TODO
|
||||
}
|
||||
Reference in New Issue
Block a user