WARNING! Access to this system is limited to authorised users only.
Unauthorised users may be subject to prosecution.
Unauthorised access to this system is a criminal offence under Australian law (Federal Crimes Act 1914 Part VIA)
It is a criminal offence to:
(1) Obtain access to data without authority. -Penalty 2 years imprisonment.
(2) Damage, delete, alter or insert data without authority. -Penalty 10 years imprisonment.
User activity is monitored and recorded. Anyone using this system expressly consents to such monitoring and recording.

To protect your data, the CISO officer has suggested users to enable 2FA as soon as possible.
Currently 2.7% of users enabled 2FA.

test_ir.rs 15.6 KB
Newer Older
1
2
3
4
extern crate mu;

use self::mu::ast::types::*;
use self::mu::ast::ir::*;
5
use self::mu::ast::inst::*;
6
use self::mu::ast::ptr::*;
qinsoon's avatar
qinsoon committed
7
use self::mu::ast::op::*;
qinsoon's avatar
qinsoon committed
8
use self::mu::vm::*;
qinsoon's avatar
qinsoon committed
9
use self::mu::vm::api::*;
10

11
use std::cell::RefCell;
12
use std::collections::HashMap;
13

14
15
16
17
18
19
#[test]
#[allow(unused_variables)]
fn test_factorial() {
    let vm = factorial();
}

qinsoon's avatar
qinsoon committed
20
21
22
23
24
25
#[test]
#[allow(unused_variables)]
fn test_sum() {
    let vm = sum();
}

qinsoon's avatar
qinsoon committed
26
27
28
29
30
31
#[test]
#[allow(unused_variables)]
fn test_global_access() {
    let vm = global_access();
}

