]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link/internal/wasm: do not generate more than 100000 data segments
authorRichard Musiol <mail@richard-musiol.de>
Sun, 24 Mar 2019 17:21:11 +0000 (18:21 +0100)
committerRichard Musiol <neelance@gmail.com>
Mon, 25 Mar 2019 07:54:44 +0000 (07:54 +0000)
Some WebAssembly runtimes (e.g. Node.js) fail to load a wasm binary if
it has more than 100000 data segments. Do not skip zero regions any more
if the limit was reached.

Change-Id: I14c4c2aba142d1d2b887bce6d03b8c1c1746c5ec
Reviewed-on: https://go-review.googlesource.com/c/go/+/168884
Run-TryBot: Richard Musiol <neelance@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
src/cmd/link/internal/wasm/asm.go

index 2665659fe064e3bd4581556eb815a42ac2a08a8b..abb4409188f29004468aa1849ee54b7d3a68661f 100644 (file)
@@ -427,8 +427,11 @@ func writeDataSec(ctxt *ld.Link) {
        // overhead of adding a new segment (same as wasm-opt's memory-packing optimization uses).
        const segmentOverhead = 8
 
+       // Generate at most this many segments. A higher number of segments gets rejected by some WebAssembly runtimes.
+       const maxNumSegments = 100000
+
        var segments []*dataSegment
-       for _, sec := range sections {
+       for secIndex, sec := range sections {
                data := ld.DatblkBytes(ctxt, int64(sec.Vaddr), int64(sec.Length))
                offset := int32(sec.Vaddr)
 
@@ -441,21 +444,26 @@ func writeDataSec(ctxt *ld.Link) {
                for len(data) > 0 {
                        dataLen := int32(len(data))
                        var segmentEnd, zeroEnd int32
-                       for {
-                               // look for beginning of zeroes
-                               for segmentEnd < dataLen && data[segmentEnd] != 0 {
-                                       segmentEnd++
-                               }
-                               // look for end of zeroes
-                               zeroEnd = segmentEnd
-                               for zeroEnd < dataLen && data[zeroEnd] == 0 {
-                                       zeroEnd++
-                               }
-                               // emit segment if omitting zeroes reduces the output size
-                               if zeroEnd-segmentEnd >= segmentOverhead || zeroEnd == dataLen {
-                                       break
+                       if len(segments)+(len(sections)-secIndex) == maxNumSegments {
+                               segmentEnd = dataLen
+                               zeroEnd = dataLen
+                       } else {
+                               for {
+                                       // look for beginning of zeroes
+                                       for segmentEnd < dataLen && data[segmentEnd] != 0 {
+                                               segmentEnd++
+                                       }
+                                       // look for end of zeroes
+                                       zeroEnd = segmentEnd
+                                       for zeroEnd < dataLen && data[zeroEnd] == 0 {
+                                               zeroEnd++
+                                       }
+                                       // emit segment if omitting zeroes reduces the output size
+                                       if zeroEnd-segmentEnd >= segmentOverhead || zeroEnd == dataLen {
+                                               break
+                                       }
+                                       segmentEnd = zeroEnd
                                }
-                               segmentEnd = zeroEnd
                        }
 
                        segments = append(segments, &dataSegment{