Navigation Menu

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

wasm/misc: getInt64 won't work in JavaScript #29786

Closed
xtuc opened this issue Jan 17, 2019 · 7 comments
Closed

wasm/misc: getInt64 won't work in JavaScript #29786

xtuc opened this issue Jan 17, 2019 · 7 comments
Labels
arch-wasm WebAssembly issues FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@xtuc
Copy link

xtuc commented Jan 17, 2019

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

$ go version
go version go1.11.4 linux/amd64

Does this issue reproduce with the latest release?

The file on master has the same issue -

go/misc/wasm/wasm_exec.js

Lines 104 to 108 in 006a5e7

const getInt64 = (addr) => {
const low = mem().getUint32(addr + 0, true);
const high = mem().getInt32(addr + 4, true);
return low + high * 4294967296;
}
.

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

Not relevant.

go env Output
$ go env
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/sven/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/sven/go"
GOPROXY=""
GORACE=""
GOROOT="/opt/go"
GOTMPDIR=""
GOTOOLDIR="/opt/go/pkg/tool/linux_amd64"
GCCGO="/usr/bin/gccgo"
CC="gcc"
CXX="g++"
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 -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build772238647=/tmp/go-build -gno-record-gcc-switches"

What did you do?

I'm working on https://github.com/wasm-tool/golang and ran into the issue when trying to bundle the following code:

package main

import "log"

func main() {
	log.Println("Called main!")
}

func foo() {
	log.Println("Called foo!")
}

What did you expect to see?

Wasm loading successully.

What did you see instead?

Uncaught (in promise) RangeError: Invalid typed array length: 1547732327792813600
    at typedArrayConstructByArrayBuffer (<anonymous>)
    at new Uint8Array (:8080/native)
    at loadSlice (wasm-loader.js?e1ab:267)
    at Object.runtime.getRandomData (wasm-loader.js?e1ab:344)
    at runtime.getRandomData (bundle.js:80)
    at :8080/wasm-function[892]:7
    at :8080/wasm-function[97]:118
    at :8080/wasm-function[480]:573
    at :8080/wasm-function[826]:165
    at :8080/wasm-function[873]:71
loadSlice @ wasm-loader.js?e1ab:267
runtime.getRandomData @ wasm-loader.js?e1ab:344
runtime.getRandomData @ bundle.js:80
<WASM UNNAMED> @ wasm-0099e9e2-892:4
<WASM UNNAMED> @ wasm-0099e9e2-97:53
<WASM UNNAMED> @ wasm-0099e9e2-480:248
<WASM UNNAMED> @ wasm-0099e9e2-826:65
<WASM UNNAMED> @ wasm-0099e9e2-873:37
run @ wasm-loader.js?e1ab:497
(anonymous) @ test.go?aa27:555
(anonymous) @ test.go:562
./src/test.go @ 1.bundle.js:67
__webpack_require__ @ bundle.js:132
Promise.then (async)
(anonymous) @ index.js?b635:1
./src/index.js @ bundle.js:311
__webpack_require__ @ bundle.js:132
(anonymous) @ bundle.js:299
(anonymous) @ bundle.js:302

Note that the error is not really relevant, the issue is that you cannot represent the full range of a 64 integrer is JavaScript (because it uses 64 bits floats as numbers).

@bradfitz bradfitz added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Jan 17, 2019
@bradfitz bradfitz added this to the Go1.13 milestone Jan 17, 2019
@dmitshur dmitshur added the arch-wasm WebAssembly issues label Jan 17, 2019
@neelance
Copy link
Member

I can not reproduce this issue. The code

package main

import "log"

func main() {
	log.Println("Called main!")
}

func foo() {
	log.Println("Called foo!")
}

works fine for me.

Yes, it is known that getInt64 only returns a precision of 53 bits. I don't see how this is related to your crash. Please elaborate.

@agnivade
Copy link
Contributor

OP is writing a webpack loader for Go. @xtuc - Could you please mention the entire steps for bundling the file through your loader and checking it in the browser ?

@xtuc
Copy link
Author

xtuc commented Jan 18, 2019

I mentioned the the Webpack loader for context, but it's not relevant.

The issue is that passing an out-of-range Integer throws in JavaScript. For example the crash described here does something like:

const b = new ArrayBuffer(254);
const ptr = 2 ** 55;
const len = ptr + 4;
new Uint8Array(b, ptr, len);

Throws with Invalid typed array length: 36028797018963970.


I can reproduce it using the example in the repo https://github.com/wasm-tool/golang/tree/master/example.

That said, I'm wondering why I'm having such high addresses. Please let me know if I can provide more informations/tests.

@neelance
Copy link
Member

Please provide a test that can reproduce the issue with env GOOS=js GOARCH=wasm go run test.go. If this is not possible, then the issue is not with the Go compiler/runtime itself.

I took a quick look at your code and my best guess is that getInt64 is for some reason not getting the same memory instance as the current WebAssembly instance is using and thus is reading bad values.

@xtuc
Copy link
Author

xtuc commented Jan 18, 2019

I pretty sure I won't be able to reproduce the issue using the Go compiler itself and my example (Go run returns fork/exec /tmp/go-build105899162/b001/exe/test: exec format error my setup might be wrong).

However, the issue could theoretically occur in real world, if a program has adresses > 2**53. I agree that my bug might be caused by the Webpack loader itself.

Note that I opened the issue because of the potential usage of invalid numbers in JavaScript.

Edit: while you are taking a look at the loader; it's more or less a hack to use the wasm_exec.js in Webpack and its plugin system. It would be great if we had a better way to do it and I would be happy to discuss about it further.

@neelance
Copy link
Member

2**53 is 8 PiB. Currently WebAssembly uses a continuous linear memory starting at address zero. So this is unlikely an issue.

@xtuc
Copy link
Author

xtuc commented Jan 18, 2019

Yes, that's a good point. It's even unrepresentable in Wasm currently.

Ok, let's close this for now.

@xtuc xtuc closed this as completed Jan 18, 2019
@golang golang locked and limited conversation to collaborators Jan 18, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
arch-wasm WebAssembly issues FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

6 participants