makepad_wasm_bridge/
wasm_types.rs

1use crate::from_wasm::*;
2use crate::to_wasm::*;
3pub struct WasmDataU8(Vec<u8>);
4use makepad_derive_wasm_bridge::*;
5use crate::{LiveId,live_id};
6
7impl WasmDataU8 {
8    pub fn new_and_release_ownership(capacity: usize) -> u32 {
9        let mut v = Vec::<u8>::new();
10        v.reserve_exact(capacity);
11        let mut v = std::mem::ManuallyDrop::new(v);
12        let ptr = v.as_mut_ptr();
13        let cap = v.capacity();
14        if cap != capacity {panic!()};
15        ptr as u32
16    }
17    
18    pub fn take_ownership(ptr:u32, len:u32, cap:u32)->Self{
19        unsafe {
20            Self(Vec::from_raw_parts(ptr as *mut u8, len as usize, cap as usize))
21        }
22    }
23    
24    pub fn from_vec_u8(v:Vec<u8>)->Self{
25        Self(v)
26    }
27    
28    pub fn into_vec_u8(self)->Vec<u8>{
29        self.0
30    }
31    
32    pub fn into_utf8(self)->String{
33        String::from_utf8(self.0).unwrap()
34    }
35}
36
37impl ToWasm for WasmDataU8 {
38    fn read_to_wasm(inp: &mut ToWasmMsgRef) -> Self {
39        
40        let ptr = inp.read_u32();
41        let len = inp.read_u32() as usize;
42        unsafe {
43            Self (Vec::from_raw_parts(ptr as *mut u8, len, len))
44        }
45    }
46    
47    fn to_wasm_js_body(out: &mut WasmJSOutput, slot: usize, _is_recur: bool, prop: &str, _temp: usize) {
48        out.push_ln(slot, &format!("this.push_data_u8({});", prop));
49    }
50    
51    fn u32_size() -> usize {2}
52}
53
54impl FromWasm for WasmDataU8 {
55    fn from_wasm_js_body(out: &mut WasmJSOutput, slot: usize, _is_recur: bool, prop: &str, _temp: usize) {
56        out.push_ln(slot, &format!("{} = {{ptr:app.u32[this.u32_offset++],len:app.u32[this.u32_offset++],capacity:app.u32[this.u32_offset++]}};", prop));
57    }
58    
59    fn from_wasm_inner(self, out: &mut FromWasmMsg) {
60        let mut v = std::mem::ManuallyDrop::new(self.0);
61        out.push_u32(v.as_mut_ptr() as u32);
62        out.push_u32(v.len() as u32);
63        out.push_u32(v.capacity() as u32);
64    }
65}
66/*
67impl FromWasm for WasmDataU8 {
68    fn write_from_wasm(&self, out: &mut FromWasmMsg) {
69        let swap = Vec::new();
70        
71        let mut v = std::mem::ManuallyDrop::new(v);
72        let ptr = v.as_mut_ptr();
73        let cap = v.capacity();
74        
75        out.push_u32()
76        let ptr = inp.read_u32();
77        let len = inp.read_u32() as usize;
78        unsafe {
79            Self (Vec::from_raw_parts(ptr as *mut u8, len, len))
80        }
81    }
82    
83    fn to_wasm_js_body(out: &mut WasmJSOutput, slot: usize, _is_recur: bool, prop: &str, _temp: usize) {
84        out.push_ln(slot, &format!("this.push_data_u8({});", prop));
85    }
86    
87    fn u32_size() -> usize {2}
88}*/
89
90#[derive(FromWasm)]
91pub struct WasmPtrF32{
92    ptr:u32,
93    len: usize
94}
95
96impl WasmPtrF32 {
97    pub fn new(data:&[f32]) -> Self {
98        if !data.is_empty(){
99            Self{
100                ptr: data.as_ptr() as u32,
101                len: data.len()
102            }
103        }
104        else{
105            Self{ptr:0, len:0}
106        }
107    }
108}
109
110#[derive(FromWasm)]
111pub struct WasmPtrU32 {
112    pub ptr: u32,
113    pub len: usize
114}
115
116impl WasmPtrU32 {
117    pub fn new(data:&[u32]) -> Self {
118        if !data.is_empty(){
119            Self{
120                ptr: data.as_ptr() as u32, 
121                len:data.len()
122            }
123        }
124        else{
125            Self{
126                ptr:0, 
127                len:0
128            }
129        }
130    }
131}
132
133#[derive(FromWasm)]
134pub struct WasmPtrU8 {
135    pub ptr: u32,
136    pub len: usize
137}
138
139impl WasmPtrU8 {
140    pub fn new(data:&[u8]) -> Self {
141        if !data.is_empty(){
142            Self{
143                ptr: data.as_ptr() as u32, 
144                len: data.len()
145            }
146        }
147        else{
148            Self{
149                ptr:0, 
150                len:0
151            }
152        }
153    }
154}
155
156impl FromWasm for String {
157    fn from_wasm_js_body(out: &mut WasmJSOutput, slot: usize, _is_recur: bool, prop: &str, _temp: usize) {
158        out.push_ln(slot, &format!("{} = this.read_str();", prop));
159    }
160    
161    fn from_wasm_inner(self, out: &mut FromWasmMsg) {
162        out.push_str(&self);
163    }
164}
165
166impl FromWasm for &str {
167    fn from_wasm_js_body(out: &mut WasmJSOutput, slot: usize, _is_recur: bool, prop: &str, _temp: usize) {
168        out.push_ln(slot, &format!("{} = this.read_str();", prop));
169    }
170    
171    fn from_wasm_inner(self, out: &mut FromWasmMsg) {
172        out.push_str(self);
173    }
174}
175
176impl ToWasm for String {
177    fn read_to_wasm(inp: &mut ToWasmMsgRef) -> Self {
178        inp.read_string()
179    }
180    
181    fn to_wasm_js_body(out: &mut WasmJSOutput, slot: usize, _is_recur: bool, prop: &str, _temp: usize) {
182        out.push_ln(slot, &format!("this.push_str({});", prop));
183    }
184    
185    fn u32_size() -> usize {1}
186}
187
188
189
190impl FromWasm for bool {
191    fn from_wasm_js_body(out: &mut WasmJSOutput, slot: usize, _is_recur: bool, prop: &str, _temp: usize) {
192        out.push_ln(slot, &format!("{} = app.u32[this.u32_offset++]!==0?true:false;", prop));
193    }
194    
195    fn from_wasm_inner(self, out: &mut FromWasmMsg) {
196        out.push_u32(if self {1} else {0})
197    }
198}
199
200impl ToWasm for bool {
201    fn read_to_wasm(inp: &mut ToWasmMsgRef) -> Self {
202        inp.read_u32() != 0
203    }
204    
205    fn to_wasm_js_body(out: &mut WasmJSOutput, slot: usize, _is_recur: bool, prop: &str, _temp: usize) {
206        out.push_ln(slot, &format!("app.u32[this.u32_offset++] = {};", prop));
207    }
208    fn u32_size() -> usize {1}
209}
210
211
212impl FromWasm for usize {
213    
214    fn from_wasm_js_body(out: &mut WasmJSOutput, slot: usize, _is_recur: bool, prop: &str, _temp: usize) {
215        out.push_ln(slot, &format!("{} = app.u32[this.u32_offset++];", prop));
216    }
217    
218    fn from_wasm_inner(self, out: &mut FromWasmMsg) {
219        out.push_u32(self as u32)
220    }
221}
222
223impl ToWasm for usize {
224    fn read_to_wasm(inp: &mut ToWasmMsgRef) -> Self {
225        inp.read_u32() as usize
226    }
227    
228    fn to_wasm_js_body(out: &mut WasmJSOutput, slot: usize, _is_recur: bool, prop: &str, _temp: usize) {
229        out.push_ln(slot, &format!("app.u32[this.u32_offset++] = {};", prop));
230    }
231    fn u32_size() -> usize {1}
232}
233
234
235
236impl FromWasm for u32 {
237    fn from_wasm_js_body(out: &mut WasmJSOutput, slot: usize, _is_recur: bool, prop: &str, _temp: usize) {
238        out.push_ln(slot, &format!("{} = app.u32[this.u32_offset++];", prop));
239    }
240    
241    fn from_wasm_inner(self, out: &mut FromWasmMsg) {
242        out.push_u32(self)
243    }
244}
245
246impl ToWasm for u32 {
247    fn read_to_wasm(inp: &mut ToWasmMsgRef) -> Self {
248        inp.read_u32()
249    }
250    
251    fn to_wasm_js_body(out: &mut WasmJSOutput, slot: usize, _is_recur: bool, prop: &str, _temp: usize) {
252        out.push_ln(slot, &format!("app.u32[this.u32_offset++] = {};", prop));
253    }
254    fn u32_size() -> usize {1}
255}
256
257
258
259
260impl FromWasm for f32 {
261    fn from_wasm_js_body(out: &mut WasmJSOutput, slot: usize, _is_recur: bool, prop: &str, _temp: usize) {
262        out.push_ln(slot, &format!("{} = app.f32[this.u32_offset++];", prop));
263    }
264    
265    fn from_wasm_inner(self, out: &mut FromWasmMsg) {
266        out.push_f32(self)
267    }
268}
269
270impl ToWasm for f32 {
271    fn read_to_wasm(inp: &mut ToWasmMsgRef) -> Self {
272        inp.read_f32()
273    }
274    
275    fn to_wasm_js_body(out: &mut WasmJSOutput, slot: usize, _is_recur: bool, prop: &str, _temp: usize) {
276        out.push_ln(slot, &format!("app.f32[this.u32_offset++] = {};", prop));
277    }
278    fn u32_size() -> usize {1}
279}
280
281
282
283
284impl FromWasm for f64 {
285    fn from_wasm_js_body(out: &mut WasmJSOutput, slot: usize, _is_recur: bool, prop: &str, _temp: usize) {
286        out.push_ln(slot, "this.u32_offset += this.u32_offset&1;");
287        out.push_ln(slot, &format!("{} = app.f64[this.u32_offset>>1];", prop));
288        out.push_ln(slot, "this.u32_offset += 2;");
289    }
290    
291    fn from_wasm_inner(self, out: &mut FromWasmMsg) {
292        out.push_f64(self)
293    }
294}
295
296impl ToWasm for f64 {
297    fn read_to_wasm(inp: &mut ToWasmMsgRef) -> Self {
298        inp.read_f64()
299    }
300    
301    fn to_wasm_js_body(out: &mut WasmJSOutput, slot: usize, _is_recur: bool, prop: &str, _temp: usize) {
302        out.push_ln(slot, "this.u32_offset += this.u32_offset&1;");
303        out.push_ln(slot, &format!("app.f64[this.u32_offset>>1] = {};", prop));
304        out.push_ln(slot, "this.u32_offset += 2;");
305    }
306    
307    fn u32_size() -> usize {3}
308}
309
310
311
312
313
314impl<T, const N: usize> FromWasm for [T; N] where T: FromWasm {
315    fn from_wasm_inner(self, out: &mut FromWasmMsg) {
316        for item in self {
317            item.from_wasm_inner(out);
318        }
319    }
320    
321    fn from_wasm_js_body(out: &mut WasmJSOutput, slot: usize, is_recur: bool, prop: &str, temp: usize) {
322        out.push_ln(slot, &format!("if({0} === undefined) {0} = [];", prop));
323        out.push_ln(slot, &format!("let t{} = {};", temp, prop));
324        out.push_ln(slot, &format!("for(let i{0} = 0; i{0} < {1}; i{0}++){{", temp, N));
325        let new_temp = out.alloc_temp();
326        T::from_wasm_js_body(out, slot, is_recur, &format!("t{0}[i{0}]", temp), new_temp);
327        out.push_ln(slot, "}");
328    }
329}
330
331impl<T, const N: usize> ToWasm for [T; N] where T: ToWasm {
332    fn u32_size() -> usize {T::u32_size() * N}
333    
334    fn read_to_wasm(inp: &mut ToWasmMsgRef) -> Self {
335        unsafe {
336            let mut to = std::mem::MaybeUninit::<[T; N]>::uninit();
337            let top: *mut T = &mut to as *mut _ as *mut T;
338            for i in 0..N {
339                top.add(i).write(ToWasm::read_to_wasm(inp));
340            }
341            to.assume_init()
342        }
343    }
344    
345    fn to_wasm_js_body(out: &mut WasmJSOutput, slot: usize, is_recur: bool, prop: &str, temp: usize) {
346        out.push_ln(slot, &format!("let t{} = {}", temp, prop));
347        out.push_ln(slot, &format!("for(let i{0} = 0; i{0} < {1}; i{0}++){{", temp, N));
348        let new_temp = out.alloc_temp();
349        T::to_wasm_js_body(out, slot, is_recur, &format!("t{0}[i{0}]", temp), new_temp);
350        out.push_ln(slot, "}");
351    }
352}
353
354impl<T> FromWasm for Vec<T> where T: FromWasm {
355    fn from_wasm_inner(self, out: &mut FromWasmMsg) {
356        out.push_u32(self.len() as u32);
357        for item in self {
358            item.from_wasm_inner(out);
359        }
360    }
361    
362    fn from_wasm_js_body(out: &mut WasmJSOutput, slot: usize, _is_recur: bool, prop: &str, temp: usize) {
363        out.push_ln(slot, &format!("let t{} = {} = [];", temp, prop));
364        out.push_ln(slot, &format!("t{}.length = app.u32[this.u32_offset++];", temp));
365        out.push_ln(slot, &format!("for(let i{0} = 0; i{0} < t{0}.length; i{0}++){{", temp));
366        let new_temp = out.alloc_temp();
367        T::from_wasm_js_body(out, slot, true, &format!("t{0}[i{0}]", temp), new_temp);
368        out.push_ln(slot, "}");
369    }
370}
371
372impl<T> ToWasm for Vec<T> where T: ToWasm {
373    fn u32_size() -> usize {1}
374    
375    fn read_to_wasm(inp: &mut ToWasmMsgRef) -> Self {
376        let len = inp.read_u32();
377        let mut ret = Vec::new();
378        for _ in 0..len {
379            ret.push(ToWasm::read_to_wasm(inp));
380        }
381        ret
382    }
383    
384    fn to_wasm_js_body(out: &mut WasmJSOutput, slot: usize, _is_recur: bool, prop: &str, temp: usize) {
385        let item_size = T::u32_size();
386        
387        out.push_ln(slot, &format!("let t{} = {};", temp, prop));
388        out.push_ln(slot, &format!("if(Array.isArray(t{})){{", temp));
389        out.push_ln(slot, &format!("app.u32[this.u32_offset ++] = t{}.length;", temp));
390        out.push_ln(slot, &format!("this.reserve_u32({} * t{}.length);", item_size, temp));
391        out.push_ln(slot, &format!("for(let i{0} = 0; i{0} < t{0}.length; i{0}++){{", temp));
392        let new_temp = out.alloc_temp();
393        T::to_wasm_js_body(out, slot, true, &format!("t{0}[i{0}]", temp), new_temp);
394        out.push_ln(slot, "}} else {");
395        out.push_ln(slot, "   app.u32[this.u32_offset ++] = 0;");
396        out.push_ln(slot, "}");
397        
398    }
399}
400
401impl<T> FromWasm for Box<T> where T: FromWasm {
402    fn from_wasm_inner(self, out: &mut FromWasmMsg) {
403        (*self).from_wasm_inner(out);
404    }
405    
406    fn from_wasm_js_body(out: &mut WasmJSOutput, slot: usize, _is_recur: bool, prop: &str, _temp: usize) {
407        let new_temp = out.alloc_temp();
408        T::from_wasm_js_body(out, slot, true, prop, new_temp);
409    }
410}
411
412impl<T> ToWasm for Box<T> where T: ToWasm {
413    fn u32_size() -> usize {0}
414    
415    fn read_to_wasm(inp: &mut ToWasmMsgRef) -> Self {
416        Self::new(ToWasm::read_to_wasm(inp))
417
418    }
419    
420    fn to_wasm_js_body(out: &mut WasmJSOutput, slot: usize, _is_recur: bool, prop: &str, temp: usize) {
421        let item_size = T::u32_size();
422        out.push_ln(slot, &format!("this.reserve_u32({});", item_size));
423        T::to_wasm_js_body(out, slot, true, prop, temp);
424    }
425}
426
427impl<T> FromWasm for Option<T> where T: FromWasm {
428    fn from_wasm_inner(self, out: &mut FromWasmMsg) {
429        if let Some(val) = self {
430            out.push_u32(1);
431            val.from_wasm_inner(out);
432        }
433        else {
434            out.push_u32(0);
435        }
436    }
437    
438    fn from_wasm_js_body(out: &mut WasmJSOutput, slot: usize, is_recur: bool, prop: &str, _temp: usize) {
439        out.push_ln(slot, "if(app.u32[this.u32_offset++] !== 0){");
440        let new_temp = out.alloc_temp();
441        T::from_wasm_js_body(out, slot, is_recur, prop, new_temp);
442        out.push_ln(slot, "} else {");
443        out.push_ln(slot, &format!("{} = undefined;", prop));
444        out.push_ln(slot, "}");
445    }
446}
447
448impl<T> ToWasm for Option<T> where T: ToWasm {
449    fn u32_size() -> usize {1 + T::u32_size()}
450    
451    fn read_to_wasm(inp: &mut ToWasmMsgRef) -> Self {
452        if inp.read_u32() == 0 {
453            None
454        }
455        else {
456            Some(ToWasm::read_to_wasm(inp))
457        }
458    }
459    
460    fn to_wasm_js_body(out: &mut WasmJSOutput, slot: usize, is_recur: bool, prop: &str, temp: usize) {
461        out.push_ln(slot, &format!("if({0} === undefined){{", prop));
462        out.push_ln(slot, "app.u32[this.u32_offset ++] = 0;");
463        out.push_ln(slot, "} else {");
464        out.push_ln(slot, "app.u32[this.u32_offset ++] = 1;");
465        T::to_wasm_js_body(out, slot, is_recur, prop, temp);
466        out.push_ln(slot, "}");
467    }
468}
469
470