fn append_word_ty(
        res: &mut Vec<WordType>,
        cur_offset: ByteSize,
        cur_ty: &P<MuType>,
        vm: &VM
    ) -> ByteSize {
        debug!(
            "append_word_ty(): cur_offset={}, cur_ty={}",
            cur_offset,
            cur_ty
        );
        let cur_backend_ty = BackendType::resolve(cur_ty, vm);
        let cur_offset = math::align_up(cur_offset, cur_backend_ty.alignment);
        let pointer_aligned = cur_offset % POINTER_SIZE == 0;
        match cur_ty.v {
            MuType_::Int(_) => {
                if pointer_aligned {
                    res.push(WordType::NonRef);
                }
            }
            MuType_::Void => {
                if pointer_aligned {
                    res.push(WordType::NonRef);
                }
            }
            MuType_::Ref(_) | MuType_::IRef(_) => {
                debug_assert!(pointer_aligned);
                res.push(WordType::Ref);
            }
            MuType_::WeakRef(_) => {
                debug_assert!(pointer_aligned);
                res.push(WordType::WeakRef);
            }
            MuType_::UPtr(_) |
            MuType_::UFuncPtr(_) |
            MuType_::FuncRef(_) |
            MuType_::ThreadRef |
            MuType_::StackRef => {
                debug_assert!(pointer_aligned);
                res.push(WordType::NonRef);
            }
            MuType_::Tagref64 => {
                debug_assert!(pointer_aligned);
                res.push(WordType::TaggedRef);
            }
            MuType_::Float => {
                if pointer_aligned {
                    res.push(WordType::NonRef);
                }
            }
            MuType_::Double => {
                debug_assert!(pointer_aligned);
                res.push(WordType::NonRef);
            }
            MuType_::Struct(ref name) => {
                let struct_tys = {
                    let lock = STRUCT_TAG_MAP.read().unwrap();
                    let struc = lock.get(name).unwrap();
                    struc.get_tys().to_vec()
                };
                debug_assert!(cur_backend_ty.struct_layout.is_some());
                let struct_ty_offsets = cur_backend_ty.struct_layout.as_ref().unwrap();
                debug_assert_eq!(struct_tys.len(), struct_ty_offsets.len());
                for i in 0..struct_tys.len() {
                    let next_offset =
                        BackendType::append_word_ty(res, struct_ty_offsets[i], &struct_tys[i], vm);

                    if cfg!(debug_assertions) && i != struct_tys.len() - 1 {
                        assert!(next_offset <= struct_ty_offsets[i + 1]);
                    }
                }
            }
            MuType_::Array(ref ty, len) => {
                let backend_ty = BackendType::resolve(cur_ty, vm);
                for i in 0..len {
                    let offset = backend_ty.elem_size.unwrap() * i;
                    let next_offset = BackendType::append_word_ty(res, offset, ty, vm);
                    debug_assert!((next_offset - offset) <= backend_ty.elem_size.unwrap());
                }
            }
            MuType_::Hybrid(_) => unreachable!(),
            _ => unimplemented!()
        }
        cur_offset + cur_backend_ty.size
    }
/// finish current type, and returns new offset
finish current type, and returns new offset
finish current type and returns new offset
fn append_word_ty(
        res: &mut Vec<WordType>,
        cur_offset: ByteSize,
        cur_ty: &P<MuType>,
        vm: &VM
    ) -> ByteSize {
        debug!(
            "append_word_ty(): cur_offset={}, cur_ty={}",
            cur_offset,
            cur_ty
        );
        let cur_backend_ty = BackendType::resolve(cur_ty, vm);
        let cur_offset = math::align_up(cur_offset, cur_backend_ty.alignment);
        let pointer_aligned = cur_offset % POINTER_SIZE == 0;
        match cur_ty.v {
            MuType_::Int(_) => {
                if pointer_aligned {
                    res.push(WordType::NonRef);
                }
            }
            MuType_::Void => {
                if pointer_aligned {
                    res.push(WordType::NonRef);
                }
            }
            MuType_::Ref(_) | MuType_::IRef(_) => {
                debug_assert!(pointer_aligned);
                res.push(WordType::Ref);
            }
            MuType_::WeakRef(_) => {
                debug_assert!(pointer_aligned);
                res.push(WordType::WeakRef);
            }
            MuType_::UPtr(_) |
            MuType_::UFuncPtr(_) |
            MuType_::FuncRef(_) |
            MuType_::ThreadRef |
            MuType_::StackRef => {
                debug_assert!(pointer_aligned);
                res.push(WordType::NonRef);
            }
            MuType_::Tagref64 => {
                debug_assert!(pointer_aligned);
                res.push(WordType::TaggedRef);
            }
            MuType_::Float => {
                if pointer_aligned {
                    res.push(WordType::NonRef);
                }
            }
            MuType_::Double => {
                debug_assert!(pointer_aligned);
                res.push(WordType::NonRef);
            }
            MuType_::Struct(ref name) => {
                let struct_tys = {
                    let lock = STRUCT_TAG_MAP.read().unwrap();
                    let struc = lock.get(name).unwrap();
                    struc.get_tys().to_vec()
                };
                debug_assert!(cur_backend_ty.struct_layout.is_some());
                let struct_ty_offsets = cur_backend_ty.struct_layout.as_ref().unwrap();
                debug_assert_eq!(struct_tys.len(), struct_ty_offsets.len());
                for i in 0..struct_tys.len() {
                    let next_offset =
                        BackendType::append_word_ty(res, struct_ty_offsets[i], &struct_tys[i], vm);
                    if cfg!(debug_assertions) && i != struct_tys.len() - 1 {
                        assert!(next_offset <= struct_ty_offsets[i + 1]);
                    }
                }
            }
            MuType_::Array(ref ty, len) => {
                let backend_ty = BackendType::resolve(cur_ty, vm);
                for i in 0..len {
                    let offset = backend_ty.elem_size.unwrap() * i;
                    let next_offset = BackendType::append_word_ty(res, offset, ty, vm);
                    debug_assert!((next_offset - offset) <= backend_ty.elem_size.unwrap());
                }
            }
            MuType_::Hybrid(_) => unreachable!(),
            _ => unimplemented!()
        }
        cur_offset + cur_backend_ty.size
    }
