Very experimental WASM code generation by MST in contexts of Int and Real #158
@ -16,4 +16,11 @@ kotlin.sourceSets {
|
||||
implementation("org.ow2.asm:asm-commons:8.0.1")
|
||||
}
|
||||
}
|
||||
|
||||
jsMain {
|
||||
dependencies {
|
||||
implementation(npm("binaryen", "98.0.0"))
|
||||
implementation(npm("js-base64", "3.6.0"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
67
kmath-ast/src/jsMain/kotlin/Base64/base64.kt
Normal file
67
kmath-ast/src/jsMain/kotlin/Base64/base64.kt
Normal 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
135
kmath-ast/src/jsMain/kotlin/base64.d.ts
vendored
Normal 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 };
|
2216
kmath-ast/src/jsMain/kotlin/binaryen/index.binaryen.kt
Normal file
2216
kmath-ast/src/jsMain/kotlin/binaryen/index.binaryen.kt
Normal file
File diff suppressed because it is too large
Load Diff
11
kmath-ast/src/jsMain/kotlin/binaryen/typealises.kt
Normal file
11
kmath-ast/src/jsMain/kotlin/binaryen/typealises.kt
Normal 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
1787
kmath-ast/src/jsMain/kotlin/index.d.ts
vendored
Normal file
File diff suppressed because it is too large
Load Diff
5986
kmath-ast/src/jsMain/kotlin/kscience/kmath/ast/Initial.kt
Normal file
5986
kmath-ast/src/jsMain/kotlin/kscience/kmath/ast/Initial.kt
Normal file
File diff suppressed because one or more lines are too long
@ -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()
|
||||
}
|
||||
}
|
31
kmath-ast/src/jsMain/kotlin/tsstdlib/lib.es2015.iterable.kt
Normal file
31
kmath-ast/src/jsMain/kotlin/tsstdlib/lib.es2015.iterable.kt
Normal 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>
|
37
kmath-ast/src/jsMain/kotlin/tsstdlib/lib.es5.kt
Normal file
37
kmath-ast/src/jsMain/kotlin/tsstdlib/lib.es5.kt
Normal 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
2
kmath-ast/src/jsMain/kotlin/wasm.d.ts
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
import * as binaryen from "./index";
|
||||
export = binaryen;
|
BIN
kmath-ast/src/jsMain/resources/main.wasm
Normal file
BIN
kmath-ast/src/jsMain/resources/main.wasm
Normal file
Binary file not shown.
12
kmath-ast/src/jsTest/kotlin/Test.kt
Normal file
12
kmath-ast/src/jsTest/kotlin/Test.kt
Normal 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")) })
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user