Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix string passing at interface C++ to JS #1905

Merged
merged 4 commits into from
Oct 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,7 @@ if(EMSCRIPTEN)
_duckdb_web_pending_query_cancel, \
_duckdb_web_pending_query_poll, \
_duckdb_web_pending_query_start, \
_duckdb_web_pending_query_start_buffer, \
_duckdb_web_prepared_close, \
_duckdb_web_prepared_create, \
_duckdb_web_prepared_run, \
Expand All @@ -333,6 +334,7 @@ if(EMSCRIPTEN)
_duckdb_web_query_run_buffer, \
_duckdb_web_reset, \
_duckdb_web_tokenize, \
_duckdb_web_tokenize_buffer, \
_duckdb_web_udf_scalar_create \
]' \
-s EXPORTED_RUNTIME_METHODS='[\"ccall\", \"stackSave\", \"stackAlloc\", \"stackRestore\"]' \
Expand Down
15 changes: 15 additions & 0 deletions lib/src/webdb_api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,13 @@ void duckdb_web_tokenize(WASMResponse* packed, const char* query) {
auto tokens = webdb.Tokenize(query);
WASMResponseBuffer::Get().Store(*packed, arrow::Result(std::move(tokens)));
}
/// Tokenize a query
void duckdb_web_tokenize_buffer(WASMResponse* packed, const uint8_t* buffer, size_t buffer_length) {
GET_WEBDB(*packed);
std::string_view query(reinterpret_cast<const char*>(buffer), buffer_length);
auto tokens = webdb.Tokenize(query);
WASMResponseBuffer::Get().Store(*packed, arrow::Result(std::move(tokens)));
}
/// Create scalar UDF queries
void duckdb_web_udf_scalar_create(WASMResponse* packed, ConnectionHdl connHdl, const char* args) {
auto c = reinterpret_cast<WebDB::Connection*>(connHdl);
Expand Down Expand Up @@ -203,6 +210,14 @@ void duckdb_web_pending_query_start(WASMResponse* packed, ConnectionHdl connHdl,
auto r = c->PendingQuery(script, allow_stream_result);
WASMResponseBuffer::Get().Store(*packed, std::move(r));
}
/// Start a pending query
void duckdb_web_pending_query_start_buffer(WASMResponse* packed, ConnectionHdl connHdl, const uint8_t* buffer,
size_t buffer_length, bool allow_stream_result) {
auto c = reinterpret_cast<WebDB::Connection*>(connHdl);
std::string_view S(reinterpret_cast<const char*>(buffer), buffer_length);
auto r = c->PendingQuery(S, allow_stream_result);
WASMResponseBuffer::Get().Store(*packed, std::move(r));
}
/// Poll a pending query
void duckdb_web_pending_query_poll(WASMResponse* packed, ConnectionHdl connHdl, const char* script) {
auto c = reinterpret_cast<WebDB::Connection*>(connHdl);
Expand Down
21 changes: 13 additions & 8 deletions packages/duckdb-wasm/src/bindings/bindings_base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,12 @@ export abstract class DuckDBBindingsBase implements DuckDBBindings {

/** Tokenize a script */
public tokenize(text: string): ScriptTokens {
const [s, d, n] = callSRet(this.mod, 'duckdb_web_tokenize', ['string'], [text]);
const BUF = TEXT_ENCODER.encode(text);
const bufferPtr = this.mod._malloc(BUF.length );
const bufferOfs = this.mod.HEAPU8.subarray(bufferPtr, bufferPtr + BUF.length );
bufferOfs.set(BUF);
const [s, d, n] = callSRet(this.mod, 'duckdb_web_tokenize_buffer', ['number', 'number'], [bufferPtr, BUF.length]);
this.mod._free(bufferPtr);
if (s !== StatusCode.SUCCESS) {
throw new Error(readString(this.mod, d, n));
}
Expand Down Expand Up @@ -168,12 +173,12 @@ export abstract class DuckDBBindingsBase implements DuckDBBindings {
const bufferOfs = this.mod.HEAPU8.subarray(bufferPtr, bufferPtr + BUF.length);
bufferOfs.set(BUF);
const [s, d, n] = callSRet(this.mod, 'duckdb_web_query_run_buffer', ['number', 'number', 'number'], [conn, bufferPtr, BUF.length]);
this.mod._free(bufferPtr);
if (s !== StatusCode.SUCCESS) {
throw new Error(readString(this.mod, d, n));
}
const res = copyBuffer(this.mod, d, n);
dropResponseBuffers(this.mod);
this.mod._free(bufferPtr);
return res;
}
/**
Expand All @@ -183,12 +188,12 @@ export abstract class DuckDBBindingsBase implements DuckDBBindings {
* Results can then be fetched using `fetchQueryResults`
*/
public startPendingQuery(conn: number, text: string, allowStreamResult: boolean = false): Uint8Array | null {
const [s, d, n] = callSRet(
this.mod,
'duckdb_web_pending_query_start',
['number', 'string', 'boolean'],
[conn, text, allowStreamResult],
);
const BUF = TEXT_ENCODER.encode(text);
const bufferPtr = this.mod._malloc(BUF.length );
const bufferOfs = this.mod.HEAPU8.subarray(bufferPtr, bufferPtr + BUF.length );
bufferOfs.set(BUF);
const [s, d, n] = callSRet(this.mod, 'duckdb_web_pending_query_start_buffer', ['number', 'number', 'number', 'boolean'], [conn, bufferPtr, BUF.length, allowStreamResult]);
this.mod._free(bufferPtr);
if (s !== StatusCode.SUCCESS) {
throw new Error(readString(this.mod, d, n));
}
Expand Down