I think read will now read integers and symbols, but it's untested.
Everything compiles.
This commit is contained in:
parent
cc8e96eda4
commit
9eb0d3c5a0
28 changed files with 594 additions and 293 deletions
|
|
@ -29,24 +29,35 @@ struct pso_pointer make_pointer( uint32_t node, uint16_t page,
|
|||
|
||||
/**
|
||||
* @brief returns the in-memory address of the object indicated by this
|
||||
* pointer. TODO: Yhe reason I'm doing it this way is because I'm not
|
||||
* pointer `p`.
|
||||
*
|
||||
* NOTE THAT: It's impossible, with our calling conventions, to pass an
|
||||
* exception back from this function. Consequently, if anything goes wrong
|
||||
* we return NULL. The caller *should* check for that and throw an exception.
|
||||
*
|
||||
* NOTE THAT: The return signature of these functions is pso2, because it is
|
||||
* safe to cast any paged space object to a pso2, but safe to cast an object
|
||||
* of a smaller size class to a larger one. If you know what size class you
|
||||
* want, you should prefer `pointer_to_object_of_size_class()`, q.v.
|
||||
*
|
||||
* TODO: The reason I'm doing it this way is because I'm not
|
||||
* certain reference counter updates work right it we work with 'the object'
|
||||
* rather than 'the address of the object'. I really ought to have a
|
||||
* conversation with someone who understands this bloody language.
|
||||
*
|
||||
* @param pointer a pso_pointer which references an object.
|
||||
* @return struct pso2* the actual address in memory of that object.
|
||||
* @param p a pso_pointer which references an object.
|
||||
*
|
||||
* @return the actual address in memory of that object, or NULL if `p` is
|
||||
* invalid.
|
||||
*/
|
||||
struct pso2 *pointer_to_object( struct pso_pointer pointer ) {
|
||||
struct pso2 *pointer_to_object( struct pso_pointer p ) {
|
||||
struct pso2 *result = NULL;
|
||||
|
||||
if ( pointer.node == node_index ) {
|
||||
if (pointer.page < get_pages_allocated() && pointer.offset < (PAGE_BYTES / 8)) {
|
||||
if ( p.node == node_index ) {
|
||||
if (p.page < get_pages_allocated() && p.offset < (PAGE_BYTES / 8)) {
|
||||
// TODO: that's not really a safe test of whether this is a valid pointer.
|
||||
union page *pg = pages[pointer.page];
|
||||
result = ( struct pso2 * ) &pg->words[pointer.offset];
|
||||
} else {
|
||||
// TODO: throw bad pointer exception.
|
||||
union page *pg = pages[p.page];
|
||||
result = ( struct pso2 * ) &pg->words[p.offset];
|
||||
}
|
||||
}
|
||||
// TODO: else if we have a copy of the object in cache, return that;
|
||||
|
|
@ -54,3 +65,51 @@ struct pso2 *pointer_to_object( struct pso_pointer pointer ) {
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief returns the memory address of the object indicated by this pointer
|
||||
* `p`, if it is of this `size_class`.
|
||||
*
|
||||
* NOTE THAT: It's impossible, with our calling conventions, to pass an
|
||||
* exception back from this function. Consequently, if anything goes wrong
|
||||
* we return NULL. The caller *should* check for that and throw an exception.
|
||||
*
|
||||
* NOTE THAT: The return signature of these functions is pso2, because it is
|
||||
* safe to cast any paged space object to a pso2, but safe to cast an object
|
||||
* of a smaller size class to a larger one. You should check that the object
|
||||
* returned has the size class you expect.
|
||||
*
|
||||
* @param p a pointer to an object;
|
||||
* @param size_class a size class.
|
||||
*
|
||||
* @return the memory address of the object, provided it is a valid object and
|
||||
* of the specified size class, else NULL.
|
||||
*/
|
||||
struct pso2 * pointer_to_object_of_size_class( struct pso_pointer p, uint8_t size_class) {
|
||||
struct pso2 * result = pointer_to_object( p);
|
||||
|
||||
if (result->header.tag.bytes.size_class != size_class) {
|
||||
result = NULL;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief returns the memory address of the object indicated by this pointer
|
||||
* `p`, if it has this `tag_value`.
|
||||
*
|
||||
* NOTE THAT: It's impossible, with our calling conventions, to pass an
|
||||
* exception back from this function. Consequently, if anything goes wrong
|
||||
* we return NULL. The caller *should* check for that and throw an exception.
|
||||
*/
|
||||
struct pso2 * pointer_to_object_with_tag_value( struct pso_pointer p, uint32_t tag_value) {
|
||||
struct pso2 * result = pointer_to_object( p);
|
||||
|
||||
if ((result->header.tag.value & 0xffffff) != tag_value) {
|
||||
result = NULL;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue