1 /*
2  * Copyright (c) 2022 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 <cfenv>
18 #include <js_native_api_types.h>
19 
20 #define PARAM_0 0
21 #define PARAM_1 1
22 #define PARAM_2 2
23 #define PARAM_4 4
24 #define PARAM_8 8
25 #define PARAM_16 16
26 #define MPARAM_1 (-1)
27 
FeTestExcept(napi_env env, napi_callback_info info)28 static napi_value FeTestExcept(napi_env env, napi_callback_info info)
29 {
30     size_t argc = PARAM_1;
31     napi_value args[1] = {nullptr};
32     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
33     int firstParam;
34     napi_get_value_int32(env, args[0], &firstParam);
35     int backParam = fetestexcept(firstParam);
36     napi_value result;
37     napi_create_int32(env, backParam, &result);
38     return result;
39 }
40 
FeUpdateEnv(napi_env env, napi_callback_info info)41 static napi_value FeUpdateEnv(napi_env env, napi_callback_info info)
42 {
43     int backParam;
44     const fenv_t *envp;
45     backParam = feupdateenv(envp);
46     napi_value result = nullptr;
47     napi_create_int32(env, backParam, &result);
48     return result;
49 }
50 
FeSetRound(napi_env env, napi_callback_info info)51 static napi_value FeSetRound(napi_env env, napi_callback_info info)
52 {
53     size_t argc = PARAM_1;
54     napi_value args[1] = {nullptr};
55     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
56     int backParam, rounding_mode;
57     napi_get_value_int32(env, args[0], &rounding_mode);
58     backParam = fesetround(rounding_mode);
59     napi_value result = nullptr;
60     napi_create_int32(env, backParam, &result);
61     return result;
62 }
63 
FeSetExceptFlag(napi_env env, napi_callback_info info)64 static napi_value FeSetExceptFlag(napi_env env, napi_callback_info info)
65 {
66     size_t argc = PARAM_1;
67     napi_value args[1] = {nullptr};
68     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
69     int backParam, excepts;
70     napi_get_value_int32(env, args[0], &excepts);
71     const fexcept_t flagp = PARAM_0;
72     backParam = fesetexceptflag(&flagp, excepts);
73     napi_value result = nullptr;
74     napi_create_int32(env, backParam, &result);
75     return result;
76 }
77 
FeSetEnv(napi_env env, napi_callback_info info)78 static napi_value FeSetEnv(napi_env env, napi_callback_info info)
79 {
80     int backParam;
81     const fenv_t *envp;
82     backParam = fesetenv(envp);
83     feupdateenv(envp);
84     napi_value result = nullptr;
85     napi_create_int32(env, backParam, &result);
86     return result;
87 }
88 
FeRaiseExcept(napi_env env, napi_callback_info info)89 static napi_value FeRaiseExcept(napi_env env, napi_callback_info info)
90 {
91     size_t argc = PARAM_1;
92     napi_value args[1] = {nullptr};
93     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
94     int backParam, excepts;
95     napi_get_value_int32(env, args[0], &excepts);
96     backParam = feraiseexcept(excepts);
97     napi_value result = nullptr;
98     napi_create_int32(env, backParam, &result);
99     return result;
100 }
101 
FeHoldExcept(napi_env env, napi_callback_info info)102 static napi_value FeHoldExcept(napi_env env, napi_callback_info info)
103 {
104     int backParam;
105     fenv_t envp;
106     backParam = feholdexcept(&envp);
107     feupdateenv(&envp);
108     napi_value result = nullptr;
109     napi_create_int32(env, backParam, &result);
110     return result;
111 }
112 
FeGetRound(napi_env env, napi_callback_info info)113 static napi_value FeGetRound(napi_env env, napi_callback_info info)
114 {
115     int backParam;
116     backParam = fegetround();
117     napi_value result = nullptr;
118     napi_create_int32(env, backParam, &result);
119     return result;
120 }
121 
FeGetExceptFlag(napi_env env, napi_callback_info info)122 static napi_value FeGetExceptFlag(napi_env env, napi_callback_info info)
123 {
124     size_t argc = PARAM_1;
125     napi_value args[1] = {nullptr};
126     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
127     int backParam, excepts;
128     napi_get_value_int32(env, args[0], &excepts);
129     fexcept_t *flagp = nullptr;
130     backParam = fegetexceptflag(flagp, excepts);
131     napi_value result = nullptr;
132     napi_create_int32(env, backParam, &result);
133     return result;
134 }
135 
FeGetEnv(napi_env env, napi_callback_info info)136 static napi_value FeGetEnv(napi_env env, napi_callback_info info)
137 {
138     int backParam;
139     fenv_t fenv;
140     backParam = fegetenv(&fenv);
141     feupdateenv(&fenv);
142     napi_value result = nullptr;
143     napi_create_int32(env, backParam, &result);
144     return result;
145 }
146 
FeClearExcept(napi_env env, napi_callback_info info)147 static napi_value FeClearExcept(napi_env env, napi_callback_info info)
148 {
149     size_t argc = PARAM_1;
150     napi_value args[1] = {nullptr};
151     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
152     int backParam, list;
153     napi_get_value_int32(env, args[0], &list);
154     switch (list) {
155     case PARAM_0:
156         backParam = feclearexcept(list);
157         break;
158     case PARAM_1:
159         backParam = feclearexcept(list);
160         break;
161     case PARAM_2:
162         backParam = feclearexcept(list);
163         break;
164     case PARAM_4:
165         backParam = feclearexcept(list);
166         break;
167     case PARAM_8:
168         backParam = feclearexcept(list);
169         break;
170     case PARAM_16:
171         backParam = feclearexcept(list);
172         break;
173     case MPARAM_1:
174         backParam = feclearexcept(list);
175         break;
176     default:
177         backParam = feclearexcept(list);
178     }
179     napi_value result = nullptr;
180     napi_create_int32(env, backParam, &result);
181     return result;
182 }
183 
184 EXTERN_C_START
Init(napi_env env, napi_value exports)185 static napi_value Init(napi_env env, napi_value exports)
186 {
187     napi_property_descriptor desc[] = {
188         {"fetestexcept", nullptr, FeTestExcept, nullptr, nullptr, nullptr, napi_default, nullptr},
189         {"feupdateenv", nullptr, FeUpdateEnv, nullptr, nullptr, nullptr, napi_default, nullptr},
190         {"fesetround", nullptr, FeSetRound, nullptr, nullptr, nullptr, napi_default, nullptr},
191         {"fesetexceptflag", nullptr, FeSetExceptFlag, nullptr, nullptr, nullptr, napi_default, nullptr},
192         {"fesetenv", nullptr, FeSetEnv, nullptr, nullptr, nullptr, napi_default, nullptr},
193         {"fegetround", nullptr, FeGetRound, nullptr, nullptr, nullptr, napi_default, nullptr},
194         {"feraiseexcept", nullptr, FeRaiseExcept, nullptr, nullptr, nullptr, napi_default, nullptr},
195         {"fegetexceptflag", nullptr, FeGetExceptFlag, nullptr, nullptr, nullptr, napi_default, nullptr},
196         {"feholdexcept", nullptr, FeHoldExcept, nullptr, nullptr, nullptr, napi_default, nullptr},
197         {"fegetenv", nullptr, FeGetEnv, nullptr, nullptr, nullptr, napi_default, nullptr},
198         {"feclearexcept", nullptr, FeClearExcept, nullptr, nullptr, nullptr, napi_default, nullptr},
199     };
200     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
201     return exports;
202 }
203 EXTERN_C_END
204 
205 static napi_module demoModule = {
206     .nm_version = 1,
207     .nm_flags = 0,
208     .nm_filename = nullptr,
209     .nm_register_func = Init,
210     .nm_modname = "libfenvndk",
211     .nm_priv = ((void *)0),
212     .reserved = {0},
213 };
214 
RegisterModule(void)215 extern "C" __attribute__((constructor)) void RegisterModule(void) { napi_module_register(&demoModule); }
216