ms_VM *ms_VMNew(void) { ms_VM *vm = malloc(sizeof(ms_VM)); if (!vm) { return NULL; } vm->fstack = dsarray_new_cap(VM_FRAME_STACK_LIMIT, NULL, (dsarray_free_fn)VMFrameDestroy); if (!vm->fstack) { free(vm); return NULL; } vm->env = dsdict_new((dsdict_hash_fn)dsbuf_hash, (dsdict_compare_fn)dsbuf_compare, (dsdict_free_fn)dsbuf_destroy, NULL); if (!vm->env) { dsarray_destroy(vm->fstack); free(vm); return NULL; } if (!VMGeneratePrototypes(vm)) { dsarray_destroy(vm->fstack); dsdict_destroy(vm->env); free(vm); return NULL; } vm->err = NULL; return vm; }
static void scmd_padd(const dstring* cmd, int argc, dstring** argv) { ClientPeer* peers; unsigned int peer_id, i; if (argc != 2) { fprintf(stderr, "[%s]\n", cmd->data); fprintf(stderr, "Invalid server command: PADD with %i arguments.\n", argc-1); return; } peer_id = decode_peer_id(argv[1]); if (client.peers_size == 0) { client.peers_size = peer_id + 1; client.peers = (ClientPeer*)malloc(sizeof(ClientPeer) * client.peers_size); for(i = 0; i < client.peers_size; i++) { client.peers[i].connected = 0; client.peers[i].data = NULL; client.peers[i].id = i; client.peers[i].peer = NULL; } } else if (client.peers_size <= peer_id) { /* enlarge peer vector */ peers = (ClientPeer*)malloc(sizeof(ClientPeer) * (peer_id + 1)); for (i = 0; i < client.peers_size; i++) { peers[i] = client.peers[i]; } for(i = client.peers_size; i < (peer_id + 1); i++) { peers[i].connected = 0; peers[i].data = NULL; peers[i].id = i; peers[i].peer = NULL; } free(client.peers); client.peers = peers; client.peers_size = peer_id + 1; } client.peers[peer_id].connected = 1; client.peers[peer_id].data = dsdict_new(); if (peer_id == client.my_id) { client.peers[peer_id].peer = NULL; } else { client.peers[peer_id].peer = svc_peer_join(); } fprintf(stdout, "%s\n", cmd->data); }
static ms_VMBlock *VMBlockNew(void) { ms_VMBlock *blk = malloc(sizeof(ms_VMBlock)); if (!blk) { return NULL; } blk->env = dsdict_new((dsdict_hash_fn)dsbuf_hash, (dsdict_compare_fn)dsbuf_compare, NULL, /* keys are stored in ms_VMByteCode structure and are freed by a separate function */ NULL); // TODO: this should have a free function that decrements the (future) reference counter if (!blk->env) { free(blk); return NULL; } return blk; }
int main(int argc, char* argv[]) { dstring* input; int input_done; int code; ENetEvent event; if (argc > 1) { fprintf(stderr, "svcc doesn't accept any command line arguments, use stdin instead.\n"); return 1; } /* initialize enet */ if (enet_initialize()) { fprintf(stderr, "Failed to initialize ENet\n"); return 1; } /* initialize client state */ init_client_state(); /* init SVC */ svc_init(send_callback); /* main loop */ input = dnew(); client.main_done = 0; signal(SIGINT, sigint); while(!client.main_done) { /* enet event handler */ if (client.state == SVCECLIENT_STATE_CONNECTED) { /* handle connection state */ while (1) { mutex_lock(&client.network_lock); code = enet_host_service(client.host, &event, 0); mutex_unlock(&client.network_lock); if (code <= 0) break; /* handle event */ switch(event.type) { case ENET_EVENT_TYPE_DISCONNECT: /* we got disconnected */ mutex_lock(&client.network_lock); client.state = SVCECLIENT_STATE_DISCONNECTED; free_server_info(); mutex_unlock(&client.network_lock); msg_state(); break; case ENET_EVENT_TYPE_RECEIVE: /* some data just arrived */ if (event.channelID == 0) { handle_server_msg(event.packet); } else if (event.channelID == 1) { handle_server_audio(event.packet); } else { fprintf(stderr, "Received message from server on invalid channel %i.\n", event.channelID); } mutex_lock(&client.network_lock); enet_packet_destroy(event.packet); mutex_unlock(&client.network_lock); break; case ENET_EVENT_TYPE_CONNECT: /* no one will connect, ignore the bastard */ default: break; } } } else if (client.state == SVCECLIENT_STATE_CONNECTING) { /* handle connecting state */ mutex_lock(&client.network_lock); code = enet_host_service(client.host, &event, 0); mutex_unlock(&client.network_lock); if (code > 0) { if (event.type == ENET_EVENT_TYPE_CONNECT) { client.state = SVCECLIENT_STATE_CONNECTED; client.server_info = dsdict_new(); msg_state(); } else { mutex_lock(&client.network_lock); client.state = SVCECLIENT_STATE_DISCONNECTED; enet_peer_disconnect(client.client, 0); client.client = NULL; enet_host_destroy(client.host); client.host = NULL; msg_state(); mutex_unlock(&client.network_lock); } } } else { /* sleep for 8ms */ usleep(8000); } /* play with the input queue */ if (!client.main_done) { input_done = 0; while (!input_done) { /* get next input command */ mutex_lock(&client.input_lock); if (client.input_queue->size) { dcpy(input, client.input_queue->front->string); dlist_erase(client.input_queue, client.input_queue->front); } else { input_done = 1; } mutex_unlock(&client.input_lock); /* quit input loop if queue is empty */ if (input_done) { break; } /* handle commands */ input_done = client.main_done = handle_input_command(input); } } /* check if input died for some reasons */ mutex_lock(&client.input_lock); if (client.input_error) { /* if so, leave main loop */ client.main_done = 1; } mutex_unlock(&client.input_lock); fflush(stdout); fflush(stderr); /* sleep for 8ms */ usleep(8000); } fprintf(stdout, ":STATE exiting\n"); dfree(input); svc_close(); quit_client_state(); enet_deinitialize(); return 0; }
// Generate prototypes for the base/primitive objects objects static bool VMGeneratePrototypes(ms_VM *vm) { assert(vm); vm->float_ = NULL; vm->int_ = NULL; vm->str = NULL; vm->bool_ = NULL; vm->null = NULL; vm->float_ = dsdict_new((dsdict_hash_fn)hash_fnv1, (dsdict_compare_fn)strcmp, NULL, NULL); vm->int_ = dsdict_new((dsdict_hash_fn)hash_fnv1, (dsdict_compare_fn)strcmp, NULL, NULL); vm->str = dsdict_new((dsdict_hash_fn)hash_fnv1, (dsdict_compare_fn)strcmp, NULL, NULL); vm->bool_ = dsdict_new((dsdict_hash_fn)hash_fnv1, (dsdict_compare_fn)strcmp, NULL, NULL); vm->null = dsdict_new((dsdict_hash_fn)hash_fnv1, (dsdict_compare_fn)strcmp, NULL, NULL); if ((!vm->float_) || (!vm->int_) || (!vm->str) || (!vm->bool_) || (!vm->null)) { dsdict_destroy(vm->float_); dsdict_destroy(vm->int_); dsdict_destroy(vm->str); dsdict_destroy(vm->bool_); dsdict_destroy(vm->null); return false; } const ms_FuncDef *f = &MS_FLOAT_PROTOTYPE[0]; while (f->name) { dsdict_put(vm->float_, (void *)f->name, (void *)f); f++; } const ms_FuncDef *i = &MS_INT_PROTOTYPE[0]; while (i->name) { dsdict_put(vm->int_, (void *)i->name, (void *)i); i++; } const ms_FuncDef *s = &MS_STR_PROTOTYPE[0]; while (s->name) { dsdict_put(vm->str, (void *)s->name, (void *)s); s++; } const ms_FuncDef *b = &MS_BOOL_PROTOTYPE[0]; while (b->name) { dsdict_put(vm->bool_, (void *)b->name, (void *)b); b++; } const ms_FuncDef *n = &MS_NULL_PROTOTYPE[0]; while (n->name) { dsdict_put(vm->null, (void *)n->name, (void *)n); n++; } return true; }