-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathc0vm_main.c
106 lines (91 loc) · 2.73 KB
/
c0vm_main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/**************************************************************************/
/* COPYRIGHT Carnegie Mellon University 2024 */
/* Do not post this file or any derivative on a public site or repository */
/**************************************************************************/
/* C0VM, main file
* 15-122, Fall 2010
* William Lovas, Tom Cortina, Frank Pfenning
*
* Performs some OS compatibility checks before
* running the VM.
*/
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <alloca.h>
#include "lib/c0vm.h"
/* for the args library */
int c0_argc;
char **c0_argv;
/* fail-fast file function wrappers */
FILE *xfopen(const char *filename, const char *mode, char *error) {
FILE *f = fopen(filename, mode);
if (f == NULL) {
perror(error);
exit(EXIT_FAILURE);
}
return f;
}
void xfwrite(const void *ptr, size_t size, size_t nitems, FILE *stream,
char *error) {
if (fwrite(ptr, size, nitems, stream) < nitems) {
perror(error);
exit(EXIT_FAILURE);
}
}
void xfclose(FILE *stream, char *error) {
if (fclose(stream) != 0) {
perror(error);
exit(EXIT_FAILURE);
}
}
int main(int argc, char **argv) {
if (argc < 2) {
fprintf(stderr, "usage: %s <bc0_file> [args...]\n", argv[0]);
exit(1);
}
/* test for two's complement */
if (~(-1) != 0) {
fprintf(stderr, "Error: not a two's complement machine\n");
exit(1);
}
/* test representation sizes */
if (sizeof(int) != 4) {
fprintf(stderr, "Error: sizeof(int) == %zd != 4\n", sizeof(int));
exit(1);
}
if (CHAR_BIT != 8) {
fprintf(stderr, "Error: CHAR_BITS == %d != 8\n", CHAR_BIT);
exit(1);
}
/* test of sign-extending shift */
if ((int)(-1) >> 31 != -1) {
fprintf(stderr, "Error: right shift does not sign-extend\n");
exit(1);
}
/* for the args library -- skip the binary name */
c0_argc = argc - 1;
c0_argv = argv + 1;
char *filename = getenv("C0_RESULT_FILE");
struct bc0_file *bc0 = read_program(argv[1]);
// Move string pool to stack
char *stack_allocate_string_pool = alloca(bc0->string_count);
for (size_t i = 0; i < bc0->string_count; i++) {
stack_allocate_string_pool[i] = bc0->string_pool[i];
}
free(bc0->string_pool);
bc0->string_pool = stack_allocate_string_pool;
if (filename == NULL) {
int result = execute(bc0);
printf("%d\n", result);
} else {
FILE *f = xfopen(filename, "w", "Couldn't open $C0_RESULT_FILE");
xfwrite("\0", 1, 1, f, "Couldn't write to $C0_RESULT_FILE");
int result = execute(bc0);
printf("Result = %d\n", result);
xfwrite(&result, sizeof(int), 1, f, "Couldn't write to $C0_RESULT_FILE");
xfclose(f, "Couldn't close $C0_RESULT_FILE");
}
free_program(bc0);
return 0;
}