qinsoon's avatar
qinsoon committed
32
33
pub fn sum() -> VM {
    let vm = VM::new();
34

qinsoon's avatar
qinsoon committed
35
    // .typedef @int_64 = int<64>
qinsoon's avatar
qinsoon committed
36
37
38
39
    let mut type_def_int64 = vm.declare_type(vm.next_id(), MuType_::int(64));
    type_def_int64.set_name("int_64");
    let mut type_def_int1  = vm.declare_type(vm.next_id(), MuType_::int(1));
    type_def_int1.set_name("int_1");
40

qinsoon's avatar
qinsoon committed
41
42
    // .const @int_64_0 <@int_64> = 0
    // .const @int_64_1 <@int_64> = 1
qinsoon's avatar
qinsoon committed
43
44
    let const_def_int64_0 = vm.declare_const(vm.next_id(), "int64_0", type_def_int64.clone(), Constant::Int(0));
    let const_def_int64_1 = vm.declare_const(vm.next_id(), "int64_1", type_def_int64.clone(), Constant::Int(1));
45

qinsoon's avatar
qinsoon committed
46
47
    // .funcsig @sum_sig = (@int_64) -> (@int_64)
    let sum_sig = vm.declare_func_sig("sum_sig", vec![type_def_int64.clone()], vec![type_def_int64.clone()]);
48

49
    // .funcdecl @sum <@sum_sig>
qinsoon's avatar
qinsoon committed
50
51
52
    let mut func = MuFunction::new(vm.next_id(), sum_sig.clone());
    func.set_name("sum");
    let func_id = func.id;
53
54
55
    vm.declare_func(func);

    // .funcdef @sum VERSION @sum_v1 <@sum_sig> 
qinsoon's avatar
qinsoon committed
56
57
    let mut func_ver = MuFunctionVersion::new(vm.next_id(), func_id, sum_sig.clone());
    func_ver.set_name("sum_v1");
58

qinsoon's avatar
qinsoon committed
59
    // %entry(<@int_64> %n):
qinsoon's avatar
qinsoon committed
60
61
62
    let mut blk_entry = Block::new(vm.next_id());
    blk_entry.set_name("entry");
    
63
64
65
    let blk_entry_n = func_ver.new_ssa(vm.next_id(), "blk_entry_n", type_def_int64.clone());
    let const_def_int64_0_local = func_ver.new_constant(vm.next_id(), const_def_int64_0.clone()); // FIXME: why we need a local version?
    let const_def_int64_1_local = func_ver.new_constant(vm.next_id(), const_def_int64_1.clone());
66

qinsoon's avatar
qinsoon committed
67
    // BRANCH %head
qinsoon's avatar
qinsoon committed
68
69
    let mut blk_head = Block::new(vm.next_id());
    blk_head.set_name("head");
70
    let blk_entry_term = func_ver.new_inst(vm.next_id(), Instruction {
qinsoon's avatar
qinsoon committed
71
72
73
        value: None,
        ops: RefCell::new(vec![blk_entry_n.clone(), const_def_int64_0_local.clone(), const_def_int64_0_local.clone()]),
        v: Instruction_::Branch1(Destination{
qinsoon's avatar
qinsoon committed
74
            target: blk_head.id(),
qinsoon's avatar
qinsoon committed
75
76
77
            args: vec![DestArg::Normal(0), DestArg::Normal(1), DestArg::Normal(2)]
        })
    });
78

qinsoon's avatar
qinsoon committed
79
    let blk_entry_content = BlockContent {
80
        args: vec![blk_entry_n.clone_value()],
qinsoon's avatar
qinsoon committed
81
82
83
84
        body: vec![blk_entry_term],
        keepalives: None
    };
    blk_entry.content = Some(blk_entry_content);
85

qinsoon's avatar
qinsoon committed
86
    // %head(<@int_64> %n, <@int_64> %s, <@int_64> %i):
qinsoon's avatar
qinsoon committed
87

88
89
90
    let blk_head_n = func_ver.new_ssa(vm.next_id(), "blk_head_n", type_def_int64.clone());
    let blk_head_s = func_ver.new_ssa(vm.next_id(), "blk_head_s", type_def_int64.clone());
    let blk_head_i = func_ver.new_ssa(vm.next_id(), "blk_head_i", type_def_int64.clone());
91

qinsoon's avatar
qinsoon committed
92
    // %s2 = ADD %s %i
93
94
    let blk_head_s2 = func_ver.new_ssa(vm.next_id(), "blk_head_s2", type_def_int64.clone());
    let blk_head_inst0 = func_ver.new_inst(vm.next_id(), Instruction {
qinsoon's avatar
qinsoon committed
95
        value: Some(vec![blk_head_s2.clone_value()]),
qinsoon's avatar
qinsoon committed
96
97
98
        ops: RefCell::new(vec![blk_head_s.clone(), blk_head_i.clone()]),
        v: Instruction_::BinOp(BinOp::Add, 0, 1)
    });
99

qinsoon's avatar
qinsoon committed
100
    // %i2 = ADD %i 1
101
102
    let blk_head_i2 = func_ver.new_ssa(vm.next_id(), "blk_head_i2", type_def_int64.clone());
    let blk_head_inst1 = func_ver.new_inst(vm.next_id(), Instruction {
qinsoon's avatar
qinsoon committed
103
        value: Some(vec![blk_head_i2.clone_value()]),
qinsoon's avatar
qinsoon committed
104
105
106
        ops: RefCell::new(vec![blk_head_i.clone(), const_def_int64_1_local.clone()]),
        v: Instruction_::BinOp(BinOp::Add, 0, 1)
    });
107

qinsoon's avatar
qinsoon committed
108
    // %cond = UGT %i %n
109
110
    let blk_head_cond = func_ver.new_ssa(vm.next_id(), "blk_head_cond", type_def_int1.clone());
    let blk_head_inst2 = func_ver.new_inst(vm.next_id(), Instruction {
qinsoon's avatar
qinsoon committed
111
        value: Some(vec![blk_head_cond.clone_value()]),
qinsoon's avatar
qinsoon committed
112
113
114
115
116
        ops: RefCell::new(vec![blk_head_i.clone(), blk_head_n.clone()]),
        v: Instruction_::CmpOp(CmpOp::UGT, 0, 1)
    });

    // BRANCH2 %cond %ret(%s2) %head(%n %s2 %i2)
qinsoon's avatar
qinsoon committed
117
118
    let mut blk_ret = Block::new(vm.next_id());
    blk_ret.set_name("ret");    
119
    let blk_head_term = func_ver.new_inst(vm.next_id(), Instruction{
qinsoon's avatar
qinsoon committed
120
121
122
123
124
        value: None,
        ops: RefCell::new(vec![blk_head_cond.clone(), blk_head_n.clone(), blk_head_s2.clone(), blk_head_i2.clone()]),
        v: Instruction_::Branch2 {
            cond: 0,
            true_dest: Destination {
qinsoon's avatar
qinsoon committed
125
                target: blk_ret.id(),
qinsoon's avatar
qinsoon committed
126
127
128
                args: vec![DestArg::Normal(2)]
            },
            false_dest: Destination {
qinsoon's avatar
qinsoon committed
129
                target: blk_head.id(),
qinsoon's avatar
qinsoon committed
130
131
132
133
134
135
136
                args: vec![DestArg::Normal(1), DestArg::Normal(2), DestArg::Normal(3)]
            },
            true_prob: 0.6f32
        }
    });

    let blk_head_content = BlockContent {
137
        args: vec![blk_head_n.clone_value(), blk_head_s.clone_value(), blk_head_i.clone_value()],
qinsoon's avatar
qinsoon committed
138
139
140
141
        body: vec![blk_head_inst0, blk_head_inst1, blk_head_inst2, blk_head_term],
        keepalives: None
    };
    blk_head.content = Some(blk_head_content);
142

qinsoon's avatar
qinsoon committed
143
    // %ret(<@int_64> %s):
144
    let blk_ret_s = func_ver.new_ssa(vm.next_id(), "blk_ret_s", type_def_int64.clone());
145

qinsoon's avatar
qinsoon committed
146
    // RET %s
147
    let blk_ret_term = func_ver.new_inst(vm.next_id(), Instruction{
qinsoon's avatar
qinsoon committed
148
149
150
151
        value: None,
        ops: RefCell::new(vec![blk_ret_s.clone()]),
        v: Instruction_::Return(vec![0])
    });
152

qinsoon's avatar
qinsoon committed
153
    let blk_ret_content = BlockContent {
154
        args: vec![blk_ret_s.clone_value()],
qinsoon's avatar
qinsoon committed
155
156
157
158
159
160
        body: vec![blk_ret_term],
        keepalives: None
    };
    blk_ret.content = Some(blk_ret_content);

    // wrap into a function
161
    func_ver.define(FunctionContent{
qinsoon's avatar
qinsoon committed
162
            entry: blk_entry.id(),
qinsoon's avatar
qinsoon committed
163
164
            blocks: {
                let mut blocks = HashMap::new();
qinsoon's avatar
qinsoon committed
165
166
167
                blocks.insert(blk_entry.id(), blk_entry);
                blocks.insert(blk_head.id(), blk_head);
                blocks.insert(blk_ret.id(), blk_ret);
qinsoon's avatar
qinsoon committed
168
169
170
                blocks
            }
    });
171

172
    vm.define_func_version(func_ver);
173

qinsoon's avatar
qinsoon committed
174
175
176
    vm
}

