Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit aaf96d0

Browse files
committed
Use a ByteBuffer inside BinaryWriter.Buffer.
1 parent 6d7f278 commit aaf96d0

File tree

3 files changed

+45
-53
lines changed

3 files changed

+45
-53
lines changed

ir/shared/src/main/scala/org/scalajs/ir/UTF8String.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
package org.scalajs.ir
1414

15-
import java.nio.CharBuffer
15+
import java.nio.{ByteBuffer, CharBuffer}
1616
import java.nio.charset.CharacterCodingException
1717
import java.nio.charset.CodingErrorAction
1818
import java.nio.charset.StandardCharsets.UTF_8
@@ -48,6 +48,9 @@ final class UTF8String private (private[ir] val bytes: Array[Byte])
4848
System.arraycopy(that.bytes, 0, result, thisLen, thatLen)
4949
new UTF8String(result)
5050
}
51+
52+
def writeTo(buffer: ByteBuffer): Unit =
53+
buffer.put(bytes)
5154
}
5255

5356
object UTF8String {

linker/shared/src/main/scala/org/scalajs/linker/backend/WebAssemblyLinkerBackend.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,12 +124,12 @@ final class WebAssemblyLinkerBackend(config: LinkerBackendImpl.Config)
124124
wasmModule, emitDebugInfo, smWriter, sourceMapURI)
125125
smWriter.complete()
126126

127-
outputImpl.writeFull(wasmFileName, ByteBuffer.wrap(binaryOutput)).flatMap { _ =>
127+
outputImpl.writeFull(wasmFileName, binaryOutput).flatMap { _ =>
128128
outputImpl.writeFull(sourceMapFileName, sourceMapWriter.toByteBuffer())
129129
}
130130
} else {
131131
val binaryOutput = BinaryWriter.write(wasmModule, emitDebugInfo)
132-
outputImpl.writeFull(wasmFileName, ByteBuffer.wrap(binaryOutput))
132+
outputImpl.writeFull(wasmFileName, binaryOutput)
133133
}
134134
}
135135

linker/shared/src/main/scala/org/scalajs/linker/backend/webassembly/BinaryWriter.scala

Lines changed: 39 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ package org.scalajs.linker.backend.webassembly
1414

1515
import scala.annotation.tailrec
1616

17+
import java.nio.{ByteBuffer, ByteOrder}
18+
1719
import org.scalajs.ir.{Position, UTF8String}
1820
import org.scalajs.linker.backend.javascript.SourceMapWriter
1921

