From fdf459b1a586df1f5c4d4f7600a38c30d9b95c7b Mon Sep 17 00:00:00 2001 From: Luchs Date: Thu, 26 Mar 2015 20:42:20 +0100 Subject: [PATCH 1/7] Make callFunction() unique --- src/vm/wren_core.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/vm/wren_core.c b/src/vm/wren_core.c index 9fce8d68..89bccbcc 100644 --- a/src/vm/wren_core.c +++ b/src/vm/wren_core.c @@ -485,7 +485,7 @@ DEF_PRIMITIVE(fn_arity) RETURN_NUM(AS_FN(args[0])->arity); } -static PrimitiveResult callFunction(WrenVM* vm, Value* args, int numArgs) +static PrimitiveResult callFn(WrenVM* vm, Value* args, int numArgs) { ObjFn* fn; if (IS_CLOSURE(args[0])) @@ -502,23 +502,23 @@ static PrimitiveResult callFunction(WrenVM* vm, Value* args, int numArgs) return PRIM_CALL; } -DEF_PRIMITIVE(fn_call0) { return callFunction(vm, args, 0); } -DEF_PRIMITIVE(fn_call1) { return callFunction(vm, args, 1); } -DEF_PRIMITIVE(fn_call2) { return callFunction(vm, args, 2); } -DEF_PRIMITIVE(fn_call3) { return callFunction(vm, args, 3); } -DEF_PRIMITIVE(fn_call4) { return callFunction(vm, args, 4); } -DEF_PRIMITIVE(fn_call5) { return callFunction(vm, args, 5); } -DEF_PRIMITIVE(fn_call6) { return callFunction(vm, args, 6); } -DEF_PRIMITIVE(fn_call7) { return callFunction(vm, args, 7); } -DEF_PRIMITIVE(fn_call8) { return callFunction(vm, args, 8); } -DEF_PRIMITIVE(fn_call9) { return callFunction(vm, args, 9); } -DEF_PRIMITIVE(fn_call10) { return callFunction(vm, args, 10); } -DEF_PRIMITIVE(fn_call11) { return callFunction(vm, args, 11); } -DEF_PRIMITIVE(fn_call12) { return callFunction(vm, args, 12); } -DEF_PRIMITIVE(fn_call13) { return callFunction(vm, args, 13); } -DEF_PRIMITIVE(fn_call14) { return callFunction(vm, args, 14); } -DEF_PRIMITIVE(fn_call15) { return callFunction(vm, args, 15); } -DEF_PRIMITIVE(fn_call16) { return callFunction(vm, args, 16); } +DEF_PRIMITIVE(fn_call0) { return callFn(vm, args, 0); } +DEF_PRIMITIVE(fn_call1) { return callFn(vm, args, 1); } +DEF_PRIMITIVE(fn_call2) { return callFn(vm, args, 2); } +DEF_PRIMITIVE(fn_call3) { return callFn(vm, args, 3); } +DEF_PRIMITIVE(fn_call4) { return callFn(vm, args, 4); } +DEF_PRIMITIVE(fn_call5) { return callFn(vm, args, 5); } +DEF_PRIMITIVE(fn_call6) { return callFn(vm, args, 6); } +DEF_PRIMITIVE(fn_call7) { return callFn(vm, args, 7); } +DEF_PRIMITIVE(fn_call8) { return callFn(vm, args, 8); } +DEF_PRIMITIVE(fn_call9) { return callFn(vm, args, 9); } +DEF_PRIMITIVE(fn_call10) { return callFn(vm, args, 10); } +DEF_PRIMITIVE(fn_call11) { return callFn(vm, args, 11); } +DEF_PRIMITIVE(fn_call12) { return callFn(vm, args, 12); } +DEF_PRIMITIVE(fn_call13) { return callFn(vm, args, 13); } +DEF_PRIMITIVE(fn_call14) { return callFn(vm, args, 14); } +DEF_PRIMITIVE(fn_call15) { return callFn(vm, args, 15); } +DEF_PRIMITIVE(fn_call16) { return callFn(vm, args, 16); } DEF_PRIMITIVE(fn_toString) { From 8d90333ebc9288ff0dd848ef9c30f92f07585bf4 Mon Sep 17 00:00:00 2001 From: Luchs Date: Thu, 26 Mar 2015 21:16:43 +0100 Subject: [PATCH 2/7] `#undef` some macros which are redefined elsewhere --- src/vm/wren_debug.c | 3 +++ src/vm/wren_vm.c | 2 ++ 2 files changed, 5 insertions(+) diff --git a/src/vm/wren_debug.c b/src/vm/wren_debug.c index 7e243157..cf50f7d6 100644 --- a/src/vm/wren_debug.c +++ b/src/vm/wren_debug.c @@ -333,6 +333,9 @@ static int dumpInstruction(WrenVM* vm, ObjFn* fn, int i, int* lastLine) // Return how many bytes this instruction takes, or -1 if it's an END. if (code == CODE_END) return -1; return i - start; + + #undef READ_BYTE + #undef READ_SHORT } int wrenDumpInstruction(WrenVM* vm, ObjFn* fn, int i) diff --git a/src/vm/wren_vm.c b/src/vm/wren_vm.c index 26f424b7..d4c81a1b 100644 --- a/src/vm/wren_vm.c +++ b/src/vm/wren_vm.c @@ -1219,6 +1219,8 @@ static bool runInterpreter(WrenVM* vm) UNREACHABLE(); return false; } +#undef READ_BYTE +#undef READ_SHORT // Creates an [ObjFn] that invokes a method with [signature] when called. static ObjFn* makeCallStub(WrenVM* vm, ObjModule* module, const char* signature) From 4dad9cd68801d768703d6f49eeffc53c25de4842 Mon Sep 17 00:00:00 2001 From: Luchs Date: Thu, 16 Apr 2015 13:07:14 +0200 Subject: [PATCH 3/7] Make builtin statics unambigous --- script/generate_builtins.py | 4 ++-- src/vm/wren_core.c | 4 ++-- src/vm/wren_io.c | 4 ++-- src/vm/wren_meta.c | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/script/generate_builtins.py b/script/generate_builtins.py index 56d6e1bb..99c8bfe1 100755 --- a/script/generate_builtins.py +++ b/script/generate_builtins.py @@ -4,7 +4,7 @@ import glob import os.path import re -PATTERN = re.compile(r'libSource =\n("(.|[\n])*?);') +PATTERN = re.compile(r'LibSource =\n("(.|[\n])*?);') def copy_builtin(filename): name = os.path.basename(filename) @@ -24,7 +24,7 @@ def copy_builtin(filename): # in the C string literal. wren_source = wren_source.replace('\\', '\\\\') - constant = "libSource =\n" + wren_source + ";" + constant = "LibSource =\n" + wren_source + ";" with open("src/vm/wren_" + name + ".c", "r") as f: c_source = f.read() diff --git a/src/vm/wren_core.c b/src/vm/wren_core.c index 89bccbcc..5d0e2b28 100644 --- a/src/vm/wren_core.c +++ b/src/vm/wren_core.c @@ -11,7 +11,7 @@ #include "wren_value.h" // This string literal is generated automatically from core. Do not edit. -static const char* libSource = +static const char* coreLibSource = "class Bool {}\n" "class Fiber {}\n" "class Fn {}\n" @@ -1331,7 +1331,7 @@ void wrenInitializeCore(WrenVM* vm) // '---------' '--------------' -' // The rest of the classes can now be defined normally. - wrenInterpret(vm, "", libSource); + wrenInterpret(vm, "", coreLibSource); vm->boolClass = AS_CLASS(wrenFindVariable(vm, "Bool")); PRIMITIVE(vm->boolClass, "toString", bool_toString); diff --git a/src/vm/wren_io.c b/src/vm/wren_io.c index ff079f02..8463ca8d 100644 --- a/src/vm/wren_io.c +++ b/src/vm/wren_io.c @@ -10,7 +10,7 @@ #define MAX_READ_LEN 1024 // This string literal is generated automatically from io.wren. Do not edit. -static const char* libSource = +static const char* ioLibSource = "class IO {\n" " static print {\n" " IO.writeString_(\"\n\")\n" @@ -142,7 +142,7 @@ static void ioTime(WrenVM* vm) void wrenLoadIOLibrary(WrenVM* vm) { - wrenInterpret(vm, "", libSource); + wrenInterpret(vm, "", ioLibSource); } WrenForeignMethodFn wrenBindIOForeignMethod(WrenVM* vm, const char* className, diff --git a/src/vm/wren_meta.c b/src/vm/wren_meta.c index ff8cd10a..6f20f6fd 100644 --- a/src/vm/wren_meta.c +++ b/src/vm/wren_meta.c @@ -7,7 +7,7 @@ #include "wren_primitive.h" // This string literal is generated automatically from meta.wren. Do not edit. -static const char* libSource = +static const char* metaLibSource = "class Meta {}\n"; DEF_PRIMITIVE(meta_eval) @@ -43,7 +43,7 @@ DEF_PRIMITIVE(meta_eval) void wrenLoadMetaLibrary(WrenVM* vm) { - wrenInterpret(vm, "", libSource); + wrenInterpret(vm, "", metaLibSource); // The methods on "Meta" are static, so get the metaclass for the Meta class. ObjClass* meta = AS_CLASS(wrenFindVariable(vm, "Meta"))->obj.classObj; From 9bcf31e14d90ee40f5bbd246e489c7449f04b47f Mon Sep 17 00:00:00 2001 From: Luchs Date: Thu, 26 Mar 2015 21:21:41 +0100 Subject: [PATCH 4/7] Add amalgamation generation script --- Makefile | 5 +++++ script/generate_amalgamation.py | 28 ++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100755 script/generate_amalgamation.py diff --git a/Makefile b/Makefile index 4155985f..32b3d573 100644 --- a/Makefile +++ b/Makefile @@ -53,4 +53,9 @@ watchdocs: gh-pages: docs @ cp -r build/docs/. build/gh-pages +# Build amalgamation of all Wren library files. +wren.c: src/include/wren.h src/vm/*.h src/vm/*.c + ./script/generate_amalgamation.py $^ > $@ + +.DELETE_ON_ERROR: wren.c .PHONY: debug release all clean test builtin docs watchdocs gh-pages diff --git a/script/generate_amalgamation.py b/script/generate_amalgamation.py new file mode 100755 index 00000000..d0749fd7 --- /dev/null +++ b/script/generate_amalgamation.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python + +import sys +import os.path +import re + +INCLUDE_PATTERN = re.compile(r'^\s*#include "([\w.]+)"') + +seen_files = set() + +def add_file(filename): + basename = os.path.basename(filename) + # Only include each file at most once. + if basename in seen_files: + return + seen_files.add(basename) + path = os.path.dirname(filename) + + with open(filename, 'r') as f: + for line in f: + m = INCLUDE_PATTERN.match(line) + if m: + add_file(os.path.join(path, m.group(1))) + else: + sys.stdout.write(line) + +for f in sys.argv[1:]: + add_file(f) From c44be6418bbf92121e56bf68d6c8e2ebef483e17 Mon Sep 17 00:00:00 2001 From: Luchs Date: Thu, 16 Apr 2015 13:17:38 +0200 Subject: [PATCH 5/7] Add comments for file start/end --- script/generate_amalgamation.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/script/generate_amalgamation.py b/script/generate_amalgamation.py index d0749fd7..cf34cc02 100755 --- a/script/generate_amalgamation.py +++ b/script/generate_amalgamation.py @@ -1,28 +1,31 @@ #!/usr/bin/env python import sys -import os.path +from os.path import basename, dirname, join import re INCLUDE_PATTERN = re.compile(r'^\s*#include "([\w.]+)"') seen_files = set() +out = sys.stdout def add_file(filename): - basename = os.path.basename(filename) + bname = basename(filename) # Only include each file at most once. - if basename in seen_files: + if bname in seen_files: return - seen_files.add(basename) - path = os.path.dirname(filename) + seen_files.add(bname) + path = dirname(filename) + out.write('// Begin file "{0}"\n'.format(filename)) with open(filename, 'r') as f: for line in f: m = INCLUDE_PATTERN.match(line) if m: - add_file(os.path.join(path, m.group(1))) + add_file(join(path, m.group(1))) else: - sys.stdout.write(line) + out.write(line) + out.write('// End file "{0}"\n'.format(filename)) for f in sys.argv[1:]: add_file(f) From bc7bf2a09fe430bb2048842626ecbb476bc6b40c Mon Sep 17 00:00:00 2001 From: Luchs Date: Thu, 16 Apr 2015 14:39:39 +0200 Subject: [PATCH 6/7] Print LICENSE on top of the amalgamation --- script/generate_amalgamation.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/script/generate_amalgamation.py b/script/generate_amalgamation.py index cf34cc02..01faad6c 100755 --- a/script/generate_amalgamation.py +++ b/script/generate_amalgamation.py @@ -5,10 +5,19 @@ from os.path import basename, dirname, join import re INCLUDE_PATTERN = re.compile(r'^\s*#include "([\w.]+)"') +WREN_DIR = dirname(dirname(realpath(__file__))) seen_files = set() out = sys.stdout +# Prints a plain text file, adding comment markers. +def add_comment_file(filename): + with open(filename, 'r') as f: + for line in f: + out.write('// ') + out.write(line) + +# Prints the given C source file, recursively resolving local #includes. def add_file(filename): bname = basename(filename) # Only include each file at most once. @@ -27,5 +36,9 @@ def add_file(filename): out.write(line) out.write('// End file "{0}"\n'.format(filename)) +# Print license on top. +add_comment_file(join(WREN_DIR, 'LICENSE')) +out.write('\n') +# Source files. for f in sys.argv[1:]: add_file(f) From 796639e3710e1b5530be81dc85b7bdb191cf7bda Mon Sep 17 00:00:00 2001 From: Luchs Date: Thu, 16 Apr 2015 14:40:17 +0200 Subject: [PATCH 7/7] Fix amalgamation to work with X Macro files --- Makefile | 2 +- script/generate_amalgamation.py | 18 +++++++++++++++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 32b3d573..9ba2c480 100644 --- a/Makefile +++ b/Makefile @@ -55,7 +55,7 @@ gh-pages: docs # Build amalgamation of all Wren library files. wren.c: src/include/wren.h src/vm/*.h src/vm/*.c - ./script/generate_amalgamation.py $^ > $@ + ./script/generate_amalgamation.py > $@ .DELETE_ON_ERROR: wren.c .PHONY: debug release all clean test builtin docs watchdocs gh-pages diff --git a/script/generate_amalgamation.py b/script/generate_amalgamation.py index 01faad6c..6f862e90 100755 --- a/script/generate_amalgamation.py +++ b/script/generate_amalgamation.py @@ -1,10 +1,12 @@ #!/usr/bin/env python import sys -from os.path import basename, dirname, join +from os.path import basename, dirname, join, realpath +from glob import iglob import re INCLUDE_PATTERN = re.compile(r'^\s*#include "([\w.]+)"') +GUARD_PATTERN = re.compile(r'^#ifndef wren(_\w+)?_h$') WREN_DIR = dirname(dirname(realpath(__file__))) seen_files = set() @@ -23,7 +25,7 @@ def add_file(filename): # Only include each file at most once. if bname in seen_files: return - seen_files.add(bname) + once = False path = dirname(filename) out.write('// Begin file "{0}"\n'.format(filename)) @@ -34,11 +36,21 @@ def add_file(filename): add_file(join(path, m.group(1))) else: out.write(line) + if GUARD_PATTERN.match(line): + once = True out.write('// End file "{0}"\n'.format(filename)) + # Only skip header files which use #ifndef guards. + # This is necessary because of the X Macro technique. + if once: + seen_files.add(bname) + # Print license on top. add_comment_file(join(WREN_DIR, 'LICENSE')) out.write('\n') # Source files. -for f in sys.argv[1:]: +add_file(join(WREN_DIR, 'src', 'include', 'wren.h')) +# Must be included here because of conditional compilation. +add_file(join(WREN_DIR, 'src', 'vm', 'wren_debug.h')) +for f in iglob(join(WREN_DIR, 'src', 'vm', '*.c')): add_file(f)