You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: ntdll.rs
    path of file: ./repos/libscemu/src/emu/winapi32
    
    the code of the file until where you have to start completion: use crate::emu;
use crate::emu::constants;
use crate::emu::context32::Context32;
use crate::emu::structures;
use crate::emu::winapi32::helper;
use crate::emu::winapi32::kernel32;

use scan_fmt::scan_fmt_some;

pub fn gateway(addr: u32, emu: &mut emu::Emu) -> String {
    match addr {
        0x775b52d8 => NtAllocateVirtualMemory(emu),
        0x775b5a18 => NtGetContextThread(emu),
        0x7757f774 => RtlVectoredExceptionHandler(emu),
        0x775d22b8 => LdrLoadDll(emu),
        0x775b6258 => NtQueryVirtualMemory(emu),
        0x775d531f => stricmp(emu),
        0x7759f611 => RtlExitUserThread(emu),
        0x7763a4dd => sscanf(emu),
        0x7761b3de => NtGetTickCount(emu),
        0x775b6158 => NtQueryPerformanceCounter(emu),
        0x775eabd1 => RtlGetProcessHeaps(emu),
        0x775d27e0 => RtlDosPathNameToNtPathName_U(emu),
        0x775b55c8 => NtCreateFile(emu),
        0x775c2c6a => RtlFreeHeap(emu),
        0x775b6018 => NtQueryInformationFile(emu),
        0x775c2dd6 => RtlAllocateHeap(emu),
        0x775b62b8 => NtReadFile(emu),
        0x775b54c8 => NtClose(emu),
        0x775cee8d => RtlInitializeCriticalSectionAndSpinCount(emu),
        0x775b5f18 => NtProtectVirtualMemory(emu),
        0x775b77a0 => RtlEnterCriticalSection(emu),
        0x775b7760 => RtlLeaveCriticalSection(emu),
        0x775d65e3 => RtlGetVersion(emu),
        0x775c6db9 => RtlInitializeCriticalSectionEx(emu),
        0x775a5340 => memset(emu),
        0x775d7de2 => RtlSetUnhandledExceptionFilter(emu),
        0x775a55c0 => strlen(emu),
        0x77593030 => VerSetConditionMask(emu),
        0x775a53d0 => strcat(emu),
        // TODO: 0x775a4cc0 => memcpy(emu), 

        _ => {
            let apiname = kernel32::guess_api_name(emu, addr);
            println!("calling unimplemented ntdll API 0x{:x} {}", addr, apiname);
            return apiname;
        }
    }

    return String::new();
}

fn NtAllocateVirtualMemory(emu: &mut emu::Emu) {
    /*
        __kernel_entry NTSYSCALLAPI NTSTATUS NtAllocateVirtualMemory(
            [in]      HANDLE    ProcessHandle,
            [in, out] PVOID     *B
    
fn NtAllocateVirtualMemory(emu: &mut emu::Emu) {
    /*
        __kernel_entry NTSYSCALLAPI NTSTATUS NtAllocateVirtualMemory(
            [in]      HANDLE    ProcessHandle,
            [in, out] PVOID     *BaseAddress,
            [in]      ULONG_PTR ZeroBits,
            [in, out] PSIZE_T   RegionSize,
            [in]      ULONG     AllocationType,
            [in]      ULONG     Protect
            );
    */

    let addr_ptr = emu
        .maps
        .read_dword(emu.regs.get_esp() + 4)
        .expect("bad NtAllocateVirtualMemory address pointer parameter") as u64;
    let size_ptr = emu
        .maps
        .read_dword(emu.regs.get_esp() + 12)
        .expect("bad NtAllocateVirtualMemory size pointer parameter") as u64;
    let addr = emu
        .maps
        .read_dword(addr_ptr)
        .expect("bad NtAllocateVirtualMemory address parameter") as u64;
    let size = emu
        .maps
        .read_dword(size_ptr)
        .expect("bad NtAllocateVirtualMemory size parameter") as u64;
    let do_alloc: bool;
    let alloc_addr: u64;

    if addr == 0 {
        do_alloc = true;
    } else {
        do_alloc = emu.maps.is_mapped(addr);
    }

    if size == 0 {
        panic!("NtAllocateVirtualMemory mapping zero bytes.")
    }

    if do_alloc {
        alloc_addr = match emu.maps.alloc(size) {
            Some(a) => a,
            None => {
                panic!("/!\\ out of memory   cannot allocate forntdll!NtAllocateVirtualMemory ")
            }
        };
    } else {
        alloc_addr = addr;
    }

    println!(
        "{}** {} ntdll!NtAllocateVirtualMemory  addr: 0x{:x} sz: {} alloc: 0x{:x} {}",
        emu.colors.light_red, emu.pos, addr, size, alloc_addr, emu.colors.nc
    );

    let alloc = emu
        .maps
        .create_map(format!("valloc_{:x}", alloc_addr).as_str());
    alloc.set_base(alloc_addr);
    alloc.set_size(size);
    //alloc.set_bottom(alloc_addr + size);

    if !emu.maps.write_dword(addr_ptr, alloc_addr as u32) {
        panic!("NtAllocateVirtualMemory: cannot write on address pointer");
    }

    emu.regs.rax = emu::constants::STATUS_SUCCESS;

    for _ in 0..6 {
        emu.stack_pop32(false);
    }
}