@@ -25,6 +25,27 @@ static JSValue cfuncdata_callback(JSContext *ctx, JSValueConst this_val,
2525 return JS_ThrowTypeError (ctx , "from cfuncdata" );
2626}
2727
28+ static JSValue cclosure_callback (JSContext * ctx , JSValueConst this_val ,
29+ int argc , JSValueConst * argv ,
30+ int magic , JSValueConst * func_data )
31+ {
32+ return JS_ThrowTypeError (ctx , "from cclosure" );
33+ }
34+
35+ static JSValue cclosure_callback (JSContext * ctx , JSValueConst this_val ,
36+ int argc , JSValueConst * argv ,
37+ int magic , JSValueConst * func_data )
38+ {
39+ return JS_ThrowTypeError (ctx , "from cclosure" );
40+ }
41+
42+ static bool closure_finalized = false;
43+ static void cclosure_opaque_finalize (void * opaque )
44+ {
45+ if ((intptr_t )opaque = 12 )
46+ closure_finalized = true;
47+ }
48+
2849static void cfunctions (void )
2950{
3051 uint32_t length ;
@@ -37,6 +58,9 @@ static void cfunctions(void)
3758 JSValue cfuncdata =
3859 JS_NewCFunctionData2 (ctx , cfuncdata_callback , "cfuncdata" ,
3960 /*length*/ 1337 , /*magic*/ 0 , /*data_len*/ 0 , NULL );
61+ JSValue cclosure =
62+ JS_NewCClosure (ctx , cclosure_callback , "cclosure" , cclosure_opaque_finalize ,
63+ /*length*/ 0xC0DE , /*magic*/ 11 , /*opaque*/ (void * )12 );
4064 JSValue global = JS_GetGlobalObject (ctx );
4165 JS_SetPropertyStr (ctx , global , "cfunc" , cfunc );
4266 JS_SetPropertyStr (ctx , global , "cfuncdata" , cfuncdata );
@@ -70,6 +94,20 @@ static void cfunctions(void)
7094 assert (0 == JS_ToUint32 (ctx , & length , ret ));
7195 assert (length == 1337 );
7296
97+ ret = eval (ctx , "cclosure.name" );
98+ assert (!JS_IsException (ret ));
99+ assert (JS_IsString (ret ));
100+ s = JS_ToCString (ctx , ret );
101+ JS_FreeValue (ctx , ret );
102+ assert (s );
103+ assert (!strcmp (s , "cclosure" ));
104+ JS_FreeCString (ctx , s );
105+ ret = eval (ctx , "cclosure.length" );
106+ assert (!JS_IsException (ret ));
107+ assert (JS_IsNumber (ret ));
108+ assert (0 == JS_ToUint32 (ctx , & length , ret ));
109+ assert (length == 0xC0DE );
110+
73111 ret = eval (ctx , "cfunc()" );
74112 assert (JS_IsException (ret ));
75113 ret = JS_GetException (ctx );
@@ -104,8 +142,27 @@ static void cfunctions(void)
104142 assert (!strcmp (s , "TypeError: from cfuncdata" ));
105143 JS_FreeCString (ctx , s );
106144
145+ ret = eval (ctx , "cclosure()" );
146+ assert (JS_IsException (ret ));
147+ ret = JS_GetException (ctx );
148+ assert (JS_IsError (ret ));
149+ stack = JS_GetPropertyStr (ctx , ret , "stack" );
150+ assert (JS_IsString (stack ));
151+ s = JS_ToCString (ctx , stack );
152+ JS_FreeValue (ctx , stack );
153+ assert (s );
154+ assert (!strcmp (s , " at cclosure (native)\n at <eval> (<input>:1:1)\n" ));
155+ JS_FreeCString (ctx , s );
156+ s = JS_ToCString (ctx , ret );
157+ JS_FreeValue (ctx , ret );
158+ assert (s );
159+ assert (!strcmp (s , "TypeError: from cclosure" ));
160+ JS_FreeCString (ctx , s );
161+
107162 JS_FreeContext (ctx );
108163 JS_FreeRuntime (rt );
164+
165+ assert (closure_finalized );
109166}
110167
111168#define MAX_TIME 10
0 commit comments