1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
use wasm_gen;
use wasm_gen::FuncCode;
use wasm_runtime::heap;

/*
 * String layout
 *
 *      4 byte       1 byte*
 * |    length    | ... chars |
 */
pub fn generate_get_length() -> wasm_gen::Func {
    return wasm_gen::Func{
        sig: wasm_gen::FuncType{
            params: vec![
                wasm_gen::I32 // base ptr
            ],
            results: vec![
                wasm_gen::I32 // length
            ],
        },
        locals: vec![],
        code: vec![
            FuncCode::new1(wasm_gen::LOCAL_GET, 0x0), // load base ptr

            // skip header
            FuncCode::new1(wasm_gen::I32_CONST, heap::HEADER_SIZE as u64),
            FuncCode::new0(wasm_gen::I32_ADD),

            FuncCode::new2(wasm_gen::I32_LOAD, 0x2, 0x0),
        ]
    }
}

pub fn generate_char_code_at() -> wasm_gen::Func {
    return wasm_gen::Func{
        sig: wasm_gen::FuncType{
            params: vec![
                wasm_gen::I32, // base ptr
                wasm_gen::I32, // at
            ],
            results: vec![
                wasm_gen::I32 // char code
            ],
        },
        locals: vec![],
        code: vec![
            // load base ptr
            FuncCode::new1(wasm_gen::LOCAL_GET, 0x0),

            // skip length and header
            FuncCode::new1(wasm_gen::I32_CONST, 0x4 + heap::HEADER_SIZE as u64),
            FuncCode::new0(wasm_gen::I32_ADD),

            // at calculation
            FuncCode::new1(wasm_gen::LOCAL_GET, 0x1),
            FuncCode::new0(wasm_gen::I32_ADD),

            // load and return
            FuncCode::new2(wasm_gen::I32_LOAD8_U, 0x0, 0x0),
        ]
    }
}

pub fn generate_put_char_code_at() -> wasm_gen::Func {
    let at = 1;
    let c = 2;

    return wasm_gen::Func{
        sig: wasm_gen::FuncType{
            params: vec![
                wasm_gen::I32, // base ptr
                wasm_gen::I32, // at
                wasm_gen::I32, // char
            ],
            results: vec![],
        },
        locals: vec![],
        code: vec![
            // load base ptr
            FuncCode::new1(wasm_gen::LOCAL_GET, 0x0),

            // skip length and header
            FuncCode::new1(wasm_gen::I32_CONST, 0x4 + heap::HEADER_SIZE as u64),
            FuncCode::new0(wasm_gen::I32_ADD),

            // at calculation
            FuncCode::new1(wasm_gen::LOCAL_GET, at),
            FuncCode::new0(wasm_gen::I32_ADD),

            // put char code
            FuncCode::new1(wasm_gen::LOCAL_GET, c),
            FuncCode::new2(wasm_gen::I32_STORE8, 0x0, 0x0),
        ]
    }
}