mirror of
https://github.com/fluencelabs/asmble
synced 2025-07-30 13:31:58 +00:00
Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
9172fba948 |
@@ -21,7 +21,7 @@ buildscript {
|
||||
allprojects {
|
||||
apply plugin: 'java'
|
||||
group 'com.github.cretz.asmble'
|
||||
version '0.4.1-fl'
|
||||
version '0.4.2-fl'
|
||||
|
||||
// skips building and running for the specified examples
|
||||
ext.skipExamples = ['c-simple', 'go-simple', 'rust-regex']
|
||||
|
@@ -2,9 +2,11 @@ package asmble.cli
|
||||
|
||||
import asmble.ast.Script
|
||||
import asmble.compile.jvm.javaIdent
|
||||
import asmble.run.jvm.LoggerModule
|
||||
import asmble.run.jvm.Module
|
||||
import asmble.run.jvm.ScriptContext
|
||||
import java.io.File
|
||||
import java.io.PrintWriter
|
||||
import java.util.*
|
||||
|
||||
abstract class ScriptCommand<T> : Command<T>() {
|
||||
@@ -41,6 +43,13 @@ abstract class ScriptCommand<T> : Command<T>() {
|
||||
desc = "The maximum number of memory pages when a module doesn't say.",
|
||||
default = "5",
|
||||
lowPriority = true
|
||||
).toInt(),
|
||||
loggerMemPages = bld.arg(
|
||||
name = "loggerMemPages",
|
||||
opt = "loggermempages",
|
||||
desc = "The maximum number of memory pages of the logger module.",
|
||||
default = "0",
|
||||
lowPriority = true
|
||||
).toInt()
|
||||
)
|
||||
|
||||
@@ -82,7 +91,16 @@ abstract class ScriptCommand<T> : Command<T>() {
|
||||
ctx.withModuleRegistered(moduleName,
|
||||
Module.Native(Class.forName(className, true, ctx.classLoader).newInstance()))
|
||||
}
|
||||
if (args.specTestRegister) context = context.withHarnessRegistered() // проверить что не так с "Cannot find compatible import for spectest::print"
|
||||
if (args.specTestRegister) context = context.withHarnessRegistered()
|
||||
|
||||
if (args.loggerMemPages > 0) {
|
||||
// creates additional Wasm module with logger functionality
|
||||
context =
|
||||
context.withModuleRegistered(
|
||||
"logger",
|
||||
Module.Native(LoggerModule(args.loggerMemPages, PrintWriter(System.out)))
|
||||
)
|
||||
}
|
||||
return context
|
||||
}
|
||||
|
||||
@@ -94,12 +112,14 @@ abstract class ScriptCommand<T> : Command<T>() {
|
||||
* @param disableAutoRegister If set, this will not auto-register modules with names
|
||||
* @param specTestRegister If true, registers the spec test harness as 'spectest'
|
||||
* @param defaultMaxMemPages The maximum number of memory pages when a module doesn't say
|
||||
* @param loggerMemPages The maximum number of memory pages of the logger module.
|
||||
*/
|
||||
data class ScriptArgs(
|
||||
val inFiles: List<String>,
|
||||
val registrations: List<Pair<String, String>>,
|
||||
val disableAutoRegister: Boolean,
|
||||
val specTestRegister: Boolean,
|
||||
val defaultMaxMemPages: Int
|
||||
val defaultMaxMemPages: Int,
|
||||
val loggerMemPages: Int
|
||||
)
|
||||
}
|
||||
}
|
||||
|
44
compiler/src/main/kotlin/asmble/run/jvm/LoggerModule.kt
Normal file
44
compiler/src/main/kotlin/asmble/run/jvm/LoggerModule.kt
Normal file
@@ -0,0 +1,44 @@
|
||||
package asmble.run.jvm
|
||||
|
||||
import asmble.compile.jvm.Mem
|
||||
import java.io.PrintWriter
|
||||
import java.nio.ByteBuffer
|
||||
|
||||
/**
|
||||
* Module with possibility to write bytes to any 'writer'. This module actually
|
||||
* used for logging from the Wasm code outside to 'embedder' (host environment).
|
||||
*/
|
||||
open class LoggerModule(pagesOfMemory: Int, val writer: PrintWriter) {
|
||||
|
||||
private val memory =
|
||||
ByteBuffer.allocate(pagesOfMemory * Mem.PAGE_SIZE) as ByteBuffer
|
||||
|
||||
/**
|
||||
* [Wasm function]
|
||||
* Writes one byte to the logger memory buffer. If there is no place to write
|
||||
* one byte into the buffer then flush all data from the buffer to [PrintWriter]
|
||||
* and after that try to put the byte again.
|
||||
*/
|
||||
fun write(byte: Int) {
|
||||
val isFull = memory.position() >= memory.limit()
|
||||
if (isFull) {
|
||||
flush()
|
||||
}
|
||||
memory.put(byte.toByte())
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* [Wasm function]
|
||||
* Reads all bytes from the logger memory buffer, convert its to UTF-8
|
||||
* string and writes to stdout.
|
||||
* Cleans the logger memory buffer.
|
||||
*/
|
||||
fun flush() {
|
||||
val message = String(memory.array(), 0, memory.position())
|
||||
writer.print(message)
|
||||
writer.flush()
|
||||
memory.clear()
|
||||
}
|
||||
|
||||
}
|
@@ -45,6 +45,7 @@ data class ScriptContext(
|
||||
val defaultMaxMemPages: Int = 1,
|
||||
val includeBinaryInCompiledClass: Boolean = false
|
||||
) : Logger by logger {
|
||||
|
||||
fun withHarnessRegistered(out: PrintWriter = PrintWriter(System.out, true)) =
|
||||
withModuleRegistered("spectest", Module.Native(TestHarness(out)))
|
||||
|
||||
@@ -344,4 +345,4 @@ data class ScriptContext(
|
||||
defineClass(className, bytes, 0, bytes.size)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
51
compiler/src/test/kotlin/asmble/run/jvm/LoggerModuleTest.kt
Normal file
51
compiler/src/test/kotlin/asmble/run/jvm/LoggerModuleTest.kt
Normal file
@@ -0,0 +1,51 @@
|
||||
package asmble.run.jvm
|
||||
|
||||
import asmble.TestBase
|
||||
import org.junit.Test
|
||||
import java.io.PrintWriter
|
||||
import java.io.StringWriter
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class LoggerModuleTest : TestBase() {
|
||||
|
||||
@Test
|
||||
fun writeAndFlushTest() {
|
||||
val stream = StringWriter()
|
||||
val logger = LoggerModule(1, PrintWriter(stream))
|
||||
|
||||
logger.flush() // checks that no raise error
|
||||
|
||||
val testString = "test String for log to stdout"
|
||||
for (byte: Byte in testString.toByteArray()) {
|
||||
logger.write(byte.toInt())
|
||||
}
|
||||
|
||||
logger.flush()
|
||||
val loggedString = stream.toString()
|
||||
assertEquals(testString, loggedString)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun writeAndFlushMoreThanLoggerBufferTest() {
|
||||
val stream = StringWriter()
|
||||
// logger buffer has 65Kb size
|
||||
val logger = LoggerModule(1, PrintWriter(stream))
|
||||
|
||||
val testString = longString(65_000 * 2) // twice as much as logger buffer
|
||||
for (byte: Byte in testString.toByteArray()) {
|
||||
logger.write(byte.toInt())
|
||||
}
|
||||
|
||||
logger.flush()
|
||||
val loggedString = stream.toString()
|
||||
assertEquals(testString, loggedString)
|
||||
}
|
||||
|
||||
private fun longString(size: Int): String {
|
||||
val stringBuffer = StringBuffer()
|
||||
for (idx: Int in (1 until size)) {
|
||||
stringBuffer.append((idx % Byte.MAX_VALUE).toChar())
|
||||
}
|
||||
return stringBuffer.toString()
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user