aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2022-02-11 17:41:33 +0100
committerdec05eba <dec05eba@protonmail.com>2022-02-11 17:41:33 +0100
commit6cad09ec9c801e90d41f53ebcd673ef89050cc86 (patch)
treea57b30c824c663ed7730a6df6f2478a4a5b500e8
parent8d1532abb6f7441e00ffbc7ed4d0231e5023e19a (diff)
Check if file to read is really a fileHEADmaster
-rw-r--r--README.md8
-rwxr-xr-xdoc/doc_extract.py2
-rw-r--r--executor/x86_64/asm.c6
-rw-r--r--optimize.md33
-rw-r--r--src/program.c6
-rw-r--r--src/std/file.c28
-rw-r--r--src/std/hash_map.c3
-rwxr-xr-xtools/highlevel_c.py2
8 files changed, 67 insertions, 21 deletions
diff --git a/README.md b/README.md
index 4b12d62..fb2e44f 100644
--- a/README.md
+++ b/README.md
@@ -25,7 +25,7 @@ Locks are only used in one place in the whole compilation stage, during @import
# Dependencies
Right now only the C standard library (C89) is required for a release build. In the future dependency on the C standard library might be removed
and then amalgam would have 0 dependencies.\
-python2 is needed for tests to run additional code analyzis.
+python3 is needed for tests to run additional code analyzis.
# Limits
Amalgam places limits on code for performance reasons. These are the limits:
@@ -74,6 +74,12 @@ All branch targets should be 16-byte aligned.
* Do not allow (re)assigning to variables in global scope. This wouldn't be consistent since files are parsed asynchronously so the order wouldn't be deterministic.
* Compile error if a variable has the same name as a keyword.
* Only allow importing files that has .amal extension, this also fixes the issue where windows has illegal filenames such as aux, nul, etc. Also do the same for the main file.
+* Generate optimization report, where the code should be annotated with patterns the compiler sees and optimizes. This would help the user write code that the compiler can optimize.
+* Handle a situation similar to this: https://github.com/ziglang/zig/issues/4021.
+* Change the size of pthreads with setrlimit.
+* Handle EINTR.
+* Use semaphore instead of mutex to unlock other thread.
+* Check redefinition of variables, parameters and member variables/functions.
# Documents
Documents are located under doc. The file doc/Documentation.md is generated from source files by running doc/doc_extract.py
but there is no need to run this script unless you are modifying documentation in the source.
diff --git a/doc/doc_extract.py b/doc/doc_extract.py
index 3331ae0..16f7732 100755
--- a/doc/doc_extract.py
+++ b/doc/doc_extract.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
import sys
import os
diff --git a/executor/x86_64/asm.c b/executor/x86_64/asm.c
index f57f117..718ebef 100644
--- a/executor/x86_64/asm.c
+++ b/executor/x86_64/asm.c
@@ -206,7 +206,7 @@ int asm_init(Asm *self) {
amal_log_debug("asm: page size: %u", self->allocated_size);
self->code = mmap(NULL, self->allocated_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if(self->code == MAP_FAILED)
- return -errno;
+ return -1;
self->code_it = self->code;
return 0;
}
@@ -253,7 +253,7 @@ typedef union {
int asm_execute(Asm *self, u32 offset) {
RawFuncCallPtr raw_func_ptr;
if(mprotect(self->code, self->allocated_size, PROT_READ | PROT_EXEC) != 0)
- return -errno;
+ return -1;
/*asm_print_code_hex(self);*/
@@ -270,7 +270,7 @@ int asm_ensure_capacity(Asm *self, usize size) {
usize new_size = self->allocated_size + am_pagesize();
void *new_mem = mmap(NULL, new_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if(new_mem == MAP_FAILED)
- return -errno;
+ return -1;
am_memcpy(new_mem, self->code, self->allocated_size);
munmap(self->code, self->allocated_size);
diff --git a/optimize.md b/optimize.md
new file mode 100644
index 0000000..b2418ef
--- /dev/null
+++ b/optimize.md
@@ -0,0 +1,33 @@
+Turn ['a', 'i', 'u', 'e', 'o'].contains(c) into:
+
+1 - inline:
+char arr[] = { 'a', 'i', 'u', 'e', 'o' };
+for(int i = 0; i < 5; ++i) {
+ if(arr[i] == c)
+ return true;
+}
+return false;
+
+2 - constant loop unrolling:
+if('a' == c)
+ return true;
+if('i' == c)
+ return true;
+if('u' == c)
+ return true;
+if('e' == c)
+ return true;
+if('o' == c)
+ return true;
+return false;
+
+3 - multiple comparisons to same variable turned into a switch:
+switch(c) {
+ case 'a':
+ case 'i':
+ case 'u':
+ case 'e':
+ case 'o':
+ return true;
+}
+return false;
diff --git a/src/program.c b/src/program.c
index e53eb6b..e163b9b 100644
--- a/src/program.c
+++ b/src/program.c
@@ -871,12 +871,14 @@ int amal_program_save(amal_program *self, const char *filepath) {
int err = 0;
FILE *file = fopen(filepath, "wb");
if(!file) {
- err = -errno;
+ perror(filepath);
+ err = -1;
goto cleanup;
}
if(fwrite(self->data.data, 1, self->data.size, file) != self->data.size) {
- err = -errno;
+ fprintf(stderr, "Failed to write %zu bytes to %s\n", self->data.size, filepath);
+ err = -1;
goto cleanup;
}
diff --git a/src/std/file.c b/src/std/file.c
index 4542aba..d486843 100644
--- a/src/std/file.c
+++ b/src/std/file.c
@@ -28,10 +28,8 @@ static int scan_dir_recursive_internal(char *dir_path, int path_length, scan_dir
path_length_start = path_length;
if((dir = opendir(dir_path)) == NULL) {
- int error;
- error = errno;
amal_log_perror("scan_dir_recursive");
- return error;
+ return -1;
}
while((entry = readdir(dir)) != NULL) {
@@ -178,9 +176,16 @@ int read_whole_file(const char *filepath, Buffer *data_result) {
file = fopen(filepath, "rb");
if(!file) {
- int error = errno;
- amal_log_error("read_whole_file: %s failed, error: %s", filepath, strerror(error));
- return error;
+ amal_log_error("read_whole_file: %s failed, error: %s", filepath, strerror(errno));
+ return -1;
+ }
+
+ int fd = fileno(file);
+ struct stat s;
+ if(fstat(fd, &s) == -1 || !S_ISREG(s.st_mode)) {
+ amal_log_error("read_whole_file: %s failed, error: attempted to read a non-file", filepath);
+ fclose(file);
+ return -1;
}
result = fseek(file, 0, SEEK_END);
@@ -191,9 +196,8 @@ int read_whole_file(const char *filepath, Buffer *data_result) {
size = ftell(file);
if(size == -1) {
- int error = errno;
- result = error;
- amal_log_error("read_whole_file: %s failed, error: %s", filepath, strerror(error));
+ result = -1;
+ amal_log_error("read_whole_file: %s failed, error: %s", filepath, strerror(errno));
goto cleanup;
}
@@ -223,10 +227,8 @@ int read_whole_file(const char *filepath, Buffer *data_result) {
int file_get_canonical_path(const char *filepath, char **result_path, usize *result_path_size) {
char result_path_tmp[PATH_MAX];
if(!realpath(filepath, result_path_tmp)) {
- int ret;
- ret = errno;
- amal_log_error("file_get_canonical_path: realpath failed for path %s, error: %s", filepath, strerror(ret));
- return ret;
+ amal_log_error("file_get_canonical_path: realpath failed for path %s, error: %s", filepath, strerror(errno));
+ return -1;
}
*result_path_size = strnlen(result_path_tmp, PATH_MAX);
return_if_error(am_malloc(*result_path_size + 1, (void**)result_path));
diff --git a/src/std/hash_map.c b/src/std/hash_map.c
index b4bd4c1..4bf55c6 100644
--- a/src/std/hash_map.c
+++ b/src/std/hash_map.c
@@ -224,6 +224,9 @@ bool hash_map_get_ref(HashMap *self, BufferView key, void **value) {
HashMapBucketNode *bucket_node;
bucket_size = buffer_get_size(&self->buckets, HashMapBucket);
+ if(bucket_size == 0)
+ return bool_false;
+
hash = self->hash_func((const u8*)key.data, key.size);
bucket_index = hash % bucket_size;
diff --git a/tools/highlevel_c.py b/tools/highlevel_c.py
index b1c2dc3..cb75044 100755
--- a/tools/highlevel_c.py
+++ b/tools/highlevel_c.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
import os
import sys