synthemesc-codex 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,8 @@
1
+ codex
2
+ .DS_Store
3
+ *.map
4
+ build/*
5
+ *.o
6
+ *.bundle
7
+ *.log
8
+ Makefile
@@ -0,0 +1,47 @@
1
+ # -*- Mode: Makefile; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2
+ #
3
+ # Makefile for 'codex'.
4
+ #
5
+ # Type 'make' or 'make codex' to create the binary.
6
+ # Type 'make clean' to delete all temporaries.
7
+ # Type 'make run' to execute the binary.
8
+ # Type 'make debug' to debug the binary using gdb(1).
9
+ #
10
+
11
+ # build target specs
12
+ CC = cc
13
+ CFLAGS = -O3 -pipe -fPIC -fomit-frame-pointer -fno-common \
14
+ -Wall -Wshadow -Wpointer-arith \
15
+ # -march=native -mcpu=native -mtune=native
16
+
17
+ LIBS = -levent
18
+
19
+ # first target entry is the target invoked when typing 'make'
20
+ default: codex.c.o vm.c.o tpl.c.o
21
+ @echo -n 'Increasing build number in build.h... '
22
+ @awk '!/define CODEX_BUILD/ {print} /define CODEX_BUILD/ {print "#define CODEX_BUILD\t"$$3+1}' build.h > build.h~
23
+ @mv build.h~ build.h
24
+ @echo Done.
25
+ @echo -n 'Linking codex... '
26
+ @$(CC) $(CFLAGS) -o codex codex.c.o vm.c.o tpl.c.o $(LIBS)
27
+ @echo Done.
28
+
29
+ codex.c.o: codex.c
30
+ @echo -n 'Compiling codex.c... '
31
+ @$(CC) $(CFLAGS) -o codex.c.o -c codex.c
32
+ @echo Done.
33
+
34
+ vm.c.o: vm.c
35
+ @echo -n 'Compiling vm.c... '
36
+ @$(CC) $(CFLAGS) -o vm.c.o -c vm.c
37
+ @echo Done.
38
+
39
+ tpl.c.o: tpl.c
40
+ @echo -n 'Compiling tpl.c... '
41
+ @$(CC) $(CFLAGS) -o tpl.c.o -c tpl.c
42
+ @echo Done.
43
+
44
+ clean:
45
+ @echo -n 'Removing all temporary binaries... '
46
+ @rm -f codex *.o *.core *.map *.bundle
47
+ @echo Done.
@@ -0,0 +1,3 @@
1
+ Codex
2
+ =====
3
+ Codex is a network virtual machine. You can use it at [cloudburst.net](http://www.cloudburst.net).
@@ -0,0 +1,71 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "codex"
8
+ gem.summary = %Q{Codex network machine}
9
+ gem.email = "josh@eksdyne.com"
10
+ gem.homepage = "http://github.com/synthemesc/codex"
11
+ gem.authors = ["Joshua Eckstein"]
12
+ # gem.rubyforge_project = "codex"
13
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
14
+ end
15
+
16
+ Jeweler::RubyforgeTasks.new
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
19
+ end
20
+
21
+ require 'rake/testtask'
22
+ Rake::TestTask.new(:test) do |test|
23
+ test.libs << 'lib' << 'test'
24
+ test.pattern = 'test/**/*_test.rb'
25
+ test.verbose = true
26
+ end
27
+
28
+ begin
29
+ require 'rcov/rcovtask'
30
+ Rcov::RcovTask.new do |test|
31
+ test.libs << 'test'
32
+ test.pattern = 'test/**/*_test.rb'
33
+ test.verbose = true
34
+ end
35
+ rescue LoadError
36
+ task :rcov do
37
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
38
+ end
39
+ end
40
+
41
+
42
+ task :default => :extconf
43
+
44
+ task :extconf do
45
+ ruby(File.join(File.dirname(__FILE__), 'extconf.rb'))
46
+ sh((PLATFORM =~ /win32/ ? 'nmake' : 'make') + ' -f Makefile.server')
47
+ sh(PLATFORM =~ /win32/ ? 'nmake' : 'make')
48
+
49
+ begin
50
+ require 'lib/codex'
51
+ File.new('VERSION', 'wb') << Codex::VERSION + "\n"
52
+ rescue LoadError
53
+ end
54
+ end
55
+
56
+ require 'rake/rdoctask'
57
+ Rake::RDocTask.new do |rdoc|
58
+ if File.exist?('VERSION.yml')
59
+ config = YAML.load(File.read('VERSION.yml'))
60
+ version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
61
+ else
62
+ version = ""
63
+ end
64
+
65
+ rdoc.rdoc_dir = 'rdoc'
66
+ rdoc.title = "codex #{version}"
67
+ rdoc.rdoc_files.include('README*')
68
+ rdoc.rdoc_files.include('lib/**/*.rb')
69
+ rdoc.options << '--accessor' << 'attr_xml=RW'
70
+ end
71
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.0
data/build.h ADDED
@@ -0,0 +1,11 @@
1
+ /* Version and build number header for codex VM. */
2
+
3
+ #ifndef _BUILD_H
4
+ #define _BUILD_H
5
+
6
+ #define VERSION_MAJOR 0
7
+ #define VERSION_MINOR 0
8
+ #define VERSION_PATCH 0
9
+ #define CODEX_BUILD 535
10
+
11
+ #endif
data/codex.c ADDED
@@ -0,0 +1,470 @@
1
+ /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
+
3
+ #include <sys/mman.h>
4
+ #include <sys/socket.h>
5
+ #include <sys/stat.h>
6
+ #include <sys/types.h>
7
+
8
+ #include <arpa/inet.h>
9
+ #include <assert.h>
10
+ #include <event.h>
11
+ #include <fcntl.h>
12
+ #include <inttypes.h>
13
+ #include <signal.h>
14
+ #include <stdint.h>
15
+ #include <stdio.h>
16
+ #include <stdlib.h>
17
+ #include <string.h>
18
+ #include <unistd.h>
19
+ #include <getopt.h>
20
+
21
+ #include "tpl.h"
22
+ #include "codex.h"
23
+ #include "format.h"
24
+ #include "vm.h"
25
+
26
+ static int verbose = VERBOSITY;
27
+ static int daemonize = FOREGROUND;
28
+
29
+ #if 0
30
+ static uint64_t CONSTANTS[] = { 0, 1 };
31
+ #endif
32
+
33
+ static struct codex sys;
34
+ static struct event event_handle;
35
+ static tpl_node *tpl_instructions = NULL;
36
+ static tpl_node *tpl_registers = NULL;
37
+ static struct sockaddr_in addr;
38
+ static socklen_t addr_size = sizeof(addr);
39
+ static struct instruction_word current;
40
+
41
+ static void codex_message(int socket_descriptor, short event, void* args)
42
+ {
43
+ static char buffer[PIPELINE_SIZE+1];
44
+ static int recv_length;
45
+
46
+ static uint64_t src;
47
+ static uint64_t arg;
48
+ static uint64_t result;
49
+
50
+ static uint64_t fetch_src;
51
+ static uint64_t fetch_arg;
52
+
53
+ #define NO_FLAGS 0
54
+ recv_length = recvfrom(socket_descriptor, buffer, PIPELINE_SIZE,
55
+ NO_FLAGS, (struct sockaddr*) &addr, (socklen_t*) &addr_size);
56
+
57
+ if (UNLIKELY(recv_length < 1))
58
+ {
59
+ if (UNLIKELY(verbose)) fprintf(stderr, "Got < 1 bytes: socket error or useless.\n");
60
+ return;
61
+ }
62
+
63
+ if (UNLIKELY(tpl_load(tpl_instructions, TPL_MEM | TPL_EXCESS_OK, buffer, recv_length) == -1))
64
+ {
65
+ if (UNLIKELY(verbose)) fprintf(stderr, "Got %d bytes, but they were invalid.\n", recv_length);
66
+ return;
67
+ }
68
+
69
+ while(tpl_unpack(tpl_instructions, 1) > 0)
70
+ {
71
+ current.opcode &= VALID_INSTRUCTION;
72
+
73
+ #define VALID_OFFSET(sys,off) (off>=sys.offset&&off<(sys.offset+sys.size))
74
+
75
+ /* Source decode */
76
+ switch(current.opcode & SRC_TYPE)
77
+ {
78
+ case SRC_TYPE_VAL:
79
+ fetch_src = current.src;
80
+ break;
81
+
82
+ case SRC_TYPE_REF:
83
+ if (VALID_OFFSET(sys, current.src))
84
+ fetch_src = sys.memory[current.src];
85
+ else
86
+ continue;
87
+ break;
88
+
89
+ default:
90
+ continue;
91
+ }
92
+
93
+ /* Argument decode */
94
+ switch(current.opcode & ARG_TYPE)
95
+ {
96
+ case ARG_TYPE_VAL:
97
+ fetch_arg = current.arg;
98
+ break;
99
+
100
+ case ARG_TYPE_REF:
101
+ if (VALID_OFFSET(sys, current.arg))
102
+ fetch_arg = sys.memory[current.arg];
103
+ else
104
+ continue;
105
+ break;
106
+
107
+ default:
108
+ continue;
109
+ }
110
+
111
+ /* Fetch src */
112
+ switch(current.opcode & SRC_MODE)
113
+ {
114
+ /* Source operand contains a hardcoded value. */
115
+ case SRC_MODE_IMM: src = fetch_src; break;
116
+ /* Source operand contains an address. */
117
+ case SRC_MODE_ADDR: src = sys.memory[fetch_src]; break;
118
+ /* Source operand contains a reference to a register. */
119
+ case SRC_MODE_REG: src = sys.registers[fetch_src & VALID_REGISTER]; break;
120
+ #if 0
121
+ /* Source operand contains a hardcoded constant. */
122
+ case SRC_MODE_CONST: src = CONSTANTS[fetch_src & CONSTANT_COUNT]; break;
123
+ #endif
124
+
125
+ default:
126
+ continue;
127
+ }
128
+
129
+ /* Fetch argument */
130
+ switch(current.opcode & ARG_MODE)
131
+ {
132
+ /* Source operand contains a hardcoded value. */
133
+ case ARG_MODE_IMM: arg = fetch_arg; break;
134
+ /* Source operand contains an address. */
135
+ case ARG_MODE_ADDR: arg = sys.memory[fetch_arg]; break;
136
+ /* Source operand contains a reference to a register. */
137
+ case ARG_MODE_REG: arg = sys.registers[fetch_arg & VALID_REGISTER]; break;
138
+ #if 0
139
+ /* Source operand contains a hardcoded constant. */
140
+ case ARG_MODE_CONST: arg = CONSTANTS[fetch_arg & CONSTANT_COUNT]; break;
141
+ #endif
142
+
143
+ default:
144
+ continue;
145
+ }
146
+
147
+ switch(current.opcode & OP_FULL)
148
+ {
149
+ /* clr %ax */
150
+ case OP_CLR:
151
+ result = 0;
152
+ break;
153
+
154
+ /* mov %ax, %bx */
155
+ case OP_MOV:
156
+ result = src;
157
+ break;
158
+
159
+ case OP_SORT:
160
+ if (src < arg)
161
+ result = -1;
162
+ else if (src > arg)
163
+ result = +1;
164
+ else
165
+ result = 0;
166
+
167
+ case OP_AVG:
168
+ result = (src + arg) / 2;
169
+
170
+ /*case OP_BE:*/
171
+ /*case OP_BNE:*/
172
+ /*case OP_BEZ:*/
173
+ /*case OP_BNEZ:*/
174
+ /*case OP_BLTEZ:*/
175
+ /*case OP_BGTEZ:*/
176
+ /*case OP_JMP:*/
177
+ /*case OP_SKP:*/
178
+
179
+ case OP_MIN:
180
+ if (src < arg)
181
+ result = src;
182
+ else
183
+ result = arg;
184
+ break;
185
+
186
+ case OP_MAX:
187
+ if (src > arg)
188
+ result = src;
189
+ else
190
+ result = arg;
191
+ break;
192
+
193
+ /*case OP_BLT:*/
194
+ /*case OP_BGT:*/
195
+ /*case OP_BLTZ:*/
196
+ /*case OP_BGTZ:*/
197
+ /*case OP_BLTE:*/
198
+ /*case OP_BGTE:*/
199
+ /*case OP_PUSH:*/
200
+ /*case OP_POP:*/
201
+
202
+ case OP_OR:
203
+ result = src | arg;
204
+ break;
205
+
206
+ case OP_NOR:
207
+ result = ~(src | arg);
208
+ break;
209
+
210
+ case OP_ADD:
211
+ result = src + arg;
212
+ break;
213
+
214
+ case OP_SUB:
215
+ result = src - arg;
216
+ break;
217
+
218
+ case OP_INC:
219
+ result = src + 1;
220
+ break;
221
+
222
+ case OP_DEC:
223
+ result = src - 1;
224
+ break;
225
+
226
+ case OP_GRY:
227
+ result = src ^ (src >> 1);
228
+ break;
229
+
230
+ /*case OP_HUE:*/
231
+ /*case OP_CALL:*/
232
+ /*case OP_RET:*/
233
+
234
+ case OP_AND:
235
+ result = src & arg;
236
+ break;
237
+
238
+ case OP_NAND:
239
+ result = ~(src & arg);
240
+ break;
241
+
242
+ case OP_MUL:
243
+ result = src * arg;
244
+ break;
245
+
246
+ case OP_DIV:
247
+ result = src / arg;
248
+ break;
249
+
250
+ case OP_SHL:
251
+ result = src << arg;
252
+ break;
253
+
254
+ case OP_SHR:
255
+ result = src >> arg;
256
+ break;
257
+
258
+ /*case OP_ROTL:*/
259
+ /*case OP_ROTR:*/
260
+
261
+ case OP_XOR:
262
+ result = src ^ arg;
263
+ break;
264
+
265
+ case OP_NOT:
266
+ result = ~src;
267
+ break;
268
+
269
+ case OP_SQR:
270
+ result = src * src;
271
+ break;
272
+
273
+ default:
274
+ continue;
275
+ }
276
+
277
+ if (UNLIKELY(verbose))
278
+ fprintf(stderr, "%llu <%x> %llu => %llu\n",
279
+ LLU current.src, current.opcode, LLU current.arg, LLU result);
280
+
281
+ switch(current.opcode & DST_TYPE)
282
+ {
283
+ case DST_MODE_ADDR:
284
+ if (VALID_OFFSET(sys, current.dst))
285
+ sys.memory[current.dst] = result;
286
+ else
287
+ continue;
288
+ break;
289
+
290
+ case DST_MODE_REG:
291
+ sys.registers[current.dst & VALID_REGISTER] = result;
292
+ break;
293
+
294
+ default:
295
+ continue;
296
+ }
297
+ }
298
+
299
+ char *reply_buffer;
300
+ int reply_buffer_size;
301
+ #define NO_FLAGS 0
302
+ tpl_pack(tpl_registers, 0);
303
+ tpl_dump(tpl_registers, TPL_MEM, &reply_buffer, &reply_buffer_size);
304
+ sendto(socket_descriptor, reply_buffer, reply_buffer_size,
305
+ NO_FLAGS, (struct sockaddr*) &addr, addr_size);
306
+ free(reply_buffer);
307
+ }
308
+
309
+ static void codex_shutdown()
310
+ {
311
+ signal(SIGHUP, SIG_IGN);
312
+ signal(SIGINT, SIG_IGN);
313
+ signal(SIGQUIT, SIG_IGN);
314
+ signal(SIGABRT, SIG_IGN);
315
+
316
+ fprintf(stderr, "Got signal, cleaning up.. ");
317
+
318
+ if (event_initialized(&event_handle))
319
+ {
320
+ event_loopbreak();
321
+ fprintf(stderr, "event ");
322
+ }
323
+
324
+ if (sys.memory != NULL)
325
+ {
326
+ munmap(sys.memory, sys.size);
327
+ fprintf(stderr, "map ");
328
+ }
329
+
330
+ if (sys.descriptor > 0)
331
+ {
332
+ fsync(sys.descriptor); fprintf(stderr, "sync ");
333
+ close(sys.descriptor); fprintf(stderr, "close ");
334
+ fsync(sys.descriptor); fprintf(stderr, "sync ");
335
+ }
336
+
337
+ if (tpl_instructions != NULL)
338
+ {
339
+ tpl_free(tpl_instructions);
340
+ fprintf(stderr, "tpl ");
341
+ }
342
+
343
+ fprintf(stderr, "done.\n");
344
+ exit(0);
345
+ }
346
+
347
+ static void usage()
348
+ {
349
+ fprintf(stderr, "codex [--daemonize] [--verbose | --silent] [--range <offset+length>] [--file <filename>] [--port <port>]\n");
350
+ fprintf(stderr, "codex [-d] [-v | -s] [-r <offset+length>] [-f <filename>] [-p <port>]\n");
351
+ exit(EXIT_FAILURE);
352
+ }
353
+
354
+ int main(int argc, char *argv[])
355
+ {
356
+ signal(SIGHUP, codex_shutdown);
357
+ signal(SIGINT, codex_shutdown);
358
+ signal(SIGQUIT, codex_shutdown);
359
+ signal(SIGABRT, codex_shutdown);
360
+
361
+ static struct option long_options[] =
362
+ {
363
+ { "verbose", no_argument, &verbose, VERBOSE },
364
+ { "silent", no_argument, &verbose, SILENT },
365
+ { "daemonize", no_argument, &daemonize, DAEMONIZE },
366
+ { "range", required_argument, NULL, 'r' },
367
+ { "file", required_argument, NULL, 'f' },
368
+ { "port", required_argument, NULL, 'p' },
369
+ { 0, 0, 0, 0 }
370
+ };
371
+
372
+ #define TO_STR(x) #x
373
+
374
+ char* range = TO_STR(DEFAULT_START+DEFAULT_SIZE);
375
+
376
+ int truth = 1;
377
+ uint16_t port = PORT;
378
+ sys.offset = DEFAULT_START;
379
+ sys.size = DEFAULT_SIZE;
380
+
381
+ if (argc < 2)
382
+ {
383
+ usage();
384
+ return(EXIT_FAILURE);
385
+ }
386
+
387
+ int c;
388
+ while ((c = getopt_long(argc, argv, "vsdr:f:p:", long_options, NULL)) != -1)
389
+ {
390
+ switch (c)
391
+ {
392
+ case 'r':
393
+ range = strdup(optarg);
394
+ /* Allocate a range string (0x0000+0xFFFF), copy safely */
395
+ sys.offset = strtoll(strsep(&range, "+"), (char **)NULL, 16);
396
+ sys.size = strtoll(range, (char **)NULL, 16);
397
+ break;
398
+
399
+ case 'f':
400
+ /* Allocate a filename, copy safely */
401
+ strncpy(sys.filename, optarg, sizeof(sys.filename)-1);
402
+ sys.filename[sizeof(sys.filename)-1] = '\0';
403
+ break;
404
+
405
+ case 'p':
406
+ port = atoi(optarg);
407
+ break;
408
+
409
+ default:
410
+ break;
411
+ }
412
+ }
413
+
414
+ if (daemonize == DAEMONIZE)
415
+ {
416
+ pid_t pid, sid;
417
+
418
+ fprintf(stderr, "Daemonizing.. ");
419
+ pid = fork();
420
+
421
+ if (pid < 0) exit(EXIT_FAILURE);
422
+ else if (pid > 0) exit(EXIT_SUCCESS);
423
+ umask(0);
424
+
425
+ sid = setsid();
426
+ if (sid < 0) exit(EXIT_FAILURE);
427
+ fprintf(stderr, "done.\n");
428
+ }
429
+
430
+ assert(port > 0);
431
+ assert(port < 65535);
432
+
433
+ codex_init(&sys);
434
+
435
+ #define NO_PROTOCOL 0
436
+ int socket_descriptor;
437
+ assert((socket_descriptor = socket(AF_INET, SOCK_DGRAM, NO_PROTOCOL)) > 0);
438
+
439
+ fprintf(stderr, "Setting socket options.. ");
440
+ assert(setsockopt(socket_descriptor, SOL_SOCKET, SO_REUSEADDR, &truth, sizeof(truth)) == 0);
441
+ assert(setsockopt(socket_descriptor, SOL_SOCKET, SO_REUSEPORT, &truth, sizeof(truth)) == 0);
442
+ fprintf(stderr, "done.\n");
443
+
444
+ addr.sin_family = AF_INET;
445
+ addr.sin_port = htons(port);
446
+ addr.sin_addr.s_addr = INADDR_ANY;
447
+
448
+ fprintf(stderr, "Binding to interface on port %d.. ", port);
449
+ assert(bind(socket_descriptor, (struct sockaddr*) &addr, addr_size) == 0);
450
+ fprintf(stderr, "done.\n");
451
+
452
+ fprintf(stderr, "Constructing serializer.. ");
453
+ tpl_instructions = tpl_map(TPL_INSTRUCTION_FORMAT, &current);
454
+ tpl_registers = tpl_map(TPL_REGISTER_FORMAT, sys.registers, REGISTER_COUNT);
455
+ assert(tpl_instructions != NULL);
456
+ assert(tpl_registers != NULL);
457
+ fprintf(stderr, "done.\n");
458
+
459
+ #define NO_CALLBACK_ARGS 0
460
+ #define NO_TIMEOUT NULL
461
+ #define NO_FLAGS 0
462
+ event_init();
463
+ event_set(&event_handle, socket_descriptor, EV_READ | EV_PERSIST, codex_message, NO_CALLBACK_ARGS);
464
+ event_add(&event_handle, NO_TIMEOUT);
465
+ event_loop(NO_FLAGS);
466
+
467
+ codex_shutdown();
468
+ return (EXIT_SUCCESS);
469
+ }
470
+