Very experimental WASM code generation by MST in contexts of Int and Real #158

Closed
CommanderTvis wants to merge 16 commits from feature/binaryen into dev
13 changed files with 10352 additions and 0 deletions
Showing only changes of commit b2263b1feb - Show all commits

View File

@ -16,4 +16,11 @@ kotlin.sourceSets {
implementation("org.ow2.asm:asm-commons:8.0.1") implementation("org.ow2.asm:asm-commons:8.0.1")
} }
} }
jsMain {
dependencies {
implementation(npm("binaryen", "98.0.0"))
implementation(npm("js-base64", "3.6.0"))
}
}
} }

View File

@ -0,0 +1,67 @@
@file:Suppress(
"INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE",
"CONFLICTING_OVERLOADS", "NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING", "KDocMissingDocumentation", "ClassName",
"SpellCheckingInspection", "PackageName"
)
@file:JsModule("js-base64")
@file:JsNonModule
package Base64
import org.khronos.webgl.Uint8Array
external var version: Any
external var VERSION: Any
external var btoaPolyfill: (bin: String) -> String
external var _btoa: (bin: String) -> String
external var fromUint8Array: (u8a: Uint8Array, urlsafe: Boolean) -> String
external var utob: (u: String) -> String
external var encode: (src: String, urlsafe: Boolean) -> String
external var encodeURI: (src: String) -> String
external var btou: (b: String) -> String
external var atobPolyfill: (asc: String) -> String
external var _atob: (asc: String) -> String
external var toUint8Array: (a: String) -> Uint8Array
external var decode: (src: String) -> String
external var isValid: (src: Any) -> Boolean
external var extendString: () -> Unit
external var extendUint8Array: () -> Unit
external var extendBuiltins: () -> Unit
external object gBase64 {
var version: String
var VERSION: String
var atob: (asc: String) -> String
var atobPolyfill: (asc: String) -> String
var btoa: (bin: String) -> String
var btoaPolyfill: (bin: String) -> String
var fromBase64: (src: String) -> String
var toBase64: (src: String, urlsafe: Boolean) -> String
var encode: (src: String, urlsafe: Boolean) -> String
var encodeURI: (src: String) -> String
var encodeURL: (src: String) -> String
var utob: (u: String) -> String
var btou: (b: String) -> String
var decode: (src: String) -> String
var isValid: (src: Any) -> Boolean
var fromUint8Array: (u8a: Uint8Array, urlsafe: Boolean) -> String
var toUint8Array: (a: String) -> Uint8Array
var extendString: () -> Unit
var extendUint8Array: () -> Unit
var extendBuiltins: () -> Unit
}

135
kmath-ast/src/jsMain/kotlin/base64.d.ts vendored Normal file
View File

