Skip to content

Commit

Permalink
Support dynamic resource parameters in Rib
Browse files Browse the repository at this point in the history
  • Loading branch information
afsalthaj committed Sep 20, 2024
1 parent 2ab08f3 commit 3ac3441
Show file tree
Hide file tree
Showing 13 changed files with 714 additions and 162 deletions.
4 changes: 2 additions & 2 deletions golem-rib/src/call_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use crate::ParsedFunctionName;
use crate::{DynamicParsedFunctionName, ParsedFunctionName};
use bincode::{Decode, Encode};
use std::convert::TryFrom;
use std::fmt::Display;

#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)]
pub enum CallType {
Function(ParsedFunctionName),
Function(DynamicParsedFunctionName),
VariantConstructor(String),
EnumConstructor(String),
}
Expand Down
173 changes: 139 additions & 34 deletions golem-rib/src/compiler/byte_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,10 @@ impl From<RibByteCode> for ProtoRibByteCode {

mod internal {
use crate::compiler::desugar::desugar_pattern_match;
use crate::{AnalysedTypeWithUnit, Expr, InferredType, InstructionId, RibIR};
use crate::{
AnalysedTypeWithUnit, DynamicParsedFunctionReference, Expr, FunctionReferenceType,
InferredType, InstructionId, ParsedFunctionName, ParsedFunctionReference, RibIR,
};
use golem_wasm_ast::analysis::AnalysedType;
use golem_wasm_rpc::protobuf::type_annotated_value::TypeAnnotatedValue;

Expand Down Expand Up @@ -235,43 +238,144 @@ mod internal {
)?));
}

