From 58ac957eee57e301ed0cc52b5de5495a7e1c1827 Mon Sep 17 00:00:00 2001
From: landerlyoung <landerlyoung@gmail.com>
Date: Tue, 6 Apr 2021 16:18:13 +0800
Subject: [PATCH] Add new APIs for ScriptX based on QuickJs version
 "2021-03-27" Changes: 1. add JS_StrictEqual 2. add JS_NewWeakRef 3. add
 JS_GetWeakRef

WeakRef is implemented based on WeakSet
---
 quickjs.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 quickjs.h |  5 +++++
 2 files changed, 51 insertions(+)

diff --git a/quickjs.c b/quickjs.c
index 48aeffc..89eba07 100644
--- a/quickjs.c
+++ b/quickjs.c
@@ -1111,6 +1111,10 @@ typedef enum JSStrictEqModeEnum {
 static BOOL js_strict_eq2(JSContext *ctx, JSValue op1, JSValue op2,
                           JSStrictEqModeEnum eq_mode);
 static BOOL js_strict_eq(JSContext *ctx, JSValue op1, JSValue op2);
+int JS_StrictEqual(JSContext *ctx, JSValueConst op1, JSValueConst op2)
+{
+    return js_strict_eq(ctx, JS_DupValue(ctx, op1), JS_DupValue(ctx, op2));
+}
 static BOOL js_same_value(JSContext *ctx, JSValueConst op1, JSValueConst op2);
 static BOOL js_same_value_zero(JSContext *ctx, JSValueConst op1, JSValueConst op2);
 static JSValue JS_ToObject(JSContext *ctx, JSValueConst val);
@@ -54034,3 +54038,45 @@ void JS_AddIntrinsicTypedArrays(JSContext *ctx)
     JS_AddIntrinsicAtomics(ctx);
 #endif
 }
+
+/************* WeakRef ***********/
+
+JSValue JS_NewWeakRef(JSContext* ctx, JSValueConst v)
+{
+    if (JS_IsObject(v)) {
+        JSValue map = js_map_constructor(ctx, JS_UNDEFINED, 0, NULL, MAGIC_SET | MAGIC_WEAK);
+        if (JS_IsException(map)) return JS_EXCEPTION;
+        // check
+        JSValue ret = js_map_set(ctx, map, 1, &v, MAGIC_SET | MAGIC_WEAK);
+        if (JS_IsException(ret)) return JS_EXCEPTION;
+        JS_FreeValue(ctx, ret);
+        return map;
+    } else {
+        return JS_DupValue(ctx, v);
+    }
+}
+
+static JSValue js_map_get_first_key(JSContext *ctx, JSValueConst this_val)
+{
+    JSMapState *s = JS_GetOpaque2(ctx, this_val, JS_CLASS_WEAKSET);
+    JSMapRecord *mr;
+    JSValueConst key = JS_UNDEFINED;
+    struct list_head *el;
+
+    if (!s) return JS_EXCEPTION;
+    el = s->records.next;
+    if (el != &(s->records)) {
+        mr = list_entry(el, JSMapRecord, link);
+        key = mr->key;
+    }
+    return JS_DupValue(ctx, key);
+}
+
+JSValue JS_GetWeakRef(JSContext* ctx, JSValueConst w)
+{
+    if (JS_IsObject(w)) {
+        return js_map_get_first_key(ctx, w);
+    } else {
+        return JS_DupValue(ctx, w);
+    }
+}
diff --git a/quickjs.h b/quickjs.h
index d4a5cd3..6ffffa3 100644
--- a/quickjs.h
+++ b/quickjs.h
@@ -678,6 +678,11 @@ static inline JSValue JS_DupValueRT(JSRuntime *rt, JSValueConst v)
     return (JSValue)v;
 }
 
+#define QUICK_JS_HAS_SCRIPTX_PATCH
+JSValue JS_NewWeakRef(JSContext* ctx, JSValueConst v);
+JSValue JS_GetWeakRef(JSContext* ctx, JSValueConst w);
+int JS_StrictEqual(JSContext *ctx, JSValueConst op1, JSValueConst op2);
+
 int JS_ToBool(JSContext *ctx, JSValueConst val); /* return -1 for JS_EXCEPTION */
 int JS_ToInt32(JSContext *ctx, int32_t *pres, JSValueConst val);
 static inline int JS_ToUint32(JSContext *ctx, uint32_t *pres, JSValueConst val)
-- 
2.29.2

