| /* |
| * Copyright 2010-2025 JetBrains s.r.o. and Kotlin Programming Language contributors. |
| * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. |
| */ |
| |
| @file:Suppress("OPT_IN_USAGE") |
| |
| package kotlin.wasm.internal |
| |
| import kotlin.internal.UsedFromCompilerGeneratedCode |
| |
| /** |
| * The following Js builtins are internal and used for the implementation of String class in Wasm target. |
| * Range/bound checks in Js code are omitted, as the String class performs checks in Kotlin code, before calling builtins. |
| * When calling following functions, range/bound checks must be performed. |
| */ |
| private const val jsStringModuleName = "js-string" |
| |
| @JsBuiltin( |
| jsStringModuleName, |
| "length", |
| "export const length = (s) => s.length" |
| ) |
| internal external fun jsLength(a: JsString): Int |
| |
| |
| @JsBuiltin( |
| jsStringModuleName, |
| "concat", |
| "export const concat = (a, b) => a + b" |
| ) |
| @UsedFromCompilerGeneratedCode |
| internal external fun jsConcat(a: JsString, b: JsString): JsStringRef |
| |
| |
| @JsBuiltin( |
| jsStringModuleName, |
| "charCodeAt", |
| "export const charCodeAt = (s, i) => s.charCodeAt(i >>> 0)" |
| ) |
| internal external fun jsCharCodeAt(s: JsString, i: Int): Int |
| |
| |
| @JsBuiltin( |
| jsStringModuleName, |
| "substring", |
| """export const substring = (s, start, end) => { |
| start >>>= 0; |
| end >>>= 0; |
| return s.substring(start, end); |
| } |
| """ |
| ) |
| internal external fun jsSubstring(s: JsString, start: Int, end: Int): JsStringRef |
| |
| |
| @JsBuiltin( |
| jsStringModuleName, |
| "compare", |
| """export const compare = (a, b) => { |
| return a === b ? 0 : a < b ? -1 : 1; |
| } |
| """ |
| ) |
| internal external fun jsCompare(a: JsString, b: JsString): Int |
| |
| |
| @JsBuiltin( |
| jsStringModuleName, |
| "equals", |
| "export const equals = (a, b) => a === b ? 1 : 0" |
| ) |
| internal external fun jsEquals(a: JsString, b: JsString): Int |
| |
| |
| /* |
| * Loads the following wasm helpers: |
| * ```wat |
| * (module |
| * (type $array_i16 (array (mut i16))) |
| * (func (export "a16_set") (param (ref $array_i16) i32 i32) |
| * local.get 0 |
| * local.get 1 |
| * local.get 2 |
| * array.set $array_i16 |
| * ) |
| * ) |
| * ``` |
| */ |
| @Suppress("WRONG_JS_INTEROP_TYPE") |
| @IgnorableReturnValue |
| @JsBuiltin( |
| jsStringModuleName, |
| "intoCharCodeArray", |
| """const moduleIntoCharCode = new WebAssembly.Module(new Uint8Array([ |
| 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0b, 0x02, 0x5e, |
| 0x77, 0x01, 0x60, 0x03, 0x64, 0x00, 0x7f, 0x7f, 0x00, 0x03, 0x02, 0x01, |
| 0x01, 0x07, 0x0b, 0x01, 0x07, 0x61, 0x31, 0x36, 0x5f, 0x73, 0x65, 0x74, |
| 0x00, 0x00, 0x0a, 0x0d, 0x01, 0x0b, 0x00, 0x20, 0x00, 0x20, 0x01, 0x20, |
| 0x02, 0xfb, 0x0e, 0x00, 0x0b, 0x00, 0x13, 0x04, 0x6e, 0x61, 0x6d, 0x65, |
| 0x04, 0x0c, 0x01, 0x00, 0x09, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5f, 0x69, |
| 0x31, 0x36 |
| ])); |
| const helpersIntoCharCode = new WebAssembly.Instance(moduleIntoCharCode).exports; |
| |
| export const intoCharCodeArray = (s, array, start) => { |
| start >>>= 0; |
| for (let i = 0; i < s.length; i++) { |
| helpersIntoCharCode.a16_set(array, start + i, s.charCodeAt(i)); |
| } |
| return s.length; |
| } |
| """ |
| ) |
| internal external fun jsIntoCharCodeArray(string: JsString, array: WasmCharArray, start: Int): Int |
| |
| |
| /* |
| * Loads the following wasm helpers: |
| * ```wat |
| * (module |
| * (type $array_i16 (array (mut i16))) |
| * (func (export "a16_get") (param (ref $array_i16) i32) (result i32) |
| * local.get 0 |
| * local.get 1 |
| * array.get_u $array_i16 |
| * ) |
| * ) |
| * ``` |
| */ |
| @Suppress("WRONG_JS_INTEROP_TYPE") |
| @JsBuiltin( |
| jsStringModuleName, |
| "fromCharCodeArray", |
| """const moduleFromCharCodeArray = new WebAssembly.Module(new Uint8Array([ |
| 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0b, 0x02, 0x5e, |
| 0x77, 0x01, 0x60, 0x02, 0x64, 0x00, 0x7f, 0x01, 0x7f, 0x03, 0x02, 0x01, |
| 0x01, 0x07, 0x0b, 0x01, 0x07, 0x61, 0x31, 0x36, 0x5f, 0x67, 0x65, 0x74, |
| 0x00, 0x00, 0x0a, 0x0b, 0x01, 0x09, 0x00, 0x20, 0x00, 0x20, 0x01, 0xfb, |
| 0x0d, 0x00, 0x0b, 0x00, 0x13, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x04, 0x0c, |
| 0x01, 0x00, 0x09, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5f, 0x69, 0x31, 0x36 |
| ])); |
| const helpersFromCharCodeArray = new WebAssembly.Instance(moduleFromCharCodeArray).exports; |
| |
| export const fromCharCodeArray = (array, start, end) => { |
| start >>>= 0; |
| end >>>= 0; |
| let result = []; |
| for (let i = start; i < end; i++) { |
| result.push(String.fromCharCode(helpersFromCharCodeArray.a16_get(array, i))); |
| } |
| return result.join(""); |
| } |
| """ |
| ) |
| internal external fun jsFromCharCodeArray(array: WasmCharArray, start: Int, end: Int): JsStringRef |