Hello, world! in MoarVM

I wrote "Hello, world!" program, because I'm newbie.

#include <stdio.h>
#include <assert.h>
#include "moarvm.h"

static void toplevel\_initial\_invoke(MVMThreadContext \*tc, void \*data) {
    /\* Dummy, 0-arg callsite. \*/
    static MVMCallsite no\_arg\_callsite;
    no\_arg\_callsite.arg\_flags = NULL;
    no\_arg\_callsite.arg\_count = 0;
    no\_arg\_callsite.num\_pos   = 0;

    /\* Create initial frame, which sets up all of the interpreter state also. \*/
    MVM\_frame\_invoke(tc, (MVMStaticFrame \*)data, &no\_arg\_callsite, NULL, NULL, NULL);
}

int main(int argc, char \*\*argv) { 
    MVMInstance \* vm = MVM\_vm\_create\_instance();

    // init compunit.
    MVMThreadContext \*tc = vm->main\_thread;
    MVMCompUnit      \*cu = malloc(sizeof(MVMCompUnit));
    memset(cu, 0, sizeof(MVMCompUnit));
    int          apr\_return\_status;
    apr\_pool\_t  \*pool        = NULL;
    /\* Ensure the file exists, and get its size. \*/
    if ((apr\_return\_status = apr\_pool\_create(&pool, NULL)) != APR\_SUCCESS) {
        MVM\_panic(MVM\_exitcode\_compunit, "Could not allocate APR memory pool: errorcode %d", apr\_return\_status);
    }
    cu->pool       = pool;
    cu->num\_frames  = 1;
    cu->main\_frame = malloc(sizeof(MVMStaticFrame));
    cu->frames = malloc(sizeof(MVMStaticFrame) \* 1);
    cu->frames\[0\] = cu->main\_frame;
    memset(cu->main\_frame, 0, sizeof(MVMStaticFrame));
    cu->main\_frame->bytecode = malloc(sizeof(MVMuint8)\*1000);
    memset(cu->main\_frame->bytecode, 0, sizeof(MVMuint8)\*1000);
    cu->main\_frame->cuuid = MVM\_string\_utf8\_decode(tc, tc->instance->VMString, "cuuid", strlen("cuuid"));
    cu->main\_frame->name = MVM\_string\_utf8\_decode(tc, tc->instance->VMString, "main frame", strlen("main frame"));
    assert(cu->main\_frame->cuuid);
    cu->main\_frame->cu = cu;
    int i=0;

    // const\_s 0, 0
    cu->main\_frame->bytecode\[i++\] = MVM\_OP\_BANK\_primitives; // bank\_num
    cu->main\_frame->bytecode\[i++\] = MVM\_OP\_const\_s;

    cu->main\_frame->bytecode\[i++\] = 0;
    cu->main\_frame->bytecode\[i++\] = 0;

    cu->main\_frame->bytecode\[i++\] = 0;
    cu->main\_frame->bytecode\[i++\] = 0;

    // say 0
    cu->main\_frame->bytecode\[i++\] = MVM\_OP\_BANK\_io; // bank num
    cu->main\_frame->bytecode\[i++\] = MVM\_OP\_say;
    cu->main\_frame->bytecode\[i++\] = 0;
    cu->main\_frame->bytecode\[i++\] = 0;

    // return
    cu->main\_frame->bytecode\[i++\] = MVM\_OP\_BANK\_primitives; // bank num
    cu->main\_frame->bytecode\[i++\] = MVM\_OP\_return;

    cu->main\_frame->bytecode\_size = i;
    cu->main\_frame->work\_size = 10; // register size?

    cu->main\_frame->num\_locals= 1; // register size?
    cu->main\_frame->local\_types = malloc(sizeof(MVMuint16)\*cu->main\_frame->num\_locals);
    cu->main\_frame->local\_types\[0\] = MVM\_reg\_str;

    cu->strings = malloc(sizeof(MVMString)\*1);
    cu->strings\[0\] = MVM\_string\_utf8\_decode(tc, tc->instance->VMString, "Hello, world!", strlen("Hello, world!"));
    cu->num\_strings = 1;

    // And fill bytecode.
    MVMStaticFrame \*start\_frame = cu->main\_frame ? cu->main\_frame : cu->frames\[0\];

    if (argc>1) {
        // dump it
        char \*dump = MVM\_bytecode\_dump(tc, cu);
        
        printf("%s", dump);
        free(dump);
    } else {
        // Or, run it.
        MVM\_interp\_run(tc, &toplevel\_initial\_invoke, start\_frame);
    }

    // cleanup
    MVM\_vm\_destroy\_instance(vm);
}

Published: 2013-06-13(Thu) 10:00