Просмотр исходного кода

Implement caching compilation results

Unfortunately they aren't yet reused, but that will come later.
Lucas Stadler лет назад: 9
Родитель
Сommit
430580d34c
1 измененных файлов с 122 добавлено и 0 удалено
  1. 122 0
      c/ton/main.c

+ 122 - 0
c/ton/main.c

1
#include <assert.h>
1
#include <assert.h>
2
#include <errno.h>
2
#include <errno.h>
3
#include <getopt.h>
3
#include <getopt.h>
4
#include <libgen.h>
4
#include <stdio.h>
5
#include <stdio.h>
5
#include <stdlib.h>
6
#include <stdlib.h>
6
#include <string.h>
7
#include <string.h>
18
JSStringRef to_string(JSContextRef ctx, JSValueRef val);
19
JSStringRef to_string(JSContextRef ctx, JSValueRef val);
19
JSValueRef evaluate_script(JSContextRef ctx, char *script, char *source);
20
JSValueRef evaluate_script(JSContextRef ctx, char *script, char *source);
20
21
22
char *value_to_c_string(JSContextRef ctx, JSValueRef val);
23
21
JSValueRef evaluate_source(JSContextRef ctx, char *type, char *source_value, bool expression, char *set_ns);
24
JSValueRef evaluate_source(JSContextRef ctx, char *type, char *source_value, bool expression, char *set_ns);
22
char *munge(char *s);
25
char *munge(char *s);
23
26
25
JSObjectRef get_function(JSContextRef ctx, char *namespace, char *name);
28
JSObjectRef get_function(JSContextRef ctx, char *namespace, char *name);
26
29
27
char* get_contents(char *path);
30
char* get_contents(char *path);
31
void write_contents(char *path, char *contents);
32
int mkdir_p(char *path);
28
33
29
#ifdef DEBUG
34
#ifdef DEBUG
30
#define debug_print_value(prefix, ctx, val)	print_value(prefix ": ", ctx, val)
35
#define debug_print_value(prefix, ctx, val)	print_value(prefix ": ", ctx, val)
152
	return JSObjectMakeArray(ctx, 0, NULL, NULL);
157
	return JSObjectMakeArray(ctx, 0, NULL, NULL);
