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")
|
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