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