177
#[allow(unused_variables)]
qinsoon's avatar
qinsoon committed
178
179
pub fn factorial() -> VM {
    let vm = VM::new();
180

181
182
183
184
185
186
187
    // .typedef @int_64 = int<64>
    // .typedef @int_1 = int<1>
    // .typedef @float = float
    // .typedef @double = double
    // .typedef @void = void
    // .typedef @int_8 = int<8>
    // .typedef @int_32 = int<32>
qinsoon's avatar
qinsoon committed
188
189
190
191
192
193
194
195
196
197
198
199
200
201
    let mut type_def_int64 = vm.declare_type(vm.next_id(), MuType_::int(64));
    type_def_int64.set_name("int_64");
    let mut type_def_int1  = vm.declare_type(vm.next_id(), MuType_::int(1));
    type_def_int1.set_name("int_1");
    let mut type_def_float = vm.declare_type(vm.next_id(), MuType_::float());
    type_def_float.set_name("float");
    let mut type_def_double = vm.declare_type(vm.next_id(), MuType_::double());
    type_def_double.set_name("double");
    let mut type_def_void  = vm.declare_type(vm.next_id(), MuType_::void());
    type_def_void.set_name("void");
    let mut type_def_int8  = vm.declare_type(vm.next_id(), MuType_::int(8));
    type_def_int8.set_name("int8");
    let mut type_def_int32 = vm.declare_type(vm.next_id(), MuType_::int(32));
    type_def_int32.set_name("int32");
202

203
    // .const @int_64_1 <@int_64> = 1
qinsoon's avatar
qinsoon committed
204
    let const_def_int64_1 = vm.declare_const(vm.next_id(), "int64_1", type_def_int64.clone(), Constant::Int(1));
205

206
207
    // .funcsig @fac_sig = (@int_64) -> (@int_64)
    let fac_sig = vm.declare_func_sig("fac_sig", vec![type_def_int64.clone()], vec![type_def_int64.clone()]);
qinsoon's avatar
qinsoon committed
208
209
    let mut type_def_funcref_fac = vm.declare_type(vm.next_id(), MuType_::funcref(fac_sig.clone()));
    type_def_funcref_fac.set_name("fac_sig");
210

211
    // .funcdecl @fac <@fac_sig>
qinsoon's avatar
qinsoon committed
212
213
    let func = MuFunction::new(vm.next_id(), fac_sig.clone());
    let func_id = func.id;
214
215
    vm.declare_func(func);

216
    // .funcdef @fac VERSION @fac_v1 <@fac_sig>
qinsoon's avatar
qinsoon committed
217
    let const_func_fac = vm.declare_const(vm.next_id(), "fac", type_def_funcref_fac, Constant::FuncRef("fac"));
qinsoon's avatar
qinsoon committed
218
    let mut func_ver = MuFunctionVersion::new(vm.next_id(), func_id, fac_sig.clone());
219

220
    // %blk_0(<@int_64> %n_3):
qinsoon's avatar
qinsoon committed
221
222
    let mut blk_0 = Block::new(vm.next_id());
    blk_0.set_name("blk_0");
223
224
    let blk_0_n_3 = func_ver.new_ssa(vm.next_id(), "blk_0_n_3", type_def_int64.clone());
    let const_def_int64_1_local = func_ver.new_constant(vm.next_id(), const_def_int64_1.clone());
225

226
    //   %v48 = EQ <@int_64> %n_3 @int_64_1
227
228
    let blk_0_v48 = func_ver.new_ssa(vm.next_id(), "blk_0_v48", type_def_int64.clone());
    let blk_0_inst0 = func_ver.new_inst(vm.next_id(), Instruction {
qinsoon's avatar
qinsoon committed
229
            value: Some(vec![blk_0_v48.clone_value()]),
230
231
            ops: RefCell::new(vec![blk_0_n_3.clone(), const_def_int64_1_local.clone()]),
            v: Instruction_::CmpOp(CmpOp::EQ, 0, 1)
232
233
    });

234
    //   BRANCH2 %v48 %blk_2(@int_64_1) %blk_1(%n_3)
qinsoon's avatar
qinsoon committed
235
236
237
238
    let mut blk_1 = Block::new(vm.next_id());
    blk_1.set_name("blk_1");    
    let mut blk_2 = Block::new(vm.next_id());
    blk_2.set_name("blk_2");
239
    let blk_0_term = func_ver.new_inst(vm.next_id(), Instruction{
240
241
242
243
244
        value: None,
        ops: RefCell::new(vec![blk_0_v48.clone(), const_def_int64_1_local.clone(), blk_0_n_3.clone()]),
        v: Instruction_::Branch2 {
            cond: 0,
            true_dest: Destination {
qinsoon's avatar
qinsoon committed
245
                target: blk_2.id,
246
247
248
                args: vec![DestArg::Normal(1)]
            },
            false_dest: Destination {
qinsoon's avatar
qinsoon committed
249
                target: blk_1.id,
250
                args: vec![DestArg::Normal(2)]
251
            },
252
            true_prob: 0.3f32
253
        }
qinsoon's avatar
qinsoon committed
254
    });
255

256
    let blk_0_content = BlockContent {
257
        args: vec![blk_0_n_3.clone_value()],
258
        body: vec![blk_0_inst0, blk_0_term],
259
        keepalives: None
260
    };
261
    blk_0.content = Some(blk_0_content);
262
263

    // %blk_2(<@int_64> %v53):
264
    let blk_2_v53 = func_ver.new_ssa(vm.next_id(), "blk_2_v53", type_def_int64.clone());
265

266
    //   RET %v53
267
    let blk_2_term = func_ver.new_inst(vm.next_id(), Instruction{
268
269
270
271
        value: None,
        ops: RefCell::new(vec![blk_2_v53.clone()]),
        v: Instruction_::Return(vec![0])
    });
272

273
    let blk_2_content = BlockContent {
274
        args: vec![blk_2_v53.clone_value()],
275
        body: vec![blk_2_term],
276
277
        keepalives: None
    };
278
    blk_2.content = Some(blk_2_content);
279

280
    // %blk_1(<@int_64> %n_3):
281
    let blk_1_n_3 = func_ver.new_ssa(vm.next_id(), "blk_1_n_3", type_def_int64.clone());
282

283
    //   %v50 = SUB <@int_64> %n_3 @int_64_1
284
285
    let blk_1_v50 = func_ver.new_ssa(vm.next_id(), "blk_1_v50", type_def_int64.clone());
    let blk_1_inst0 = func_ver.new_inst(vm.next_id(), Instruction{
qinsoon's avatar
qinsoon committed
286
        value: Some(vec![blk_1_v50.clone_value()]),
287
288
289
        ops: RefCell::new(vec![blk_1_n_3.clone(), const_def_int64_1_local.clone()]),
        v: Instruction_::BinOp(BinOp::Sub, 0, 1)
    });
290

291
    //   %v51 = CALL <@fac_sig> @fac (%v50)
292
293
294
    let blk_1_v51 = func_ver.new_ssa(vm.next_id(), "blk_1_v51", type_def_int64.clone());
    let blk_1_fac = func_ver.new_constant(vm.next_id(), const_func_fac.clone());
    let blk_1_inst1 = func_ver.new_inst(vm.next_id(), Instruction{
qinsoon's avatar
qinsoon committed
295
296
        value: Some(vec![blk_1_v51.clone_value()]),
        ops: RefCell::new(vec![blk_1_fac, blk_1_v50.clone()]),
297
298
299
300
301
302
303
304
        v: Instruction_::ExprCall {
            data: CallData {
                func: 0,
                args: vec![1],
                convention: CallConvention::Mu
            },
            is_abort: true
        }
qinsoon's avatar
qinsoon committed
305
    });
306

307
    //   %v52 = MUL <@int_64> %n_3 %v51
308
309
    let blk_1_v52 = func_ver.new_ssa(vm.next_id(), "blk_1_v52", type_def_int64.clone());
    let blk_1_inst2 = func_ver.new_inst(vm.next_id(), Instruction{
qinsoon's avatar
qinsoon committed
310
        value: Some(vec![blk_1_v52.clone_value()]),
311
312
        ops: RefCell::new(vec![blk_1_n_3.clone(), blk_1_v51.clone()]),
        v: Instruction_::BinOp(BinOp::Mul, 0, 1)
qinsoon's avatar
qinsoon committed
313
    });
314

315
    // BRANCH blk_2 (%blk_1_v52)
316
    let blk_1_term = func_ver.new_inst(vm.next_id(), Instruction{
317
318
319
        value: None,
        ops: RefCell::new(vec![blk_1_v52.clone()]),
        v: Instruction_::Branch1(Destination {
qinsoon's avatar
qinsoon committed
320
                target: blk_2.id,
321
322
323
                args: vec![DestArg::Normal(0)]
           })
    });
324

325
    let blk_1_content = BlockContent {
326
        args: vec![blk_1_n_3.clone_value()],
327
        body: vec![blk_1_inst0, blk_1_inst1, blk_1_inst2, blk_1_term],
328
329
        keepalives: None
    };
330
    blk_1.content = Some(blk_1_content);
331

332
    // wrap into a function
333
    func_ver.define(FunctionContent{
qinsoon's avatar
qinsoon committed
334
            entry: blk_0.id,
335
336
            blocks: {
                let mut blocks = HashMap::new();
qinsoon's avatar
qinsoon committed
337
338
339
                blocks.insert(blk_0.id, blk_0);
                blocks.insert(blk_1.id, blk_1);
                blocks.insert(blk_2.id, blk_2);
340
341
342
                blocks
            }
    });
343

344
    vm.define_func_version(func_ver);
345

346
    vm
347
}
qinsoon's avatar
qinsoon committed
348
349

