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

runtime: compiled WASM with NodeJS fails with “ TypeError: (intermediate value).arrayBuffer is not a function” #39381

Closed
carlskii opened this issue Jun 3, 2020 · 4 comments

Comments

@carlskii
Copy link

@carlskii carlskii commented Jun 3, 2020

What version of Go are you using (go version)?

$ go version
go version go1.14.4 darwin/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/user1/Library/Caches/go-build"
GOENV="/Users/user1/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/user1/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/l7/08p741zd43xbsnqvxz68wdch0000gn/T/go-build062348627=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

I compiled my go application using this:

GOOS=js GOARCH=wasm go build -o test.wasm

And tested it using the example .JS/HTML from the $(go env GOROOT)/misc/wasm duirectory. This works perfectly in my Chrome browser. However, it does't work using nodejs (v14.3.0).

const fs = require('fs');
require('./wasm_exec.js');

if (!WebAssembly.instantiateStreaming) { // polyfill
    WebAssembly.instantiateStreaming = async (resp, importObject) => {
        const source = await (await resp).arrayBuffer();
        return await WebAssembly.instantiate(source, importObject);
    };
}

const go = new Go();
let mod, inst;
WebAssembly.instantiateStreaming(fs.readFileSync('./test.wasm'), go.importObject).then((result) => {
    mod = result.module;
    inst = result.instance;
   // document.getElementById("runButton").disabled = false;
}).catch((err) => {
    console.error(err);
});

async function run() {
    console.clear();
    await go.run(inst);
    inst = await WebAssembly.instantiate(mod, go.importObject); // reset instance
}

run()

However, here's the problem:

TypeError: (intermediate value).arrayBuffer is not a function
    at WebAssembly.instantiateStreaming (/Users/cbourne/development/go-wasm/scratch4.js:6:43)
(node:23644) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'exports' of undefined
    at global.Go.run (/Users/cbourne/development/go-wasm/wasm_exec.js:483:39)
    at run (/Users/cbourne/development/go-wasm/scratch4.js:23:14)
    at Object.<anonymous> (/Users/cbourne/development/go-wasm/scratch4.js:27:1)
    at Module._compile (internal/modules/cjs/loader.js:1200:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1220:10)
    at Module.load (internal/modules/cjs/loader.js:1049:32)
    at Function.Module._load (internal/modules/cjs/loader.js:937:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
    at internal/main/run_main_module.js:17:47

-->

@carlskii carlskii changed the title Using compiles WASM with NodeJS Using compiled WASM with NodeJS Jun 3, 2020
@carlskii
Copy link
Author

@carlskii carlskii commented Jun 3, 2020

Further to this it seems that Node.js v14.4.0 has experimental support for a WebAssembly System Interface (WASI) https://nodejs.org/api/wasi.html.

Should this work with Golang. I tried the following, but was unable to get it working:

'use strict';
const fs = require('fs');
const { WASI } = require('wasi');
require('./wasm_exec.js');

const wasi = new WASI({
  args: process.argv,
  env: process.env,
  preopens: {
    '/sandbox': '/Users/user/development/go-wasm/'
  }
});
const importObject = { wasi_snapshot_preview1: wasi.wasiImport };


(async () => {
  const wasm = await WebAssembly.compile(fs.readFileSync('./main.wasm'));
  const instance = await WebAssembly.instantiate(wasm, importObject);

  wasi.start(instance);
})();
@odeke-em odeke-em changed the title Using compiled WASM with NodeJS runtime: compiled WASM with NodeJS fails with “ TypeError: (intermediate value).arrayBuffer is not a function” Jun 5, 2020
@odeke-em
Copy link
Member

@odeke-em odeke-em commented Jun 5, 2020

Thank you for the report and details @carlskii! I shall kindly ping some experts @neelance @agnivade

@neelance
Copy link
Member

@neelance neelance commented Jun 5, 2020

wasm_exec.html is not meant to be used with Node.js. Either simply use go run ... or use the go_js_wasm_exec helper for running the wasm binary with Node.js.

@carlskii
Copy link
Author

@carlskii carlskii commented Jun 5, 2020

Got it thanks. Think I've got passed this now so will close.

@carlskii carlskii closed this Jun 5, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
3 participants
You can’t perform that action at this time.