Skip to content
New issue

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

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

Already on GitHub? # to your account

ArrayBuffer and Binary json encoding #111

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