fn append_word_ty ( res : & mut Vec < WordType > , cur_offset : ByteSize , cur_ty : & P < MuType > , vm : & VM ) -> ByteSize { debug ! ( " " cur_offset cur_ty ) ; let cur_backend_ty = BackendType :: resolve ( cur_ty , vm ) ; let cur_offset = math :: align_up ( cur_offset , cur_backend_ty . alignment ) ; let pointer_aligned = cur_offset % POINTER_SIZE == 0 ; match cur_ty . v { MuType_ :: Int ( _ ) => { if pointer_aligned { res . push ( WordType :: NonRef ) ; } } MuType_ :: Void => { if pointer_aligned { res . push ( WordType :: NonRef ) ; } } MuType_ :: Ref ( _ ) | MuType_ :: IRef ( _ ) => { debug_assert ! ( pointer_aligned ) ; res . push ( WordType :: Ref ) ; } MuType_ :: WeakRef ( _ ) => { debug_assert ! ( pointer_aligned ) ; res . push ( WordType :: WeakRef ) ; } MuType_ :: UPtr ( _ ) | MuType_ :: UFuncPtr ( _ ) | MuType_ :: FuncRef ( _ ) | MuType_ :: ThreadRef | MuType_ :: StackRef => { debug_assert ! ( pointer_aligned ) ; res . push ( WordType :: NonRef ) ; } MuType_ :: Tagref64 => { debug_assert ! ( pointer_aligned ) ; res . push ( WordType :: TaggedRef ) ; } MuType_ :: Float => { if pointer_aligned { res . push ( WordType :: NonRef ) ; } } MuType_ :: Double => { debug_assert ! ( pointer_aligned ) ; res . push ( WordType :: NonRef ) ; } MuType_ :: Struct ( ref name ) => { let struct_tys = { let lock = STRUCT_TAG_MAP . read ( ) . unwrap ( ) ; let struc = lock . get ( name ) . unwrap ( ) ; struc . get_tys ( ) . to_vec ( ) } ; debug_assert ! ( cur_backend_ty struct_layout is_some ( ) ) ; let struct_ty_offsets = cur_backend_ty . struct_layout . as_ref ( ) . unwrap ( ) ; debug_assert_eq ! ( struct_tys len ( ) struct_ty_offsets len ( ) ) ; for i in 0 .. struct_tys . len ( ) { let next_offset = BackendType :: append_word_ty ( res , struct_ty_offsets [ i ] , & struct_tys [ i ] , vm ) ; if cfg ! ( debug_assertions ) && i != struct_tys . len ( ) - 1 { assert ! ( next_offset struct_ty_offsets [ i 1 ] ) ; } } } MuType_ :: Array ( ref ty , len ) => { let backend_ty = BackendType :: resolve ( cur_ty , vm ) ; for i in 0 .. len { let offset = backend_ty . elem_size . unwrap ( ) * i ; let next_offset = BackendType :: append_word_ty ( res , offset , ty , vm ) ; debug_assert ! ( ( next_offset offset ) backend_ty elem_size unwrap ( ) ) ; } } MuType_ :: Hybrid ( _ ) => unreachable ! ( ) , _ => unimplemented ! ( ) } cur_offset + cur_backend_ty . size }
finish current type, and returns new offset
finish current type and returns new offset
res
&mut Vec<WordType>
cur_offset
ByteSize
cur_ty
&P<MuType>
vm
&VM
res
&mut Vec<WordType>
cur_offset
ByteSize
cur_ty
&P<MuType>
vm
&VM