]> gitweb.factorcode.org Git - factor.git/blob - vm/tagged.hpp
vm: 4 bit tags, new representation of alien objects makes unbox-any-c-ptr more effici...
[factor.git] / vm / tagged.hpp
1 namespace factor
2 {
3
4 template<typename Type> cell tag(Type *value)
5 {
6         return RETAG(value,Type::type_number);
7 }
8
9 inline static cell tag_dynamic(object *value)
10 {
11         return RETAG(value,value->h.hi_tag());
12 }
13
14 template<typename Type>
15 struct tagged
16 {
17         cell value_;
18
19         cell type() const {
20                 return TAG(value_);
21         }
22
23         bool type_p(cell type_) const
24         {
25                 return type() == type_;
26         }
27
28         bool type_p() const
29         {
30                 if(Type::type_number == TYPE_COUNT)
31                         return true;
32                 else
33                         return type_p(Type::type_number);
34         }
35
36         cell value() const {
37 #ifdef FACTOR_DEBUG
38                 assert(type_p());
39 #endif
40                 return value_;
41         }
42         Type *untagged() const {
43 #ifdef FACTOR_DEBUG
44                 assert(type_p());
45 #endif
46                 return (Type *)(UNTAG(value_));
47         }
48
49         Type *untag_check(factor_vm *parent) const {
50                 if(!type_p())
51                         parent->type_error(Type::type_number,value_);
52                 return untagged();
53         }
54
55         explicit tagged(cell tagged) : value_(tagged) {}
56         explicit tagged(Type *untagged) : value_(factor::tag(untagged)) {}
57
58         Type *operator->() const { return untagged(); }
59         cell *operator&() const { return &value_; }
60
61         const tagged<Type> &operator=(const Type *x) { value_ = tag(x); return *this; }
62         const tagged<Type> &operator=(const cell &x) { value_ = x; return *this; }
63
64         bool operator==(const tagged<Type> &x) { return value_ == x.value_; }
65         bool operator!=(const tagged<Type> &x) { return value_ != x.value_; }
66
67         template<typename NewType> tagged<NewType> as() { return tagged<NewType>(value_); }
68 };
69
70 template<typename Type> Type *factor_vm::untag_check(cell value)
71 {
72         return tagged<Type>(value).untag_check(this);
73 }
74
75 template<typename Type> Type *untag(cell value)
76 {
77         return tagged<Type>(value).untagged();
78 }
79
80 }