-
Notifications
You must be signed in to change notification settings - Fork 53
Expand file tree
/
Copy pathunity_ext.c
More file actions
137 lines (120 loc) · 3.88 KB
/
Copy pathunity_ext.c
File metadata and controls
137 lines (120 loc) · 3.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/*
* The JSB_ and jsb_ shim com.reactunity.quickjs P/Invokes into.
*
* Vendored from unity-jsb (jsb_build/quickjs/unity_ext.c), MIT, Copyright (c) 2019
* huliangjie, and ported to quickjs-ng. See ../README.md for every change and why.
*/
JS_EXPORT JSValue jsb_crossbind_constructor(JSContext *ctx, JSValue new_target)
{
JSValue proto = JS_GetProperty(ctx, new_target, JS_ATOM_prototype);
if (!JS_IsException(proto))
{
JSValue val = JS_NewObjectProtoClass(ctx, proto, js_bridge_class_id);
JS_FreeValue(ctx, proto);
return val;
}
return proto;
}
/* ng's JS_SetOpaque returns -1 for anything that is not an object of a registered
class, where Bellard's wrote the pointer unconditionally. Unchecked, a failure
leaks the payload and hands C# a bridge object whose id reads back as 0. */
static JSValue jsb_attach_payload(JSContext *ctx, JSValue obj, int32_t type_id, int32_t value, size_t size)
{
JSPayload *sv = (JSPayload *)js_mallocz(ctx, sizeof(JSPayloadHeader) + size);
if (!sv)
{
JS_FreeValue(ctx, obj);
return JS_EXCEPTION; // js_mallocz already threw
}
sv->header.type_id = type_id;
sv->header.value = value;
if (JS_SetOpaque(obj, sv) < 0)
{
js_free(ctx, sv);
JS_FreeValue(ctx, obj);
return JS_ThrowInternalError(ctx, "cannot attach a bridge payload to this object");
}
return obj;
}
JS_EXPORT JSValue jsb_new_bridge_object(JSContext *ctx, JSValue proto, int32_t object_id)
{
JSValue obj = JS_NewObjectProtoClass(ctx, proto, js_bridge_class_id);
if (JS_IsException(obj))
{
return obj;
}
return jsb_attach_payload(ctx, obj, JS_BO_OBJECT, object_id, 0);
}
// for constructor new_target
JS_EXPORT JSValue JSB_NewBridgeClassObject(JSContext *ctx, JSValue new_target, int32_t object_id)
{
JSValue proto = JS_GetProperty(ctx, new_target, JS_ATOM_prototype);
if (!JS_IsException(proto))
{
JSValue obj = jsb_new_bridge_object(ctx, proto, object_id);
JS_FreeValue(ctx, proto);
return obj;
}
return proto;
}
JS_EXPORT JSValue jsb_new_bridge_value(JSContext *ctx, JSValue proto, int32_t size)
{
if (size < 0)
{
return JS_ThrowRangeError(ctx, "invalid bridge payload size: %d", (int)size);
}
JSValue obj = JS_NewObjectProtoClass(ctx, proto, js_bridge_class_id);
if (JS_IsException(obj))
{
return obj;
}
return jsb_attach_payload(ctx, obj, JS_BO_VALUE, size, (size_t)size);
}
JS_EXPORT JSValue JSB_NewBridgeClassValue(JSContext *ctx, JSValue new_target, int32_t size)
{
JSValue proto = JS_GetProperty(ctx, new_target, JS_ATOM_prototype);
if (!JS_IsException(proto))
{
JSValue obj = jsb_new_bridge_value(ctx, proto, size);
JS_FreeValue(ctx, proto);
return obj;
}
return proto;
}
JS_EXPORT JSPayloadHeader jsb_get_payload_header(JSContext *ctx, JSValue val)
{
JSPayloadHeader *sv = (JSPayloadHeader *)JS_GetOpaque(val, js_bridge_class_id);
if (sv)
{
return *sv;
}
return _null_payload;
}
JS_EXPORT JS_BOOL jsb_get_bytes(JSContext *ctx, JSValue val, int n, byte *v0)
{
JSPayload *sv = (JSPayload *)JS_GetOpaque(val, js_bridge_class_id);
if (sv && sv->header.type_id == JS_BO_VALUE && sv->header.value == sizeof(byte) * n)
{
byte *ptr = (byte *)&(sv->data[0]);
for (int i = 0; i < n; ++i)
{
*(v0 + i) = ptr[i];
}
return TRUE;
}
return FALSE;
}
JS_EXPORT JS_BOOL jsb_set_bytes(JSContext *ctx, JSValue val, int n, byte *v0)
{
JSPayload *sv = (JSPayload *)JS_GetOpaque(val, js_bridge_class_id);
if (sv && sv->header.type_id == JS_BO_VALUE && sv->header.value == sizeof(byte) * n)
{
byte *ptr = (byte *)&(sv->data[0]);
for (int i = 0; i < n; ++i)
{
ptr[i] = *(v0 + i);
}
return TRUE;
}
return FALSE;
}