%PDF- <> %âãÏÓ endobj 2 0 obj <> endobj 3 0 obj <>/ExtGState<>/ProcSet[/PDF/Text/ImageB/ImageC/ImageI] >>/Annots[ 28 0 R 29 0 R] /MediaBox[ 0 0 595.5 842.25] /Contents 4 0 R/Group<>/Tabs/S>> endobj ºaâÚÎΞ-ÌE1ÍØÄ÷{òò2ÿ ÛÖ^ÔÀá TÎ{¦?§®¥kuµùÕ5sLOšuY>endobj 2 0 obj<>endobj 2 0 obj<>endobj 2 0 obj<>endobj 2 0 obj<> endobj 2 0 obj<>endobj 2 0 obj<>es 3 0 R>> endobj 2 0 obj<> ox[ 0.000000 0.000000 609.600000 935.600000]/Fi endobj 3 0 obj<> endobj 7 1 obj<>/ProcSet[/PDF/Text/ImageB/ImageC/ImageI]>>/Subtype/Form>> stream
#include "wasi_serdes.h"
#include "wasi_types.h"
void uvwasi_serdes_write_uint64_t(void* ptr,
size_t offset,
uint64_t value) {
uvwasi_serdes_write_uint32_t(ptr, offset, (uint32_t) value);
uvwasi_serdes_write_uint32_t(ptr, offset + 4, value >> 32);
}
void uvwasi_serdes_write_uint32_t(void* ptr,
size_t offset,
uint32_t value) {
uvwasi_serdes_write_uint16_t(ptr, offset, (uint16_t) value);
uvwasi_serdes_write_uint16_t(ptr, offset + 2, value >> 16);
}
void uvwasi_serdes_write_uint16_t(void* ptr,
size_t offset,
uint16_t value) {
uvwasi_serdes_write_uint8_t(ptr, offset, (uint8_t) value);
uvwasi_serdes_write_uint8_t(ptr, offset + 1, value >> 8);
}
void uvwasi_serdes_write_uint8_t(void* ptr,
size_t offset,
uint8_t value) {
((uint8_t*) ptr)[offset] = value;
}
uint64_t uvwasi_serdes_read_uint64_t(const void* ptr, size_t offset) {
uint64_t low = uvwasi_serdes_read_uint32_t(ptr, offset);
uint64_t high = uvwasi_serdes_read_uint32_t(ptr, offset + 4);
return low | (high << 32);
}
uint32_t uvwasi_serdes_read_uint32_t(const void* ptr, size_t offset) {
uint32_t low = uvwasi_serdes_read_uint16_t(ptr, offset);
uint32_t high = uvwasi_serdes_read_uint16_t(ptr, offset + 2);
return low | (high << 16);
}
uint16_t uvwasi_serdes_read_uint16_t(const void* ptr, size_t offset) {
uint16_t low = uvwasi_serdes_read_uint8_t(ptr, offset);
uint16_t high = uvwasi_serdes_read_uint8_t(ptr, offset + 1);
return low | (high << 8);
}
uint8_t uvwasi_serdes_read_uint8_t(const void* ptr, size_t offset) {
return ((const uint8_t*) ptr)[offset];
}
#define TYPE_SWITCH switch (value->type)
#define ALL_TYPES(STRUCT, FIELD, ALIAS) \
\
ALIAS(advice_t, uint8_t) \
ALIAS(clockid_t, uint32_t) \
ALIAS(device_t, uint64_t) \
ALIAS(dircookie_t, uint64_t) \
ALIAS(errno_t, uint16_t) \
ALIAS(eventrwflags_t, uint16_t) \
ALIAS(eventtype_t, uint8_t) \
ALIAS(exitcode_t, uint32_t) \
ALIAS(fd_t, uint32_t) \
ALIAS(fdflags_t, uint16_t) \
ALIAS(filesize_t, uint64_t) \
ALIAS(filetype_t, uint8_t) \
ALIAS(fstflags_t, uint16_t) \
ALIAS(inode_t, uint64_t) \
ALIAS(linkcount_t, uint64_t) \
ALIAS(lookupflags_t, uint32_t) \
ALIAS(oflags_t, uint16_t) \
ALIAS(preopentype_t, uint8_t) \
ALIAS(riflags_t, uint16_t) \
ALIAS(rights_t, uint64_t) \
ALIAS(roflags_t, uint16_t) \
ALIAS(sdflags_t, uint8_t) \
ALIAS(siflags_t, uint16_t) \
ALIAS(signal_t, uint8_t) \
ALIAS(size_t, uint32_t) \
ALIAS(subclockflags_t, uint16_t) \
ALIAS(timestamp_t, uint64_t) \
ALIAS(userdata_t, uint64_t) \
ALIAS(whence_t, uint8_t) \
\
STRUCT(dirent_t) { \
FIELD( 0, dircookie_t, d_next); \
FIELD( 8, inode_t, d_ino); \
FIELD(16, uint32_t, d_namlen); \
FIELD(20, filetype_t, d_type); \
} \
\
STRUCT(fdstat_t) { \
FIELD( 0, filetype_t, fs_filetype); \
FIELD( 2, fdflags_t, fs_flags); \
FIELD( 8, rights_t, fs_rights_base); \
FIELD(16, rights_t, fs_rights_inheriting); \
} \
\
STRUCT(filestat_t) { \
FIELD( 0, device_t, st_dev); \
FIELD( 8, inode_t, st_ino); \
FIELD(16, filetype_t, st_filetype); \
FIELD(24, linkcount_t, st_nlink); \
FIELD(32, filesize_t, st_size); \
FIELD(40, timestamp_t, st_atim); \
FIELD(48, timestamp_t, st_mtim); \
FIELD(56, timestamp_t, st_ctim); \
} \
\
STRUCT(prestat_t) { \
FIELD(0, preopentype_t, pr_type); \
FIELD(4, uint32_t, u.dir.pr_name_len); \
} \
\
STRUCT(event_t) { \
FIELD( 0, userdata_t, userdata); \
FIELD( 8, errno_t, error); \
FIELD(10, eventtype_t, type); \
TYPE_SWITCH { \
case UVWASI_EVENTTYPE_FD_READ: \
case UVWASI_EVENTTYPE_FD_WRITE: \
FIELD(16, filesize_t, u.fd_readwrite.nbytes); \
FIELD(24, eventrwflags_t, u.fd_readwrite.flags); \
} \
} \
\
STRUCT(subscription_t) { \
FIELD(0, userdata_t, userdata); \
FIELD(8, eventtype_t, type); \
TYPE_SWITCH { \
case UVWASI_EVENTTYPE_CLOCK: \
FIELD(16, clockid_t, u.clock.clock_id); \
FIELD(24, timestamp_t, u.clock.timeout); \
FIELD(32, timestamp_t, u.clock.precision); \
FIELD(40, subclockflags_t, u.clock.flags); \
break; \
case UVWASI_EVENTTYPE_FD_READ: \
case UVWASI_EVENTTYPE_FD_WRITE: \
FIELD(16, fd_t, u.fd_readwrite.fd); \
} \
} \
#define WRITE_STRUCT(name) \
void uvwasi_serdes_write_##name(void* ptr, \
size_t offset, \
const uvwasi_##name* value) \
#define READ_STRUCT(name) \
void uvwasi_serdes_read_##name(const void* ptr, \
size_t offset, \
uvwasi_##name* value) \
#define WRITE_FIELD(field_offset, type, field) \
do { \
uvwasi_serdes_write_##type(ptr, offset + field_offset, value->field); \
} while (0) \
#define READ_FIELD(field_offset, type, field) \
do { \
value->field = uvwasi_serdes_read_##type(ptr, offset + field_offset); \
} while (0) \
#define WRITE_ALIAS(new_name, old_name) \
void uvwasi_serdes_write_##new_name(void* ptr, \
size_t offset, \
uvwasi_##new_name value) { \
uvwasi_serdes_write_##old_name(ptr, offset, value); \
} \
#define READ_ALIAS(new_name, old_name) \
uvwasi_##new_name uvwasi_serdes_read_##new_name(const void* ptr, \
size_t offset) { \
return uvwasi_serdes_read_##old_name(ptr, offset); \
} \
ALL_TYPES(WRITE_STRUCT, WRITE_FIELD, WRITE_ALIAS)
ALL_TYPES(READ_STRUCT, READ_FIELD, READ_ALIAS)
uvwasi_errno_t uvwasi_serdes_read_ciovec_t(const void* ptr,
size_t end,
size_t offset,
uvwasi_ciovec_t* value) {
uint32_t buf_ptr;
buf_ptr = uvwasi_serdes_read_uint32_t(ptr, offset);
value->buf_len = uvwasi_serdes_read_size_t(ptr, offset + 4);
if (!uvwasi_serdes_check_bounds(buf_ptr, end, value->buf_len))
return UVWASI_EOVERFLOW;
value->buf = ((uint8_t*) ptr + buf_ptr);
return UVWASI_ESUCCESS;
}
uvwasi_errno_t uvwasi_serdes_read_iovec_t(const void* ptr,
size_t end,
size_t offset,
uvwasi_iovec_t* value) {
uint32_t buf_ptr;
buf_ptr = uvwasi_serdes_read_uint32_t(ptr, offset);
value->buf_len = uvwasi_serdes_read_size_t(ptr, offset + 4);
if (!uvwasi_serdes_check_bounds(buf_ptr, end, value->buf_len))
return UVWASI_EOVERFLOW;
value->buf = ((uint8_t*) ptr + buf_ptr);
return UVWASI_ESUCCESS;
}
uvwasi_errno_t uvwasi_serdes_readv_ciovec_t(const void* ptr,
size_t end,
size_t offset,
uvwasi_ciovec_t* iovs,
uvwasi_size_t iovs_len) {
uvwasi_errno_t err;
uvwasi_size_t i;
for (i = 0; i < iovs_len; i++) {
err = uvwasi_serdes_read_ciovec_t(ptr, end, offset, &iovs[i]);
if (err != UVWASI_ESUCCESS)
return err;
offset += UVWASI_SERDES_SIZE_ciovec_t;
}
return UVWASI_ESUCCESS;
}
uvwasi_errno_t uvwasi_serdes_readv_iovec_t(const void* ptr,
size_t end,
size_t offset,
uvwasi_iovec_t* iovs,
uvwasi_size_t iovs_len) {
uvwasi_errno_t err;
uvwasi_size_t i;
for (i = 0; i < iovs_len; i++) {
err = uvwasi_serdes_read_iovec_t(ptr, end, offset, &iovs[i]);
if (err != UVWASI_ESUCCESS)
return err;
offset += UVWASI_SERDES_SIZE_iovec_t;
}
return UVWASI_ESUCCESS;
}
int uvwasi_serdes_check_bounds(size_t offset, size_t end, size_t size) {
return end > offset && size <= (end - offset);
}
int uvwasi_serdes_check_array_bounds(size_t offset,
size_t end,
size_t size,
size_t count) {
return end > offset &&
((count * size) / size == count) &&
(count * size <= end - offset);
}