Skip to content

onconflict only works with lambdas #18

@xgroleau

Description

@xgroleau

onconflict resolution only seems to work with lambdas, when it's a named function and the conflict is called the vm gets a BBZVM_ERROR_RET error.

Here is the code to tests

#define FILE_TEST6 "resources/6_Onconflict_namedFunction.bbo"
TEST(vm_onconflict_named_function) {
    // Init VM
    vm = &vmObj;

    uint16_t robot = 0;
    bbzvm_construct(robot);
    bbzvm_set_error_receiver(&set_last_error);
    fbcode = fopen(FILE_TEST6, "rb");
    REQUIRE(fbcode != NULL);
    REQUIRE(fseek(fbcode, 0, SEEK_END) == 0);
    fsize = ftell(fbcode);
    REQUIRE(fsize > 0);
    REQUIRE(fseek(fbcode, 0, SEEK_SET) >= 0);

    bbzvm_set_bcode(&testBcode, fsize);

    REQUIRE(vm->state == BBZVM_STATE_READY);
    REQUIRE(bbzvm_register_functions() >= 0); // If this fails, it means that the heap doesn't have enough memory allocated to execute this test.

    // Stepping through script
    while (vm->state == BBZVM_STATE_READY) {
#ifdef DEBUG
        uint8_t instr = *vm->bcode_fetch_fun(vm->pc,1);
        if (instr > BBZVM_INSTR_CALLS) {
            printf("[%d: %s %d]\n", vm->pc, instr_desc[instr], *(int16_t*)vm->bcode_fetch_fun(vm->pc+1,2));
        }
        else {
            printf("[%d: %s]\n", vm->pc, instr_desc[instr]);
        }
#endif
        bbzvm_step();
        ASSERT(vm->state != BBZVM_STATE_ERROR);
    }
    ASSERT_EQUAL(vm->state, BBZVM_STATE_DONE);
    ASSERT_EQUAL(vm->error, BBZVM_ERROR_NONE);

    vm->state = BBZVM_STATE_READY;

    // Sending stigmergy message, loop twice, once for inserting in stig, other for conflict to be called
    for(uint8_t i=0; i<2; i++) {
        bbzmsg_payload_t payload;
        uint8_t buff[] = {1, i, 0, __BBZSTRID_data, 0, 57, 2, 0, 1};
        bbzringbuf_construct(&payload, buff, 1, 16);
        payload.elsize = 1;
        payload.capacity = 10;
        payload.datastart = 0;
        payload.dataend = 9;

        bbzinmsg_queue_append(&payload);
        bbzvm_process_inmsgs();
        if(vm->error == BBZVM_ERROR_MEM){
            break;
        }

        bbzvm_gc();
    }

    // In actually error state BBZVM_ERROR_RET 
    ASSERT_EQUAL(vm->state, BBZVM_STATE_READY);
    ASSERT_EQUAL(vm->error, BBZVM_ERROR_NONE);

    bbzvm_destruct();
    fclose(fbcode);
}

When it uses a lambda, the tests passes (though it leaks memory as stated here)

conflict_resolver = function(key, ld, rd) {
        return ld
}

stig = stigmergy.create(0);
stig.onconflict(conflict_resolver)

But when it uses a function name, the test fails:

function conflict_resolver(key, ld, rd) {
        return ld
}

stig = stigmergy.create(0);
stig.onconflict(conflict_resolver)

The closure is registered properly with bbzvstig_onconflict, but when the closure is called, the blockptr doesn't seem to change. It call as a c function instead of changing the pc and execute buzz code since it's not a native closure which would explain the blockptr not increasing. In my case it calls bbzvm_dummy c function instead of conflict_resolver, though that may be undefined behavior.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions