Exemple #1
0
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;
}
Exemple #2
0
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);
}
Exemple #3
0
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;
}
Exemple #4
0
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;
}
Exemple #5
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;
}