Expr::Call(invocation_name, arguments, inferred_type) => {
for expr in arguments.iter().rev() {
stack.push(ExprState::from_expr(expr));
}

match invocation_name {
CallType::Function(parsed_function_name) => {
let function_result_type = if inferred_type.is_unit() {
AnalysedTypeWithUnit::Unit
} else {
AnalysedTypeWithUnit::Type(convert_to_analysed_type_for(
expr,
inferred_type,
)?)
};

instructions.push(RibIR::InvokeFunction(
parsed_function_name.clone(),
arguments.len(),
function_result_type,
));
Expr::Call(invocation_name, arguments, inferred_type) => match invocation_name {
CallType::Function(parsed_function_name) => {
let function_result_type = if inferred_type.is_unit() {
AnalysedTypeWithUnit::Unit
} else {
AnalysedTypeWithUnit::Type(convert_to_analysed_type_for(
expr,
inferred_type,
)?)
};

let site = parsed_function_name.site.clone();

match &parsed_function_name.function {
DynamicParsedFunctionReference::Function { function } => {
instructions.push(RibIR::CreateFunctionName(
site,
FunctionReferenceType::Function(function.clone()),
))
}

DynamicParsedFunctionReference::RawResourceConstructor { resource } => {
instructions.push(RibIR::CreateFunctionName(
site,
FunctionReferenceType::RawResourceConstructor(resource.clone()),
))
}
DynamicParsedFunctionReference::RawResourceDrop { resource } => {
instructions.push(RibIR::CreateFunctionName(
site,
FunctionReferenceType::RawResourceDrop(resource.clone()),
))
}
DynamicParsedFunctionReference::RawResourceMethod { resource, method } => {
instructions.push(RibIR::CreateFunctionName(
site,
FunctionReferenceType::RawResourceMethod(
resource.clone(),
method.clone(),
),
))
}
DynamicParsedFunctionReference::RawResourceStaticMethod {
resource,
method,
} => instructions.push(RibIR::CreateFunctionName(
site,
FunctionReferenceType::RawResourceStaticMethod(
resource.clone(),
method.clone(),
),
)),
DynamicParsedFunctionReference::IndexedResourceConstructor {
resource,
resource_params,
} => {
for param in resource_params {
stack.push(ExprState::from_expr(&param.0));
}
instructions.push(RibIR::CreateFunctionName(
site,
FunctionReferenceType::IndexedResourceConstructor(
resource.clone(),
resource_params.len(),
),
))
}
DynamicParsedFunctionReference::IndexedResourceMethod {
resource,
resource_params,
method,
} => {
for param in resource_params {
stack.push(ExprState::from_expr(&param.0));
}
instructions.push(RibIR::CreateFunctionName(
site,
FunctionReferenceType::IndexedResourceMethod(
resource.clone(),
resource_params.len(),
method.clone(),
),
))
}
DynamicParsedFunctionReference::IndexedResourceStaticMethod {
resource,
resource_params,
method,
} => {
for param in resource_params {
stack.push(ExprState::from_expr(&param.0));
}
instructions.push(RibIR::CreateFunctionName(
site,
FunctionReferenceType::IndexedResourceStaticMethod(
resource.clone(),
resource_params.len(),
method.clone(),
),
))
}
DynamicParsedFunctionReference::IndexedResourceDrop {
resource,
resource_params,
} => {
for param in resource_params {
stack.push(ExprState::from_expr(&param.0));
}
instructions.push(RibIR::CreateFunctionName(
site,
FunctionReferenceType::IndexedResourceDrop(
resource.clone(),
resource_params.len(),
),
))
}
}

CallType::VariantConstructor(variant_name) => {
instructions.push(RibIR::PushVariant(
variant_name.clone(),
convert_to_analysed_type_for(expr, inferred_type)?,
));
}
CallType::EnumConstructor(enmum_name) => {
instructions.push(RibIR::PushEnum(
enmum_name.clone(),
convert_to_analysed_type_for(expr, inferred_type)?,
));
for expr in arguments.iter().rev() {
stack.push(ExprState::from_expr(expr));
}

instructions.push(RibIR::InvokeFunction(arguments.len(), function_result_type));
}
}

CallType::VariantConstructor(variant_name) => {
instructions.push(RibIR::PushVariant(
variant_name.clone(),
convert_to_analysed_type_for(expr, inferred_type)?,
));
}
CallType::EnumConstructor(enmum_name) => {
instructions.push(RibIR::PushEnum(
enmum_name.clone(),
convert_to_analysed_type_for(expr, inferred_type)?,
));
}
},

Expr::Flags(flag_values, inferred_type) => match inferred_type {
InferredType::Flags(all_flags) => {
Expand Down Expand Up @@ -380,6 +484,7 @@ mod internal {
stack.push(ExprState::from_ir(RibIR::Label(else_ending_id.clone())));
}
}

#[cfg(test)]
mod compiler_tests {
use super::*;
Expand Down
18 changes: 16 additions & 2 deletions golem-rib/src/compiler/ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use crate::{AnalysedTypeWithUnit, ParsedFunctionName, VariableId};
use crate::{AnalysedTypeWithUnit, ParsedFunctionName, ParsedFunctionSite, VariableId};
use bincode::{Decode, Encode};
use golem_api_grpc::proto::golem::rib::rib_ir::Instruction;
use golem_api_grpc::proto::golem::rib::{
Expand Down Expand Up @@ -51,7 +51,8 @@ pub enum RibIR {
Jump(InstructionId),
Label(InstructionId),
Deconstruct,
InvokeFunction(ParsedFunctionName, usize, AnalysedTypeWithUnit),
CreateFunctionName(ParsedFunctionSite, FunctionReferenceType),
InvokeFunction(usize, AnalysedTypeWithUnit),
PushVariant(String, AnalysedType), // There is no arg size since the type of each variant case is only 1 from beginning
PushEnum(String, AnalysedType),
Throw(String),
Expand All @@ -60,6 +61,19 @@ pub enum RibIR {
Negate,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Encode, Decode)]
pub enum FunctionReferenceType {
Function(String),
RawResourceConstructor(String),
RawResourceDrop(String),
RawResourceMethod(String, String),
RawResourceStaticMethod(String, String),
IndexedResourceConstructor(String, usize),
IndexedResourceMethod(String, usize, String),
IndexedResourceStaticMethod(String, usize, String),
IndexedResourceDrop(String, usize),
}

// Every instruction can have a unique ID, and the compiler
// can assign this and label the start and end of byte code blocks.
// This is more efficient than assigning index to every instruction and incrementing it
Expand Down
14 changes: 7 additions & 7 deletions golem-rib/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use crate::function_name::ParsedFunctionName;
use crate::parser::rib_expr::rib_program;
use crate::parser::type_name::TypeName;
use crate::type_registry::FunctionTypeRegistry;
use crate::{text, type_inference, InferredType, VariableId};
use crate::{text, type_inference, DynamicParsedFunctionName, InferredType, VariableId};
use bincode::{Decode, Encode};
use combine::stream::position;
use combine::EasyParser;
Expand All @@ -30,7 +30,7 @@ use std::fmt::Display;
use std::ops::Deref;
use std::str::FromStr;

#[derive(Debug, Clone, PartialEq, Encode, Decode)]
#[derive(Debug, Clone, PartialEq, Eq, Encode, Decode)]
pub enum Expr {
Let(VariableId, Option<TypeName>, Box<Expr>, InferredType),
SelectField(Box<Expr>, String, InferredType),
Expand Down Expand Up @@ -256,9 +256,9 @@ impl Expr {
cond
}

pub fn call(parsed_fn_name: ParsedFunctionName, args: Vec<Expr>) -> Self {
pub fn call(dynamic_parsed_fn_name: DynamicParsedFunctionName, args: Vec<Expr>) -> Self {
Expr::Call(
CallType::Function(parsed_fn_name),
CallType::Function(dynamic_parsed_fn_name),
args,
InferredType::Unknown,
)
Expand Down Expand Up @@ -692,7 +692,7 @@ impl Expr {
}
}

#[derive(Debug, Clone, PartialEq, Encode, Decode)]
#[derive(Debug, Clone, PartialEq, Eq, Encode, Decode)]
pub struct Number {
pub value: f64, // Change to bigdecimal
}
Expand Down Expand Up @@ -721,7 +721,7 @@ impl Display for Number {
}
}

#[derive(Debug, Clone, PartialEq, Encode, Decode)]
#[derive(Debug, Clone, PartialEq, Eq, Encode, Decode)]
pub struct MatchArm {
pub arm_pattern: ArmPattern,
pub arm_resolution_expr: Box<Expr>,
Expand All @@ -735,7 +735,7 @@ impl MatchArm {
}
}
}
#[derive(Debug, Clone, PartialEq, Encode, Decode)]
#[derive(Debug, Clone, PartialEq, Eq, Encode, Decode)]
pub enum ArmPattern {
WildCard,
As(String, Box<ArmPattern>),
Expand Down
Loading

0 comments on commit 3ac3441

Please sign in to comment.