1#[allow(unused_imports)]
2use super::*;
3
4
5#[macro_export]
80macro_rules! extension {
81 {extern $symbol_initializer:ident $(, $symbol_finalizer:ident;
83 move $initializer:path, final $($finalizer:path)?)?;
84 gen $context_initializer:path, final $($context_finalizer:path)?;
85 } => {
86 const _: () = {
87 mod __flash_runtime_extension {
88 use super::*;
89 $crate::extension! {@Extern [$symbol_initializer $(, $symbol_finalizer, $initializer $(, $finalizer)?)?]}
90 #[allow(unsafe_op_in_unsafe_fn)]
91 unsafe extern "C" fn ctx_initializer (
92 ext_data: $crate::c::FREData,
93 ctx_type: $crate::c::FREStr,
94 ctx: $crate::c::FREContext,
95 num_funcs_to_set: *mut u32,
96 funcs_to_set: *mut *const $crate::c::FRENamedFunction,
97 ) {
98 let context_initializer: $crate::function::ContextInitializer = $context_initializer;
99 $crate::__private::context::with_initializer(ext_data, ctx_type, &ctx, num_funcs_to_set, funcs_to_set, $context_initializer);
100 }
101 #[allow(unsafe_op_in_unsafe_fn)]
102 unsafe extern "C" fn ctx_finalizer (ctx: $crate::c::FREContext) {
103 $crate::__private::context::with(&ctx, |ctx| {
104 $(
105 let context_finalizer: $crate::function::ContextFinalizer = $context_finalizer;
106 context_finalizer(ctx);
107 )?
108 let ctx = *(ctx as *mut $crate::context::CurrentContext as *mut $crate::context::ForeignContext);
109 let raw = ctx
110 .get_native_data()
111 .expect("Failed to retrieve native data from FFI.")
112 .expect("`ContextRegistry` is expected in native data but is missing.");
113 assert!(<::std::cell::RefCell<$crate::context::ContextRegistry> as $crate::data::Data>::ref_from(raw).is_ok());
114 $crate::data::drop_from(raw);
115 });
116
117 }
118 }
119 };
120 };
121 {@Extern [$symbol_initializer:ident, $symbol_finalizer:ident, $initializer:path $(, $finalizer:path)?]
123 } => {
124 #[allow(unsafe_op_in_unsafe_fn, non_snake_case)]
125 #[unsafe(no_mangle)]
126 pub unsafe extern "C" fn $symbol_initializer (
127 ext_data_to_set: *mut $crate::c::FREData,
128 ctx_initializer_to_set: *mut $crate::c::FREContextInitializer,
129 ctx_finalizer_to_set: *mut $crate::c::FREContextFinalizer,
130 ) {
131 assert!(!ext_data_to_set.is_null());
132 assert!(!ctx_initializer_to_set.is_null());
133 assert!(!ctx_finalizer_to_set.is_null());
134 let initializer: $crate::function::Initializer = $initializer;
135 if let Some(ext_data) = initializer() {
136 let ext_data = ::std::sync::Arc::new(::std::sync::Mutex::new(ext_data));
137 *ext_data_to_set = <::std::sync::Arc<::std::sync::Mutex<Box<dyn ::std::any::Any>>> as $crate::data::Data>::into_raw(ext_data).as_ptr();
138 }
139 *ctx_initializer_to_set = ctx_initializer;
140 *ctx_finalizer_to_set = ctx_finalizer;
141 }
142 #[allow(unsafe_op_in_unsafe_fn, non_snake_case)]
143 #[unsafe(no_mangle)]
144 pub unsafe extern "C" fn $symbol_finalizer (ext_data: $crate::c::FREData) {
145 let ext_data = $crate::validated::NonNullFREData::new(ext_data)
146 .map(|raw| {
147 let arc_mutex_boxed = <::std::sync::Arc<::std::sync::Mutex<Box<dyn ::std::any::Any>>> as $crate::data::Data>::from_raw(raw);
148 let mutex = ::std::sync::Arc::try_unwrap(arc_mutex_boxed).expect("INVARIANT: No context exists.");
149 let boxed = mutex.into_inner().expect("The mutex is poisoned.");
150 boxed
151 });
152 $(
153 let finalizer: $crate::function::Finalizer = $finalizer;
154 finalizer(ext_data);
155 )?
156 }
157 };
158 {@Extern [$symbol_initializer:ident]
160 } => {
161 #[allow(unsafe_op_in_unsafe_fn, non_snake_case)]
162 #[unsafe(no_mangle)]
163 pub unsafe extern "C" fn $symbol_initializer (
164 ext_data_to_set: *mut $crate::c::FREData,
165 ctx_initializer_to_set: *mut $crate::c::FREContextInitializer,
166 ctx_finalizer_to_set: *mut $crate::c::FREContextFinalizer,
167 ) {
168 assert!(!ctx_initializer_to_set.is_null());
169 assert!(!ctx_finalizer_to_set.is_null());
170 *ctx_initializer_to_set = ctx_initializer;
171 *ctx_finalizer_to_set = ctx_finalizer;
172 }
173 };
174}
175
176
177#[macro_export]
226macro_rules! function {
227 {$name:ident ($($arguments:tt)+) $(-> $return_type:ty)? $body:block
229 } => {
230 #[allow(non_upper_case_globals)]
231 pub const $name: &'static $crate::function::FunctionImplementation = & $crate::__private::function::implement(
232 $crate::ucstringify! ($name), {
233 #[allow(unsafe_op_in_unsafe_fn)]
234 unsafe extern "C" fn abi(
235 ctx: $crate::c::FREContext,
236 func_data: $crate::c::FREData,
237 argc: u32,
238 argv: *const $crate::c::FREObject,
239 ) -> $crate::c::FREObject {
240 fn func <'a> (
241 ctx: &mut $crate::context::CurrentContext<'a>,
242 func_data: Option<&mut dyn ::std::any::Any>,
243 args: &[$crate::as3::Object<'a>],
244 ) -> $crate::as3::Object<'a> {
245 $crate::function! {@Parameters [ctx, func_data, args] $($arguments)+}
246 (|| -> $crate::function!(@Return $($return_type)?) {
247 $body
248 })().into()
249 }
250 $crate::__private::context::with_method(&ctx, func_data, argc, argv, func)
251 }
252 abi},
253 );
254 };
255 ($name:ident use $func:path
257 ) => {
258 #[allow(non_upper_case_globals)]
259 pub const $name: &'static $crate::function::FunctionImplementation = & $crate::__private::function::implement(
260 $crate::ucstringify! ($name), {
261 #[allow(unsafe_op_in_unsafe_fn)]
262 unsafe extern "C" fn abi(
263 ctx: $crate::c::FREContext,
264 func_data: $crate::c::FREData,
265 argc: u32,
266 argv: *const $crate::c::FREObject,
267 ) -> $crate::c::FREObject {
268 $crate::__private::context::with_method(&ctx, func_data, argc, argv, $func)
269 }
270 abi},
271 );
272 };
273 (@Return $return_type:ty
275 ) => ($return_type);
276 (@Return
278 ) => (());
279 {@Parameters [$c:ident, $d:ident, $a:ident $(,)?]
281 $ctx:ident, $data:ident, $args:ident $(,)?
282 } => {
283 let $ctx: &mut $crate::context::CurrentContext<'a> = $c;
284 let $data: Option<&mut dyn ::std::any::Any> = $d;
285 let $args: &[$crate::as3::Object<'a>] = $a;
286 };
287 {@Parameters [$c:ident, $d:ident, $a:ident $(,)?]
289 $ctx:ident, $data:ident, _ $(,)?
290 } => {
291 $crate::function! {@Parameters [$c, $d, $a]
292 $ctx, $data, _args
293 }
294 };
295 {@Parameters [$c:ident, $d:ident, $a:ident $(,)?]
297 $ctx:ident, _, $args:ident $(,)?
298 } => {
299 $crate::function! {@Parameters [$c, $d, $a]
300 $ctx, _data, $args
301 }
302 };
303 {@Parameters [$c:ident, $d:ident, $a:ident $(,)?]
305 _, $data:ident, $args:ident $(,)?
306 } => {
307 $crate::function! {@Parameters [$c, $d, $a]
308 _ctx, $data, $args
309 }
310 };
311 {@Parameters [$c:ident, $d:ident, $a:ident $(,)?]
313 _, _, $args:ident $(,)?
314 } => {
315 $crate::function! {@Parameters [$c, $d, $a]
316 _ctx, _data, $args
317 }
318 };
319 {@Parameters [$c:ident, $d:ident, $a:ident $(,)?]
321 _, $data:ident, _ $(,)?
322 } => {
323 $crate::function! {@Parameters [$c, $d, $a]
324 _ctx, $data, _args
325 }
326 };
327 {@Parameters [$c:ident, $d:ident, $a:ident $(,)?]
329 $ctx:ident, _, _ $(,)?
330 } => {
331 $crate::function! {@Parameters [$c, $d, $a]
332 $ctx, _data, _args
333 }
334 };
335 {@Parameters [$c:ident, $d:ident, $a:ident $(,)?]
337 _, _, _ $(,)?
338 } => {
339 $crate::function! {@Parameters [$c, $d, $a]
340 _ctx, _data, _args
341 }
342 };
343}
344
345
346#[macro_export]
373macro_rules! class {
374
375 {
377 $(#[$meta:meta])*
378 $name:ident $($modifier:tt)*
379 } => {
380 $crate::class! {@Define
381 $(#[$meta])*
382 $name $($modifier)*
383 }
384 unsafe impl<'a> $crate::types::object::AsObject<'a> for $name<'a> {
385 const TYPE: $crate::types::Type = $crate::types::Type::Named(stringify!($name));
386 }
387 };
388
389 {@Typeof
391 $(#[$meta:meta])*
392 $name:ident $($modifier:tt)*
393 } => { const _: () = $crate::__private::SEALED;
394 $crate::class! {@Define
395 $(#[$meta])*
396 $name $($modifier)*
397 }
398 unsafe impl<'a> $crate::types::object::AsObject<'a> for $name<'a> {
399 const TYPE: $crate::types::Type = $crate::types::Type::$name;
400 }
401 impl<'a> TryFrom<$crate::as3::Object<'a>> for $name<'a> {
402 type Error = $crate::types::Type;
403 fn try_from (object: $crate::as3::Object<'a>) -> Result<Self, Self::Error> {
404 let ty = <$crate::as3::Object as $crate::types::object::AsObject>::get_type(object);
405 if ty == <Self as $crate::types::object::AsObject>::TYPE {
406 Ok(unsafe {<$crate::as3::Object as $crate::types::object::AsObject>::as_unchecked(object)})
407 }else{Err(ty)}
408 }
409 }
410 impl<'a> TryFrom<$crate::types::object::NonNullObject<'a>> for $name<'a> {
411 type Error = $crate::types::Type;
412 fn try_from (object: $crate::types::object::NonNullObject<'a>) -> Result<Self, Self::Error> {
413 <$crate::types::object::NonNullObject as $crate::types::object::AsObject>::as_object(object).try_into()
414 }
415 }
416 };
417
418 {@Define
420 $(#[$meta:meta])*
421 $name:ident
422 } => {
423 $(#[$meta])*
424 #[derive(::std::fmt::Debug, Clone, Copy, PartialEq, Eq)]
425 #[repr(transparent)]
426 pub struct $name <'a> (::std::ptr::NonNull<::std::ffi::c_void>, ::std::marker::PhantomData<&'a ()>);
427 $crate::class!(@Implement $name);
428 };
429
430 {@Define
432 $(#[$meta:meta])*
433 $name:ident: ?PartialEq
434 } => {
435 $(#[$meta])*
436 #[derive(::std::fmt::Debug, Clone, Copy)]
437 #[repr(transparent)]
438 pub struct $name <'a> (::std::ptr::NonNull<::std::ffi::c_void>, ::std::marker::PhantomData<&'a ()>);
439 $crate::class!(@Implement $name);
440 };
441
442 {@Implement
444 $name:ident
445 } => {
446 #[cfg(debug_assertions)]
447 const _: () = {
448 #[used]
449 #[unsafe(export_name = concat!("__class_", stringify!($name)))]
450 pub static CLASS_NAME_MUST_UNIQUE: u8 = 0;
451 };
452
453 unsafe impl $crate::__private::Sealed for $name<'_> {}
454
455 impl<'a> $crate::types::object::AsNonNullObject<'a> for $name<'a> {}
456 impl<'a> From<$name<'a>> for $crate::types::object::NonNullObject<'a> {fn from(object: $name<'a>) -> Self {<$name as $crate::types::object::AsNonNullObject>::as_non_null_object(object)}}
457
458 impl From<$name<'_>> for $crate::c::FREObject {fn from(object: $name) -> Self {<$name as $crate::types::object::AsObject>::as_ptr(object)}}
459
460 impl ::std::fmt::Display for $name<'_> {fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {::std::fmt::Display::fmt(&(<Self as $crate::types::object::AsNonNullObject>::as_non_null_object(*self)), f)}}
461
462 impl $crate::validated::ToUcstrLossy for $name<'_> {fn to_ucstr_lossy(&self) -> $crate::validated::UCStr {
463 let object = <$name as $crate::types::object::AsObject>::as_object(*self);
464 <$crate::as3::Object as $crate::validated::ToUcstrLossy>::to_ucstr_lossy(&object)
465 }}
466 };
467}
468
469
470#[macro_export]
488macro_rules! ucstringify {
489
490 {$($tokens:tt)*} => {
492 {
493 const STR: &'static str = concat!(stringify!($($tokens)*), "\0");
494 const CSTR: &'static ::std::ffi::CStr = unsafe {::std::ffi::CStr::from_bytes_with_nul_unchecked(STR.as_bytes())};
495 const UCSTR: $crate::validated::UCStr = unsafe {$crate::validated::UCStr::from_literal_unchecked(CSTR)};
496 UCSTR
497 }
498 };
499}
500