Пример #1
0
int64_t buzzmsg_deserialize_u16(uint16_t* data,
                                buzzdarray_t buf,
                                uint32_t pos) {
   if(pos + sizeof(uint16_t) > buzzdarray_size(buf)) return -1;
   *data =
      buzzdarray_get(buf, pos,   uint8_t)       +
      (buzzdarray_get(buf, pos+1, uint8_t) << 8);
   *data = ntohs(*data);
   return pos + sizeof(uint16_t);
}
Пример #2
0
int64_t buzzmsg_deserialize_u32(uint32_t* data,
                                buzzdarray_t buf,
                                uint32_t pos) {
   if(pos + sizeof(uint32_t) > buzzdarray_size(buf)) return -1;
   *data =
      buzzdarray_get(buf, pos,   uint8_t)         +
      (buzzdarray_get(buf, pos+1, uint8_t) << 8)  +
      (buzzdarray_get(buf, pos+2, uint8_t) << 16) +
      (buzzdarray_get(buf, pos+3, uint8_t) << 24);
   *data = ntohl(*data);
   return pos + sizeof(uint32_t);
}
Пример #3
0
buzzvm_state buzzvm_call(buzzvm_t vm, int isswrm) {
   /* Get argument number and pop it */
   buzzvm_stack_assert(vm, 1);
   buzzvm_type_assert(vm, 1, BUZZTYPE_INT);
   int32_t argn = buzzvm_stack_at(vm, 1)->i.value;
   buzzvm_pop(vm);
   /* Make sure the stack has enough elements */
   buzzvm_stack_assert(vm, argn+1);
   /* Make sure the closure is where expected */
   buzzvm_type_assert(vm, argn+1, BUZZTYPE_CLOSURE);
   buzzobj_t c = buzzvm_stack_at(vm, argn+1);
   /* Make sure that that data about C closures is correct */
   if((!c->c.value.isnative) &&
      ((c->c.value.ref) >= buzzdarray_size(vm->flist))) {
      buzzvm_seterror(vm, BUZZVM_ERROR_FLIST, NULL);
      return vm->state;
   }
   /* Create a new local symbol list copying the parent's */
   vm->lsyms =
      buzzvm_lsyms_new(isswrm,
                       buzzdarray_clone(c->c.value.actrec));
   buzzdarray_push(vm->lsymts, &(vm->lsyms));
   /* Add function arguments to the local symbols */
   int32_t i;
   for(i = argn; i > 0; --i)
      buzzdarray_push(vm->lsyms->syms,
                      &buzzdarray_get(vm->stack,
                                      buzzdarray_size(vm->stack) - i,
                                      buzzobj_t));
   /* Get rid of the function arguments */
   for(i = argn+1; i > 0; --i)
      buzzdarray_pop(vm->stack);
   /* Pop unused self table */
   buzzdarray_pop(vm->stack);
   /* Push return address */
   buzzvm_pushi((vm), vm->pc);
   /* Make a new stack for the function */
   vm->stack = buzzdarray_new(1, sizeof(buzzobj_t), NULL);
   buzzdarray_push(vm->stacks, &(vm->stack));
   /* Jump to/execute the function */
   if(c->c.value.isnative) {
      vm->oldpc = vm->pc;
      vm->pc = c->c.value.ref;
   }
   else buzzdarray_get(vm->flist,
                       c->c.value.ref,
                       buzzvm_funp)(vm);
   return vm->state;
}
Пример #4
0
int buzzvm_swarm_id(struct buzzvm_s* vm) {
   /* Is the swarm stack empty? */
   if(buzzdarray_isempty(vm->swarmstack)) {
      /* Yes, no swarm to push, push nil instead */
      buzzvm_pushnil(vm);
   }
   else {
      /* Take the stack top by default */
      uint16_t stackpos = 1;
      /* Do we have an argument? */
      if(buzzvm_lnum(vm) > 1) {
         buzzvm_lload(vm, 1);
         buzzvm_type_assert(vm, 1, BUZZTYPE_INT);
         stackpos = buzzvm_stack_at(vm, 1)->i.value;
      }
      /* Limit stackpos value to avoid out-of-bounds operations */
      if(stackpos > buzzdarray_size(vm->swarmstack))
         stackpos = buzzdarray_size(vm->swarmstack);
      /* Push the swarm id located at stackpos */
      buzzvm_pushi(vm,
                   buzzdarray_get(
                      vm->swarmstack,
                      buzzdarray_size(vm->swarmstack) - stackpos,
                      uint16_t));
   }
   /* Return the value */
   return buzzvm_ret1(vm);
}
Пример #5
0
int64_t buzzmsg_deserialize_u8(uint8_t* data,
                               buzzdarray_t buf,
                               uint32_t pos) {
   if(pos + sizeof(uint8_t) > buzzdarray_size(buf)) return -1;
   *data = buzzdarray_get(buf, pos, uint8_t);
   return pos + sizeof(uint8_t);
}
Пример #6
0
int buzzneighbors_kin(buzzvm_t vm) {
   buzzvm_lnum_assert(vm, 0);
   /* Initialize the swarm id to 'unknown' */
   int32_t swarmid = -1;
   /* If the swarm stack is not empty, look for the swarm id */
   if(!buzzdarray_isempty(vm->swarmstack)) {
      /* Get position in swarm stack */
      uint16_t sstackpos = 1;
      if(buzzdarray_size(vm->lsyms->syms) > 1)
         sstackpos = buzzdarray_get(vm->lsyms->syms, 1, buzzobj_t)->i.value;
      /* Get swarm id */
      if(sstackpos <= buzzdarray_size(vm->swarmstack))
         swarmid = buzzdarray_get(vm->swarmstack,
                                  buzzdarray_size(vm->swarmstack) - sstackpos,
                                  uint16_t);
   }
   /* Get the self table */
   buzzvm_lload(vm, 0);
   buzzvm_type_assert(vm, 1, BUZZTYPE_TABLE);
   /* Get the data table */
   buzzvm_pushs(vm, buzzvm_string_register(vm, "data", 1));
   buzzvm_tget(vm);
   buzzobj_t data = buzzvm_stack_at(vm, 1);
   /* Create a new table as return value */
   buzzobj_t t;
   vm->state = make_table(vm, &t);
   if(vm->state != BUZZVM_STATE_READY) return vm->state;
   /* If data is available, filter it */
   if(data->o.type == BUZZTYPE_TABLE) {
      /* Create a new data table */
      buzzobj_t kindata = buzzheap_newobj(vm->heap, BUZZTYPE_TABLE);
      /* Filter the neighbors in data and add them to kindata */
      struct neighbor_filter_s fdata = { .vm = vm, .swarm_id = swarmid, .result = kindata->t.value };
      buzzdict_foreach(data->t.value, neighbor_filter_kin, &fdata);
      /* Add kindata as the "data" field in t */
      buzzvm_push(vm, t);
      buzzvm_pushs(vm, buzzvm_string_register(vm, "data", 1));
      buzzvm_push(vm, kindata);
      buzzvm_tput(vm);
   }
   /* Return the table */
   buzzvm_push(vm, t);
   return buzzvm_ret1(vm);
}
Пример #7
0
void buzzvm_dump(buzzvm_t vm) {
   int64_t i, j;
   fprintf(stderr, "============================================================\n");
   fprintf(stderr, "state: %d\terror: %d\n", vm->state, vm->error);
   fprintf(stderr, "code size: %u\tpc: %d\n", vm->bcode_size, vm->pc);
   fprintf(stderr, "stacks: %" PRId64 "\tcur elem: %" PRId64 " (size %" PRId64 ")\n", buzzdarray_size(vm->stacks), buzzvm_stack_top(vm), buzzvm_stack_top(vm));
   for(i = buzzdarray_size(vm->stacks)-1; i >= 0 ; --i) {
      fprintf(stderr, "===== stack: %" PRId64 " =====\n", i);
      for(j = buzzdarray_size(buzzdarray_get(vm->stacks, i, buzzdarray_t)) - 1; j >= 0; --j) {
         fprintf(stderr, "\t%" PRId64 "\t", j);
         buzzobj_t o = buzzdarray_get(buzzdarray_get(vm->stacks, i, buzzdarray_t), j, buzzobj_t);
         switch(o->o.type) {
            case BUZZTYPE_NIL:
               fprintf(stderr, "[nil]\n");
               break;
            case BUZZTYPE_INT:
               fprintf(stderr, "[int] %d\n", o->i.value);
               break;
            case BUZZTYPE_FLOAT:
               fprintf(stderr, "[float] %f\n", o->f.value);
               break;
            case BUZZTYPE_TABLE:
               fprintf(stderr, "[table] %d elements\n", buzzdict_size(o->t.value));
               break;
            case BUZZTYPE_CLOSURE:
               if(o->c.value.isnative) {
                  fprintf(stderr, "[n-closure] %d\n", o->c.value.ref);
               }
               else {
                  fprintf(stderr, "[c-closure] %d\n", o->c.value.ref);
               }
               break;
            case BUZZTYPE_STRING:
               fprintf(stderr, "[string] %d:'%s'\n", o->s.value.sid, o->s.value.str);
               break;
            default:
               fprintf(stderr, "[TODO] type = %d\n", o->o.type);
         }
      }
   }
   fprintf(stderr, "============================================================\n\n");
}
Пример #8
0
void print_swarm_elem(const void* key, void* data, void* params) {
   uint32_t i;
   buzzswarm_elem_t e = *(buzzswarm_elem_t*)data;
   fprintf(stdout, "ROBOT %u -> R%u:", *(uint16_t*)params, *(uint16_t*)key);
   for(i = 0; i < buzzdarray_size(e->swarms); ++i) {
      fprintf(stdout,
              " %u",
              buzzdarray_get(e->swarms, i, uint16_t));
   }
   fprintf(stdout, "\n");
}
Пример #9
0
int buzzswarm_members_isrobotin(buzzswarm_members_t m,
                                uint16_t robot,
                                uint16_t swarm) {
   /* Is an entry for the passed robot present?
    * If not, return false */
   buzzswarm_elem_t* e = buzzdict_get(m, &robot, buzzswarm_elem_t);
   if(!e) return 0;
   /* If we get here, an entry is present
    * Does it contain the passed swarm id? */
   uint32_t i;
   for(i = 0; i < buzzdarray_size((*e)->swarms); ++i) {
      if(buzzdarray_get((*e)->swarms, i, uint16_t) == swarm) return 1;
   }
   /* If we get here, it's because we couldn't find the id */
   return 0;
}
Пример #10
0
buzzvm_state buzzvm_pushl(buzzvm_t vm, int32_t addr) {
   buzzobj_t o = buzzheap_newobj(vm, BUZZTYPE_CLOSURE);
   o->c.value.isnative = 1;
   o->c.value.ref = addr;
   if(vm->lsyms) {
      int i;
      for(i = 0; i < buzzdarray_size(vm->lsyms->syms); ++i)
         buzzdarray_push(o->c.value.actrec,
                         &buzzdarray_get(vm->lsyms->syms,
                                         i, buzzobj_t));
   }
   else {
      buzzobj_t nil = buzzheap_newobj(vm, BUZZTYPE_NIL);
      buzzdarray_push(o->c.value.actrec,
                      &nil);
   }
   return buzzvm_push(vm, o);
}
Пример #11
0
void buzzswarm_members_leave(buzzswarm_members_t m,
                             uint16_t robot,
                             uint16_t swarm) {
   /* Is an entry for the passed robot present? */
   buzzswarm_elem_t* e = buzzdict_get(m, &robot, buzzswarm_elem_t);
   if(e) {
      /* Yes, update it */
      (*e)->age = 0;
      /* Search for the passed id */
      uint32_t i;
      for(i = 0; i < buzzdarray_size((*e)->swarms); ++i) {
         if(buzzdarray_get((*e)->swarms, i, uint16_t) == swarm) break;
      }
      /* If the element was found, remove it */
      if(i < buzzdarray_size((*e)->swarms))
         buzzdarray_remove((*e)->swarms, i);
      /* If no swarm id is known for this robot, remove the entry altogether */
      if(buzzdarray_isempty((*e)->swarms))
         buzzdict_remove(m, &robot);
   }
   /* Nothing to do if you get a 'leave' message for someone you don't know */
}
Пример #12
0
buzzvm_state buzzvm_tput(buzzvm_t vm) {
   buzzvm_stack_assert(vm, 3);
   buzzvm_type_assert(vm, 3, BUZZTYPE_TABLE);
   buzzobj_t v = buzzvm_stack_at(vm, 1);
   buzzobj_t k = buzzvm_stack_at(vm, 2);
   buzzobj_t t = buzzvm_stack_at(vm, 3);
   buzzvm_pop(vm);
   buzzvm_pop(vm);
   buzzvm_pop(vm);
   if(k->o.type != BUZZTYPE_INT &&
      k->o.type != BUZZTYPE_FLOAT &&
      k->o.type != BUZZTYPE_STRING) {
      buzzvm_seterror(vm, BUZZVM_ERROR_TYPE, "a %s value can't be used as table key", buzztype_desc[k->o.type]);
      return vm->state;
   }
   if(v->o.type == BUZZTYPE_NIL) {
      /* Nil, erase entry */
      buzzdict_remove(t->t.value, &k);
   }
   else if(v->o.type == BUZZTYPE_CLOSURE) {
      /* Method call */
      int i;
      buzzobj_t o = buzzheap_newobj(vm, BUZZTYPE_CLOSURE);
      o->c.value.isnative = v->c.value.isnative;
      o->c.value.ref = v->c.value.ref;
      buzzdarray_push(o->c.value.actrec, &t);
      for(i = 1; i < buzzdarray_size(v->c.value.actrec); ++i)
         buzzdarray_push(o->c.value.actrec,
                         &buzzdarray_get(v->c.value.actrec,
                                         i, buzzobj_t));
      buzzdict_set(t->t.value, &k, &o);
   }
   else {
      buzzdict_set(t->t.value, &k, &v);
   }
   return BUZZVM_STATE_READY;
}
Пример #13
0
void buzzswarm_members_join(buzzswarm_members_t m,
                            uint16_t robot,
                            uint16_t swarm) {
   /* Is an entry for the passed robot already present? */
   buzzswarm_elem_t* e = buzzdict_get(m, &robot, buzzswarm_elem_t);
   if(e) {
      /* Yes, update it */
      (*e)->age = 0;
      /* Search for the passed id; if found, nothing to do */
      uint32_t i;
      for(i = 0; i < buzzdarray_size((*e)->swarms); ++i) {
         if(buzzdarray_get((*e)->swarms, i, uint16_t) == swarm) return;
      }
      /* If we get here, it's because we got new information - add it */
      buzzdarray_push((*e)->swarms, &swarm);
   }
   else {
      /* No, create it */
      buzzswarm_elem_t ne = buzzswarm_elem_new();
      buzzdarray_push(ne->swarms, &swarm);
      /* Add it to the structure */
      buzzdict_set(m, &robot, &ne);
   }
}