1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "napi/native_api.h"
17 #include <cerrno>
18 #include <csetjmp>
19 #include <js_native_api.h>
20 #include <node_api.h>
21 #include <pthread.h>
22
23 #define PARAM_0 0
24 #define PARAM_1 1
25 #define PARAM_2 2
26 #define PARAM_UNNORMAL (-1)
27 #define ERRON_0 0
28 #define ONEVAL 1
29 #define MINUSONE (-1)
30 #define NO_ERR 0
31
subroutine(jmp_buf jumper)32 void subroutine(jmp_buf jumper) { longjmp(jumper, PARAM_1); }
33 void subroutine(jmp_buf);
Longjmp(napi_env env, napi_callback_info info)34 static napi_value Longjmp(napi_env env, napi_callback_info info)
35 {
36 napi_value result = nullptr;
37 int value = PARAM_0;
38 jmp_buf jumper;
39 errno = ERRON_0;
40 value = setjmp(jumper);
41 if (value != PARAM_0) {
42 napi_create_int32(env, PARAM_0, &result);
43 } else {
44 napi_create_int32(env, PARAM_UNNORMAL, &result);
45 subroutine(jumper);
46 }
47 return result;
48 }
49
_Longjmp(napi_env env, napi_callback_info info)50 static napi_value _Longjmp(napi_env env, napi_callback_info info)
51 {
52 int returnValue = PARAM_0;
53 errno = ERRON_0;
54 sigjmp_buf bufJmp;
55 _setjmp(bufJmp);
56 _longjmp(bufJmp, PARAM_0);
57 if (errno == PARAM_0) {
58 returnValue = ONEVAL;
59 }
60 napi_value result = nullptr;
61 napi_create_int32(env, returnValue, &result);
62 return result;
63 }
64
_Setjmp(napi_env env, napi_callback_info info)65 static napi_value _Setjmp(napi_env env, napi_callback_info info)
66 {
67 napi_value result = nullptr;
68 int valueFirst = PARAM_0;
69 int valueSecond = PARAM_0;
70 jmp_buf jmp;
71 if (valueFirst == PARAM_0) {
72 int setValue = _setjmp(jmp);
73 napi_create_int32(env, setValue, &result);
74 return result;
75 } else {
76 int setValue = _setjmp(jmp);
77 if (setValue == PARAM_0) {
78 _longjmp(jmp, valueSecond);
79 }
80 napi_create_int32(env, setValue, &result);
81 return result;
82 }
83 }
84
sigThread(void *args)85 void *sigThread(void *args)
86 {
87 sigjmp_buf jmpbuf;
88 sigsetjmp(jmpbuf, PARAM_1);
89 siglongjmp(jmpbuf, PARAM_1);
90 return nullptr;
91 }
92
SigLongJmp(napi_env env, napi_callback_info info)93 static napi_value SigLongJmp(napi_env env, napi_callback_info info)
94 {
95 pthread_t tid = PARAM_0;
96 pthread_create(&tid, nullptr, sigThread, nullptr);
97 pthread_detach(tid);
98 napi_value result = nullptr;
99 napi_create_int32(env, NO_ERR, &result);
100 return result;
101 }
102
SetJmp(napi_env env, napi_callback_info info)103 static napi_value SetJmp(napi_env env, napi_callback_info info)
104 {
105 napi_value result = nullptr;
106 jmp_buf jb;
107 int ret = setjmp(jb);
108 napi_create_int32(env, ret, &result);
109 return result;
110 }
111
SigSetJmp(napi_env env, napi_callback_info info)112 static napi_value SigSetJmp(napi_env env, napi_callback_info info)
113 {
114 napi_value result = nullptr;
115 sigjmp_buf sjb;
116 int ret = sigsetjmp(sjb, PARAM_1);
117 napi_create_int32(env, ret, &result);
118 return result;
119 }
120
121 EXTERN_C_START
Init(napi_env env, napi_value exports)122 static napi_value Init(napi_env env, napi_value exports)
123 {
124 napi_property_descriptor desc[] = {
125 {"longjmp", nullptr, Longjmp, nullptr, nullptr, nullptr, napi_default, nullptr},
126 {"_longjmp", nullptr, _Longjmp, nullptr, nullptr, nullptr, napi_default, nullptr},
127 {"_setjmp", nullptr, _Setjmp, nullptr, nullptr, nullptr, napi_default, nullptr},
128 {"setJmp", nullptr, SetJmp, nullptr, nullptr, nullptr, napi_default, nullptr},
129 {"sigLongJmp", nullptr, SigLongJmp, nullptr, nullptr, nullptr, napi_default, nullptr},
130 {"sigSetJmp", nullptr, SigSetJmp, nullptr, nullptr, nullptr, napi_default, nullptr},
131 };
132 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
133 return exports;
134 }
135 EXTERN_C_END
136
137 static napi_module demoModule = {
138 .nm_version = 1,
139 .nm_flags = 0,
140 .nm_filename = nullptr,
141 .nm_register_func = Init,
142 .nm_modname = "setjmp",
143 .nm_priv = ((void *)0),
144 .reserved = {0},
145 };
146
RegisterEntryModule(void)147 extern "C" __attribute__((constructor)) void RegisterEntryModule(void) { napi_module_register(&demoModule); }
148