diff --git a/developer/src/kmc-kmn/src/compiler/compiler.ts b/developer/src/kmc-kmn/src/compiler/compiler.ts index c46b894cb3..a88999e99c 100644 --- a/developer/src/kmc-kmn/src/compiler/compiler.ts +++ b/developer/src/kmc-kmn/src/compiler/compiler.ts @@ -42,50 +42,10 @@ const baseOptions: CompilerOptions = { */ let callbackProcIdentifier = 0; -/** - * Pointer in wasm-space - */ -type WasmPtr = number; - -/** - * The wrapped functions - */ -class WasmWrapper { - Module: any; - - compileKeyboardFile?: (pszInfile: string, pszOutfile: string, aSaveDebug: number, aCompilerWarningsAsErrors: number, aWarnDeprecatedCode: number, msgProc: string) => boolean; - parseUnicodeSet?: (pat: string, buf: WasmPtr, length: number) => number; - setCompilerOptions?: (shouldAddCompilerVersion: number) => boolean; - - constructor(wasmModule: any) { - this.Module = wasmModule; - if (!wasmModule) { - throw Error(`wasm host did not load`); - } - this.compileKeyboardFile = this.Module.cwrap('kmcmp_Wasm_CompileKeyboardFile', 'boolean', ['string', 'string', 'number', 'number', 'number', 'string']); - this.parseUnicodeSet = this.Module.cwrap('kmcmp_Wasm_ParseUnicodeSet', 'number', ['string', 'number', 'number']); - this.setCompilerOptions = this.Module.cwrap('kmcmp_Wasm_SetCompilerOptions', 'boolean', ['number']); - - if (this.parseUnicodeSet === undefined - || this.setCompilerOptions === undefined - || this.compileKeyboardFile === undefined) { - throw Error(`some wasm functions did not load properly.`); - } - } - - /** - * Entry point into Wasm functions - * @returns WasmWrapper - */ - public static async load() : Promise { - return new WasmWrapper(await loadWasmHost()); - } -}; - export class KmnCompiler { + private Module: any; callbackName: string; callbacks: CompilerCallbacks; - wasm: WasmWrapper; constructor() { this.callbackName = 'kmnCompilerCallback' + callbackProcIdentifier; @@ -94,9 +54,9 @@ export class KmnCompiler { public async init(callbacks: CompilerCallbacks): Promise { this.callbacks = callbacks; - if(!this.wasm) { + if(!this.Module) { try { - this.wasm = await WasmWrapper.load(); + this.Module = await loadWasmHost(); } catch(e: any) { this.callbacks.reportMessage(CompilerMessages.Fatal_MissingWasmModule({e})); return false; @@ -114,7 +74,7 @@ export class KmnCompiler { // Can't report a message here. throw Error('Must call Compiler.init(callbacks) before proceeding'); } - if(!this.wasm) { // fail if wasm not loaded or function not found + if(!this.Module) { // fail if wasm not loaded or function not found this.callbacks.reportMessage(CompilerMessages.Fatal_MissingWasmModule({})); return false; } @@ -153,7 +113,7 @@ export class KmnCompiler { private runCompiler(infile: string, outfile: string, options: CompilerOptions): CompilerResult { let result: CompilerResult = {}; - let wasm_interface = new this.wasm.Module.CompilerInterface(); + let wasm_interface = new this.Module.CompilerInterface(); let wasm_result = null; try { wasm_interface.saveDebug = options.saveDebug; @@ -161,7 +121,7 @@ export class KmnCompiler { wasm_interface.warnDeprecatedCode = options.warnDeprecatedCode; wasm_interface.messageCallback = this.callbackName; wasm_interface.loadFileCallback = this.callbackName; // TODO: this is wrong, needs to be a new callback; not yet used though - wasm_result = this.wasm.Module.kmcmp_compile(infile, wasm_interface); + wasm_result = this.Module.kmcmp_compile(infile, wasm_interface); if(!wasm_result.result) { return null; } @@ -175,7 +135,7 @@ export class KmnCompiler { result.kmx = { filename: outfile, - data: new Uint8Array(this.wasm.Module.HEAP8.buffer, wasm_result.kmx, wasm_result.kmxSize) + data: new Uint8Array(this.Module.HEAP8.buffer, wasm_result.kmx, wasm_result.kmxSize) }; return result; @@ -230,16 +190,15 @@ export class KmnCompiler { if (!bufferSize) { bufferSize = 100; // TODO-LDML: Preflight mode? Reuse buffer? } - const { Module } = this.wasm; - const buf = Module.asm.malloc(bufferSize * 2 * Module.HEAPU32.BYTES_PER_ELEMENT); + const buf = this.Module.asm.malloc(bufferSize * 2 * this.Module.HEAPU32.BYTES_PER_ELEMENT); // TODO-LDML: Catch OOM - const rc = this.wasm.parseUnicodeSet(pattern, buf, bufferSize); + const rc = this.Module.kmcmp_parseUnicodeSet(pattern, buf, bufferSize); if (rc >= 0) { const ranges = []; - const startu = (buf / Module.HEAPU32.BYTES_PER_ELEMENT); + const startu = (buf / this.Module.HEAPU32.BYTES_PER_ELEMENT); for (let i = 0; i < rc; i++) { - const low = Module.HEAPU32[startu + (i * 2) + 0]; - const high = Module.HEAPU32[startu + (i * 2) + 1]; + const low = this.Module.HEAPU32[startu + (i * 2) + 0]; + const high = this.Module.HEAPU32[startu + (i * 2) + 1]; ranges.push([low, high]); } // TODO-LDML: no free?? diff --git a/developer/src/kmcmplib/include/kmcmplibapi.h b/developer/src/kmcmplib/include/kmcmplibapi.h index 2fb35979b2..f4591612ec 100644 --- a/developer/src/kmcmplib/include/kmcmplibapi.h +++ b/developer/src/kmcmplib/include/kmcmplibapi.h @@ -62,7 +62,7 @@ EXTERN bool kmcmp_ValidateJsonFile( ); /** - * kmcmp_ParseUnicodeSet is successful if it returns >= USET_OK + * kmcmp_parseUnicodeSet is successful if it returns >= USET_OK */ static const int KMCMP_USET_OK = 0; @@ -83,24 +83,19 @@ static const int KMCMP_ERROR_UNSUPPORTED_PROPERTY = -3; */ static const int KMCMP_FATAL_OUT_OF_RANGE = -4; -/** - * Function pointer to kmcmp_ParseUnicodeSet - */ -typedef int (*kmcmp_ParseUnicodeSetProc)(const char* szText, uint32_t* output, uint32_t outputLength); - /** * Parse a UnicodeSet into 32-bit ranges. * For example, "[]" will return 0 (KMCMP_USET_OK) as a zero-length set. * "[" will return KMCMP_ERROR_SYNTAX_ERR, * and "[x A-C]" will return 2 and [0x41, 0x43, 0x78, 0x78] - * @param szText input txt, null terminated, in UTF-8 format + * @param text input txt, null terminated, in UTF-8 format * @param outputBuffer output buffer, owned by caller: Pairs of ranges in order * @param outputBufferSize length of output buffer. Needs to be twice the number of expected ranges * @return If >= KMCMP_USET_OK, number of ranges, otherwise one of the negative error values. */ -EXTERN int kmcmp_ParseUnicodeSet( - const char* szText, - uint32_t* outputBuffer, +EXTERN int kmcmp_parseUnicodeSet( + const std::string text, + uintptr_t outputBuffer_, uint32_t outputBufferSize ); diff --git a/developer/src/kmcmplib/src/CompilerInterfaces.cpp b/developer/src/kmcmplib/src/CompilerInterfaces.cpp index a1609d3544..56ecf4cdcf 100644 --- a/developer/src/kmcmplib/src/CompilerInterfaces.cpp +++ b/developer/src/kmcmplib/src/CompilerInterfaces.cpp @@ -46,39 +46,6 @@ int wasm_CompilerMessageProc(int line, uint32_t dwMsgCode, char* szText, void* c return wasm_msgproc(line, dwMsgCode, szText, msgProc); } -//DEPRECATED -EXTERN bool kmcmp_Wasm_SetCompilerOptions(int ShouldAddCompilerVersion) { - KMCMP_COMPILER_OPTIONS options; - options.dwSize = sizeof(KMCMP_COMPILER_OPTIONS); - options.ShouldAddCompilerVersion = ShouldAddCompilerVersion; - return kmcmp_SetCompilerOptions(&options); -} - -//DEPRECATED -EXTERN bool kmcmp_Wasm_CompileKeyboardFile(char* pszInfile, - char* pszOutfile, int ASaveDebug, int ACompilerWarningsAsErrors, - int AWarnDeprecatedCode, char* msgProc -) { - return kmcmp_CompileKeyboardFile( - pszInfile, - pszOutfile, - ASaveDebug, - ACompilerWarningsAsErrors, - AWarnDeprecatedCode, - wasm_CompilerMessageProc, - msgProc - ); -} - -EXTERN int kmcmp_Wasm_ParseUnicodeSet(char* pat, - uint32_t* buf, int length -) { - return kmcmp_ParseUnicodeSet( - pat, buf, length - ); -} - - struct COMPILER_INTERFACE { bool saveDebug; bool compilerWarningsAsErrors; @@ -162,6 +129,7 @@ EMSCRIPTEN_BINDINGS(compiler_interface) { ; emscripten::function("kmcmp_compile", &kmcmp_compile); + emscripten::function("kmcmp_parseUnicodeSet", &kmcmp_parseUnicodeSet); } #endif diff --git a/developer/src/kmcmplib/src/meson.build b/developer/src/kmcmplib/src/meson.build index 292b158ce2..3cd9abd6e1 100644 --- a/developer/src/kmcmplib/src/meson.build +++ b/developer/src/kmcmplib/src/meson.build @@ -24,7 +24,7 @@ endif name_suffix = [] if cpp_compiler.get_id() == 'emscripten' - links += ['-lnodefs.js', '-sMODULARIZE', '-sEXPORT_ES6', '--whole-archive', '--bind', '-sEXPORTED_RUNTIME_METHODS=[\'cwrap\', \'UTF8ToString\']'] + links += ['-lnodefs.js', '-sMODULARIZE', '-sEXPORT_ES6', '--whole-archive', '--bind', '-sEXPORTED_RUNTIME_METHODS=[\'UTF8ToString\']'] # tests are building as ES6 so we need to declare the file extension # note that meson currently struggles with the sanitycheckc_cross.exe # program, because it has a hard coded extension (.exe) which is not diff --git a/developer/src/kmcmplib/src/uset-api.cpp b/developer/src/kmcmplib/src/uset-api.cpp index 1aa22477b2..c2c72cab34 100644 --- a/developer/src/kmcmplib/src/uset-api.cpp +++ b/developer/src/kmcmplib/src/uset-api.cpp @@ -4,16 +4,13 @@ #include "unicode/uniset.h" #include "unicode/unistr.h" -EXTERN int kmcmp_ParseUnicodeSet( - const char* szText, - uint32_t* outputBuffer, +EXTERN int kmcmp_parseUnicodeSet( + const std::string text, + uintptr_t outputBuffer_, uint32_t outputBufferSize ) { - if (szText == nullptr) { - // null string coming in - return KMCMP_ERROR_SYNTAX_ERR; - } - const icu::UnicodeString str = icu::UnicodeString::fromUTF8(szText); + uint32_t* outputBuffer = reinterpret_cast(outputBuffer_); + const icu::UnicodeString str = icu::UnicodeString::fromUTF8(text.c_str()); if (str.isBogus() || str.isEmpty()) { // empty string return KMCMP_ERROR_SYNTAX_ERR; diff --git a/developer/src/kmcmplib/tests/uset-api-test.cpp b/developer/src/kmcmplib/tests/uset-api-test.cpp index 4fe599ca2e..61d263ad15 100644 --- a/developer/src/kmcmplib/tests/uset-api-test.cpp +++ b/developer/src/kmcmplib/tests/uset-api-test.cpp @@ -19,30 +19,32 @@ #include "../src/compfile.h" #include -void test_kmcmp_ParseUnicodeSetProc(); +void test_kmcmp_parseUnicodeSet(); // std::vector error_vec; int main(int argc, char *argv[]) { - test_kmcmp_ParseUnicodeSetProc(); + test_kmcmp_parseUnicodeSet(); return 0; } -void test_kmcmp_ParseUnicodeSetProc() { +void test_kmcmp_parseUnicodeSet() { { // null test const auto bufsiz = 128; uint32_t buf[bufsiz]; - int rc = kmcmp_ParseUnicodeSet(u8"[]", buf, bufsiz); + uintptr_t buf_ = reinterpret_cast(buf); + int rc = kmcmp_parseUnicodeSet(u8"[]", buf_, bufsiz); assert(rc == KMCMP_USET_OK); } { // basic test const auto bufsiz = 128; uint32_t buf[bufsiz]; - int rc = kmcmp_ParseUnicodeSet(u8"[x A-C]", buf, bufsiz); + uintptr_t buf_ = reinterpret_cast(buf); + int rc = kmcmp_parseUnicodeSet(u8"[x A-C]", buf_, bufsiz); assert(rc == 2); assert(buf[0] == 0x41); assert(buf[1] == 0x43); @@ -53,7 +55,8 @@ void test_kmcmp_ParseUnicodeSetProc() { // bigger test const auto bufsiz = 128; uint32_t buf[bufsiz]; - int rc = kmcmp_ParseUnicodeSet(u8"[[🙀A-C]-[CB]]", buf, bufsiz); + uintptr_t buf_ = reinterpret_cast(buf); + int rc = kmcmp_parseUnicodeSet(u8"[[🙀A-C]-[CB]]", buf_, bufsiz); assert(rc == 2); assert(buf[0] == 0x41); assert(buf[1] == 0x41); @@ -64,35 +67,40 @@ void test_kmcmp_ParseUnicodeSetProc() { // overflow test const auto bufsiz = 1; uint32_t buf[bufsiz]; - int rc = kmcmp_ParseUnicodeSet(u8"[x A-C]", buf, bufsiz); + uintptr_t buf_ = reinterpret_cast(buf); + int rc = kmcmp_parseUnicodeSet(u8"[x A-C]", buf_, bufsiz); assert(rc == KMCMP_FATAL_OUT_OF_RANGE); } { // err test const auto bufsiz = 128; uint32_t buf[bufsiz]; - int rc = kmcmp_ParseUnicodeSet(u8"[:Adlm:]", buf, bufsiz); + uintptr_t buf_ = reinterpret_cast(buf); + int rc = kmcmp_parseUnicodeSet(u8"[:Adlm:]", buf_, bufsiz); assert(rc == KMCMP_ERROR_UNSUPPORTED_PROPERTY); } { // err test const auto bufsiz = 128; uint32_t buf[bufsiz]; - int rc = kmcmp_ParseUnicodeSet(u8"[[\\p{Mn}]&[A-Z]]", buf, bufsiz); + uintptr_t buf_ = reinterpret_cast(buf); + int rc = kmcmp_parseUnicodeSet(u8"[[\\p{Mn}]&[A-Z]]", buf_, bufsiz); assert(rc == KMCMP_ERROR_UNSUPPORTED_PROPERTY); } { // err test const auto bufsiz = 128; uint32_t buf[bufsiz]; - int rc = kmcmp_ParseUnicodeSet(u8"[abc{def}]", buf, bufsiz); + uintptr_t buf_ = reinterpret_cast(buf); + int rc = kmcmp_parseUnicodeSet(u8"[abc{def}]", buf_, bufsiz); assert(rc == KMCMP_ERROR_HAS_STRINGS); } { // err test const auto bufsiz = 128; uint32_t buf[bufsiz]; - int rc = kmcmp_ParseUnicodeSet(u8"[[]", buf, bufsiz); + uintptr_t buf_ = reinterpret_cast(buf); + int rc = kmcmp_parseUnicodeSet(u8"[[]", buf_, bufsiz); assert(rc == KMCMP_ERROR_SYNTAX_ERR); } }