summaryrefslogtreecommitdiffstats
path: root/sys/link.c
blob: 592fe8f0b1bb709bd51f53ae553f583c4db1155c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include "link.h"
#include "arch/x86_64/hal/obj.h"
#include "hal/memory.h"

uint8_t 
link_gettype(jove_owned_obj_t *obj)
{
    return obj_gettype(link_deref(obj));
}

uint8_t 
link_getperm(jove_owned_obj_t *link)
{
    struct obj_link *linkval = obj_deref(link);
    return linkval->permissions;
}

uint64_t 
link_getvalue(jove_owned_obj_t *obj)
{
    return obj_getvalue(link_deref(obj));
}

jove_owned_obj_t*
link_deref(jove_owned_obj_t *link)
{
    struct obj_link *linkval = obj_deref(link);
    return obj_take(&linkval->obj);
}

jove_owned_obj_t*
link_try_deref(jove_owned_obj_t *link)
{
    struct obj_link *linkval = obj_deref(link);
    return obj_trytake(&linkval->obj);
}

jove_perm_obj_t 
link_traverse(jove_owned_obj_t *link, lockstack_t *lockstack)
{
    jove_perm_obj_t perm_obj = { .obj = link, .permissions = JOVE_PERM_ALL };
    while(obj_gettype(perm_obj.obj) == JOVE_OBJ_LINK) {
        perm_obj.permissions &= link_getperm(perm_obj.obj);
        perm_obj.obj = lockstack_push(lockstack, link_deref(perm_obj.obj));
    }
    return perm_obj;
}

jove_perm_obj_t 
link_try_traverse(jove_owned_obj_t *link, lockstack_t *lockstack)
{
    jove_perm_obj_t perm_obj = { .obj = link, .permissions = JOVE_PERM_ALL };
    while(perm_obj.obj != NULL && obj_gettype(perm_obj.obj) == JOVE_OBJ_LINK) {
        perm_obj.permissions &= link_getperm(perm_obj.obj);
        perm_obj.obj = lockstack_push(lockstack, link_deref(perm_obj.obj));
    }
    return perm_obj;
}

jove_owned_obj_t *link_new(jove_obj_t *tgt, jove_owned_obj_t *dst, uint16_t permissions)
{
    struct obj_link *linkval = obj_deref(dst);
    linkval->obj = *tgt;
    linkval->refcount = 2;
    linkval->permissions = permissions;

    {
        jove_owned_obj_t *tgt_owned = obj_take(tgt);
        obj_settype(tgt_owned, JOVE_OBJ_LINK);
        obj_setvalue(tgt_owned, (uintptr_t)linkval);
        obj_release(tgt_owned);
    }
    return dst;
}