pub(crate) struct ExprCodegen<'cx, 'db> {
cx: &'cx mut Cx<'db>,
generics: Map<SymVariable<'db>, SymGenericTerm<'db>>,
wasm_locals: Vec<ValType>,
wasm_stack_pointer: WasmLocal,
wasm_stack_frame_size: u32,
variables: Map<SymVariable<'db>, Arc<WasmPlaceRepr>>,
instructions: Vec<Instruction<'static>>,
}Fields§
§cx: &'cx mut Cx<'db>§generics: Map<SymVariable<'db>, SymGenericTerm<'db>>Values of any generic variables
wasm_locals: Vec<ValType>Accumulates wasm locals. We make no effort to reduce the number of local variables created.
wasm_stack_pointer: WasmLocalLocal variable that stores starting address in our stack frame
wasm_stack_frame_size: u32Values we are putting onto the stack frame (actually located in the WASM heap)
variables: Map<SymVariable<'db>, Arc<WasmPlaceRepr>>Maps each Dada variable to a range of wasm locals. Note that a single value can be inlined into multiple wasm locals.
instructions: Vec<Instruction<'static>>Accumulates wasm instructions.
Implementations§
Source§impl<'db> ExprCodegen<'_, 'db>
impl<'db> ExprCodegen<'_, 'db>
Sourcepub(super) fn next_stack_frame(&self) -> WasmPointer
pub(super) fn next_stack_frame(&self) -> WasmPointer
Returns a WasmPointer to the current start of a callee’s stack frame.
This value is only valid until Self::insert_variable is next called.
Sourcepub(super) fn insert_variable(&mut self, lv: SymVariable<'db>, ty: SymTy<'db>)
pub(super) fn insert_variable(&mut self, lv: SymVariable<'db>, ty: SymTy<'db>)
Introduce the variable lv into scope and create a place for it.
This can allocate more stack space in WASM memory.
You can find this place by invoking Self::place_for_local later on.
Sourcepub(super) fn place_for_local(
&self,
local_variable: SymVariable<'db>,
) -> Arc<WasmPlaceRepr>
pub(super) fn place_for_local( &self, local_variable: SymVariable<'db>, ) -> Arc<WasmPlaceRepr>
The representation of the place represented by local_variable.
Sourcepub(super) fn place(&self, place: SymPlaceExpr<'db>) -> Arc<WasmPlaceRepr>
pub(super) fn place(&self, place: SymPlaceExpr<'db>) -> Arc<WasmPlaceRepr>
The representation of the given Dada place.
Sourcepub(super) fn push_from(&mut self, place: &WasmPlaceRepr)
pub(super) fn push_from(&mut self, place: &WasmPlaceRepr)
Push the value found in place onto the WASM stack.
Push a shared copy the value found in place onto the WASM stack.
Sourcepub(super) fn push_leased_from(&mut self, place: &WasmPlaceRepr)
pub(super) fn push_leased_from(&mut self, place: &WasmPlaceRepr)
Push a shared copy the value found in place onto the WASM stack.
Sourcepub(super) fn pop_and_store(&mut self, to_place: &WasmPlaceRepr)
pub(super) fn pop_and_store(&mut self, to_place: &WasmPlaceRepr)
Given that a value of type value_ty is on the wasm stack, pop it and store it into to_place.
Sourcefn field_place(
&self,
owner_place_repr: Arc<WasmPlaceRepr>,
owner_ty: SymTy<'db>,
field: SymField<'db>,
) -> Arc<WasmPlaceRepr>
fn field_place( &self, owner_place_repr: Arc<WasmPlaceRepr>, owner_ty: SymTy<'db>, field: SymField<'db>, ) -> Arc<WasmPlaceRepr>
Representation for the place storing a given field found in
an owner of type owner_ty that is stored in owner_place.
Sourcefn emplace_local(&mut self, repr: &WasmRepr) -> Arc<WasmPlaceRepr>
fn emplace_local(&mut self, repr: &WasmRepr) -> Arc<WasmPlaceRepr>
Returns the representation of a “local” storing a value of type repr.
A “local” place is one that uses WASM local variables as much as possible.
Sourcefn emplace_memory(&mut self, repr: &WasmRepr) -> Arc<WasmPlaceRepr>
fn emplace_memory(&mut self, repr: &WasmRepr) -> Arc<WasmPlaceRepr>
The representation for a Dada place found in WASM memory
that stores values with representation repr.
Sourcefn fresh_local_index(&mut self, v: ValType) -> WasmLocal
fn fresh_local_index(&mut self, v: ValType) -> WasmLocal
Create a fresh local index storing a value of type v.
Sourcefn fresh_memory_slot(&mut self, v: ValType) -> WasmPointer
fn fresh_memory_slot(&mut self, v: ValType) -> WasmPointer
Create a fresh slot in memory storing a value of type v.
Sourcefn push_from_local(&mut self, val_type: ValType, local: WasmLocal)
fn push_from_local(&mut self, val_type: ValType, local: WasmLocal)
Push a value of type val_type found in local.
Sourcefn pop_to_local(&mut self, v: ValType, local: WasmLocal)
fn pop_to_local(&mut self, v: ValType, local: WasmLocal)
Pop a value of type val_type and store it in local.
Sourcefn push_from_memory(&mut self, v: ValType, _: WasmPointer)
fn push_from_memory(&mut self, v: ValType, _: WasmPointer)
Push a value of type val_type found in the given memory slot.
Sourcepub(super) fn push_pointer(&mut self, _: WasmPointer)
pub(super) fn push_pointer(&mut self, _: WasmPointer)
Push a pointer itself onto the WASM stack (not the data it refers to).
Sourcefn pop_to_memory(&mut self, v: ValType, _: WasmPointer)
fn pop_to_memory(&mut self, v: ValType, _: WasmPointer)
Pop a value of type val_type and store it to the given memory slot.
Source§impl<'cx, 'db> ExprCodegen<'cx, 'db>
impl<'cx, 'db> ExprCodegen<'cx, 'db>
pub fn new( cx: &'cx mut Cx<'db>, generics: Map<SymVariable<'db>, SymGenericTerm<'db>>, ) -> Self
pub fn into_function(self) -> Function
Sourcepub fn wasm_repr_of_type(&self, ty: SymTy<'db>) -> WasmRepr
pub fn wasm_repr_of_type(&self, ty: SymTy<'db>) -> WasmRepr
Returns the WasmRepr for a Dada type.
pub fn pop_arguments( &mut self, inputs: &[SymVariable<'db>], input_tys: &[SymTy<'db>], )
Sourcepub fn push_expr(&mut self, expr: SymExpr<'db>)
pub fn push_expr(&mut self, expr: SymExpr<'db>)
Generate code to execute the expression, leaving the result on the top of the wasm stack.
fn pop_and_drop(&mut self, _of_type: SymTy<'db>)
pub(super) fn pop_and_return(&mut self, _of_type: SymTy<'db>)
Sourcefn execute_binary_op(
&mut self,
binary_op: SymBinaryOp,
lhs_ty: SymTy<'db>,
rhs_ty: SymTy<'db>,
)
fn execute_binary_op( &mut self, binary_op: SymBinaryOp, lhs_ty: SymTy<'db>, rhs_ty: SymTy<'db>, )
Push the correct instructions to execute binary_op on operands of type lhs_ty and rhs_ty
Sourcefn execute_binary_op_on_primitives(
&mut self,
binary_op: SymBinaryOp,
prim_kind: SymPrimitiveKind,
)
fn execute_binary_op_on_primitives( &mut self, binary_op: SymBinaryOp, prim_kind: SymPrimitiveKind, )
Push the correct instructions to execute binary_op on operands of type prim_kind
Sourcefn primitive_kind(
&self,
ty: SymTy<'db>,
) -> Result<SymPrimitiveKind, NotPrimitive>
fn primitive_kind( &self, ty: SymTy<'db>, ) -> Result<SymPrimitiveKind, NotPrimitive>
Return the primitive kind that represents ty or Err if ty is not a primitive.
fn push_match_expr(&mut self, match_ty: SymTy<'db>, arms: &[SymMatchArm<'db>])
Sourcefn block_type(&mut self, match_ty: SymTy<'db>) -> BlockType
fn block_type(&mut self, match_ty: SymTy<'db>) -> BlockType
Block control-flow instructions like if and friends
come equipped with an associated “block type”. This is a function
type indicating the inputs they consume from the stack (in our case,
always none) and the outputs they produce. As a shorthand, if they produce
nothing or a single value, there is a shorthand form. This function converts
an object-type into this form.
fn push_literal(&mut self, ty: SymTy<'db>, literal: SymLiteral)
fn push_error(&mut self, _reported: Reported)
Auto Trait Implementations§
impl<'cx, 'db> Freeze for ExprCodegen<'cx, 'db>
impl<'cx, 'db> !RefUnwindSafe for ExprCodegen<'cx, 'db>
impl<'cx, 'db> !Send for ExprCodegen<'cx, 'db>
impl<'cx, 'db> !Sync for ExprCodegen<'cx, 'db>
impl<'cx, 'db> Unpin for ExprCodegen<'cx, 'db>
impl<'cx, 'db> UnsafeUnpin for ExprCodegen<'cx, 'db>
impl<'cx, 'db> !UnwindSafe for ExprCodegen<'cx, 'db>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more