6
6
#ifndef KRAKENBRIDGE_JS_CONTEXT_H
7
7
#define KRAKENBRIDGE_JS_CONTEXT_H
8
8
9
+ #include " js_context_macros.h"
9
10
#include " kraken_foundation.h"
11
+ #include " qjs_patch.h"
10
12
#include < memory>
11
- #include < unordered_map>
12
- #include < quickjs/quickjs.h>
13
13
#include < quickjs/list.h>
14
- #include " js_context_macros.h"
14
+ #include < quickjs/quickjs.h>
15
+ #include < unordered_map>
15
16
16
17
using QjsContext = JSContext;
17
18
using JSExceptionHandler = std::function<void (int32_t contextId, const char *message)>;
@@ -66,10 +67,10 @@ class JSContext {
66
67
bool handleException (JSValue *exc);
67
68
void drainPendingPromiseJobs ();
68
69
void defineGlobalProperty (const char *prop, JSValueConst value);
69
- uint8_t *dumpByteCode (const char * code, uint32_t codeLength, const char *sourceURL, size_t * bytecodeLength);
70
+ uint8_t *dumpByteCode (const char * code, uint32_t codeLength, const char *sourceURL, size_t * bytecodeLength);
70
71
71
72
std::chrono::time_point<std::chrono::system_clock> timeOrigin;
72
- std::unordered_map<std::string, void *> constructorMap;
73
+ std::unordered_map<std::string, void *> constructorMap;
73
74
74
75
int32_t uniqueId;
75
76
struct list_head node_job_list;
@@ -86,7 +87,6 @@ class JSContext {
86
87
static JSClassID kHostExoticObjectClassId ;
87
88
88
89
private:
89
-
90
90
static void promiseRejectTracker (QjsContext *ctx, JSValueConst promise, JSValueConst reason, JS_BOOL is_handled,
91
91
void *opaque);
92
92
void dispatchGlobalErrorEvent (JSValueConst error);
@@ -104,26 +104,46 @@ class JSContext {
104
104
WindowInstance *m_window{nullptr };
105
105
};
106
106
107
+ // The read object's method or properties via Proxy, we should redirect this_val from Proxy into target property of
108
+ // proxy object.
109
+ static JSValue handleCallThisOnProxy (QjsContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int data_len,
110
+ JSValueConst *data) {
111
+ JSValue f = data[0 ];
112
+ JSValue result;
113
+ if (JS_IsProxy (this_val)) {
114
+ result = JS_Call (ctx, f, JS_GetProxyTarget (this_val), argc, argv);
115
+ } else {
116
+ result = JS_Call (ctx, f, this_val, argc, argv);
117
+ }
118
+ return result;
119
+ }
120
+
107
121
class ObjectProperty {
108
122
KRAKEN_DISALLOW_COPY_ASSIGN_AND_MOVE (ObjectProperty);
109
123
110
124
public:
111
125
ObjectProperty () = delete ;
112
- explicit ObjectProperty (JSContext *context, JSValueConst thisObject, const char *property,
113
- JSCFunction getterFunction, JSCFunction setterFunction) {
126
+ explicit ObjectProperty (JSContext *context, JSValueConst thisObject, const char *property, JSCFunction getterFunction,
127
+ JSCFunction setterFunction) {
114
128
JSValue ge = JS_NewCFunction (context->ctx (), getterFunction, " get" , 0 );
115
129
JSValue se = JS_NewCFunction (context->ctx (), setterFunction, " set" , 1 );
130
+
131
+ JSValue pge = JS_NewCFunctionData (context->ctx (), handleCallThisOnProxy, 0 , 0 , 1 , &ge);
132
+ JSValue pse = JS_NewCFunctionData (context->ctx (), handleCallThisOnProxy, 1 , 0 , 1 , &se);
133
+
134
+ JS_FreeValue (context->ctx (), ge);
135
+ JS_FreeValue (context->ctx (), se);
136
+
116
137
JSAtom key = JS_NewAtom (context->ctx (), property);
117
- JS_DefinePropertyGetSet (context->ctx (), thisObject, key, ge, se,
118
- JS_PROP_C_W_E);
138
+ JS_DefinePropertyGetSet (context->ctx (), thisObject, key, pge, pse, JS_PROP_C_W_E);
119
139
JS_FreeAtom (context->ctx (), key);
120
140
};
121
141
explicit ObjectProperty (JSContext *context, JSValueConst thisObject, const char *property,
122
142
JSCFunction getterFunction) {
123
143
JSValue get = JS_NewCFunction (context->ctx (), getterFunction, " get" , 0 );
124
144
JSAtom key = JS_NewAtom (context->ctx (), property);
125
145
JS_DefineProperty (context->ctx (), thisObject, key, JS_UNDEFINED, get, JS_UNDEFINED,
126
- JS_PROP_HAS_CONFIGURABLE | JS_PROP_ENUMERABLE | JS_PROP_HAS_GET);
146
+ JS_PROP_HAS_CONFIGURABLE | JS_PROP_ENUMERABLE | JS_PROP_HAS_GET);
127
147
JS_FreeAtom (context->ctx (), key);
128
148
}
129
149
};
@@ -133,26 +153,29 @@ class ObjectFunction {
133
153
134
154
public:
135
155
ObjectFunction () = delete ;
136
- explicit ObjectFunction (JSContext *context, JSValueConst thisObject, const char *functionName,
137
- JSCFunction function, int argc) {
156
+ explicit ObjectFunction (JSContext *context, JSValueConst thisObject, const char *functionName, JSCFunction function,
157
+ int argc) {
138
158
JSValue f = JS_NewCFunction (context->ctx (), function, functionName, argc);
159
+ JSValue pf = JS_NewCFunctionData (context->ctx (), handleCallThisOnProxy, argc, 0 , 1 , &f);
139
160
JSAtom key = JS_NewAtom (context->ctx (), functionName);
140
161
162
+ JS_FreeValue (context->ctx (), f);
163
+
141
164
// We should avoid overwrite exist property functions.
142
165
#ifdef DEBUG
143
- assert_m (JS_HasProperty (context->ctx (), thisObject, key) == 0 , (std::string (" Found exist function property: " ) + std::string (functionName)).c_str ());
166
+ assert_m (JS_HasProperty (context->ctx (), thisObject, key) == 0 ,
167
+ (std::string (" Found exist function property: " ) + std::string (functionName)).c_str ());
144
168
#endif
145
169
146
- JS_DefinePropertyValue (context->ctx (), thisObject, key, f,
147
- JS_PROP_ENUMERABLE);
170
+ JS_DefinePropertyValue (context->ctx (), thisObject, key, pf, JS_PROP_ENUMERABLE);
148
171
JS_FreeAtom (context->ctx (), key);
149
172
};
150
173
};
151
174
152
175
class JSValueHolder {
153
176
public:
154
177
JSValueHolder () = delete ;
155
- explicit JSValueHolder (QjsContext *ctx, JSValue value): m_value(value), m_ctx(ctx) {};
178
+ explicit JSValueHolder (QjsContext *ctx, JSValue value) : m_value(value), m_ctx(ctx){};
156
179
~JSValueHolder () {
157
180
JS_FreeValue (m_ctx, m_value);
158
181
}
@@ -162,7 +185,10 @@ class JSValueHolder {
162
185
}
163
186
m_value = JS_DupValue (m_ctx, value);
164
187
};
165
- inline JSValue value () const { return JS_DupValue (m_ctx, m_value); }
188
+ inline JSValue value () const {
189
+ return JS_DupValue (m_ctx, m_value);
190
+ }
191
+
166
192
private:
167
193
QjsContext *m_ctx{nullptr };
168
194
JSValue m_value{JS_NULL};
@@ -184,7 +210,6 @@ void arraySpliceValue(QjsContext *ctx, JSValue array, uint32_t start, uint32_t d
184
210
void arraySpliceValue (QjsContext *ctx, JSValue array, uint32_t start, uint32_t deleteCount, JSValue replacedValue);
185
211
JSValue objectGetKeys (QjsContext *ctx, JSValue obj);
186
212
187
-
188
213
} // namespace kraken::binding::qjs
189
214
190
215
#endif // KRAKENBRIDGE_JS_CONTEXT_H
0 commit comments