The Typesystem¶
Supported Types¶
Like C++, PochiVM is static-typed. All type information must be known at the time a generated program is compiled into native binary.
PochiVM currently supports the following types:
Most of the C++ fundamental types, specifically
void
,bool
,uint8_t
,int8_t
,uint16_t
,int16_t
,uint32_t
,int32_t
,uint64_t
,int64_t
,float
,double
Any
C++ class
type registered inpochivm_register_runtime.cpp
Types obtained by adding one or multiple layers of pointers to all above types
Note
Support for remaining C++ fundamental types (the most important being char
) is a TODO.
Notable valid C++ types that do not fall into the above category include:
const
-qualified orvolatile
-qualified types.C-style function-pointer, member-function-pointer, or member-object-pointer types.
Note that the template-parameter part in a C++ class is never subject to the above restriction.
For example, std::function<void(int)>
(as a whole) is just a C++ class type.
The typesystem does not care and is unaware of whatever is in the template parameter.
Terminology¶
Throughout the documentation, we will use the following terminology for types.
- C++ Type
A
C++ class
type registered inpochivm_register_runtime.cpp
thus accessible to generated code, typically denoted byC
in relavent contexts. For example,std::set<int>
is a C++ type.- Primitive Type
A type that is not a C++ type. For example,
int**
,std::set<int>*
,bool
are primitive types.
Value, Reference and Variable¶
-
template<typename
T
>
classValue
¶
Value<T>
is probably the most important class in PochiVM.
It is analogous to a RValue of type T
in C++, which resulted from some computation,
for example, the result of expression a+b+c
.
The APIs of this class are documented in a standalone section.
For now, it’s sufficient to understand that it represents a RValue of type T
.
-
template<typename
T
>
classReference
¶
Similarily, a Reference<T>
represents a LValue-reference of type T
.
It is analogous to a RValue of type T&
in C++.
For a primitive type T
, Reference<T>
inherits Value<T>
,
which implies that a Reference<T>
can be implicitly converted to a Value<T>
and passed
to any API that accepts a Value<T>
parameter, just like a lvalue-reference can be implicitly converted to a rvalue in C++.
The resulted Value<T>
will contain the value stored in the reference
at the time the dereference operation is executed in the generated program, just like in C++.
However, for a C++ type C
,
dereferencing a LValue-reference to obtain a RValue involves a call to the copy constructor of class C
,
This is an operation hidden behind the scene.
We want our generated program to have straight-forward behavior,
so we disallow such conversions. Therefore for C++ type C
, Reference<C>
does not inherit Value<C>
.
Reference<C>
is also specialized to provide APIs to access any member functions and objects of class C
that are registered in pochivm_register_runtime.cpp
.
E.g., suppose the member function void std::vector<int>::push_back(const int&)
is registered,
class Reference<std::vector<int>>
would be specialized to have a member function Value<void> push_back(Value<int>)
.
Then, given a variable a
of type Reference<std::vector<int>>
,
one can write a.push_back(Literal<int>(1))
to call the push_back
member function and push a 1
to the end of the vector.
For more information, see Interacting with C++ Runtime.
The “operation hidden behind the scene” issue also applies for Value<C>
itself.
A RValue of a C++ class C
(aka a temporary object) has to be destructed when the full-expression is evaluated –
an undesirable hidden operation behind the scene,
not even considering the additional trickiness to define “full expression” in PochiVM in a precise and intuitive way.
Therefore, we do not in general support Value<C>
.
There is only one way you can get an instance of Value<C>
:
from the return value of a C++ function. And this Value<C>
has only one usage:
either being move-assigned into a Reference<C>
,
or being in-place-constructed (C++17 guaranteed copy-elision applies here) into a Variable<C>
.
In this sense, Value<C>
is analogous to a prvalue of type C
under C++17 definition.
-
template<typename
T
>
classVariable
¶
The last important class in PochiVM is Variable<T>
. It is analogous to a local variable of type T
in C++.
As one would expect, it must be declared (and initialized by a constructor if it has a C++ type) before it can be used,
and when the declaration goes out of scope, its destructor will be called.
This class inherits Reference<T>
, so it may be passed to any API that takes a Reference<T>
(or Value<T>
, if T is not a C++ type). The semantics is clear: a local variable is obviously a reference.
Finally, C++11 rvalue-reference type (T&&
) is not supported in PochiVM, thus does not have an analogy in the typesystem.
The table below summarizes the PochiVM typesystem:
PochiVM Type |
C++ Analogy |
Inheritance |
---|---|---|
|
rvalue of type |
None |
|
rvalue of type |
Inherits |
|
prvalue of type |
None |
|
rvalue of type |
None |
|
local variable of type |
Inherits |