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

Add support for MSVC 2019 without c11 atomics #612

Closed
wants to merge 3 commits into from

Conversation

wargio
Copy link

@wargio wargio commented Oct 21, 2024

Linked to rizinorg/jsdec#60

@saghul
Copy link
Contributor

saghul commented Oct 21, 2024

I think this might have worked before, but now quickjs-libc requires atomics. Let's look at the CI!

@satk0
Copy link
Contributor

satk0 commented Oct 21, 2024

Heey, it looks like my PR #592 XD

@saghul
Copy link
Contributor

saghul commented Oct 21, 2024

It does try to accomplish the same, but alas it doesn't build.

@wargio
Copy link
Author

wargio commented Oct 22, 2024

I think this might have worked before, but now quickjs-libc requires atomics. Let's look at the CI!

Why would it need atomics if is not really needed for other targets? and why you need to have quickjs-libc? even qjsc can be built without it with just a few edits.

--- qjsc.c	2024-10-21 22:20:13.207314142 +0800
+++ qjsc-nostd.c	2024-10-18 18:02:55.536534692 +0800
@@ -29,15 +29,17 @@
 #include <inttypes.h>
 #include <string.h>
 #include <assert.h>
+#include <limits.h>
 #if defined(_MSC_VER)
+#define WIN32_LEAN_AND_MEAN
 #include "getopt_compat.h"
 #else
 #include <unistd.h>
 #endif
 #include <errno.h>
+#include "quickjs.h"
 
 #include "cutils.h"
-#include "quickjs-libc.h"
 
 typedef enum {
     OUTPUT_C,
@@ -156,6 +158,44 @@
         fprintf(f, "\n");
 }
 
+static void qjsc_dump_obj(JSContext *ctx, FILE *f, JSValue val)
+{
+    const char *str;
+
+    str = JS_ToCString(ctx, val);
+    if (str) {
+        fprintf(f, "%s\n", str);
+        JS_FreeCString(ctx, str);
+    } else {
+        fprintf(f, "[exception]\n");
+    }
+}
+
+static void qjsc_dump_error1(JSContext *ctx, JSValue exception_val)
+{
+    JSValue val;
+    BOOL is_error;
+
+    is_error = JS_IsError(ctx, exception_val);
+    qjsc_dump_obj(ctx, stderr, exception_val);
+    if (is_error) {
+        val = JS_GetPropertyStr(ctx, exception_val, "stack");
+        if (!JS_IsUndefined(val)) {
+            qjsc_dump_obj(ctx, stderr, val);
+        }
+        JS_FreeValue(ctx, val);
+    }
+}
+
+static void qjsc_dump_error(JSContext *ctx)
+{
+    JSValue exception_val;
+
+    exception_val = JS_GetException(ctx);
+    qjsc_dump_error1(ctx, exception_val);
+    JS_FreeValue(ctx, exception_val);
+}
+
 static void output_object_code(JSContext *ctx,
                                FILE *fo, JSValue obj, const char *c_name,
                                BOOL load_only)
@@ -172,7 +212,7 @@
 
     out_buf = JS_WriteObject(ctx, &out_buf_len, obj, flags);
     if (!out_buf) {
-        js_std_dump_error(ctx);
+        qjsc_dump_error(ctx);
         exit(1);
     }
 
@@ -221,6 +261,51 @@
     pstrcpy(cname, cname_size, cname1);
 }
 
+static uint8_t *js_load_file(JSContext *ctx, size_t *pbuf_len, const char *filename)
+{
+    FILE *f;
+    uint8_t *buf;
+    size_t buf_len;
+    long lret;
+
+    f = fopen(filename, "rb");
+    if (!f)
+        return NULL;
+    if (fseek(f, 0, SEEK_END) < 0)
+        goto fail;
+    lret = ftell(f);
+    if (lret < 0)
+        goto fail;
+    /* XXX: on Linux, ftell() return LONG_MAX for directories */
+    if (lret == LONG_MAX) {
+        errno = EISDIR;
+        goto fail;
+    }
+    buf_len = lret;
+    if (fseek(f, 0, SEEK_SET) < 0)
+        goto fail;
+    if (ctx)
+        buf = js_malloc(ctx, buf_len + 1);
+    else
+        buf = malloc(buf_len + 1);
+    if (!buf)
+        goto fail;
+    if (fread(buf, 1, buf_len, f) != buf_len) {
+        errno = EIO;
+        if (ctx)
+            js_free(ctx, buf);
+        else
+            free(buf);
+    fail:
+        fclose(f);
+        return NULL;
+    }
+    buf[buf_len] = '\0';
+    fclose(f);
+    *pbuf_len = buf_len;
+    return buf;
+}
+
 JSModuleDef *jsc_module_loader(JSContext *ctx,
                               const char *module_name, void *opaque)
 {
@@ -298,7 +383,7 @@
         eval_flags |= JS_EVAL_TYPE_GLOBAL;
     obj = JS_Eval(ctx, (const char *)buf, buf_len, script_name ? script_name : filename, eval_flags);
     if (JS_IsException(obj)) {
-        js_std_dump_error(ctx);
+        qjsc_dump_error(ctx);
         exit(1);
     }
     js_free(ctx, buf);

@wargio
Copy link
Author

wargio commented Oct 22, 2024

Heey, it looks like my PR #592 XD

Oh, my bad. i did not see your PR. i patched this on our side after seeing a failure on cutter which builds with an older vs version

@saghul
Copy link
Contributor

saghul commented Oct 22, 2024

We use an atomic var to avoid TSan tripping.

@wargio
Copy link
Author

wargio commented Oct 22, 2024

@saghul i pushed some changes where it uses pthreads instead of atomics when not possible, otherwise nothing.

@saghul
Copy link
Contributor

saghul commented Oct 22, 2024

All Unix compilers we support have atomics already, so no need for a fallback there.

I made #613 to try and avoid the use of the atomic var altogether in libc, but I'm not 100% sure it's kosher.

@saghul
Copy link
Contributor

saghul commented Oct 22, 2024

and why you need to have quickjs-libc? even qjsc can be built without it with just a few edits.

I don't know how to answer this. The libc provides all operating system level functionality to the interpreter, without it the qjs cannot evel write a file.

Removing the libc is not one of this project's goals.

@saghul
Copy link
Contributor

saghul commented Oct 22, 2024

#592 landed, that should be enough now.

@saghul saghul closed this Oct 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants