From 7da2f9e7919930835e23494f60c3ca43bc908d05 Mon Sep 17 00:00:00 2001 From: Peter Evans Date: Tue, 12 Dec 2017 14:58:06 -0600 Subject: [PATCH] Add support for setting read/write map functions --- include/vm_segment.h | 2 ++ src/vm_segment.c | 26 ++++++++++++++++++++++++++ tests/vm_segment.c | 21 +++++++++++++++++++++ 3 files changed, 49 insertions(+) diff --git a/include/vm_segment.h b/include/vm_segment.h index d0c6a73..5a03b85 100644 --- a/include/vm_segment.h +++ b/include/vm_segment.h @@ -58,5 +58,7 @@ extern vm_segment *vm_segment_create(size_t); extern void vm_segment_free(vm_segment *); extern vm_8bit vm_segment_get(vm_segment *, size_t); extern int vm_segment_set(vm_segment *, size_t, vm_8bit); +extern int vm_segment_read_map(vm_segment *, size_t, vm_segment_read_fn); +extern int vm_segment_write_map(vm_segment *, size_t, vm_segment_write_fn); #endif diff --git a/src/vm_segment.c b/src/vm_segment.c index 620ef7f..282e050 100644 --- a/src/vm_segment.c +++ b/src/vm_segment.c @@ -157,3 +157,29 @@ vm_segment_copy(vm_segment *dest, return OK; } + +int +vm_segment_read_map(vm_segment *segment, + size_t addr, + vm_segment_read_fn fn) +{ + if (addr >= segment->size) { + return ERR_OOB; + } + + segment->read_table[addr] = fn; + return OK; +} + +int +vm_segment_write_map(vm_segment *segment, + size_t addr, + vm_segment_write_fn fn) +{ + if (addr >= segment->size) { + return ERR_OOB; + } + + segment->write_table[addr] = fn; + return OK; +} diff --git a/tests/vm_segment.c b/tests/vm_segment.c index 9a543f5..73a4604 100644 --- a/tests/vm_segment.c +++ b/tests/vm_segment.c @@ -72,3 +72,24 @@ Test(vm_segment, copy) { vm_segment_free(src); vm_segment_free(dest); } + +Test(vm_segment, read_map) +{ + // We use some trickery here; I don't want to go to the trouble of + // defining a function for this test, so I am just passing in an + // arbitrary pointer to junk. As long as the garbage-in, garbage-out + // principle holds, we're golden. + cr_assert_eq(vm_segment_read_map(segment, 123, (vm_segment_read_fn)456), OK); + cr_assert_eq(vm_segment_read_map(segment, 321, (vm_segment_read_fn)456), ERR_OOB); + + cr_assert_eq(segment->read_table[123], (vm_segment_read_fn)456); +} + +Test(vm_segment, write_map) +{ + // See the read_map test for more details on the following trickery + cr_assert_eq(vm_segment_write_map(segment, 123, (vm_segment_write_fn)456), OK); + cr_assert_eq(vm_segment_write_map(segment, 321, (vm_segment_write_fn)456), ERR_OOB); + + cr_assert_eq(segment->write_table[123], (vm_segment_write_fn)456); +}