@ -0,0 +1,135 @@
/**
* base64.ts
*
* Licensed under the BSD 3-Clause License.
* http://opensource.org/licenses/BSD-3-Clause
*
* References:
* http://en.wikipedia.org/wiki/Base64
*
* @author Dan Kogai (https://github.com/dankogai)
*/
declare const version = "3.6.0";
/**
* @deprecated use lowercase `version`.
*/
declare const VERSION = "3.6.0";
/**
* polyfill version of `btoa`
*/
declare const btoaPolyfill: (bin: string) => string;
/**
* does what `window.btoa` of web browsers do.
* @param {String} bin binary string
* @returns {string} Base64-encoded string
*/
declare const _btoa: (bin: string) => string;
/**
* converts a Uint8Array to a Base64 string.
* @param {boolean} [urlsafe] URL-and-filename-safe a la RFC4648 §5
* @returns {string} Base64 string
*/
declare const fromUint8Array: (u8a: Uint8Array, urlsafe?: boolean) => string;
/**
* @deprecated should have been internal use only.
* @param {string} src UTF-8 string
* @returns {string} UTF-16 string
*/
declare const utob: (u: string) => string;
/**
* converts a UTF-8-encoded string to a Base64 string.
* @param {boolean} [urlsafe] if `true` make the result URL-safe
* @returns {string} Base64 string
*/
declare const encode: (src: string, urlsafe?: boolean) => string;
/**
* converts a UTF-8-encoded string to URL-safe Base64 RFC4648 §5.
* @returns {string} Base64 string
*/
declare const encodeURI: (src: string) => string;
/**
* @deprecated should have been internal use only.
* @param {string} src UTF-16 string
* @returns {string} UTF-8 string
*/
declare const btou: (b: string) => string;
/**
* polyfill version of `atob`
*/
declare const atobPolyfill: (asc: string) => string;
/**
* does what `window.atob` of web browsers do.
* @param {String} asc Base64-encoded string
* @returns {string} binary string
*/
declare const _atob: (asc: string) => string;
/**
* converts a Base64 string to a Uint8Array.
*/
declare const toUint8Array: (a: string) => Uint8Array;
/**
* converts a Base64 string to a UTF-8 string.
* @param {String} src Base64 string. Both normal and URL-safe are supported
* @returns {string} UTF-8 string
*/
declare const decode: (src: string) => string;
/**
* check if a value is a valid Base64 string
* @param {String} src a value to check
*/
declare const isValid: (src: any) => boolean;
/**
* extend String.prototype with relevant methods
*/
declare const extendString: () => void;
/**
* extend Uint8Array.prototype with relevant methods
*/
declare const extendUint8Array: () => void;
/**
* extend Builtin prototypes with relevant methods
*/
declare const extendBuiltins: () => void;
declare const gBase64: {
version: string;
VERSION: string;
atob: (asc: string) => string;
atobPolyfill: (asc: string) => string;
btoa: (bin: string) => string;
btoaPolyfill: (bin: string) => string;
fromBase64: (src: string) => string;
toBase64: (src: string, urlsafe?: boolean) => string;
encode: (src: string, urlsafe?: boolean) => string;
encodeURI: (src: string) => string;
encodeURL: (src: string) => string;
utob: (u: string) => string;
btou: (b: string) => string;
decode: (src: string) => string;
isValid: (src: any) => boolean;
fromUint8Array: (u8a: Uint8Array, urlsafe?: boolean) => string;
toUint8Array: (a: string) => Uint8Array;
extendString: () => void;
extendUint8Array: () => void;
extendBuiltins: () => void;
};
export { version };
export { VERSION };
export { _atob as atob };
export { atobPolyfill };
export { _btoa as btoa };
export { btoaPolyfill };
export { decode as fromBase64 };
export { encode as toBase64 };
export { utob };
export { encode };
export { encodeURI };
export { encodeURI as encodeURL };
export { btou };
export { decode };
export { isValid };
export { fromUint8Array };
export { toUint8Array };
export { extendString };
export { extendUint8Array };
export { extendBuiltins };
export { gBase64 as Base64 };

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
@file:Suppress("NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING", "KDocMissingDocumentation")
package binaryen
typealias Type = Number
typealias RelooperBlockRef = Number
typealias ExpressionRef = Number
typealias FunctionRef = Number
typealias GlobalRef = Number
typealias ExportRef = Number
typealias EventRef = Number

