diff --git a/api-test.c b/api-test.c index 28ff361a6..c6e9d2133 100644 --- a/api-test.c +++ b/api-test.c @@ -382,6 +382,44 @@ static void module_serde(void) JS_FreeRuntime(rt); } +static void runtime_cstring_free(void) +{ + JSRuntime *rt = JS_NewRuntime(); + JSContext *ctx = JS_NewContext(rt); + // string -> cstring + JS_FreeCStringRT + { + JSValue ret = eval(ctx, "\"testStringPleaseIgnore\""); + assert(JS_IsString(ret)); + const char *s = JS_ToCString(ctx, ret); + assert(s); + assert(strcmp(s, "testStringPleaseIgnore") == 0); + JS_FreeCStringRT(rt, s); + JS_FreeValue(ctx, ret); + } + // string -> cstring + JS_FreeCStringRT, destroying the source value first + { + JSValue ret = eval(ctx, "\"testStringPleaseIgnore\""); + assert(JS_IsString(ret)); + const char *s = JS_ToCString(ctx, ret); + assert(s); + JS_FreeValue(ctx, ret); + assert(strcmp(s, "testStringPleaseIgnore") == 0); + JS_FreeCStringRT(rt, s); + } + // number -> cstring + JS_FreeCStringRT + { + JSValue ret = eval(ctx, "123987"); + assert(JS_IsNumber(ret)); + const char *s = JS_ToCString(ctx, ret); + assert(s); + assert(strcmp(s, "123987") == 0); + JS_FreeCStringRT(rt, s); + JS_FreeValue(ctx, ret); + } + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + static void two_byte_string(void) { JSRuntime *rt = JS_NewRuntime(); @@ -804,6 +842,7 @@ int main(void) raw_context_global_var(); is_array(); module_serde(); + runtime_cstring_free(); two_byte_string(); weak_map_gc_check(); promise_hook(); diff --git a/quickjs.c b/quickjs.c index 5a15e00eb..e4a98cecf 100644 --- a/quickjs.c +++ b/quickjs.c @@ -4360,6 +4360,14 @@ void JS_FreeCString(JSContext *ctx, const char *ptr) JS_FreeValue(ctx, JS_MKPTR(JS_TAG_STRING, (JSString *)ptr - 1)); } +void JS_FreeCStringRT(JSRuntime *rt, const char *ptr) +{ + if (!ptr) + return; + /* purposely removing constness */ + JS_FreeValueRT(rt, JS_MKPTR(JS_TAG_STRING, (JSString *)ptr - 1)); +} + static int memcmp16_8(const uint16_t *src1, const uint8_t *src2, int len) { int c, i; diff --git a/quickjs.h b/quickjs.h index b1ab008d9..effc62db5 100644 --- a/quickjs.h +++ b/quickjs.h @@ -820,6 +820,7 @@ static inline const char *JS_ToCString(JSContext *ctx, JSValueConst val1) return JS_ToCStringLen2(ctx, NULL, val1, 0); } JS_EXTERN void JS_FreeCString(JSContext *ctx, const char *ptr); +JS_EXTERN void JS_FreeCStringRT(JSRuntime *rt, const char *ptr); JS_EXTERN JSValue JS_NewObjectProtoClass(JSContext *ctx, JSValueConst proto, JSClassID class_id);