1use bitflags::bitflags;
2use crate::ctx::DukContext;
3use super::*;
4
5bitflags! {
6 pub struct DukCompileFlags: u32 {
7 const DUK_COMPILE_EVAL = (1 << 3); const DUK_COMPILE_FUNCTION = (1 << 4); const DUK_COMPILE_STRICT = (1 << 5); const DUK_COMPILE_SHEBANG = (1 << 6); const DUK_COMPILE_SAFE = (1 << 7); const DUK_COMPILE_NORESULT = (1 << 8); const DUK_COMPILE_NOSOURCE = (1 << 9); const DUK_COMPILE_STRLEN = (1 << 10); const DUK_COMPILE_NOFILENAME = (1 << 11); const DUK_COMPILE_FUNCEXPR = (1 << 12); }
18}
19
20bitflags! {
21 pub struct DukDefpropFlags: u32 {
22 const DUK_DEFPROP_WRITABLE = (1 << 0); const DUK_DEFPROP_ENUMERABLE = (1 << 1); const DUK_DEFPROP_CONFIGURABLE = (1 << 2); const DUK_DEFPROP_HAVE_WRITABLE = (1 << 3); const DUK_DEFPROP_HAVE_ENUMERABLE = (1 << 4); const DUK_DEFPROP_HAVE_CONFIGURABLE = (1 << 5); const DUK_DEFPROP_HAVE_VALUE = (1 << 6); const DUK_DEFPROP_HAVE_GETTER = (1 << 7); const DUK_DEFPROP_HAVE_SETTER = (1 << 8); const DUK_DEFPROP_FORCE = (1 << 9); }
33}
34
35bitflags! {
36 pub struct DukEnumFlags: u32 {
37 const DUK_ENUM_INCLUDE_NONENUMERABLE = (1 << 0); const DUK_ENUM_INCLUDE_HIDDEN = (1 << 1); const DUK_ENUM_INCLUDE_SYMBOLS = (1 << 2); const DUK_ENUM_EXCLUDE_STRINGS = (1 << 3); const DUK_ENUM_OWN_PROPERTIES_ONLY = (1 << 4); const DUK_ENUM_ARRAY_INDICES_ONLY = (1 << 5); const DUK_ENUM_SORT_ARRAY_INDICES = (1 << 6); const DUK_ENUM_NO_PROXY_BEHAVIOR = (1 << 7); }
46}
47
48bitflags! {
49 pub struct DukBufFlags: u32 {
50 const DUK_BUF_FLAG_DYNAMIC = (1 << 0); const DUK_BUF_FLAG_EXTERNAL = (1 << 1); const DUK_BUF_FLAG_NOZERO = (1 << 2); }
54}
55
56
57bitflags! {
58 pub struct DukGcFlags: u32 {
59 const NONE = 0; const DUK_GC_COMPACT = (1 << 0); }
62}
63
64bitflags! {
65 pub struct DukThreadFlags: u32 {
66 const DUK_THREAD_NEW_GLOBAL_ENV = (1 << 0); }
68}
69
70#[derive(Debug, PartialEq, Eq, Clone, Copy)]
71#[repr(i32)]
72#[allow(non_camel_case_types, dead_code)]
73pub enum DukType {
74 DUK_TYPE_NONE = 0, DUK_TYPE_UNDEFINED = 1, DUK_TYPE_NULL = 2, DUK_TYPE_BOOLEAN = 3, DUK_TYPE_NUMBER = 4, DUK_TYPE_STRING = 5, DUK_TYPE_OBJECT = 6, DUK_TYPE_BUFFER = 7, DUK_TYPE_POINTER = 8, DUK_TYPE_LIGHTFUNC = 9, }
85
86impl From<i32> for DukType {
87 fn from(e: i32) -> Self {
88 if e >= DukType::DUK_TYPE_NONE as i32 && e <= DukType::DUK_TYPE_LIGHTFUNC as i32 {
89 unsafe { std::mem::transmute(e) }
90 } else {
91 panic!("incorrect DukType value: {}", e); }
93 }
94}
95
96
97#[allow(non_camel_case_types)]
98pub enum duk_context {}
99
100#[allow(non_camel_case_types)]
101pub type duk_fatal_function = extern "C" fn (udata: *mut c_void, msg: *const c_char);
102#[allow(non_camel_case_types)]
103pub type duk_alloc_function = extern "C" fn (udata: *mut c_void, size: usize) -> *mut c_void;
104#[allow(non_camel_case_types)]
105pub type duk_realloc_function = extern "C" fn (udata: *mut c_void, ptr: *mut c_void, size: usize) -> *mut c_void;
106#[allow(non_camel_case_types)]
107pub type duk_free_function = extern "C" fn (udata: *mut c_void, ptr: *mut c_void);
108
109#[allow(non_camel_case_types)]
110pub type duk_c_function = extern "C" fn(ctx: *mut duk_context) -> i32;
111
112#[allow(non_camel_case_types)]
113pub type duk_console_function = extern "C" fn(udata: *mut c_void, fun: u32, msg: *const c_char, msg_len: usize);
114
115#[allow(dead_code)]
116extern "C" {
117 pub fn duk_api_version() -> u32;
118 pub fn duk_api_git_describe() -> *const c_char;
119 pub fn duk_api_git_commit() -> *const c_char;
120 pub fn duk_api_git_branch() -> *const c_char;
121 pub fn duk_api_get_heap_udata(ctx: *mut duk_context) -> *mut c_void;
122 pub fn duk_api_console_init(ctx: *mut duk_context, console_func: Option<duk_console_function>);
123
124 pub fn duk_create_heap(alloc_func: Option<duk_alloc_function>,
125 realloc_func: Option<duk_realloc_function>,
126 free_func: Option<duk_free_function>,
127 heap_udata: *mut c_void,
128 fatal_handler: Option<duk_fatal_function>)
129 -> *mut duk_context;
130
131 pub fn duk_destroy_heap(ctx: *mut duk_context);
132
133 pub fn duk_eval_raw(ctx: *mut duk_context, code: *const c_char, len: usize, flags: u32) -> i32;
134 pub fn duk_compile_raw(ctx: *mut duk_context, code: *const c_char, len: usize, flags: u32) -> i32;
135
136 pub fn duk_call(ctx: *mut duk_context, nargs: i32);
137 pub fn duk_call_method(ctx: *mut duk_context, nargs: i32);
138 pub fn duk_call_prop(ctx: *mut duk_context, obj_index: i32, nargs: i32);
139 pub fn duk_pcall(ctx: *mut duk_context, nargs: i32) -> i32;
140 pub fn duk_pcall_method(ctx: *mut duk_context, nargs: i32) -> i32;
141 pub fn duk_pcall_prop(ctx: *mut duk_context, obj_index: i32, nargs: i32) -> i32;
142
143 pub fn duk_safe_to_lstring(ctx: *mut duk_context,
144 index: i32,
145 out_len: *mut usize)
146 -> *const c_char;
147
148 pub fn duk_get_top(ctx: *mut duk_context) -> i32;
149 pub fn duk_normalize_index(ctx: *mut duk_context, index: i32) -> i32;
150 pub fn duk_require_normalize_index(ctx: *mut duk_context, index: i32) -> i32;
151 pub fn duk_check_stack(ctx: *mut duk_context, extra: i32) -> bool;
152 pub fn duk_check_stack_top(ctx: *mut duk_context, top: i32) -> bool;
153
154 pub fn duk_dup(ctx: *mut duk_context, index: i32);
155 pub fn duk_remove(ctx: *mut duk_context, index: i32);
156
157 pub fn duk_pop(ctx: *mut duk_context);
158 pub fn duk_pop_1(ctx: *mut duk_context);
159 pub fn duk_pop_2(ctx: *mut duk_context);
160 pub fn duk_pop_n(ctx: *mut duk_context, n: i32);
161 pub fn duk_swap(ctx: *mut duk_context, idx1: i32, idx2: i32);
162 pub fn duk_xcopymove_raw(to_ctx: *mut duk_context, from_ctx: *mut duk_context, count: i32, is_copy: i32);
163
164 pub fn duk_push_null(ctx: *mut duk_context);
165 pub fn duk_push_undefined(ctx: *mut duk_context);
166 pub fn duk_push_boolean(ctx: *mut duk_context, val: i32);
167 pub fn duk_push_int(ctx: *mut duk_context, val: i32);
168 pub fn duk_push_uint(ctx: *mut duk_context, val: u32);
169 pub fn duk_push_number(ctx: *mut duk_context, val: f64);
170 pub fn duk_push_lstring(ctx: *mut duk_context, str: *const c_char, len: usize) -> *const c_char;
171 pub fn duk_push_array(ctx: *mut duk_context) -> i32;
172 pub fn duk_push_object(ctx: *mut duk_context) -> i32;
173 pub fn duk_push_pointer(ctx: *mut duk_context, p: *mut c_void);
174 pub fn duk_push_buffer_raw(ctx: *mut duk_context, len: usize, dynamic: u32) -> *mut c_void;
175 pub fn duk_push_c_function(ctx: *mut duk_context, func: Option<duk_c_function>, nargs: i32) -> i32;
176 pub fn duk_push_c_lightfunc(ctx: *mut duk_context, func: Option<duk_c_function>, nargs: i32, length: i32, magic: i32);
177 pub fn duk_push_current_function(ctx: *mut duk_context);
178 pub fn duk_push_this(ctx: *mut duk_context);
179 pub fn duk_push_thread_raw(ctx: *mut duk_context, flags: u32) -> i32;
180
181 pub fn duk_config_buffer(ctx: *mut duk_context, index: i32, ptr: *mut c_void, len: usize);
182
183 pub fn duk_get_type(ctx: *mut duk_context, index: i32) -> i32;
184 pub fn duk_get_length(ctx: *mut duk_context, index: i32) -> usize;
185 pub fn duk_get_context(ctx: *mut duk_context, index: i32) -> *mut duk_context;
186 pub fn duk_get_context_default(ctx: *mut duk_context, index: i32, def_value: *mut duk_context) -> *mut duk_context;
187 pub fn duk_samevalue(ctx: *mut duk_context, index1: i32, index2: i32) -> i32;
188
189 pub fn duk_is_array(ctx: *mut duk_context, index: i32) -> i32;
190 pub fn duk_is_object(ctx: *mut duk_context, index: i32) -> i32;
191 pub fn duk_is_number(ctx: *mut duk_context, index: i32) -> i32;
192 pub fn duk_is_string(ctx: *mut duk_context, index: i32) -> i32;
193 pub fn duk_is_function(ctx: *mut duk_context, index: i32) -> i32;
194 pub fn duk_is_thread(ctx: *mut duk_context, index: i32) -> i32;
195
196 pub fn duk_to_object(ctx: *mut duk_context, index: i32);
197 pub fn duk_to_number(ctx: *mut duk_context, index: i32) -> f64;
198 pub fn duk_to_string(ctx: *mut duk_context, index: i32) -> *const c_char;
199
200 pub fn duk_get_boolean(ctx: *mut duk_context, index: i32) -> i32;
201 pub fn duk_get_number(ctx: *mut duk_context, index: i32) -> f64;
202 pub fn duk_get_lstring(ctx: *mut duk_context, index: i32, len: Option<&mut usize>) -> *const c_char;
203 pub fn duk_get_buffer(ctx: *mut duk_context, index: i32, len: Option<&mut usize>) -> *mut c_void;
204 pub fn duk_get_pointer(ctx: *mut duk_context, index: i32) -> *mut c_void;
205
206 pub fn duk_get_prop(ctx: *mut duk_context, obj_index: i32) -> i32;
207 pub fn duk_put_prop(ctx: *mut duk_context, obj_index: i32) -> i32;
208 pub fn duk_def_prop(ctx: *mut duk_context, obj_index: i32, flags: u32);
209
210 pub fn duk_get_prop_lstring(ctx: *mut duk_context,
211 obj_index: i32,
212 key: *const c_char,
213 len: usize)
214 -> i32;
215 pub fn duk_put_prop_lstring(ctx: *mut duk_context,
216 obj_index: i32,
217 key: *const c_char,
218 len: usize)
219 -> i32;
220 pub fn duk_get_prop_index(ctx: *mut duk_context, obj_index: i32, index: u32) -> i32;
221 pub fn duk_put_prop_index(ctx: *mut duk_context, obj_index: i32, index: u32) -> i32;
222
223 pub fn duk_push_global_object(ctx: *mut duk_context);
224 pub fn duk_get_global_lstring(ctx: *mut duk_context, key: *const c_char, len: usize) -> i32;
225 pub fn duk_put_global_lstring(ctx: *mut duk_context, key: *const c_char, len: usize) -> i32;
226
227 pub fn duk_enum(ctx: *mut duk_context, obj_index: i32, flags: u32);
228 pub fn duk_next(ctx: *mut duk_context, enum_idx: i32, get_value: i32) -> i32;
229
230 pub fn duk_throw_raw(ctx: *mut duk_context);
231 pub fn duk_fatal(ctx: *mut duk_context, err_code: i32, err_msg: *const c_char);
232
233 pub fn duk_push_context_dump(ctx: *mut duk_context);
234 pub fn duk_set_global_object(ctx: *mut duk_context);
235
236 pub fn duk_gc(ctx: *mut duk_context, flags: u32);
237}
238
239
240#[inline(always)]
241unsafe fn interop<'a>(udata: *mut c_void) -> &'a mut InteropRef {
242 &mut (*(udata as *mut Userdata)).interop
243}
244
245pub extern "C" fn alloc_func(udata: *mut c_void, size: usize) -> *mut c_void {
246 unsafe {
247 interop(udata).alloc(size) as *mut c_void
248 }
249}
250
251pub extern "C" fn realloc_func(udata: *mut c_void, ptr: *mut c_void, size: usize) -> *mut c_void {
252 unsafe {
253 interop(udata).realloc(ptr as *mut u8, size) as *mut c_void
254 }
255}
256
257pub extern "C" fn free_func(udata: *mut c_void, ptr: *mut c_void) {
258 unsafe {
259 interop(udata).free(ptr as *mut u8);
260 }
261}
262
263pub extern "C" fn console_func(udata: *mut c_void, func: u32, msg: *const c_char, len: usize) {
264 use std::str;
265 use std::slice;
266 unsafe {
267 let msg = str::from_utf8_unchecked(slice::from_raw_parts(msg as *const u8, len));
268 interop(udata).console(ConsoleFunc::from(func), msg);
269 }
270}
271
272pub extern "C" fn func_dispatch(ctx: *mut duk_context) -> i32 {
273 use std::str;
274 use std::slice;
275 unsafe {
276 duk_push_current_function(ctx);
277 duk_get_prop_lstring(ctx, -1, FUNC_NAME_PROP.as_ptr() as *const c_char, FUNC_NAME_PROP.len());
278 let mut len: usize = 0;
279 let ptr = duk_get_lstring(ctx, -1, Some(&mut len)) as *const u8;
280 let name = str::from_utf8_unchecked(slice::from_raw_parts(ptr, len));
281 duk_pop_2(ctx);
282 let udata = duk_api_get_heap_udata(ctx);
283 let mut duk_ctx = DukContext::from_raw(ctx);
284 let r = match interop(udata).call(&mut duk_ctx, name) {
285 Ok(r) => r,
286 Err(err) => {
287 let msg = format!("{err}");
288 duk_push_lstring(ctx, msg.as_ptr() as *const c_char, msg.len());
289 duk_throw_raw(ctx);
290 Return::Error
291 },
292 };
293 r as i32
294 }
295}
296
297pub extern "C" fn fatal_handler(udata: *mut c_void, msg: *const c_char) {
298 unsafe {
299 let msg = CStr::from_ptr(msg).to_string_lossy();
300 interop(udata).fatal(&msg);
301 }
302}