#[allow(unused_variables)]
qinsoon's avatar
qinsoon committed
350
351
pub fn global_access() -> VM {
    let vm = VM::new();
qinsoon's avatar
qinsoon committed
352
353
354
    
    // .typedef @int64 = int<64>
    // .typedef @iref_int64 = iref<int<64>>
qinsoon's avatar
qinsoon committed
355
356
357
358
    let mut type_def_int64 = vm.declare_type(vm.next_id(), MuType_::int(64));
    type_def_int64.set_name("int64");
    let mut type_def_iref_int64 = vm.declare_type(vm.next_id(), MuType_::iref(type_def_int64.clone()));
    type_def_iref_int64.set_name("iref_int64");
qinsoon's avatar
qinsoon committed
359
360
361
    
    // .const @int_64_0 <@int_64> = 0
    // .const @int_64_1 <@int_64> = 1
qinsoon's avatar
qinsoon committed
362
363
    let const_def_int64_0 = vm.declare_const(vm.next_id(), "int64_0", type_def_int64.clone(), Constant::Int(0));
    let const_def_int64_1 = vm.declare_const(vm.next_id(), "int64_1", type_def_int64.clone(), Constant::Int(1));
qinsoon's avatar
qinsoon committed
364
365
    
    // .global @a <@int_64>
qinsoon's avatar
qinsoon committed
366
    let global_a = vm.declare_global(vm.next_id(), "a", type_def_int64.clone());
qinsoon's avatar
qinsoon committed
367
368
    
    // .funcsig @global_access_sig = () -> ()
qinsoon's avatar
qinsoon committed
369
    let func_sig = vm.declare_func_sig("global_access_sig", vec![type_def_int64.clone()], vec![]);
qinsoon's avatar
qinsoon committed
370
371

    // .funcdecl @global_access <@global_access_sig>
qinsoon's avatar
qinsoon committed
372
373
    let func = MuFunction::new(vm.next_id(), func_sig.clone());
    let func_id = func.id;
qinsoon's avatar
qinsoon committed
374
375
376
    vm.declare_func(func);
    
    // .funcdef @global_access VERSION @v1 <@global_access_sig>
qinsoon's avatar
qinsoon committed
377
    let mut func_ver = MuFunctionVersion::new(vm.next_id(), func_id, func_sig.clone());
qinsoon's avatar
qinsoon committed
378
379
    
    // %blk_0():
qinsoon's avatar
qinsoon committed
380
381
    let mut blk_0 = Block::new(vm.next_id());
    blk_0.set_name("blk_0");
qinsoon's avatar
qinsoon committed
382
383
    
    // STORE <@int_64> @a @int_64_1
384
385
386
    let blk_0_a = func_ver.new_global(vm.next_id(), global_a.clone());
    let blk_0_const_int64_1 = func_ver.new_constant(vm.next_id(), const_def_int64_1.clone());
    let blk_0_inst0 = func_ver.new_inst(vm.next_id(), Instruction{
qinsoon's avatar
qinsoon committed
387
388
389
390
        value: None,
        ops: RefCell::new(vec![blk_0_a.clone(), blk_0_const_int64_1.clone()]),
        v: Instruction_::Store{
            is_ptr: false,
391
            order: MemoryOrder::Relaxed,
qinsoon's avatar
qinsoon committed
392
393
394
395
            mem_loc: 0,
            value: 1
        }
    });
qinsoon's avatar
qinsoon committed
396
397
        
    // %x = LOAD <@int_64> @a
398
399
    let blk_0_x = func_ver.new_ssa(vm.next_id(), "blk_0_x", type_def_int64.clone());
    let blk_0_inst1 = func_ver.new_inst(vm.next_id(), Instruction{
qinsoon's avatar
qinsoon committed
400
401
402
403
404
405
406
407
        value: Some(vec![blk_0_x.clone_value()]),
        ops: RefCell::new(vec![blk_0_a.clone()]),
        v: Instruction_::Load{
            is_ptr: false,
            order: MemoryOrder::Relaxed,
            mem_loc: 0
        }
    });
qinsoon's avatar
qinsoon committed
408
    
409
    let blk_0_term = func_ver.new_inst(vm.next_id(), Instruction{
qinsoon's avatar
qinsoon committed
410
        value: None,
qinsoon's avatar
qinsoon committed
411
412
        ops: RefCell::new(vec![blk_0_x.clone()]),
        v: Instruction_::Return(vec![0])
qinsoon's avatar
qinsoon committed
413
414
415
416
417
418
419
420
421
422
    });
    
    let blk_0_content = BlockContent {
        args: vec![],
        body: vec![blk_0_inst0, blk_0_inst1, blk_0_term],
        keepalives: None
    };
    blk_0.content = Some(blk_0_content);
    
    func_ver.define(FunctionContent{
qinsoon's avatar
qinsoon committed
423
        entry: blk_0.id,
qinsoon's avatar
qinsoon committed
424
425
        blocks: {
            let mut ret = HashMap::new();
qinsoon's avatar
qinsoon committed
426
            ret.insert(blk_0.id, blk_0);
qinsoon's avatar
qinsoon committed
427
428
429
430
431
432
433
            ret
        }
    });
    
    vm.define_func_version(func_ver);
    
    vm
qinsoon's avatar
qinsoon committed
434
}