Make fixes, improvements, and chibicc python bindings

- python now mixes audio 10x faster
- python octal notation is restored
- chibicc now builds code 3x faster
- chibicc now has help documentation
- chibicc can now generate basic python bindings
- linenoise now supports some paredit-like features

See #141
This commit is contained in:
Justine Tunney 2021-10-08 08:11:51 -07:00
parent 28997f3acb
commit 7061c79c22
121 changed files with 5272 additions and 1928 deletions

View file

@ -1,5 +1,8 @@
#include "libc/calls/calls.h"
#include "libc/calls/struct/siginfo.h"
#include "libc/calls/ucontext.h"
#include "libc/runtime/gc.internal.h"
#include "libc/runtime/runtime.h"
#include "libc/x/x.h"
#include "third_party/chibicc/chibicc.h"
@ -36,6 +39,7 @@ bool opt_verbose;
static bool opt_A;
static bool opt_E;
static bool opt_J;
static bool opt_P;
static bool opt_M;
static bool opt_MD;
static bool opt_MMD;
@ -60,10 +64,13 @@ static StringArray std_include_paths;
char *base_file;
static char *output_file;
static StringArray input_paths;
static char **tmpfiles;
char **chibicc_tmpfiles;
static void usage(int status) {
fprintf(stderr, "chibicc [ -o <path> ] <file>\n");
char *p;
size_t n;
p = gc(xslurp("/zip/third_party/chibicc/help.txt", &n));
xwrite(1, p, n);
exit(status);
}
@ -94,6 +101,7 @@ static void add_default_include_paths(char *argv0) {
/* strarray_push(&include_paths, buf); */
// Add standard include paths.
/* strarray_push(&include_paths, "."); */
strarray_push(&include_paths, "/zip/.c");
// Keep a copy of the standard include paths for -MMD option.
for (int i = 0; i < include_paths.len; i++) {
strarray_push(&std_include_paths, include_paths.data[i]);
@ -157,6 +165,10 @@ static void PrintMemoryUsage(void) {
sizeof(Obj) * alloc_obj_count);
fprintf(stderr, "allocated %,ld types (%,ld bytes)\n", alloc_type_count,
sizeof(Type) * alloc_type_count);
fprintf(stderr, "chibicc hashmap hits %,ld\n", chibicc_hashmap_hits);
fprintf(stderr, "chibicc hashmap miss %,ld\n", chibicc_hashmap_miss);
fprintf(stderr, "as hashmap hits %,ld\n", as_hashmap_hits);
fprintf(stderr, "as hashmap miss %,ld\n", as_hashmap_miss);
}
static void strarray_push_comma(StringArray *a, char *s) {
@ -177,10 +189,10 @@ static void parse_args(int argc, char **argv) {
}
}
}
StringArray idirafter = {};
StringArray idirafter = {0};
for (int i = 1; i < argc; i++) {
if (!strcmp(argv[i], "-###")) {
opt_hash_hash_hash = true;
opt_verbose = opt_hash_hash_hash = true;
} else if (!strcmp(argv[i], "-cc1")) {
opt_cc1 = true;
} else if (!strcmp(argv[i], "--help")) {
@ -202,6 +214,8 @@ static void parse_args(int argc, char **argv) {
opt_common = false;
} else if (!strcmp(argv[i], "-fno-builtin")) {
opt_no_builtin = true;
} else if (!strcmp(argv[i], "-save-temps")) {
opt_save_temps = true;
} else if (!strcmp(argv[i], "-c")) {
opt_c = true;
} else if (!strcmp(argv[i], "-E")) {
@ -210,6 +224,8 @@ static void parse_args(int argc, char **argv) {
opt_J = true;
} else if (!strcmp(argv[i], "-A")) {
opt_A = true;
} else if (!strcmp(argv[i], "-P")) {
opt_P = true;
} else if (!strcmp(argv[i], "-I")) {
strarray_push(&include_paths, argv[++i]);
} else if (startswith(argv[i], "-I")) {
@ -350,9 +366,10 @@ static char *replace_extn(char *tmpl, char *extn) {
}
static void cleanup(void) {
if (tmpfiles && !opt_save_temps) {
for (int i = 0; tmpfiles[i]; i++) {
unlink(tmpfiles[i]);
size_t i;
if (chibicc_tmpfiles && !opt_save_temps) {
for (i = 0; chibicc_tmpfiles[i]; i++) {
unlink(chibicc_tmpfiles[i]);
}
}
}
@ -363,9 +380,9 @@ static char *create_tmpfile(void) {
if (fd == -1) error("mkstemp failed: %s", strerror(errno));
close(fd);
static int len = 2;
tmpfiles = realloc(tmpfiles, sizeof(char *) * len);
tmpfiles[len - 2] = path;
tmpfiles[len - 1] = NULL;
chibicc_tmpfiles = realloc(chibicc_tmpfiles, sizeof(char *) * len);
chibicc_tmpfiles[len - 2] = path;
chibicc_tmpfiles[len - 1] = NULL;
len++;
return path;
}
@ -377,12 +394,50 @@ static void handle_exit(bool ok) {
}
}
static bool NeedsShellQuotes(const char *s) {
if (*s) {
for (;;) {
switch (*s++ & 255) {
case 0:
return false;
case '-':
case '.':
case '/':
case '_':
case '0' ... '9':
case 'A' ... 'Z':
case 'a' ... 'z':
break;
default:
return true;
}
}
} else {
return true;
}
}
static bool run_subprocess(char **argv) {
// If -### is given, dump the subprocess's command line.
if (opt_hash_hash_hash) {
fprintf(stderr, "%s", argv[0]);
for (int i = 1; argv[i]; i++) fprintf(stderr, " %s", argv[i]);
fprintf(stderr, "\n");
int rc, ws;
size_t i, j, n;
if (opt_verbose) {
for (i = 0; argv[i]; i++) {
fputc(' ', stderr);
if (opt_hash_hash_hash && NeedsShellQuotes(argv[i])) {
fputc('\'', stderr);
for (j = 0; argv[i][j]; ++j) {
if (argv[i][j] != '\'') {
fputc(argv[i][j], stderr);
} else {
fputs("'\"'\"'", stderr);
}
}
fputc('\'', stderr);
} else {
fputs(argv[i], stderr);
}
}
fputc('\n', stderr);
}
if (!vfork()) {
// Child process. Run a new command.
@ -390,13 +445,9 @@ static bool run_subprocess(char **argv) {
_exit(1);
}
// Wait for the child process to finish.
int status;
for (;;) {
if (wait(&status) <= 0) {
break;
}
}
return !status;
do rc = wait(&ws);
while (rc == -1 && errno == EINTR);
return WIFEXITED(ws) && WEXITSTATUS(ws) == 0;
}
static bool run_cc1(int argc, char **argv, char *input, char *output) {
@ -480,7 +531,7 @@ static void print_dependencies(void) {
File **files = get_input_files();
for (int i = 0; files[i]; i++) {
if (opt_MMD && in_std_include_path(files[i]->name)) continue;
fprintf(out, " \\\n %s", files[i]->name);
fprintf(out, " \\\n\t%s", files[i]->name);
}
fprintf(out, "\n\n");
if (opt_MP) {
@ -559,6 +610,10 @@ static void cc1(void) {
output_javadown(output_file, prog);
return;
}
if (opt_P) {
output_bindings_python(output_file, prog, tok2);
return;
}
FILE *out = open_file(output_file);
codegen(prog, out);
fclose(out);
@ -573,7 +628,7 @@ static int CountArgv(char **argv) {
static void assemble(char *input, char *output) {
char *as = getenv("AS");
if (!as || !*as) as = "as";
StringArray arr = {};
StringArray arr = {0};
strarray_push(&arr, as);
strarray_push(&arr, "-W");
strarray_push(&arr, "-I.");
@ -584,9 +639,11 @@ static void assemble(char *input, char *output) {
strarray_push(&arr, input);
strarray_push(&arr, "-o");
strarray_push(&arr, output);
strarray_push(&arr, NULL);
if (1) {
bool kludge = opt_save_temps;
opt_save_temps = true;
Assembler(CountArgv(arr.data), arr.data);
opt_save_temps = kludge;
} else {
handle_exit(run_subprocess(arr.data));
}
@ -595,7 +652,7 @@ static void assemble(char *input, char *output) {
static void run_linker(StringArray *inputs, char *output) {
char *ld = getenv("LD");
if (!ld || !*ld) ld = "ld";
StringArray arr = {};
StringArray arr = {0};
strarray_push(&arr, ld);
strarray_push(&arr, "-o");
strarray_push(&arr, output);
@ -618,7 +675,6 @@ static void run_linker(StringArray *inputs, char *output) {
for (int i = 0; i < inputs->len; i++) {
strarray_push(&arr, inputs->data[i]);
}
strarray_push(&arr, NULL);
handle_exit(run_subprocess(arr.data));
}
@ -630,9 +686,16 @@ int chibicc(int argc, char **argv) {
showcrashreports();
sigaction(SIGINT, &(struct sigaction){.sa_sigaction = OnCtrlC}, NULL);
atexit(cleanup);
init_macros();
for (int i = 1; i < argc; i++) {
if (!strcmp(argv[i], "-cc1")) {
opt_cc1 = true;
break;
}
}
if (opt_cc1) init_macros();
parse_args(argc, argv);
if (opt_cc1) {
init_macros_conditional();
add_default_include_paths(argv[0]);
cc1();
return 0;
@ -640,8 +703,8 @@ int chibicc(int argc, char **argv) {
if (input_paths.len > 1 && opt_o && (opt_c || opt_S | opt_E)) {
error("cannot specify '-o' with '-c,' '-S' or '-E' with multiple files");
}
StringArray ld_args = {};
StringArray dox_args = {};
StringArray ld_args = {0};
StringArray dox_args = {0};
for (int i = 0; i < input_paths.len; i++) {
char *input = input_paths.data[i];
if (!strncmp(input, "-l", 2)) {
@ -701,6 +764,11 @@ int chibicc(int argc, char **argv) {
handle_exit(run_cc1(argc, argv, input, NULL));
continue;
}
// Python Bindings
if (opt_P) {
handle_exit(run_cc1(argc, argv, input, opt_o ? opt_o : "/dev/stdout"));
continue;
}
// Compile
if (opt_S) {
handle_exit(run_cc1(argc, argv, input, output));