1787
kmath-ast/src/jsMain/kotlin/index.d.ts vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,61 @@
package kscience.kmath.ast
import binaryen.readBinary
import kscience.kmath.operations.*
private const val ARGS_PTR = 0
private const val ARGS_SIZE = 1
public fun compileMstToWasmF64(mst: MST) {
val keys = mutableListOf<String>()
val bin = with(readBinary(rt)) {
fun MST.visit(): binaryen.ExpressionRef = when (this) {
is MST.Symbolic -> {
var idx = keys.indexOf(value)
if (idx == -1) {
keys += value
idx = keys.lastIndex
}
f64.load(idx * Double.SIZE_BYTES, 0, local.get(ARGS_PTR, binaryen.i32))
}
is MST.Numeric -> f64.const(value)
is MST.Unary -> when (operation) {
SpaceOperations.MINUS_OPERATION -> f64.neg(value.visit())
SpaceOperations.PLUS_OPERATION -> value.visit()
PowerOperations.SQRT_OPERATION -> f64.sqrt(value.visit())
TrigonometricOperations.SIN_OPERATION -> call("sin", arrayOf(value.visit()), binaryen.f64)
else -> throw UnsupportedOperationException()
}
is MST.Binary -> when (operation) {
SpaceOperations.PLUS_OPERATION -> f64.add(left.visit(), right.visit())
RingOperations.TIMES_OPERATION -> f64.mul(left.visit(), right.visit())
FieldOperations.DIV_OPERATION -> f64.div(left.visit(), right.visit())
else -> throw UnsupportedOperationException()
}
}
addFunction(
"executable",
binaryen.createType(arrayOf(binaryen.i32, binaryen.i32)),
binaryen.f64,
arrayOf(),
mst.visit()
)
setMemory(0, 10000)
addFunctionExport("executable", "executable")
optimize()
if (!validate().unsafeCast<Boolean>())
error("Invalid module produced.")
println(emitText())
emitBinary()
}
}

View File

@ -0,0 +1,31 @@
@file:Suppress(
"INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS",
"NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING", "NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING",
"KDocMissingDocumentation"
)
package tsstdlib
external interface IteratorYieldResult<TYield> {
var done: Boolean?
get() = definedExternally
set(value) = definedExternally
var value: TYield
}
external interface IteratorReturnResult<TReturn> {
var done: Boolean
var value: TReturn
}
external interface Iterator<T, TReturn, TNext> {
fun next(vararg args: Any /* JsTuple<> | JsTuple<TNext> */): dynamic /* IteratorYieldResult<T> | IteratorReturnResult<TReturn> */
val `return`: ((value: TReturn) -> dynamic)?
val `throw`: ((e: Any) -> dynamic)?
}
typealias Iterator__1<T> = Iterator<T, Any, Nothing?>
external interface Iterable<T>
external interface IterableIterator<T> : Iterator__1<T>

View File

@ -0,0 +1,37 @@
@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS",
"NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING", "DEPRECATION", "KDocMissingDocumentation", "PropertyName",
"PropertyName", "Reformat"
)
package tsstdlib
import org.khronos.webgl.ArrayBuffer
import org.khronos.webgl.Uint8Array
external interface ArrayLike<T> {
var length: Number
@nativeGetter
operator fun get(n: Number): T?
@nativeSetter
operator fun set(n: Number, value: T)
}
external interface ArrayBufferTypes {
var ArrayBuffer: ArrayBuffer
}
external interface ArrayBufferConstructor {
var prototype: ArrayBuffer
fun isView(arg: Any): Boolean
}
external interface Uint8ArrayConstructor {
fun from(arrayLike: Iterable<Number>, mapfn: (v: Number, k: Number) -> Number = definedExternally, thisArg: Any = definedExternally): Uint8Array
fun from(arrayLike: Iterable<Number>): Uint8Array
fun from(arrayLike: Iterable<Number>, mapfn: (v: Number, k: Number) -> Number = definedExternally): Uint8Array
var prototype: Uint8Array
var BYTES_PER_ELEMENT: Number
fun of(vararg items: Number): Uint8Array
fun from(arrayLike: ArrayLike<Number>): Uint8Array
fun <T> from(arrayLike: ArrayLike<T>, mapfn: (v: T, k: Number) -> Number, thisArg: Any = definedExternally): Uint8Array
fun <T> from(arrayLike: ArrayLike<T>, mapfn: (v: T, k: Number) -> Number): Uint8Array
}

2
kmath-ast/src/jsMain/kotlin/wasm.d.ts vendored Normal file
View File

@ -0,0 +1,2 @@
import * as binaryen from "./index";
export = binaryen;

Binary file not shown.

View File

@ -0,0 +1,12 @@
import kscience.kmath.ast.MstExtendedField
import kscience.kmath.ast.compileMstToWasmF64
import kscience.kmath.operations.invoke
import kotlin.test.Test
internal class Test {
@Test
fun c() {
compileMstToWasmF64(MstExtendedField { sin(symbol("x")) })
}
}