neo_solidity/cli/bytecode/bytecode_builtins/builtin_call/
emit.rs

1fn emit_builtin_call(
2    bytecode: &mut Vec<u8>,
3    builtin: &ir::BuiltinCall,
4    arg_count: usize,
5    use_callt: bool,
6    token_patches: &mut Vec<MethodTokenPatch>,
7) {
8    match builtin {
9        ir::BuiltinCall::RuntimeNotify => {
10            emit_runtime_notify(bytecode, use_callt, token_patches);
11        }
12        ir::BuiltinCall::RuntimeCheckWitness => emit_runtime_check_witness(bytecode),
13        ir::BuiltinCall::Keccak256 => emit_keccak256(bytecode, use_callt, token_patches),
14        ir::BuiltinCall::Ecrecover => emit_ecrecover(bytecode, use_callt, token_patches),
15        ir::BuiltinCall::StorageFind => emit_storage_find(bytecode, arg_count),
16        ir::BuiltinCall::StoragePut => emit_storage_put(bytecode),
17        ir::BuiltinCall::StorageGet => emit_storage_get(bytecode),
18        ir::BuiltinCall::StorageDelete => emit_storage_delete(bytecode),
19        ir::BuiltinCall::AbiEncode | ir::BuiltinCall::AbiEncodePacked | ir::BuiltinCall::AbiEncodeCall => {
20            emit_abi_encode(bytecode, arg_count, use_callt, token_patches)
21        }
22        ir::BuiltinCall::AbiDecode => emit_abi_decode(bytecode, use_callt, token_patches),
23        ir::BuiltinCall::NativeCall { contract, method } => emit_native_call(
24            bytecode,
25            *contract,
26            method.as_str(),
27            arg_count,
28            use_callt,
29            token_patches,
30        ),
31        ir::BuiltinCall::Syscall(name) => emit_syscall_builtin(bytecode, name, arg_count),
32        ir::BuiltinCall::ContractCall => emit_contract_call(bytecode, use_callt, token_patches),
33        ir::BuiltinCall::ContractCallWithFlags => {
34            emit_contract_call_with_flags(bytecode, use_callt, token_patches)
35        }
36        ir::BuiltinCall::NotifySerialized => {
37            emit_notify_serialized(bytecode, use_callt, token_patches)
38        }
39        ir::BuiltinCall::VerifySignature => emit_verify_signature(bytecode, use_callt, token_patches),
40        ir::BuiltinCall::DeployContract => {
41            emit_deploy_contract(bytecode, arg_count, use_callt, token_patches)
42        }
43        ir::BuiltinCall::GetContract => emit_get_contract(bytecode, use_callt, token_patches),
44        ir::BuiltinCall::GetContractScript => {
45            emit_get_contract_script(bytecode, use_callt, token_patches)
46        }
47        ir::BuiltinCall::GetNeoAccountState => {
48            emit_get_neo_account_state(bytecode, use_callt, token_patches)
49        }
50        ir::BuiltinCall::TypeOf | ir::BuiltinCall::AbiEncodeWithSignature => {}
51        ir::BuiltinCall::BytesConcat => {
52            // bytes.concat(a, b, c, ...) → chain NeoVM CAT opcodes.
53            // Args are already on the stack. For N args we need N-1 CAT ops.
54            // CAT pops two byte arrays and pushes their concatenation.
55            for _ in 1..arg_count {
56                bytecode.push(0x8B); // CAT opcode
57            }
58            // If zero args, push empty byte array.
59            if arg_count == 0 {
60                bytecode.push(0x00); // PUSH0 (empty buffer)
61                bytecode.push(0x28); // NEWBUFFER
62            }
63        }
64    }
65}