2018-11-27 04:29:26 +00:00
|
|
|
use super::utils::copy_cstr_into_wasm;
|
2018-11-26 21:15:49 +00:00
|
|
|
use libc::{
|
|
|
|
c_int,
|
2018-11-26 22:27:56 +00:00
|
|
|
c_long,
|
2018-11-26 21:20:10 +00:00
|
|
|
clock_gettime as libc_clock_gettime,
|
2018-11-27 04:28:13 +00:00
|
|
|
// tm,
|
2018-11-26 21:15:49 +00:00
|
|
|
localtime,
|
2018-11-27 04:29:26 +00:00
|
|
|
time,
|
2018-11-26 21:15:49 +00:00
|
|
|
time_t,
|
2018-11-27 04:29:26 +00:00
|
|
|
timespec,
|
2018-11-26 21:15:49 +00:00
|
|
|
};
|
2018-11-27 04:29:26 +00:00
|
|
|
use std::mem;
|
2018-11-26 21:30:55 +00:00
|
|
|
use std::time::SystemTime;
|
2018-11-26 20:28:20 +00:00
|
|
|
|
|
|
|
use crate::webassembly::Instance;
|
|
|
|
|
|
|
|
/// emscripten: _gettimeofday
|
2018-11-27 04:29:26 +00:00
|
|
|
pub extern "C" fn _gettimeofday(tp: c_int, tz: c_int, instance: &mut Instance) -> c_int {
|
2018-11-26 21:45:38 +00:00
|
|
|
#[repr(C)]
|
|
|
|
struct GuestTimeVal {
|
|
|
|
tv_sec: i32,
|
|
|
|
tv_usec: i32,
|
|
|
|
}
|
2018-11-26 20:28:20 +00:00
|
|
|
|
2018-11-27 04:29:26 +00:00
|
|
|
assert!(
|
|
|
|
tz == 0,
|
|
|
|
"the timezone argument of `_gettimeofday` must be null"
|
|
|
|
);
|
2018-11-26 20:28:20 +00:00
|
|
|
unsafe {
|
2018-11-26 21:45:38 +00:00
|
|
|
let now = SystemTime::now();
|
|
|
|
let since_epoch = now.duration_since(SystemTime::UNIX_EPOCH).unwrap();
|
|
|
|
let timeval_struct_ptr = instance.memory_offset_addr(0, tp as _) as *mut GuestTimeVal;
|
2018-11-26 20:28:20 +00:00
|
|
|
|
2018-11-26 21:45:38 +00:00
|
|
|
(*timeval_struct_ptr).tv_sec = since_epoch.as_secs() as _;
|
|
|
|
(*timeval_struct_ptr).tv_usec = since_epoch.subsec_nanos() as _;
|
2018-11-26 20:28:20 +00:00
|
|
|
}
|
2018-11-26 21:45:38 +00:00
|
|
|
0
|
2018-11-26 20:28:20 +00:00
|
|
|
}
|
2018-11-26 20:42:47 +00:00
|
|
|
|
2018-11-26 20:28:20 +00:00
|
|
|
/// emscripten: _clock_gettime
|
2018-11-27 04:29:26 +00:00
|
|
|
pub extern "C" fn _clock_gettime(clk_id: c_int, tp: c_int, instance: &mut Instance) -> c_int {
|
2018-11-26 21:45:38 +00:00
|
|
|
#[repr(C)]
|
|
|
|
struct GuestTimeSpec {
|
|
|
|
tv_sec: i32,
|
|
|
|
tv_nsec: i32,
|
|
|
|
}
|
2018-11-26 20:28:20 +00:00
|
|
|
|
|
|
|
unsafe {
|
2018-11-26 21:45:38 +00:00
|
|
|
let mut timespec = timespec {
|
|
|
|
tv_sec: 0,
|
|
|
|
tv_nsec: 0,
|
|
|
|
};
|
|
|
|
let ret = libc_clock_gettime(clk_id as _, &mut timespec);
|
|
|
|
if ret != 0 {
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
let timespec_struct_ptr = instance.memory_offset_addr(0, tp as _) as *mut GuestTimeSpec;
|
|
|
|
(*timespec_struct_ptr).tv_sec = timespec.tv_sec as _;
|
|
|
|
(*timespec_struct_ptr).tv_nsec = timespec.tv_nsec as _;
|
2018-11-26 20:28:20 +00:00
|
|
|
}
|
2018-11-26 21:45:38 +00:00
|
|
|
0
|
2018-11-26 20:28:20 +00:00
|
|
|
}
|
2018-11-26 21:15:49 +00:00
|
|
|
|
|
|
|
/// emscripten: _localtime
|
2018-11-26 22:27:56 +00:00
|
|
|
pub extern "C" fn _localtime(time_p: u32, instance: &mut Instance) -> c_int {
|
2018-11-26 21:15:49 +00:00
|
|
|
debug!("emscripten::_localtime {}", time_p);
|
|
|
|
|
2018-11-26 22:27:56 +00:00
|
|
|
#[repr(C)]
|
|
|
|
struct GuestTm {
|
|
|
|
tm_sec: i32,
|
|
|
|
tm_min: i32,
|
|
|
|
tm_hour: i32,
|
|
|
|
tm_mday: i32,
|
|
|
|
tm_mon: i32,
|
|
|
|
tm_year: i32,
|
|
|
|
tm_wday: i32,
|
|
|
|
tm_yday: i32,
|
|
|
|
tm_isdst: i32,
|
|
|
|
tm_gmtoff: c_long,
|
|
|
|
tm_zone: u32,
|
|
|
|
}
|
|
|
|
|
2018-11-26 21:15:49 +00:00
|
|
|
unsafe {
|
|
|
|
let time_p_addr = instance.memory_offset_addr(0, time_p as _) as *mut i64;
|
2018-11-26 22:27:56 +00:00
|
|
|
let tm_struct = &*localtime(time_p_addr);
|
|
|
|
|
|
|
|
// Webassembly allocation
|
2018-11-28 21:25:56 +00:00
|
|
|
let tm_struct_offset = (instance.emscripten_data.as_ref().unwrap().malloc)(
|
|
|
|
mem::size_of::<GuestTm>() as _,
|
|
|
|
instance,
|
|
|
|
);
|
2018-11-26 22:27:56 +00:00
|
|
|
let tm_struct_ptr = instance.memory_offset_addr(0, tm_struct_offset as _) as *mut GuestTm;
|
|
|
|
|
|
|
|
// Initializing
|
|
|
|
(*tm_struct_ptr).tm_sec = tm_struct.tm_sec;
|
|
|
|
(*tm_struct_ptr).tm_min = tm_struct.tm_min;
|
|
|
|
(*tm_struct_ptr).tm_hour = tm_struct.tm_hour;
|
|
|
|
(*tm_struct_ptr).tm_mday = tm_struct.tm_mday;
|
|
|
|
(*tm_struct_ptr).tm_mon = tm_struct.tm_mon;
|
|
|
|
(*tm_struct_ptr).tm_year = tm_struct.tm_year;
|
|
|
|
(*tm_struct_ptr).tm_wday = tm_struct.tm_wday;
|
|
|
|
(*tm_struct_ptr).tm_yday = tm_struct.tm_yday;
|
|
|
|
(*tm_struct_ptr).tm_isdst = tm_struct.tm_isdst;
|
|
|
|
(*tm_struct_ptr).tm_gmtoff = tm_struct.tm_gmtoff;
|
|
|
|
(*tm_struct_ptr).tm_zone = copy_cstr_into_wasm(instance, tm_struct.tm_zone);
|
|
|
|
|
|
|
|
tm_struct_offset as c_int
|
2018-11-26 21:15:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// emscripten: _time
|
|
|
|
pub extern "C" fn _time(time_p: u32, instance: &mut Instance) -> time_t {
|
|
|
|
debug!("emscripten::_time {}", time_p);
|
|
|
|
|
|
|
|
unsafe {
|
|
|
|
let time_p_addr = instance.memory_offset_addr(0, time_p as _) as *mut i64;
|
|
|
|
time(time_p_addr)
|
|
|
|
}
|
|
|
|
}
|
2018-11-26 22:16:51 +00:00
|
|
|
|
|
|
|
/// emscripten: _strftime
|
2018-11-27 04:29:26 +00:00
|
|
|
pub extern "C" fn _strftime(
|
|
|
|
s_ptr: c_int,
|
|
|
|
maxsize: u32,
|
|
|
|
format_ptr: c_int,
|
|
|
|
tm_ptr: c_int,
|
|
|
|
_instance: &mut Instance,
|
|
|
|
) -> time_t {
|
|
|
|
debug!(
|
|
|
|
"emscripten::_strftime {} {} {} {}",
|
|
|
|
s_ptr, maxsize, format_ptr, tm_ptr
|
|
|
|
);
|
2018-11-26 22:16:51 +00:00
|
|
|
0
|
|
|
|
}
|