neo_solidity/ir/expressions/calls/builtins/
member_runtime.rs

1fn try_lower_runtime_member_builtin(
2    base: &Identifier,
3    member: &Identifier,
4    args: &[Expression],
5    ctx: &mut LoweringContext,
6    instructions: &mut Vec<Instruction>,
7) -> Option<bool> {
8    if base.name != "Runtime" {
9        return None;
10    }
11
12    match member.name.as_str() {
13        "initializeServices" => {
14            if !args.is_empty() {
15                ctx.record_error(format!(
16                    "Runtime.initializeServices requires 0 argument(s), got {}",
17                    args.len()
18                ));
19                return Some(false);
20            }
21
22            // The devpack exposes Runtime.initializeServices() as a convenience initializer,
23            // but builtin libraries are compiler intrinsics and their Solidity bodies are
24            // not compiled. Treat this helper as a no-op so devpack-based sources remain
25            // portable while keeping the generated bytecode minimal.
26            instructions.push(Instruction::PushLiteral(LiteralValue::Boolean(true)));
27            Some(true)
28        }
29        "notifyIndexed" => {
30            if args.len() != 3 {
31                ctx.record_error(format!(
32                    "Runtime.notifyIndexed requires 3 argument(s), got {}",
33                    args.len()
34                ));
35                return Some(false);
36            }
37
38            // notifyIndexed(eventName, topics, data) => notify(eventName, abi.encode(topics, data))
39            if !lower_expression(&args[0], ctx, instructions) {
40                return Some(false);
41            }
42            if !lower_expression(&args[1], ctx, instructions) {
43                return Some(false);
44            }
45            if !lower_expression(&args[2], ctx, instructions) {
46                return Some(false);
47            }
48
49            instructions.push(Instruction::CallBuiltin {
50                builtin: BuiltinCall::AbiEncode,
51                arg_count: 2,
52            });
53            validate_runtime_notify_call(
54                &[
55                    args[0].clone(),
56                    Expression::FunctionCall(
57                        Default::default(),
58                        Box::new(Expression::MemberAccess(
59                            Default::default(),
60                            Box::new(Expression::Variable(Identifier {
61                                loc: Default::default(),
62                                name: "abi".to_string(),
63                            })),
64                            Identifier {
65                                loc: Default::default(),
66                                name: "encode".to_string(),
67                            },
68                        )),
69                        vec![args[1].clone(), args[2].clone()],
70                    ),
71                ],
72                ctx,
73            );
74            instructions.push(Instruction::CallBuiltin {
75                builtin: BuiltinCall::RuntimeNotify,
76                arg_count: 2,
77            });
78            Some(true)
79        }
80        _ => None,
81    }
82}