@@ -84,7 +86,7 @@ private sealed class BinaryWriter(module: Module, emitDebugInfo: Boolean) {
8486
protected def emitEndFuncPosition(): Unit = ()
8587
protected def emitSourceMapSection(): Unit = ()
8688

87-
def write(): Array[Byte] = {
89+
def write(): ByteBuffer = {
8890
// magic header: null char + "asm"
8991
buf.byte(0)
9092
buf.byte('a')
@@ -499,42 +501,43 @@ object BinaryWriter {
499501
private final val SectionDataCount = 0x0C
500502
private final val SectionTag = 0x0D
501503

502-
def write(module: Module, emitDebugInfo: Boolean): Array[Byte] =
504+
def write(module: Module, emitDebugInfo: Boolean): ByteBuffer =
503505
new BinaryWriter(module, emitDebugInfo).write()
504506

505507
def writeWithSourceMap(module: Module, emitDebugInfo: Boolean,
506-
sourceMapWriter: SourceMapWriter, sourceMapURI: String): Array[Byte] = {
508+
sourceMapWriter: SourceMapWriter, sourceMapURI: String): ByteBuffer = {
507509
new WithSourceMap(module, emitDebugInfo, sourceMapWriter, sourceMapURI).write()
508510
}
509511

510512
private[BinaryWriter] final class Buffer {
511-
private var buf: Array[Byte] = new Array[Byte](1024 * 1024)
512-
private var size: Int = 0
513-
514-
private def ensureCapacity(capacity: Int): Unit = {
515-
if (buf.length < capacity) {
516-
val newCapacity = Integer.highestOneBit(capacity) << 1
517-
buf = java.util.Arrays.copyOf(buf, newCapacity)
513+
private var buf: ByteBuffer =
514+
ByteBuffer.allocate(1024 * 1024).order(ByteOrder.LITTLE_ENDIAN)
515+
516+
private def ensureRemaining(requiredRemaining: Int): Unit = {
517+
if (buf.remaining() < requiredRemaining) {
518+
buf.flip()
519+
val newCapacity = Integer.highestOneBit(buf.capacity() + requiredRemaining) << 1
520+
val newBuf = ByteBuffer.allocate(newCapacity).order(ByteOrder.LITTLE_ENDIAN)
521+
newBuf.put(buf)
522+
buf = newBuf
518523
}
519524
}
520525

521-
def currentGlobalOffset: Int = size
526+
def currentGlobalOffset: Int = buf.position()
522527

523-
def result(): Array[Byte] =
524-
java.util.Arrays.copyOf(buf, size)
528+
def result(): ByteBuffer = {
529+
buf.flip()
530+
buf
531+
}
525532

526533
def byte(b: Byte): Unit = {
527-
val newSize = size + 1
528-
ensureCapacity(newSize)
529-
buf(size) = b
530-
size = newSize
534+
ensureRemaining(1)
535+
buf.put(b)
531536
}
532537

533538
def rawByteArray(array: Array[Byte]): Unit = {
534-
val newSize = size + array.length
535-
ensureCapacity(newSize)
536-
System.arraycopy(array, 0, buf, size, array.length)
537-
size = newSize
539+
ensureRemaining(array.length)
540+
buf.put(array)
538541
}
539542

540543
def boolean(b: Boolean): Unit =
@@ -555,23 +558,13 @@ object BinaryWriter {
555558
def i64(value: Long): Unit = s64(value)
556559

557560
def f32(value: Float): Unit = {
558-
val bits = java.lang.Float.floatToIntBits(value)
559-
byte(bits.toByte)
560-
byte((bits >>> 8).toByte)
561-
byte((bits >>> 16).toByte)
562-
byte((bits >>> 24).toByte)
561+
ensureRemaining(4)
562+
buf.putFloat(value)
563563
}
564564

565565
def f64(value: Double): Unit = {
566-
val bits = java.lang.Double.doubleToLongBits(value)
567-
byte(bits.toByte)
568-
byte((bits >>> 8).toByte)
569-
byte((bits >>> 16).toByte)
570-
byte((bits >>> 24).toByte)
571-
byte((bits >>> 32).toByte)
572-
byte((bits >>> 40).toByte)
573-
byte((bits >>> 48).toByte)
574-
byte((bits >>> 56).toByte)
566+
ensureRemaining(8)
567+
buf.putDouble(value)
575568
}
576569

577570
def vec[A](elems: Iterable[A])(op: A => Unit): Unit = {
@@ -589,25 +582,21 @@ object BinaryWriter {
589582
def name(utf8: UTF8String): Unit = {
590583
val len = utf8.length
591584
u32(len)
592-
ensureCapacity(size + len)
593-
var i = 0
594-
while (i != len) {
595-
byte(utf8(i))
596-
i += 1
597-
}
585+
ensureRemaining(len)
586+
utf8.writeTo(buf)
598587
}
599588

600589
def byteLengthSubSection(subSectionContent: => Unit): Unit = {
601590
// Reserve 4 bytes at the current offset to store the byteLength later
602-
val byteLengthOffset = size
603-
val startOffset = byteLengthOffset + 4
604-
ensureCapacity(startOffset)
605-
size = startOffset // do not write the 4 bytes for now
591+
val byteLengthOffset = buf.position()
592+
ensureRemaining(4)
593+
val startOffset = buf.position() + 4
594+
buf.position(startOffset) // do not write the 4 bytes for now
606595

607596
subSectionContent
608597

609598
// Compute byteLength
610-
val endOffset = size
599+
val endOffset = buf.position()
611600
val byteLength = endOffset - startOffset
612601

613602
/* Because we limited ourselves to 4 bytes, we cannot represent a size
@@ -623,10 +612,10 @@ object BinaryWriter {
623612
* when we write the code section, which is important to efficiently
624613
* generate source maps.
625614
*/
626-
buf(byteLengthOffset) = ((byteLength & 0x7F) | 0x80).toByte
627-
buf(byteLengthOffset + 1) = (((byteLength >>> 7) & 0x7F) | 0x80).toByte
628-
buf(byteLengthOffset + 2) = (((byteLength >>> 14) & 0x7F) | 0x80).toByte
629-
buf(byteLengthOffset + 3) = ((byteLength >>> 21) & 0x7F).toByte
615+
buf.put(byteLengthOffset, ((byteLength & 0x7F) | 0x80).toByte)
616+
buf.put(byteLengthOffset + 1, (((byteLength >>> 7) & 0x7F) | 0x80).toByte)
617+
buf.put(byteLengthOffset + 2, (((byteLength >>> 14) & 0x7F) | 0x80).toByte)
618+
buf.put(byteLengthOffset + 3, ((byteLength >>> 21) & 0x7F).toByte)
630619
}
631620

632621
@tailrec

0 commit comments

Comments
 (0)