153
}
158
}
154
159
160
JSValueRef function_cache(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject,
161
		size_t argc, const JSValueRef args[], JSValueRef* exception) {
162
	if (argc == 4 &&
163
			JSValueGetType (ctx, args[0]) == kJSTypeString &&
164
			JSValueGetType (ctx, args[1]) == kJSTypeString &&
165
			(JSValueGetType (ctx, args[2]) == kJSTypeString
166
				|| JSValueGetType (ctx, args[2]) == kJSTypeNull) &&
167
			(JSValueGetType (ctx, args[3]) == kJSTypeString
168
				|| JSValueGetType (ctx, args[3]) == kJSTypeNull)) {
169
		debug_print_value("cache", ctx, args[0]);
170
171
		char *cache_prefix = value_to_c_string(ctx, args[0]);
172
		char *source = value_to_c_string(ctx, args[1]);
173
		char *cache = value_to_c_string(ctx, args[2]);
174
		char *sourcemap = value_to_c_string(ctx, args[3]);
175
176
		char *suffix = NULL;
177
		int max_suffix_len = 20;
178
		int prefix_len = strlen(cache_prefix);
179
		char *path = malloc((prefix_len + max_suffix_len) * sizeof(char));
180
181
		suffix = ".js";
182
		strncpy(path, cache_prefix, prefix_len);
183
		path[prefix_len] = '\0';
184
		strncat(path, suffix, strlen(suffix));
185
		write_contents(path, source);
186
187
		suffix = ".cache.json";
188
		strncpy(path, cache_prefix, prefix_len);
189
		path[prefix_len] = '\0';
190
		strncat(path, suffix, strlen(suffix));
191
		write_contents(path, cache);
192
193
		suffix = ".js.map.json";
194
		strncpy(path, cache_prefix, prefix_len);
195
		path[prefix_len] = '\0';
196
		strncat(path, suffix, strlen(suffix));
197
		write_contents(path, sourcemap);
198
199
		free(cache_prefix);
200
		free(source);
201
		free(cache);
202
		free(sourcemap);
203
204
		free(path);
205
	}
206
207
	return  JSValueMakeNull(ctx);
208
}
209
155
JSValueRef function_eval(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject,
210
JSValueRef function_eval(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject,
156
		size_t argc, const JSValueRef args[], JSValueRef* exception) {
211
		size_t argc, const JSValueRef args[], JSValueRef* exception) {
157
	JSValueRef val = NULL;
212
	JSValueRef val = NULL;
358
	register_global_function(ctx, "PLANCK_READ_FILE", function_read_file);
413
	register_global_function(ctx, "PLANCK_READ_FILE", function_read_file);
359
	register_global_function(ctx, "PLANCK_LOAD", function_load);
414
	register_global_function(ctx, "PLANCK_LOAD", function_load);
360
	register_global_function(ctx, "PLANCK_LOAD_DEPS_CLJS_FILES", function_load_deps_cljs_files);
415
	register_global_function(ctx, "PLANCK_LOAD_DEPS_CLJS_FILES", function_load_deps_cljs_files);
416
	register_global_function(ctx, "PLANCK_CACHE", function_cache);
361
417
362
	register_global_function(ctx, "PLANCK_EVAL", function_eval);
418
	register_global_function(ctx, "PLANCK_EVAL", function_eval);
363
419
453
	return val;
509
	return val;
454
}
510
}
455
511
512
char *value_to_c_string(JSContextRef ctx, JSValueRef val) {
513
	if (!JSValueIsString(ctx, val)) {
514
#ifdef DEBUG
515
		fprintf(stderr, "WARN: not a string\n");
516
#endif
517
		return NULL;
518
	}
519
520
	JSStringRef str_ref = JSValueToStringCopy(ctx, val, NULL);
521
	size_t len = JSStringGetLength(str_ref);
522
	char *str = malloc(len * sizeof(char));
523
	JSStringGetUTF8CString(str_ref, str, len);
524
	JSStringRelease(str_ref);
525
526
	return str;
527
}
528
456
JSValueRef get_value_on_object(JSContextRef ctx, JSObjectRef obj, char *name) {
529
JSValueRef get_value_on_object(JSContextRef ctx, JSObjectRef obj, char *name) {
457
	JSStringRef name_str = JSStringCreateWithUTF8CString(name);
530
	JSStringRef name_str = JSStringCreateWithUTF8CString(name);
458
	JSValueRef val = JSObjectGetProperty(ctx, obj, name_str, NULL);
531
	JSValueRef val = JSObjectGetProperty(ctx, obj, name_str, NULL);
659
	printf("get_contents(\"%s\"): %s: %s\n", path, err_prefix, strerror(errno));
732
	printf("get_contents(\"%s\"): %s: %s\n", path, err_prefix, strerror(errno));
660
	return NULL;
733
	return NULL;
661
}
734
}
735
736
void write_contents(char *path, char *contents) {
737
	char *err_prefix;
738
739
	char *path_copy = strdup(path);
740
	char *dir = dirname(path_copy);
741
	if (mkdir_p(dir) < 0) {
742
		err_prefix = "mkdir_p";
743
		free(path_copy);
744
		goto err;
745
	}
746
	free(path_copy);
747
748
	FILE *f = fopen(path, "w");
749
	if (f == NULL) {
750
		err_prefix = "fopen";
751
		goto err;
752
	}
753
754
	int len = strlen(contents);
755
	int offset = 0;
756
	do {
757
		int res = fwrite(contents+offset, 1, len-offset, f);
758
		if (res < 0) {
759
			err_prefix = "fwrite";
760
			goto err;
761
		}
762
		offset += res;
763
	} while (offset < len);
764
765
	if (fclose(f) < 0) {
766
		err_prefix = "fclose";
767
		goto err;
768
	}
769
770
	return;
771
772
err:
773
	printf("write_contents(\"%s\", ...): %s: %s\n", path, err_prefix, strerror(errno));
774
	return;
775
}
776
777
int mkdir_p(char *path) {
778
	int res = mkdir(path, 0755);
779
	if (res < 0 && errno == EEXIST) {
780
		return 0;
781
	}
782
	return res;
783
}