Пример #1
0
int buzzvm_set_bcode(buzzvm_t vm,
                     const uint8_t* bcode,
                     uint32_t bcode_size) {
   /* Fetch the string count */
   uint16_t count;
   memcpy(&count, bcode, sizeof(uint16_t));
   /* Go through the strings and store them */
   uint32_t i = sizeof(uint16_t);
   long int c = 0;
   for(; (c < count) && (i < bcode_size); ++c) {
      /* Store string */
      buzzvm_string_register(vm, (char*)(bcode + i), 1);
      /* Advance to first character of next string */
      while(*(bcode + i) != 0) ++i;
      ++i;
   }
   /* Initialize VM state */
   vm->state = BUZZVM_STATE_READY;
   vm->error = BUZZVM_ERROR_NONE;
   /* Initialize bytecode data */
   vm->bcode_size = bcode_size;
   vm->bcode = bcode;
   /* Set program counter */
   vm->pc = i;
   vm->oldpc = vm->pc;
   /*
    * Register function definitions
    * Stop when you find a 'nop'
    */
   while(vm->bcode[vm->pc] != BUZZVM_INSTR_NOP)
      if(buzzvm_step(vm) != BUZZVM_STATE_READY) return vm->state;
   buzzvm_step(vm);
   /* Initialize empty neighbors */
   buzzneighbors_reset(vm);
   /* Register robot id */
   buzzvm_pushs(vm, buzzvm_string_register(vm, "id", 1));
   buzzvm_pushi(vm, vm->robot);
   buzzvm_gstore(vm);
   /* Register basic functions */
   buzzobj_register(vm);
   /* Register stigmergy methods */
   buzzvstig_register(vm);
   /* Register swarm methods */
   buzzswarm_register(vm);
   /* Register math methods */
   buzzmath_register(vm);
   /* Register io methods */
   buzzio_register(vm);
   /* Register string methods */
   buzzstring_register(vm);
   /* All done */
   return BUZZVM_STATE_READY;
}
Пример #2
0
int main(int argc, char** argv) {
   /* Parse command line */
   if(argc != 2) {
      fprintf(stderr, "Usage:\n\t%s <file.bo>\n\n", argv[0]);
      return 0;
   }
   /* Open file */
   int fd = open(argv[1], O_RDONLY);
   if(fd < 0) perror(argv[1]);
   /* Read data */
   size_t bcode_size = lseek(fd, 0, SEEK_END);
   lseek(fd, 0, SEEK_SET);
   uint8_t* bcode_buf = (uint8_t*)malloc(bcode_size);
   ssize_t rd;
   size_t tot = 0;
   while(tot < bcode_size) {
      rd = read(fd, bcode_buf + tot, bcode_size - tot);
      if(rd < 0) perror(argv[1]);
      tot += rd;
   }
   close(fd);
   /* Create new VM */
   buzzvm_t vm = buzzvm_new(1);
   /* Set byte code */
   buzzvm_set_bcode(vm, bcode_buf, bcode_size);
   /* Register hook function */
   buzzvm_pushs(vm, buzzvm_string_register(vm, "hook"));
   buzzvm_pushcc(vm, buzzvm_function_register(vm, hook));
   buzzvm_gstore(vm);
   /* Run byte code and dump state */
   do dump(vm);
   while(buzzvm_step(vm) == BUZZVM_STATE_READY);
   if(vm->state == BUZZVM_STATE_DONE) {
      dump(vm);
      fprintf(stdout, "%s: execution terminated correctly\n\n",
              argv[1]);
   }
   else {
      fprintf(stderr, "%s: execution terminated abnormally: %s\n\n",
              argv[1],
              buzzvm_error_desc[vm->error]);
   }
   /* Destroy VM */
   free(bcode_buf);
   buzzvm_destroy(&vm);
   return 0;
}
Пример #3
0
buzzvm_state buzzvm_closure_call(buzzvm_t vm,
                                 uint32_t argc) {
   /* Insert the self table right before the closure */
   buzzdarray_insert(vm->stack,
                     buzzdarray_size(vm->stack) - argc - 1,
                     buzzheap_newobj(vm, BUZZTYPE_NIL));
   /* Push the argument count */
   buzzvm_pushi(vm, argc);
   /* Save the current stack depth */
   uint32_t stacks = buzzdarray_size(vm->stacks);
   /* Call the closure and keep stepping until
    * the stack count is back to the saved value */
   buzzvm_callc(vm);
   do if(buzzvm_step(vm) != BUZZVM_STATE_READY) return vm->state;
   while(stacks < buzzdarray_size(vm->stacks));
   return vm->state;
}
Пример #4
0
int buzzvm_swarm_exec(buzzvm_t vm) {
   buzzvm_lnum_assert(vm, 1);
   /* Get the id */
   buzzvm_lload(vm, 0);
   buzzvm_pushs(vm, buzzvm_string_register(vm, "id"));
   buzzvm_tget(vm);
   uint16_t id = buzzvm_stack_at(vm, 1)->i.value;
   /* Get the swarm entry */
   uint8_t* x = buzzdict_get(vm->swarms, &id, uint8_t);
   if(!x) {
      vm->state = BUZZVM_STATE_ERROR;
      vm->error = BUZZVM_ERROR_SWARM;
      return BUZZVM_STATE_ERROR;
   }
   /* Check whether the robot is in the swarm */
   if(*x) {
      /* Get the closure */
      buzzvm_lload(vm, 1);
      buzzvm_type_assert(vm, 1, BUZZTYPE_CLOSURE);
      buzzobj_t c = buzzvm_stack_at(vm, 1);
      /* Get rid of the current call structure */
      if(buzzvm_ret0(vm) != BUZZVM_STATE_READY) return vm->state;
      /* Save the current stack depth */
      uint32_t stacks = buzzdarray_size(vm->stacks);
      /* Push the current swarm in the stack */
      buzzdarray_push(vm->swarmstack, &id);
      /* Call the closure */
      buzzvm_push(vm, c);
      int32_t numargs = 0;
      buzzvm_pushi(vm, numargs);
      buzzvm_calls(vm);
      do if(buzzvm_step(vm) != BUZZVM_STATE_READY) return vm->state;
      while(stacks < buzzdarray_size(vm->stacks));
      return vm->state;
   }
   else {
      /* Get rid of the current call structure */
      return buzzvm_ret0(vm);
   }
}
Пример #5
0
int main(int argc, char** argv) {
   /* The bytecode filename */
   char* bcfname;
   /* The debugging information file name */
   char* dbgfname;
   /* Whether or not to show the assembly information */
   int trace = 0;
   /* Parse command line */
   if(argc < 3 || argc > 4) usage(argv[0], 0);
   if(argc == 3) {
      bcfname = argv[1];
      dbgfname = argv[2];
   }
   else {
      bcfname = argv[2];
      dbgfname = argv[3];
      if(strcmp(argv[1], "--trace") != 0) {
         fprintf(stderr, "error: %s: unrecognized option '%s'\n", argv[0], argv[1]);
         usage(argv[0], 1);
      }
      trace = 1;
   }
   /* Read bytecode and fill in data structure */
   FILE* fd = fopen(bcfname, "rb");
   if(!fd) perror(bcfname);
   fseek(fd, 0, SEEK_END);
   size_t bcode_size = ftell(fd);
   rewind(fd);
   uint8_t* bcode_buf = (uint8_t*)malloc(bcode_size);
   if(fread(bcode_buf, 1, bcode_size, fd) < bcode_size) {
      perror(bcfname);
   }
   fclose(fd);
   /* Read debug information */
   buzzdebug_t dbg_buf = buzzdebug_new();
   if(!buzzdebug_fromfile(dbg_buf, dbgfname)) {
      perror(dbgfname);
   }
   /* Create new VM */
   buzzvm_t vm = buzzvm_new(1);
   /* Set byte code */
   buzzvm_set_bcode(vm, bcode_buf, bcode_size);
   /* Register hook functions */
   buzzvm_pushs(vm, buzzvm_string_register(vm, "print", 1));
   buzzvm_pushcc(vm, buzzvm_function_register(vm, print));
   buzzvm_gstore(vm);
   /* Run byte code */
   do if(trace) buzzdebug_stack_dump(vm, 1, stdout);
   while(buzzvm_step(vm) == BUZZVM_STATE_READY);
   /* Done running, check final state */
   int retval;
   if(vm->state == BUZZVM_STATE_DONE) {
      /* Execution terminated without errors */
      if(trace) buzzdebug_stack_dump(vm, 1, stdout);
      fprintf(stdout, "%s: execution terminated correctly\n\n",
              bcfname);
      retval = 0;
   }
   else {
      /* Execution terminated with errors */
      if(trace) buzzdebug_stack_dump(vm, 1, stdout);
      buzzdebug_entry_t dbg = *buzzdebug_info_get_fromoffset(dbg_buf, &vm->pc);
      if(dbg != NULL) {
         fprintf(stderr, "%s: execution terminated abnormally at %s:%" PRIu64 ":%" PRIu64 " : %s\n\n",
                 bcfname,
                 dbg->fname,
                 dbg->line,
                 dbg->col,
                 vm->errormsg);
      }
      else {
         fprintf(stderr, "%s: execution terminated abnormally at bytecode offset %d: %s\n\n",
                 bcfname,
                 vm->pc,
                 vm->errormsg);
      }
      retval = 1;
   }
   /* Destroy VM */
   free(bcode_buf);
   buzzdebug_destroy(&dbg_buf);
   buzzvm_destroy(&vm);
   /* All done */
   return retval;
}
Пример #6
0
buzzvm_state buzzvm_execute_script(buzzvm_t vm) {
   while(buzzvm_step(vm) == BUZZVM_STATE_READY);
   return vm->state;
}