diff --git a/src/apis/emscripten/time.rs b/src/apis/emscripten/time.rs index 8e5273dbd..e6bec77fa 100644 --- a/src/apis/emscripten/time.rs +++ b/src/apis/emscripten/time.rs @@ -1,4 +1,4 @@ -use super::utils::copy_cstr_into_wasm; +use super::utils::{copy_cstr_into_wasm, write_to_buf}; use libc::{ c_int, c_long, @@ -81,87 +81,71 @@ struct guest_tm { pub tm_zone: c_int, // 40 } +/// formats time as a C string +unsafe extern "C" fn fmt_time(time: u32, instance: &Instance) -> *const c_char { + let date = &*(instance.memory_offset_addr(0, time as _) as *mut guest_tm); + + let days = vec!["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; + let months = vec!["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; + let year = 1900 + date.tm_year; + + let time_str = format!( + // NOTE: The 14 accompanying chars are needed for some reason + "{} {} {:2} {:02}:{:02}:{:02} {:4}\n\0\0\0\0\0\0\0\0\0\0\0\0\0", + days[date.tm_wday as usize], + months[date.tm_mon as usize], + date.tm_mday, + date.tm_hour, + date.tm_min, + date.tm_sec, + year + ); + + time_str[0..26].as_ptr() as _ +} + /// emscripten: _asctime pub extern "C" fn _asctime(time: u32, instance: &mut Instance) -> u32 { debug!("emscripten::_asctime {}", time); unsafe { - let date = &*(instance.memory_offset_addr(0, time as _) as *mut guest_tm); - - let days = vec!["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; - let months = vec!["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; - let year = 1900 + date.tm_year; - - let time_str = format!( - // NOTE: The 14 accompanying chars are needed for some reason - "{} {} {:2} {:02}:{:02}:{:02} {:4}\n\0\0\0\0\0\0\0\0\0\0\0\0\0", - days[date.tm_wday as usize], - months[date.tm_mon as usize], - date.tm_mday, - date.tm_hour, - date.tm_min, - date.tm_sec, - year - ); - - let time_str_ptr = time_str[0..26].as_ptr() as _; - let time_str_offset = copy_cstr_into_wasm(instance, time_str_ptr); + let time_str_ptr = fmt_time(time, instance); + copy_cstr_into_wasm(instance, time_str_ptr) // let c_str = instance.memory_offset_addr(0, time_str_offset as _) as *mut i8; // use std::ffi::CStr; // debug!("#### cstr = {:?}", CStr::from_ptr(c_str)); - - time_str_offset } } - -// TODO -// fn asctime_fmt() -> *const c_char { - -// } - -// MOVE to utils.rs -extern "C" fn write_to_buf(string: *const c_char, buf: u32, max: u32, instance: &mut Instance) -> u32 { - let buf_addr = instance.memory_offset_addr(0, buf as _) as *mut c_char; - - unsafe { - for i in 0..max { - *buf_addr.add(i as _) = *string.add(i as _); - } - } - - buf -} - /// emscripten: _asctime_r pub extern "C" fn _asctime_r(time: u32, buf: u32, instance: &mut Instance) -> u32 { debug!("emscripten::_asctime {}", time); unsafe { - let date = &*(instance.memory_offset_addr(0, time as _) as *mut guest_tm); + // let date = &*(instance.memory_offset_addr(0, time as _) as *mut guest_tm); - let days = vec!["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; - let months = vec!["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; - let year = 1900 + date.tm_year; + // let days = vec!["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; + // let months = vec!["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; + // let year = 1900 + date.tm_year; - let time_str = format!( - // NOTE: The 14 accompanying chars are needed for some reason - "{} {} {:2} {:02}:{:02}:{:02} {:4}\n\0\0\0\0\0\0\0\0\0\0\0\0\0", - days[date.tm_wday as usize], - months[date.tm_mon as usize], - date.tm_mday, - date.tm_hour, - date.tm_min, - date.tm_sec, - year - ); + // let time_str = format!( + // // NOTE: The 14 accompanying chars are needed for some reason + // "{} {} {:2} {:02}:{:02}:{:02} {:4}\n\0\0\0\0\0\0\0\0\0\0\0\0\0", + // days[date.tm_wday as usize], + // months[date.tm_mon as usize], + // date.tm_mday, + // date.tm_hour, + // date.tm_min, + // date.tm_sec, + // year + // ); // NOTE: asctime_r is specced to behave in an undefined manner if the algorithm would attempt // to write out more than 26 bytes (including the null terminator). // See http://pubs.opengroup.org/onlinepubs/9699919799/functions/asctime.html // Our undefined behavior is to truncate the write to at most 26 bytes, including null terminator. - let time_str_ptr = time_str[0..26].as_ptr() as _; + let time_str_ptr = fmt_time(time, instance); write_to_buf(time_str_ptr, buf, 26, instance) // let c_str = instance.memory_offset_addr(0, time_str_offset as _) as *mut i8; @@ -170,7 +154,6 @@ pub extern "C" fn _asctime_r(time: u32, buf: u32, instance: &mut Instance) -> u3 } } - /// emscripten: _tvset pub extern "C" fn _tvset() { debug!("emscripten::_tvset UNIMPLEMENTED"); diff --git a/src/apis/emscripten/utils.rs b/src/apis/emscripten/utils.rs index af96463a8..a00421c7a 100644 --- a/src/apis/emscripten/utils.rs +++ b/src/apis/emscripten/utils.rs @@ -17,6 +17,18 @@ pub fn is_emscripten_module(module: &Module) -> bool { return false; } +pub unsafe fn write_to_buf(string: *const c_char, buf: u32, max: u32, instance: &Instance) -> u32 { + let buf_addr = instance.memory_offset_addr(0, buf as _) as *mut c_char; + + unsafe { + for i in 0..max { + *buf_addr.add(i as _) = *string.add(i as _); + } + } + + buf +} + pub unsafe fn copy_cstr_into_wasm(instance: &mut Instance, cstr: *const c_char) -> u32 { let s = CStr::from_ptr(cstr).to_str().unwrap(); let cstr_len = s.len();