use super::LoweringContext;
use super::specialization::{
FunctionRepresentation, SpecializedFunctionShape, SpecializedTypeSubstitution,
SpecializedValueShape, StoredValueShape,
};
use crate::plan::{execution, module};
use std::collections::HashMap;
#[derive(Clone)]
pub(super) enum SpecializedFunctionLocal {
Generic(execution::graph::GenericFunctionLocal),
Never(execution::graph::NeverFunctionLocal),
Int {
local: execution::graph::IntFunctionLocalId,
type_: execution::type_::FunctionType,
},
Float {
local: execution::graph::FloatFunctionLocalId,
type_: execution::type_::FunctionType,
},
String {
local: execution::graph::StringFunctionLocalId,
type_: execution::type_::FunctionType,
},
BitArray {
local: execution::graph::BitArrayFunctionLocalId,
type_: execution::type_::FunctionType,
},
UtfCodepoint {
local: execution::graph::UtfCodepointFunctionLocalId,
type_: execution::type_::FunctionType,
},
Custom(execution::graph::CustomFunctionLocal),
External(execution::graph::ExternalFunctionLocal),
Bool {
local: execution::graph::BoolFunctionLocalId,
type_: execution::type_::FunctionType,
},
Nil {
local: execution::graph::NilFunctionLocalId,
type_: execution::type_::FunctionType,
},
Tuple {
local: execution::graph::TupleFunctionLocalId,
type_: execution::type_::FunctionType,
},
List(execution::graph::ListFunctionLocal),
Function(execution::graph::FunctionFunctionLocal),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub(super) enum LocalKind {
Generic,
Int,
Float,
String,
BitArray,
UtfCodepoint,
Custom,
External,
Bool,
Nil,
Tuple,
GenericList,
IntList,
StringList,
BitArrayList,
UtfCodepointList,
CustomList,
ExternalList,
FloatList,
BoolList,
NilList,
TupleList,
ListList,
FunctionList,
GenericFunction,
IntFunction,
FloatFunction,
StringFunction,
BitArrayFunction,
UtfCodepointFunction,
CustomFunction,
ExternalFunction,
BoolFunction,
NilFunction,
TupleFunction,
GenericListFunction,
IntListFunction,
StringListFunction,
BitArrayListFunction,
UtfCodepointListFunction,
CustomListFunction,
ExternalListFunction,
FloatListFunction,
BoolListFunction,
NilListFunction,
TupleListFunction,
ListListFunction,
FunctionListFunction,
FunctionFunction,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub(super) struct LocalKey {
kind: LocalKind,
index: usize,
}
impl LocalKey {
pub(super) fn new(kind: LocalKind, index: usize) -> Self {
Self { kind, index }
}
}
#[derive(Clone)]
pub(super) struct FunctionEntryTemplate {
params: Box<[crate::plan::ValueShape]>,
captures: Box<[crate::plan::ValueShape]>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
enum StorageFamily {
Int,
Float,
String,
BitArray,
UtfCodepoint,
Custom,
External,
Bool,
Nil,
Tuple,
ParameterList,
IntList,
StringList,
BitArrayList,
UtfCodepointList,
CustomList,
ExternalList,
FloatList,
BoolList,
NilList,
TupleList,
ListList,
ParameterListList,
FunctionList,
IntFunction,
FloatFunction,
StringFunction,
BitArrayFunction,
UtfCodepointFunction,
CustomFunction,
ExternalFunction,
BoolFunction,
NilFunction,
TupleFunction,
GenericFunction,
NeverFunction,
ParameterListFunction,
IntListFunction,
StringListFunction,
BitArrayListFunction,
UtfCodepointListFunction,
CustomListFunction,
ExternalListFunction,
FloatListFunction,
BoolListFunction,
NilListFunction,
TupleListFunction,
ParameterListListFunction,
ListListFunction,
FunctionListFunction,
FunctionFunction,
ExternalFunctionFunction,
}
#[derive(Default)]
pub(super) struct ParameterPrefix {
next: HashMap<StorageFamily, usize>,
}
impl FunctionEntryTemplate {
pub(super) fn new(template: &module::FunctionTemplate) -> Self {
let params = template
.entry()
.params()
.iter()
.map(|param| param.shape().clone())
.collect::<Vec<_>>();
let captures = template
.entry()
.captures()
.iter()
.map(|capture| capture.shape().clone())
.collect::<Vec<_>>();
Self {
params: params.into_boxed_slice(),
captures: captures.into_boxed_slice(),
}
}
pub(super) fn from_shapes(params: Vec<crate::plan::ValueShape>) -> Self {
Self {
params: params.into_boxed_slice(),
captures: Vec::new().into_boxed_slice(),
}
}
pub(super) fn stored_parameters(
&self,
substitution: &SpecializedTypeSubstitution,
representations: &super::specialization::RepresentationContext,
) -> super::specialization::Representability<Box<[StoredValueShape]>> {
super::specialization::Representability::collect(self.params.iter().map(|shape| {
let shape = SpecializedValueShape::instantiate(shape, substitution);
representations.inhabitation(&shape).into_representability()
}))
.map(Vec::into_boxed_slice)
}
pub(super) fn capture_target(
&self,
position: module::CapturePosition,
source_shape: StoredValueShape,
substitution: &SpecializedTypeSubstitution,
representations: &super::specialization::RepresentationContext,
) -> (usize, StoredValueShape) {
let mut prefix = ParameterPrefix::default();
for shape in self.params.iter().chain(&self.captures[..position.index()]) {
let shape = SpecializedValueShape::instantiate(shape, substitution);
if let Some(stored) = representations.stored_shape(&shape) {
prefix.allocate_stored(stored, representations);
}
}
prefix.allocate_stored(source_shape, representations)
}
}
impl ParameterPrefix {
pub(super) fn allocate_stored(
&mut self,
stored: StoredValueShape,
representations: &super::specialization::RepresentationContext,
) -> (usize, StoredValueShape) {
let index = self
.next
.entry(StorageFamily::of(&stored, representations))
.or_default();
let allocated = *index;
*index += 1;
(allocated, stored)
}
}
impl StorageFamily {
fn of(
shape: &StoredValueShape,
representations: &super::specialization::RepresentationContext,
) -> Self {
match shape {
StoredValueShape::Int => Self::Int,
StoredValueShape::Float => Self::Float,
StoredValueShape::String => Self::String,
StoredValueShape::BitArray => Self::BitArray,
StoredValueShape::UtfCodepoint => Self::UtfCodepoint,
StoredValueShape::Custom(_) => Self::Custom,
StoredValueShape::External(_) => Self::External,
StoredValueShape::Bool => Self::Bool,
StoredValueShape::Nil => Self::Nil,
StoredValueShape::Tuple(_) => Self::Tuple,
StoredValueShape::List(item) => Self::list(item),
StoredValueShape::Function(function) => Self::function(function, representations),
}
}
fn list(item: &SpecializedValueShape) -> Self {
match item {
SpecializedValueShape::Parameter(_) => Self::ParameterList,
SpecializedValueShape::Int => Self::IntList,
SpecializedValueShape::String => Self::StringList,
SpecializedValueShape::BitArray => Self::BitArrayList,
SpecializedValueShape::UtfCodepoint => Self::UtfCodepointList,
SpecializedValueShape::Custom(_) => Self::CustomList,
SpecializedValueShape::External(_) => Self::ExternalList,
SpecializedValueShape::Float => Self::FloatList,
SpecializedValueShape::Bool => Self::BoolList,
SpecializedValueShape::Nil => Self::NilList,
SpecializedValueShape::Tuple(_) => Self::TupleList,
SpecializedValueShape::List(item) => match item.as_ref() {
SpecializedValueShape::Parameter(_) => Self::ParameterListList,
_ => Self::ListList,
},
SpecializedValueShape::Function(_) => Self::FunctionList,
}
}
fn function(
function: &SpecializedFunctionShape,
representations: &super::specialization::RepresentationContext,
) -> Self {
match function.representation(representations) {
FunctionRepresentation::Symbolic => Self::GenericFunction,
FunctionRepresentation::Never(_) => Self::NeverFunction,
FunctionRepresentation::Executable(return_) => match return_ {
StoredValueShape::Int => Self::IntFunction,
StoredValueShape::Float => Self::FloatFunction,
StoredValueShape::String => Self::StringFunction,
StoredValueShape::BitArray => Self::BitArrayFunction,
StoredValueShape::UtfCodepoint => Self::UtfCodepointFunction,
StoredValueShape::Custom(_) => Self::CustomFunction,
StoredValueShape::External(_) => Self::ExternalFunction,
StoredValueShape::Bool => Self::BoolFunction,
StoredValueShape::Nil => Self::NilFunction,
StoredValueShape::Tuple(_) => Self::TupleFunction,
StoredValueShape::List(item) => Self::list_function(&item),
StoredValueShape::Function(returned) => {
if is_external_function_function(&returned, representations) {
Self::ExternalFunctionFunction
} else {
Self::FunctionFunction
}
}
},
}
}
fn list_function(item: &SpecializedValueShape) -> Self {
match item {
SpecializedValueShape::Parameter(_) => Self::ParameterListFunction,
SpecializedValueShape::Int => Self::IntListFunction,
SpecializedValueShape::String => Self::StringListFunction,
SpecializedValueShape::BitArray => Self::BitArrayListFunction,
SpecializedValueShape::UtfCodepoint => Self::UtfCodepointListFunction,
SpecializedValueShape::Custom(_) => Self::CustomListFunction,
SpecializedValueShape::External(_) => Self::ExternalListFunction,
SpecializedValueShape::Float => Self::FloatListFunction,
SpecializedValueShape::Bool => Self::BoolListFunction,
SpecializedValueShape::Nil => Self::NilListFunction,
SpecializedValueShape::Tuple(_) => Self::TupleListFunction,
SpecializedValueShape::List(item) => match item.as_ref() {
SpecializedValueShape::Parameter(_) => Self::ParameterListListFunction,
_ => Self::ListListFunction,
},
SpecializedValueShape::Function(_) => Self::FunctionListFunction,
}
}
}
pub(super) fn param_local_key(local: &module::ParamLocal) -> LocalKey {
match local {
module::ParamLocal::Generic(local) => LocalKey::new(LocalKind::Generic, local.id().0),
module::ParamLocal::Int(local) => LocalKey::new(LocalKind::Int, local.0),
module::ParamLocal::Float(local) => LocalKey::new(LocalKind::Float, local.0),
module::ParamLocal::String(local) => LocalKey::new(LocalKind::String, local.0),
module::ParamLocal::BitArray(local) => LocalKey::new(LocalKind::BitArray, local.0),
module::ParamLocal::UtfCodepoint(local) => LocalKey::new(LocalKind::UtfCodepoint, local.0),
module::ParamLocal::Custom(local) => LocalKey::new(LocalKind::Custom, local.id().0),
module::ParamLocal::External(local) => LocalKey::new(LocalKind::External, local.id().0),
module::ParamLocal::Bool(local) => LocalKey::new(LocalKind::Bool, local.0),
module::ParamLocal::Nil(local) => LocalKey::new(LocalKind::Nil, local.0),
module::ParamLocal::Tuple { local, .. } => LocalKey::new(LocalKind::Tuple, local.0),
module::ParamLocal::List(local) => list_local_key(local),
module::ParamLocal::IntFunction { local, .. } => {
LocalKey::new(LocalKind::IntFunction, local.0)
}
module::ParamLocal::FloatFunction { local, .. } => {
LocalKey::new(LocalKind::FloatFunction, local.0)
}
module::ParamLocal::StringFunction { local, .. } => {
LocalKey::new(LocalKind::StringFunction, local.0)
}
module::ParamLocal::BitArrayFunction { local, .. } => {
LocalKey::new(LocalKind::BitArrayFunction, local.0)
}
module::ParamLocal::UtfCodepointFunction { local, .. } => {
LocalKey::new(LocalKind::UtfCodepointFunction, local.0)
}
module::ParamLocal::CustomFunction(local) => {
LocalKey::new(LocalKind::CustomFunction, local.id().0)
}
module::ParamLocal::ExternalFunction(local) => {
LocalKey::new(LocalKind::ExternalFunction, local.id().0)
}
module::ParamLocal::BoolFunction { local, .. } => {
LocalKey::new(LocalKind::BoolFunction, local.0)
}
module::ParamLocal::NilFunction { local, .. } => {
LocalKey::new(LocalKind::NilFunction, local.0)
}
module::ParamLocal::TupleFunction { local, .. } => {
LocalKey::new(LocalKind::TupleFunction, local.0)
}
module::ParamLocal::ListFunction(local) => list_function_local_key(local),
module::ParamLocal::FunctionFunction(local) => {
LocalKey::new(LocalKind::FunctionFunction, local.id().0)
}
module::ParamLocal::GenericFunction(local) => {
LocalKey::new(LocalKind::GenericFunction, local.id().0)
}
}
}
pub(super) fn list_local_key(local: &module::ListLocal) -> LocalKey {
match local {
module::ListLocal::Generic { local, .. } => LocalKey::new(LocalKind::GenericList, local.0),
module::ListLocal::Int(local) => LocalKey::new(LocalKind::IntList, local.0),
module::ListLocal::String(local) => LocalKey::new(LocalKind::StringList, local.0),
module::ListLocal::BitArray(local) => LocalKey::new(LocalKind::BitArrayList, local.0),
module::ListLocal::UtfCodepoint(local) => {
LocalKey::new(LocalKind::UtfCodepointList, local.0)
}
module::ListLocal::Custom { local, .. } => LocalKey::new(LocalKind::CustomList, local.0),
module::ListLocal::External { local, .. } => {
LocalKey::new(LocalKind::ExternalList, local.0)
}
module::ListLocal::Float(local) => LocalKey::new(LocalKind::FloatList, local.0),
module::ListLocal::Bool(local) => LocalKey::new(LocalKind::BoolList, local.0),
module::ListLocal::Nil(local) => LocalKey::new(LocalKind::NilList, local.0),
module::ListLocal::Tuple { local, .. } => LocalKey::new(LocalKind::TupleList, local.0),
module::ListLocal::List { local, .. } => LocalKey::new(LocalKind::ListList, local.0),
module::ListLocal::Function { local, .. } => {
LocalKey::new(LocalKind::FunctionList, local.0)
}
}
}
pub(super) fn list_function_local_key(local: &module::ListFunctionLocal) -> LocalKey {
let (kind, index, _) = list_function_local_parts(local);
LocalKey::new(kind, index)
}
fn list_function_local_parts(
local: &module::ListFunctionLocal,
) -> (LocalKind, usize, crate::plan::FunctionType) {
match local {
module::ListFunctionLocal::Generic { local, type_, .. } => {
(LocalKind::GenericListFunction, local.0, type_.clone())
}
module::ListFunctionLocal::Int { local, type_ } => {
(LocalKind::IntListFunction, local.0, type_.clone())
}
module::ListFunctionLocal::String { local, type_ } => {
(LocalKind::StringListFunction, local.0, type_.clone())
}
module::ListFunctionLocal::BitArray { local, type_ } => {
(LocalKind::BitArrayListFunction, local.0, type_.clone())
}
module::ListFunctionLocal::UtfCodepoint { local, type_ } => {
(LocalKind::UtfCodepointListFunction, local.0, type_.clone())
}
module::ListFunctionLocal::Custom { local, type_, .. } => {
(LocalKind::CustomListFunction, local.0, type_.clone())
}
module::ListFunctionLocal::External { local, type_, .. } => {
(LocalKind::ExternalListFunction, local.0, type_.clone())
}
module::ListFunctionLocal::Float { local, type_ } => {
(LocalKind::FloatListFunction, local.0, type_.clone())
}
module::ListFunctionLocal::Bool { local, type_ } => {
(LocalKind::BoolListFunction, local.0, type_.clone())
}
module::ListFunctionLocal::Nil { local, type_ } => {
(LocalKind::NilListFunction, local.0, type_.clone())
}
module::ListFunctionLocal::Tuple { local, type_, .. } => {
(LocalKind::TupleListFunction, local.0, type_.clone())
}
module::ListFunctionLocal::List { local, type_, .. } => {
(LocalKind::ListListFunction, local.0, type_.clone())
}
module::ListFunctionLocal::Function { local, type_, .. } => {
(LocalKind::FunctionListFunction, local.0, type_.clone())
}
}
}
pub(super) fn stored_value_local_at(
shape: &StoredValueShape,
index: usize,
context: &mut LoweringContext,
) -> execution::graph::ParamLocal {
match shape {
StoredValueShape::Int => {
execution::graph::ParamLocal::Int(execution::graph::IntLocalId(index))
}
StoredValueShape::Float => {
execution::graph::ParamLocal::Float(execution::graph::FloatLocalId(index))
}
StoredValueShape::String => {
execution::graph::ParamLocal::String(execution::graph::StringLocalId(index))
}
StoredValueShape::BitArray => {
execution::graph::ParamLocal::BitArray(execution::graph::BitArrayLocalId(index))
}
StoredValueShape::UtfCodepoint => {
execution::graph::ParamLocal::UtfCodepoint(execution::graph::UtfCodepointLocalId(index))
}
StoredValueShape::Custom(shape) => {
execution::graph::ParamLocal::Custom(execution::graph::CustomLocal::new(
execution::graph::CustomLocalId(index),
context.lower_concrete_custom_shape(shape),
))
}
StoredValueShape::External(shape) => {
execution::graph::ParamLocal::External(execution::graph::ExternalLocal::new(
execution::graph::ExternalLocalId(index),
context.lower_concrete_external_type(shape),
))
}
StoredValueShape::Bool => {
execution::graph::ParamLocal::Bool(execution::graph::BoolLocalId(index))
}
StoredValueShape::Nil => {
execution::graph::ParamLocal::Nil(execution::graph::NilLocalId(index))
}
StoredValueShape::Tuple(elements) => execution::graph::ParamLocal::Tuple {
local: execution::graph::TupleLocalId(index),
type_: elements
.iter()
.map(|element| context.lower_concrete_value_type(element))
.collect(),
},
StoredValueShape::List(item) => {
execution::graph::ParamLocal::List(list_local_at(item, index, context))
}
StoredValueShape::Function(function) => {
function_local_as_param(function_local_at(function, index, context))
}
}
}
pub(super) fn list_local_at(
item: &SpecializedValueShape,
index: usize,
context: &mut LoweringContext,
) -> execution::graph::ListLocal {
match item {
SpecializedValueShape::Parameter(parameter) => execution::graph::ListLocal::Parameter {
local: execution::graph::ParameterListLocalId(index),
type_id: context.parameter_list_type(*parameter),
},
SpecializedValueShape::Int => execution::graph::ListLocal::Int {
local: execution::graph::IntListLocalId(index),
type_id: context.int_list_type(),
},
SpecializedValueShape::String => execution::graph::ListLocal::String {
local: execution::graph::StringListLocalId(index),
type_id: context.string_list_type(),
},
SpecializedValueShape::BitArray => execution::graph::ListLocal::BitArray {
local: execution::graph::BitArrayListLocalId(index),
type_id: context.bit_array_list_type(),
},
SpecializedValueShape::UtfCodepoint => execution::graph::ListLocal::UtfCodepoint {
local: execution::graph::UtfCodepointListLocalId(index),
type_id: context.utf_codepoint_list_type(),
},
SpecializedValueShape::Custom(custom) => execution::graph::ListLocal::Custom {
local: execution::graph::CustomListLocalId(index),
type_id: context.specialized_custom_list_type(custom),
},
SpecializedValueShape::External(external) => execution::graph::ListLocal::External {
local: execution::graph::ExternalListLocalId(index),
type_id: context.specialized_external_list_type(external),
},
SpecializedValueShape::Float => execution::graph::ListLocal::Float {
local: execution::graph::FloatListLocalId(index),
type_id: context.float_list_type(),
},
SpecializedValueShape::Bool => execution::graph::ListLocal::Bool {
local: execution::graph::BoolListLocalId(index),
type_id: context.bool_list_type(),
},
SpecializedValueShape::Nil => execution::graph::ListLocal::Nil {
local: execution::graph::NilListLocalId(index),
type_id: context.nil_list_type(),
},
SpecializedValueShape::Tuple(elements) => execution::graph::ListLocal::Tuple {
local: execution::graph::TupleListLocalId(index),
type_id: context.specialized_tuple_list_type(elements),
},
SpecializedValueShape::List(item) => match context.specialized_list_list_type(item) {
super::value_type::NestedListTypeId::Parameter(type_id) => {
execution::graph::ListLocal::ParameterList {
local: execution::graph::ParameterListListLocalId(index),
type_id,
}
}
super::value_type::NestedListTypeId::Stored(type_id) => {
execution::graph::ListLocal::List {
local: execution::graph::ListListLocalId(index),
type_id,
}
}
},
SpecializedValueShape::Function(function) => execution::graph::ListLocal::Function {
local: execution::graph::FunctionListLocalId(index),
type_id: context.specialized_function_list_type(function),
},
}
}
pub(super) fn function_local_at(
shape: &SpecializedFunctionShape,
index: usize,
context: &mut LoweringContext,
) -> SpecializedFunctionLocal {
let type_ = context.lower_concrete_function_type(shape);
match context.function_representation(shape) {
FunctionRepresentation::Symbolic => {
SpecializedFunctionLocal::Generic(execution::graph::GenericFunctionLocal::new(
execution::graph::GenericFunctionLocalId(index),
context.generic_function_type(shape),
))
}
FunctionRepresentation::Never(_) => {
SpecializedFunctionLocal::Never(execution::graph::NeverFunctionLocal::new(
execution::graph::NeverFunctionLocalId(index),
context.generic_function_type(shape),
))
}
FunctionRepresentation::Executable(StoredValueShape::Int) => {
SpecializedFunctionLocal::Int {
local: execution::graph::IntFunctionLocalId(index),
type_,
}
}
FunctionRepresentation::Executable(StoredValueShape::Float) => {
SpecializedFunctionLocal::Float {
local: execution::graph::FloatFunctionLocalId(index),
type_,
}
}
FunctionRepresentation::Executable(StoredValueShape::String) => {
SpecializedFunctionLocal::String {
local: execution::graph::StringFunctionLocalId(index),
type_,
}
}
FunctionRepresentation::Executable(StoredValueShape::BitArray) => {
SpecializedFunctionLocal::BitArray {
local: execution::graph::BitArrayFunctionLocalId(index),
type_,
}
}
FunctionRepresentation::Executable(StoredValueShape::UtfCodepoint) => {
SpecializedFunctionLocal::UtfCodepoint {
local: execution::graph::UtfCodepointFunctionLocalId(index),
type_,
}
}
FunctionRepresentation::Executable(StoredValueShape::Custom(custom)) => {
let type_ = context.specialized_custom_function_type(shape.arguments(), &custom);
SpecializedFunctionLocal::Custom(execution::graph::CustomFunctionLocal::new(
execution::graph::CustomFunctionLocalId(index),
type_,
))
}
FunctionRepresentation::Executable(StoredValueShape::External(external)) => {
let type_ = context.specialized_external_function_type(shape.arguments(), &external);
SpecializedFunctionLocal::External(execution::graph::ExternalFunctionLocal::new(
execution::graph::ExternalFunctionLocalId(index),
type_,
))
}
FunctionRepresentation::Executable(StoredValueShape::Bool) => {
SpecializedFunctionLocal::Bool {
local: execution::graph::BoolFunctionLocalId(index),
type_,
}
}
FunctionRepresentation::Executable(StoredValueShape::Nil) => {
SpecializedFunctionLocal::Nil {
local: execution::graph::NilFunctionLocalId(index),
type_,
}
}
FunctionRepresentation::Executable(StoredValueShape::Tuple(_)) => {
SpecializedFunctionLocal::Tuple {
local: execution::graph::TupleFunctionLocalId(index),
type_,
}
}
FunctionRepresentation::Executable(StoredValueShape::List(item)) => {
SpecializedFunctionLocal::List(list_function_local_at(&item, type_, index, context))
}
FunctionRepresentation::Executable(StoredValueShape::Function(returned)) => {
let type_ = context.specialized_function_function_type(shape.arguments(), &returned);
let local = if is_external_function_function(&returned, &context.representations) {
execution::graph::FunctionFunctionLocal::External(
execution::graph::ExternalFunctionFunctionLocal::new(
execution::graph::ExternalFunctionFunctionLocalId(index),
type_,
),
)
} else {
execution::graph::FunctionFunctionLocal::Core(
execution::graph::CoreFunctionFunctionLocal::new(
execution::graph::CoreFunctionFunctionLocalId(index),
type_,
),
)
};
SpecializedFunctionLocal::Function(local)
}
}
}
fn is_external_function_function(
returned: &SpecializedFunctionShape,
representations: &super::specialization::RepresentationContext,
) -> bool {
match returned.representation(representations) {
FunctionRepresentation::Executable(StoredValueShape::External(_)) => true,
FunctionRepresentation::Executable(StoredValueShape::List(item)) => {
matches!(item.as_ref(), SpecializedValueShape::External(_))
}
FunctionRepresentation::Symbolic
| FunctionRepresentation::Never(_)
| FunctionRepresentation::Executable(_) => false,
}
}
pub(super) fn list_function_local_at(
item: &SpecializedValueShape,
type_: execution::type_::FunctionType,
index: usize,
context: &mut LoweringContext,
) -> execution::graph::ListFunctionLocal {
use execution::graph::ListFunctionLocal as L;
match item {
SpecializedValueShape::Parameter(parameter) => L::Parameter {
local: execution::graph::ParameterListFunctionLocalId(index),
type_,
list_type: context.parameter_list_type(*parameter),
},
SpecializedValueShape::Int => L::Int {
local: execution::graph::IntListFunctionLocalId(index),
type_,
list_type: context.int_list_type(),
},
SpecializedValueShape::String => L::String {
local: execution::graph::StringListFunctionLocalId(index),
type_,
list_type: context.string_list_type(),
},
SpecializedValueShape::BitArray => L::BitArray {
local: execution::graph::BitArrayListFunctionLocalId(index),
type_,
list_type: context.bit_array_list_type(),
},
SpecializedValueShape::UtfCodepoint => L::UtfCodepoint {
local: execution::graph::UtfCodepointListFunctionLocalId(index),
type_,
list_type: context.utf_codepoint_list_type(),
},
SpecializedValueShape::Custom(custom) => L::Custom {
local: execution::graph::CustomListFunctionLocalId(index),
type_,
list_type: context.specialized_custom_list_type(custom),
},
SpecializedValueShape::External(external) => L::External {
local: execution::graph::ExternalListFunctionLocalId(index),
type_,
list_type: context.specialized_external_list_type(external),
},
SpecializedValueShape::Float => L::Float {
local: execution::graph::FloatListFunctionLocalId(index),
type_,
list_type: context.float_list_type(),
},
SpecializedValueShape::Bool => L::Bool {
local: execution::graph::BoolListFunctionLocalId(index),
type_,
list_type: context.bool_list_type(),
},
SpecializedValueShape::Nil => L::Nil {
local: execution::graph::NilListFunctionLocalId(index),
type_,
list_type: context.nil_list_type(),
},
SpecializedValueShape::Tuple(elements) => L::Tuple {
local: execution::graph::TupleListFunctionLocalId(index),
type_,
list_type: context.specialized_tuple_list_type(elements),
},
SpecializedValueShape::List(item) => match context.specialized_list_list_type(item) {
super::value_type::NestedListTypeId::Parameter(list_type) => L::ParameterList {
local: execution::graph::ParameterListListFunctionLocalId(index),
type_,
list_type,
},
super::value_type::NestedListTypeId::Stored(list_type) => L::List {
local: execution::graph::ListListFunctionLocalId(index),
type_,
list_type,
},
},
SpecializedValueShape::Function(function) => L::Function {
local: execution::graph::FunctionListFunctionLocalId(index),
type_,
list_type: context.specialized_function_list_type(function),
},
}
}
pub(super) fn function_local_as_param(
local: SpecializedFunctionLocal,
) -> execution::graph::ParamLocal {
match local {
SpecializedFunctionLocal::Generic(local) => {
execution::graph::ParamLocal::GenericFunction(local)
}
SpecializedFunctionLocal::Never(local) => {
execution::graph::ParamLocal::NeverFunction(local)
}
SpecializedFunctionLocal::Int { local, type_ } => {
execution::graph::ParamLocal::IntFunction { local, type_ }
}
SpecializedFunctionLocal::Float { local, type_ } => {
execution::graph::ParamLocal::FloatFunction { local, type_ }
}
SpecializedFunctionLocal::String { local, type_ } => {
execution::graph::ParamLocal::StringFunction { local, type_ }
}
SpecializedFunctionLocal::BitArray { local, type_ } => {
execution::graph::ParamLocal::BitArrayFunction { local, type_ }
}
SpecializedFunctionLocal::UtfCodepoint { local, type_ } => {
execution::graph::ParamLocal::UtfCodepointFunction { local, type_ }
}
SpecializedFunctionLocal::Custom(local) => {
execution::graph::ParamLocal::CustomFunction(local)
}
SpecializedFunctionLocal::External(local) => {
execution::graph::ParamLocal::ExternalFunction(local)
}
SpecializedFunctionLocal::Bool { local, type_ } => {
execution::graph::ParamLocal::BoolFunction { local, type_ }
}
SpecializedFunctionLocal::Nil { local, type_ } => {
execution::graph::ParamLocal::NilFunction { local, type_ }
}
SpecializedFunctionLocal::Tuple { local, type_ } => {
execution::graph::ParamLocal::TupleFunction { local, type_ }
}
SpecializedFunctionLocal::List(local) => execution::graph::ParamLocal::ListFunction(local),
SpecializedFunctionLocal::Function(local) => {
execution::graph::ParamLocal::FunctionFunction(local)
}
}
}