1use crate::{AnalysedTypeWithUnit, ComponentDependencyKey, ParsedFunctionSite, VariableId};
16use bincode::{Decode, Encode};
17use golem_wasm_ast::analysis::AnalysedType;
18use golem_wasm_rpc::ValueAndType;
19use serde::{Deserialize, Serialize};
20
21#[derive(Debug, Clone, PartialEq, Encode, Decode)]
23pub enum RibIR {
24 PushLit(ValueAndType),
25 AssignVar(VariableId),
26 LoadVar(VariableId),
27 CreateAndPushRecord(AnalysedType),
28 UpdateRecord(String),
29 PushList(AnalysedType, usize),
30 PushTuple(AnalysedType, usize),
31 PushSome(AnalysedType),
32 PushNone(Option<AnalysedType>), PushOkResult(AnalysedType),
34 PushErrResult(AnalysedType),
35 PushFlag(ValueAndType), SelectField(String),
37 SelectIndex(usize), SelectIndexV1,
39 EqualTo,
40 GreaterThan,
41 And,
42 Or,
43 LessThan,
44 GreaterThanOrEqualTo,
45 LessThanOrEqualTo,
46 IsEmpty,
47 JumpIfFalse(InstructionId),
48 Jump(InstructionId),
49 Label(InstructionId),
50 Deconstruct,
51 CreateFunctionName(ParsedFunctionSite, FunctionReferenceType),
52 InvokeFunction(
53 ComponentDependencyKey,
54 InstanceVariable,
55 usize,
56 AnalysedTypeWithUnit,
57 ),
58 PushVariant(String, AnalysedType), PushEnum(String, AnalysedType),
60 Throw(String),
61 GetTag,
62 Concat(usize),
63 Plus(AnalysedType),
64 Minus(AnalysedType),
65 Divide(AnalysedType),
66 Multiply(AnalysedType),
67 Negate,
68 ToIterator,
69 CreateSink(AnalysedType),
70 AdvanceIterator,
71 PushToSink,
72 SinkToList,
73 Length,
74 GenerateWorkerName(Option<VariableId>),
75}
76
77#[derive(Debug, Clone, PartialEq, Encode, Decode)]
78pub enum InstanceVariable {
79 WitResource(VariableId),
80 WitWorker(VariableId),
81}
82
83impl RibIR {
84 pub fn get_instruction_id(&self) -> Option<InstructionId> {
85 match self {
86 RibIR::Label(id) => Some(id.clone()),
87 _ => None,
88 }
89 }
90}
91
92#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Encode, Decode)]
93pub enum FunctionReferenceType {
94 Function {
95 function: String,
96 },
97 RawResourceConstructor {
98 resource: String,
99 },
100 RawResourceDrop {
101 resource: String,
102 },
103 RawResourceMethod {
104 resource: String,
105 method: String,
106 },
107 RawResourceStaticMethod {
108 resource: String,
109 method: String,
110 },
111 IndexedResourceConstructor {
112 resource: String,
113 arg_size: usize,
114 },
115 IndexedResourceMethod {
116 resource: String,
117 arg_size: usize,
118 method: String,
119 },
120 IndexedResourceStaticMethod {
121 resource: String,
122 arg_size: usize,
123 method: String,
124 },
125 IndexedResourceDrop {
126 resource: String,
127 arg_size: usize,
128 },
129}
130
131#[derive(Debug, Clone, PartialEq, Hash, Eq, Serialize, Deserialize, Encode, Decode)]
137pub struct InstructionId {
138 pub index: usize,
139}
140
141impl InstructionId {
142 pub fn new(index: usize) -> Self {
143 InstructionId { index }
144 }
145
146 pub fn init() -> Self {
147 InstructionId { index: 0 }
148 }
149
150 pub fn increment(&self) -> InstructionId {
151 InstructionId {
152 index: self.index + 1,
153 }
154 }
155
156 pub fn increment_mut(&mut self) -> InstructionId {
157 self.index += 1;
158 self.clone()
159 }
160}
161
162#[cfg(feature = "protobuf")]
163mod protobuf {
164 use crate::{
165 AnalysedTypeWithUnit, ComponentDependencyKey, FunctionReferenceType, InstanceVariable,
166 InstructionId, ParsedFunctionSite, RibIR, VariableId,
167 };
168 use golem_api_grpc::proto::golem::rib::rib_ir::Instruction;
169 use golem_api_grpc::proto::golem::rib::{
170 And, ConcatInstruction, CreateFunctionNameInstruction, EqualTo, GetTag, GreaterThan,
171 GreaterThanOrEqualTo, InvokeFunctionInstruction, IsEmpty, JumpInstruction, LessThan,
172 LessThanOrEqualTo, Negate, Or, PushListInstruction, PushNoneInstruction,
173 PushTupleInstruction, RibIr as ProtoRibIR, WitResource,
174 };
175 use golem_wasm_ast::analysis::{AnalysedType, TypeStr};
176 use golem_wasm_rpc::ValueAndType;
177
178 impl TryFrom<golem_api_grpc::proto::golem::rib::FunctionReferenceType> for FunctionReferenceType {
179 type Error = String;
180 fn try_from(
181 value: golem_api_grpc::proto::golem::rib::FunctionReferenceType,
182 ) -> Result<Self, Self::Error> {
183 let value = value.r#type.ok_or("Missing type".to_string())?;
184 let function_reference_type = match value {
185 golem_api_grpc::proto::golem::rib::function_reference_type::Type::Function(name) => FunctionReferenceType::Function {
186 function: name.name
187 },
188 golem_api_grpc::proto::golem::rib::function_reference_type::Type::RawResourceConstructor(name) =>
189 FunctionReferenceType::RawResourceConstructor {
190 resource: name.resource_name
191 },
192 golem_api_grpc::proto::golem::rib::function_reference_type::Type::RawResourceDrop(name) => FunctionReferenceType::RawResourceDrop {
193 resource: name.resource_name
194 },
195 golem_api_grpc::proto::golem::rib::function_reference_type::Type::RawResourceMethod(raw_resource_method) => {
196 let resource = raw_resource_method.resource_name;
197 let method = raw_resource_method.method_name;
198 FunctionReferenceType::RawResourceMethod { resource, method }
199 }
200 golem_api_grpc::proto::golem::rib::function_reference_type::Type::RawResourceStaticMethod(raw_resource_static_method) => {
201 let resource = raw_resource_static_method.resource_name;
202 let method = raw_resource_static_method.method_name;
203 FunctionReferenceType::RawResourceStaticMethod { resource, method }
204 }
205 golem_api_grpc::proto::golem::rib::function_reference_type::Type::IndexedResourceConstructor(indexed_resource_constructor) => {
206 let resource = indexed_resource_constructor.resource_name;
207 let arg_size = indexed_resource_constructor.arg_size;
208 FunctionReferenceType::IndexedResourceConstructor { resource, arg_size: arg_size as usize }
209 }
210 golem_api_grpc::proto::golem::rib::function_reference_type::Type::IndexedResourceMethod(indexed_resource_method) => {
211 let resource = indexed_resource_method.resource_name;
212 let arg_size = indexed_resource_method.arg_size;
213 let method = indexed_resource_method.method_name;
214 FunctionReferenceType::IndexedResourceMethod { resource, arg_size: arg_size as usize, method }
215 }
216 golem_api_grpc::proto::golem::rib::function_reference_type::Type::IndexedResourceStaticMethod(indexed_resource_static_method) => {
217 let resource = indexed_resource_static_method.resource_name;
218 let arg_size = indexed_resource_static_method.arg_size;
219 let method = indexed_resource_static_method.method_name;
220 FunctionReferenceType::IndexedResourceStaticMethod { resource, arg_size: arg_size as usize, method }
221 }
222 golem_api_grpc::proto::golem::rib::function_reference_type::Type::IndexedResourceDrop(indexed_resource_drop) => {
223 let resource = indexed_resource_drop.resource_name;
224 let arg_size = indexed_resource_drop.arg_size;
225 FunctionReferenceType::IndexedResourceDrop { resource, arg_size: arg_size as usize }
226 }
227 };
228 Ok(function_reference_type)
229 }
230 }
231
232 impl From<FunctionReferenceType> for golem_api_grpc::proto::golem::rib::FunctionReferenceType {
233 fn from(value: FunctionReferenceType) -> Self {
234 match value {
235 FunctionReferenceType::Function { function } => golem_api_grpc::proto::golem::rib::FunctionReferenceType {
236 r#type: Some(golem_api_grpc::proto::golem::rib::function_reference_type::Type::Function(golem_api_grpc::proto::golem::rib::Function {
237 name: function
238 }))
239 },
240 FunctionReferenceType::RawResourceConstructor { resource } => golem_api_grpc::proto::golem::rib::FunctionReferenceType {
241 r#type: Some(golem_api_grpc::proto::golem::rib::function_reference_type::Type::RawResourceConstructor(golem_api_grpc::proto::golem::rib::RawResourceConstructor {
242 resource_name: resource
243 }))
244 },
245 FunctionReferenceType::RawResourceDrop { resource } => golem_api_grpc::proto::golem::rib::FunctionReferenceType {
246 r#type: Some(golem_api_grpc::proto::golem::rib::function_reference_type::Type::RawResourceDrop(golem_api_grpc::proto::golem::rib::RawResourceDrop {
247 resource_name: resource
248 }))
249 },
250 FunctionReferenceType::RawResourceMethod { resource, method } => golem_api_grpc::proto::golem::rib::FunctionReferenceType {
251 r#type: Some(golem_api_grpc::proto::golem::rib::function_reference_type::Type::RawResourceMethod(golem_api_grpc::proto::golem::rib::RawResourceMethod {
252 resource_name: resource,
253 method_name: method,
254 }))
255 },
256 FunctionReferenceType::RawResourceStaticMethod { resource, method } => golem_api_grpc::proto::golem::rib::FunctionReferenceType {
257 r#type: Some(golem_api_grpc::proto::golem::rib::function_reference_type::Type::RawResourceStaticMethod(golem_api_grpc::proto::golem::rib::RawResourceStaticMethod {
258 resource_name: resource,
259 method_name: method,
260 }))
261 },
262 FunctionReferenceType::IndexedResourceConstructor { resource, arg_size } => golem_api_grpc::proto::golem::rib::FunctionReferenceType {
263 r#type: Some(golem_api_grpc::proto::golem::rib::function_reference_type::Type::IndexedResourceConstructor(golem_api_grpc::proto::golem::rib::IndexedResourceConstructor {
264 resource_name: resource,
265 arg_size: arg_size as u32,
266 }))
267 },
268 FunctionReferenceType::IndexedResourceMethod { resource, arg_size, method } => golem_api_grpc::proto::golem::rib::FunctionReferenceType {
269 r#type: Some(golem_api_grpc::proto::golem::rib::function_reference_type::Type::IndexedResourceMethod(golem_api_grpc::proto::golem::rib::IndexedResourceMethod {
270 resource_name: resource,
271 arg_size: arg_size as u32,
272 method_name: method,
273 }))
274 },
275 FunctionReferenceType::IndexedResourceStaticMethod { resource, arg_size, method } => golem_api_grpc::proto::golem::rib::FunctionReferenceType {
276 r#type: Some(golem_api_grpc::proto::golem::rib::function_reference_type::Type::IndexedResourceStaticMethod(golem_api_grpc::proto::golem::rib::IndexedResourceStaticMethod {
277 resource_name: resource,
278 arg_size: arg_size as u32,
279 method_name: method,
280 }))
281 },
282 FunctionReferenceType::IndexedResourceDrop { resource, arg_size } => golem_api_grpc::proto::golem::rib::FunctionReferenceType {
283 r#type: Some(golem_api_grpc::proto::golem::rib::function_reference_type::Type::IndexedResourceDrop(golem_api_grpc::proto::golem::rib::IndexedResourceDrop {
284 resource_name: resource,
285 arg_size: arg_size as u32,
286 }))
287 }
288 }
289 }
290 }
291
292 impl TryFrom<ProtoRibIR> for RibIR {
293 type Error = String;
294
295 fn try_from(value: ProtoRibIR) -> Result<Self, Self::Error> {
296 let instruction = value
297 .instruction
298 .ok_or_else(|| "Missing instruction".to_string())?;
299
300 match instruction {
301 Instruction::GenerateWorkerName(generate_worker_name) => {
302 let variable_id = generate_worker_name
303 .variable_id
304 .map(VariableId::try_from)
305 .transpose()?;
306
307 Ok(RibIR::GenerateWorkerName(variable_id))
308 }
309 Instruction::PushLit(value) => {
310 let value: ValueAndType = value.try_into()?;
311 Ok(RibIR::PushLit(value))
312 }
313 Instruction::AssignVar(value) => Ok(RibIR::AssignVar(
314 value
315 .try_into()
316 .map_err(|_| "Failed to convert AssignVar".to_string())?,
317 )),
318 Instruction::LoadVar(value) => Ok(RibIR::LoadVar(
319 value
320 .try_into()
321 .map_err(|_| "Failed to convert LoadVar".to_string())?,
322 )),
323 Instruction::CreateAndPushRecord(value) => {
324 Ok(RibIR::CreateAndPushRecord((&value).try_into().map_err(
325 |_| "Failed to convert CreateAndPushRecord".to_string(),
326 )?))
327 }
328 Instruction::Plus(value) => {
329 Ok(RibIR::Plus((&value).try_into().map_err(|_| {
330 "Failed to convert CreateAndPushRecord".to_string()
331 })?))
332 }
333 Instruction::Multiply(value) => {
334 Ok(RibIR::Multiply((&value).try_into().map_err(|_| {
335 "Failed to convert CreateAndPushRecord".to_string()
336 })?))
337 }
338 Instruction::Minus(value) => {
339 Ok(RibIR::Minus((&value).try_into().map_err(|_| {
340 "Failed to convert CreateAndPushRecord".to_string()
341 })?))
342 }
343 Instruction::Divide(value) => {
344 Ok(RibIR::Divide((&value).try_into().map_err(|_| {
345 "Failed to convert CreateAndPushRecord".to_string()
346 })?))
347 }
348
349 Instruction::UpdateRecord(value) => Ok(RibIR::UpdateRecord(value)),
350 Instruction::PushList(value) => Ok(RibIR::PushList(
351 value
352 .list_type
353 .ok_or("List type not present".to_string())
354 .and_then(|t| {
355 (&t).try_into()
356 .map_err(|_| "Failed to convert AnalysedType".to_string())
357 })?,
358 value.list_size as usize,
359 )),
360 Instruction::CreateSome(value) => Ok(RibIR::PushSome(
361 (&value)
362 .try_into()
363 .map_err(|_| "Failed to convert CreateSome".to_string())?,
364 )),
365 Instruction::CreateNone(value) => match value.none_type {
366 Some(v) => {
367 let optional_type = (&v)
368 .try_into()
369 .map_err(|_| "Failed to convert AnalysedType".to_string());
370 Ok(RibIR::PushNone(Some(optional_type?)))
371 }
372 None => Ok(RibIR::PushNone(None)),
373 },
374 Instruction::CreateOkResult(value) => {
375 Ok(RibIR::PushOkResult((&value).try_into().map_err(|_| {
376 "Failed to convert CreateOkResult".to_string()
377 })?))
378 }
379 Instruction::CreateErrResult(value) => {
380 Ok(RibIR::PushErrResult((&value).try_into().map_err(|_| {
381 "Failed to convert CreateErrResult".to_string()
382 })?))
383 }
384 Instruction::Length(_) => Ok(RibIR::Length),
385 Instruction::SelectField(value) => Ok(RibIR::SelectField(value)),
386 Instruction::SelectIndex(value) => Ok(RibIR::SelectIndex(value as usize)),
387 Instruction::SelectIndexV1(_) => Ok(RibIR::SelectIndexV1),
388 Instruction::EqualTo(_) => Ok(RibIR::EqualTo),
389 Instruction::GreaterThan(_) => Ok(RibIR::GreaterThan),
390 Instruction::LessThan(_) => Ok(RibIR::LessThan),
391 Instruction::GreaterThanOrEqualTo(_) => Ok(RibIR::GreaterThanOrEqualTo),
392 Instruction::LessThanOrEqualTo(_) => Ok(RibIR::LessThanOrEqualTo),
393 Instruction::And(_) => Ok(RibIR::And),
394 Instruction::IsEmpty(_) => Ok(RibIR::IsEmpty),
395 Instruction::Or(_) => Ok(RibIR::Or),
396 Instruction::JumpIfFalse(value) => Ok(RibIR::JumpIfFalse(InstructionId::new(
397 value.instruction_id as usize,
398 ))),
399 Instruction::Jump(value) => Ok(RibIR::Jump(InstructionId::new(
400 value.instruction_id as usize,
401 ))),
402 Instruction::Label(value) => Ok(RibIR::Label(InstructionId::new(
403 value.instruction_id as usize,
404 ))),
405 Instruction::Deconstruct(_) => Ok(RibIR::Deconstruct),
406 Instruction::InvokeFunction(invoke_function_instruction) => {
407 let return_type = match invoke_function_instruction.return_type {
408 Some(return_type) => {
409 let analysed_type = (&return_type)
410 .try_into()
411 .map_err(|_| "Failed to convert AnalysedType".to_string())?;
412
413 AnalysedTypeWithUnit::Type(analysed_type)
414 }
415 None => AnalysedTypeWithUnit::Unit,
416 };
417
418 let instance_variable: InstanceVariable = invoke_function_instruction
419 .instance_variable
420 .ok_or("Missing instance_variable".to_string())
421 .and_then(|iv| {
422 match iv.kind.ok_or("Missing instance_variable kind".to_string())? {
423 golem_api_grpc::proto::golem::rib::instance_variable::Kind::Resource(wit_resource) => {
424 let variable_id = wit_resource.variable_id.ok_or(
425 "Missing variable_id in WitResource".to_string(),
426 )?.try_into()
427 .map_err(|_| "Failed to convert VariableId".to_string())?;
428 Ok(InstanceVariable::WitResource(variable_id))
429 }
430 golem_api_grpc::proto::golem::rib::instance_variable::Kind::Worker(wit_worker) => {
431 let variable_id = wit_worker.variable_id.ok_or(
432 "Missing variable_id in WitWorker".to_string(),
433 )?.try_into()
434 .map_err(|_| "Failed to convert VariableId".to_string())?;
435
436 Ok(InstanceVariable::WitWorker(variable_id))
437 }
438 }
439 })?;
440
441 let component_dependency_key_proto = invoke_function_instruction
442 .component
443 .ok_or("Missing component_dependency_key".to_string())?;
444
445 let component_dependency_key =
446 ComponentDependencyKey::try_from(component_dependency_key_proto)
447 .map_err(|_| "Failed to convert ComponentDependencyKey".to_string())?;
448
449 Ok(RibIR::InvokeFunction(
450 component_dependency_key,
451 instance_variable,
452 invoke_function_instruction.argument_count as usize,
453 return_type,
454 ))
455 }
456 Instruction::VariantConstruction(variant_construction) => {
457 let variant_type = variant_construction
458 .return_type
459 .ok_or("Missing return_type for variant construction".to_string())?;
460
461 let analysed_variant_type = (&variant_type)
462 .try_into()
463 .map_err(|_| "Failed to convert AnalysedType".to_string())?;
464
465 Ok(RibIR::PushVariant(
466 variant_construction.variant_name,
467 analysed_variant_type,
468 ))
469 }
470 Instruction::EnumConstruction(enum_construction) => {
471 let enum_type = enum_construction
472 .return_type
473 .ok_or("Missing return_type for enum construction".to_string())?;
474
475 let analysed_enum_type = (&enum_type)
476 .try_into()
477 .map_err(|_| "Failed to convert AnalysedType".to_string())?;
478
479 Ok(RibIR::PushEnum(
480 enum_construction.enum_name,
481 analysed_enum_type,
482 ))
483 }
484 Instruction::Throw(value) => Ok(RibIR::Throw(value)),
485 Instruction::PushFlag(flag) => {
486 let flag: ValueAndType = flag.try_into()?;
487 Ok(RibIR::PushFlag(flag))
488 }
489 Instruction::GetTag(_) => Ok(RibIR::GetTag),
490 Instruction::PushTuple(tuple_instruction) => {
491 let tuple_type = tuple_instruction
492 .tuple_type
493 .ok_or("Missing tuple_type".to_string())
494 .and_then(|t| {
495 (&t).try_into()
496 .map_err(|_| "Failed to convert AnalysedType".to_string())
497 })?;
498
499 Ok(RibIR::PushTuple(
500 tuple_type,
501 tuple_instruction.tuple_size as usize,
502 ))
503 }
504 Instruction::Negate(_) => Ok(RibIR::Negate),
505 Instruction::Concat(concat_instruction) => {
506 Ok(RibIR::Concat(concat_instruction.arg_size as usize))
507 }
508 Instruction::CreateFunctionName(instruction) => {
509 let parsed_site = instruction.site.ok_or("Missing site".to_string())?;
510 let parsed_function_site = ParsedFunctionSite::try_from(parsed_site)?;
511
512 let reference_type = instruction
513 .function_reference_details
514 .ok_or("Missing reference_type".to_string())?;
515 let function_reference_type = reference_type.try_into()?;
516
517 Ok(RibIR::CreateFunctionName(
518 parsed_function_site,
519 function_reference_type,
520 ))
521 }
522 Instruction::ListToIterator(_) => Ok(RibIR::ToIterator),
523 Instruction::CreateSink(create_sink) => {
524 let result = create_sink
525 .list_type
526 .ok_or("Sink list type not present".to_string())
527 .and_then(|t| {
528 (&t).try_into()
529 .map_err(|_| "Failed to convert AnalysedType".to_string())
530 })?;
531
532 Ok(RibIR::CreateSink(result))
533 }
534 Instruction::AdvanceIterator(_) => Ok(RibIR::AdvanceIterator),
535 Instruction::SinkToList(_) => Ok(RibIR::SinkToList),
536 Instruction::PushToSink(_) => Ok(RibIR::PushToSink),
537 }
538 }
539 }
540
541 impl TryFrom<RibIR> for ProtoRibIR {
542 type Error = String;
543
544 fn try_from(value: RibIR) -> Result<Self, Self::Error> {
545 let instruction = match value {
546 RibIR::GenerateWorkerName(variable_id) => {
547 let variable_id_proto = variable_id.map(|v| v.into());
548
549 Instruction::GenerateWorkerName(
550 golem_api_grpc::proto::golem::rib::GenerateWorkerName {
551 variable_id: variable_id_proto,
552 },
553 )
554 }
555 RibIR::PushLit(value) => {
556 Instruction::PushLit(golem_wasm_rpc::protobuf::TypeAnnotatedValue {
557 type_annotated_value: Some(
558 value
559 .try_into()
560 .map_err(|errs: Vec<String>| errs.join(", "))?,
561 ),
562 })
563 }
564 RibIR::And => Instruction::And(And {}),
565 RibIR::IsEmpty => Instruction::IsEmpty(IsEmpty {}),
566 RibIR::Or => Instruction::Or(Or {}),
567 RibIR::AssignVar(value) => Instruction::AssignVar(value.into()),
568 RibIR::LoadVar(value) => Instruction::LoadVar(value.into()),
569 RibIR::CreateAndPushRecord(value) => {
570 Instruction::CreateAndPushRecord((&value).into())
571 }
572 RibIR::Plus(value) => Instruction::Plus((&value).into()),
573 RibIR::Minus(value) => Instruction::Minus((&value).into()),
574 RibIR::Multiply(value) => Instruction::Multiply((&value).into()),
575 RibIR::Divide(value) => Instruction::Divide((&value).into()),
576 RibIR::UpdateRecord(value) => Instruction::UpdateRecord(value),
577 RibIR::PushList(value, arg_size) => Instruction::PushList(PushListInstruction {
578 list_type: Some((&value).into()),
579 list_size: arg_size as u64,
580 }),
581 RibIR::PushSome(value) => Instruction::CreateSome((&value).into()),
582 RibIR::PushNone(value) => {
583 let push_none_instruction = PushNoneInstruction {
584 none_type: value.map(|t| (&t).into()),
585 };
586 Instruction::CreateNone(push_none_instruction)
587 }
588 RibIR::PushOkResult(value) => Instruction::CreateOkResult((&value).into()),
589 RibIR::PushErrResult(value) => Instruction::CreateErrResult((&value).into()),
590 RibIR::SelectField(value) => Instruction::SelectField(value),
591 RibIR::SelectIndex(value) => Instruction::SelectIndex(value as u64),
592 RibIR::EqualTo => Instruction::EqualTo(EqualTo {}),
593 RibIR::GreaterThan => Instruction::GreaterThan(GreaterThan {}),
594 RibIR::LessThan => Instruction::LessThan(LessThan {}),
595 RibIR::Length => Instruction::Length(golem_api_grpc::proto::golem::rib::Length {}),
596 RibIR::SelectIndexV1 => {
597 Instruction::SelectIndexV1(golem_api_grpc::proto::golem::rib::SelectIndexV1 {})
598 }
599 RibIR::GreaterThanOrEqualTo => {
600 Instruction::GreaterThanOrEqualTo(GreaterThanOrEqualTo {})
601 }
602 RibIR::LessThanOrEqualTo => Instruction::LessThanOrEqualTo(LessThanOrEqualTo {}),
603 RibIR::JumpIfFalse(value) => Instruction::JumpIfFalse(JumpInstruction {
604 instruction_id: value.index as u64,
605 }),
606 RibIR::Jump(value) => Instruction::Jump(JumpInstruction {
607 instruction_id: value.index as u64,
608 }),
609 RibIR::Label(value) => Instruction::Label(JumpInstruction {
610 instruction_id: value.index as u64,
611 }),
612 RibIR::Deconstruct => {
613 Instruction::Deconstruct((&AnalysedType::Str(TypeStr)).into())
614 } RibIR::InvokeFunction(
616 component_dependency_key,
617 worker_name_presence,
618 arg_count,
619 return_type,
620 ) => {
621 let typ = match return_type {
622 AnalysedTypeWithUnit::Unit => None,
623 AnalysedTypeWithUnit::Type(analysed_type) => {
624 let typ =
625 golem_wasm_ast::analysis::protobuf::Type::from(&analysed_type);
626 Some(typ)
627 }
628 };
629
630 let instance_variable = match worker_name_presence {
631 InstanceVariable::WitResource(variable_id) => {
632 golem_api_grpc::proto::golem::rib::InstanceVariable {
633 kind: Some(
634 golem_api_grpc::proto::golem::rib::instance_variable::Kind::Resource(
635 WitResource {
636 variable_id: Some(variable_id.into()),
637 },
638 ),
639 ),
640 }
641 }
642 InstanceVariable::WitWorker(variable_id) => {
643 golem_api_grpc::proto::golem::rib::InstanceVariable {
644 kind: Some(
645 golem_api_grpc::proto::golem::rib::instance_variable::Kind::Worker(
646 golem_api_grpc::proto::golem::rib::WitWorker {
647 variable_id: Some(variable_id.into()),
648 },
649 ),
650 ),
651 }
652 }
653 };
654
655 let component_dependency_key =
656 golem_api_grpc::proto::golem::rib::ComponentDependencyKey::from(
657 component_dependency_key,
658 );
659
660 Instruction::InvokeFunction(InvokeFunctionInstruction {
661 component: Some(component_dependency_key),
662 argument_count: arg_count as u64,
663 return_type: typ,
664 instance_variable: Some(instance_variable),
665 })
666 }
667 RibIR::PushVariant(name, return_type) => {
668 let typ = golem_wasm_ast::analysis::protobuf::Type::from(&return_type);
669
670 Instruction::VariantConstruction(
671 golem_api_grpc::proto::golem::rib::VariantConstructionInstruction {
672 variant_name: name,
673 return_type: Some(typ),
674 },
675 )
676 }
677 RibIR::PushEnum(name, return_type) => {
678 let typ = golem_wasm_ast::analysis::protobuf::Type::from(&return_type);
679
680 Instruction::EnumConstruction(
681 golem_api_grpc::proto::golem::rib::EnumConstructionInstruction {
682 enum_name: name,
683 return_type: Some(typ),
684 },
685 )
686 }
687 RibIR::Throw(msg) => Instruction::Throw(msg),
688 RibIR::PushFlag(flag) => {
689 Instruction::PushFlag(golem_wasm_rpc::protobuf::TypeAnnotatedValue {
690 type_annotated_value: Some(
691 flag.try_into()
692 .map_err(|errs: Vec<String>| errs.join(", "))?,
693 ),
694 })
695 }
696 RibIR::GetTag => Instruction::GetTag(GetTag {}),
697 RibIR::PushTuple(analysed_type, size) => {
698 let typ = golem_wasm_ast::analysis::protobuf::Type::from(&analysed_type);
699
700 Instruction::PushTuple(PushTupleInstruction {
701 tuple_type: Some(typ),
702 tuple_size: size as u64,
703 })
704 }
705 RibIR::Concat(concat) => Instruction::Concat(ConcatInstruction {
706 arg_size: concat as u64,
707 }),
708 RibIR::Negate => Instruction::Negate(Negate {}),
709 RibIR::CreateFunctionName(site, reference_type) => {
710 Instruction::CreateFunctionName(CreateFunctionNameInstruction {
711 site: Some(site.into()),
712 function_reference_details: Some(reference_type.into()),
713 })
714 }
715
716 RibIR::ToIterator => Instruction::ListToIterator(
717 golem_api_grpc::proto::golem::rib::ListToIterator {},
718 ),
719 RibIR::CreateSink(analysed_type) => {
720 Instruction::CreateSink(golem_api_grpc::proto::golem::rib::CreateSink {
721 list_type: Some((&analysed_type).into()),
722 })
723 }
724 RibIR::AdvanceIterator => Instruction::AdvanceIterator(
725 golem_api_grpc::proto::golem::rib::AdvanceIterator {},
726 ),
727 RibIR::PushToSink => {
728 Instruction::PushToSink(golem_api_grpc::proto::golem::rib::PushToSink {})
729 }
730 RibIR::SinkToList => {
731 Instruction::SinkToList(golem_api_grpc::proto::golem::rib::SinkToList {})
732 }
733 };
734
735 Ok(ProtoRibIR {
736 instruction: Some(instruction),
737 })
738 }
739 }
740}