Skip to content

ArrayBuffer and Binary json encoding #111

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

Merged
merged 13 commits into from
Jul 19, 2023
Merged
50 changes: 49 additions & 1 deletion c/interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,14 @@ JSValue *QTS_NewArray(JSContext *ctx) {
return jsvalue_to_heap(JS_NewArray(ctx));
}

void qts_free_buffer(JSRuntime *unused_rt, void *unused_opaque, void *ptr) { free(ptr); }

JSValue *QTS_NewArrayBuffer(JSContext *ctx, JSVoid *buffer, size_t length) {
return jsvalue_to_heap(
JS_NewArrayBuffer(ctx, (uint8_t*)buffer, length, qts_free_buffer, NULL, false)
);
}

JSValue *QTS_NewFloat64(JSContext *ctx, double num) {
return jsvalue_to_heap(JS_NewFloat64(ctx, num));
}
Expand All @@ -328,6 +336,25 @@ JSBorrowedChar *QTS_GetString(JSContext *ctx, JSValueConst *value) {
return JS_ToCString(ctx, *value);
}

JSVoid *QTS_GetArrayBuffer(JSContext *ctx, JSValueConst *data) {
size_t length;
uint8_t *buffer = JS_GetArrayBuffer(ctx, &length, *data);
if (!buffer)
return 0;
uint8_t *result = malloc(length);
if (!result)
return result;
memcpy(result, buffer, length);
return result;
}

// I don't know how to return two values in C, maybe allocate memory in stack?
size_t QTS_GetArrayBufferLength(JSContext *ctx, JSValueConst *data) {
Comment on lines +351 to +352
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we could add stackAlloc and use it to pass in a *size_t argument like the &length arguments in QuickJS's own API, but it's not document anywhere so I think your current approach is fine.

Copy link
Contributor Author

@yourWaifu yourWaifu Apr 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking online, the best solutions I could find is to use Emscripten's embind API and a separate cpp file to use the API. However, I'm not familiar with Makefile, so I don't really know how to get it to compile the separate cpp file.

I can find what the command should look like:

$ emcc --bind -O3 --std=c++11 a_c_file.c another_c_file.c -x c++ your_cpp_file.cpp

But not how to do it using Make because I get this error

emcc: error: cannot specify -o with -c/-S/-E/-M and multiple source files

Removing -c gets me this error

wasm-ld: error: unknown file type: build/wrapper/interface.WASM_DEBUG_SYNC.o

size_t length;
uint8_t *buffer = JS_GetArrayBuffer(ctx, &length, *data);
return length;
}

JSValue qts_get_symbol_key(JSContext *ctx, JSValueConst *value) {
JSValue global = JS_GetGlobalObject(ctx);
JSValue Symbol = JS_GetPropertyStr(ctx, global, "Symbol");
Expand Down Expand Up @@ -816,4 +843,25 @@ void QTS_RuntimeEnableModuleLoader(JSRuntime *rt, int use_custom_normalize) {

void QTS_RuntimeDisableModuleLoader(JSRuntime *rt) {
JS_SetModuleLoaderFunc(rt, NULL, NULL, NULL);
}
}

JSValue *QTS_bjson_encode(JSContext *ctx, JSValueConst *val) {
size_t length;
uint8_t *buffer = JS_WriteObject(ctx, &length, *val, JS_WRITE_OBJ_REFERENCE);
if (!buffer)
return jsvalue_to_heap(JS_EXCEPTION);

JSValue array = JS_NewArrayBufferCopy(ctx, buffer, length);
js_free(ctx, buffer);
return jsvalue_to_heap(array);
}

JSValue *QTS_bjson_decode(JSContext *ctx, JSValueConst *data) {
size_t length;
uint8_t *buffer = JS_GetArrayBuffer(ctx, &length, *data);
if (!buffer)
return jsvalue_to_heap(JS_EXCEPTION);

JSValue value = JS_ReadObject(ctx, buffer, length, 0);
return jsvalue_to_heap(value);
}
Loading