|
@@ -39,13 +39,34 @@ typedef char pchar;
|
|
|
#define PSTR(x) x
|
|
|
#endif
|
|
|
|
|
|
-static hl_code *load_code( const pchar *file ) {
|
|
|
+typedef struct {
|
|
|
+ hl_code *code;
|
|
|
+ hl_module *m;
|
|
|
+ vdynamic *ret;
|
|
|
+ vclosure c;
|
|
|
+ pchar *file;
|
|
|
+ int file_time;
|
|
|
+} main_context;
|
|
|
+
|
|
|
+static int pfiletime( uchar *file ) {
|
|
|
+#ifdef HL_WIN
|
|
|
+ struct _stat32 st;
|
|
|
+ _wstat32(file,&st);
|
|
|
+ return (int)st.st_mtime;
|
|
|
+#else
|
|
|
+ struct stat st;
|
|
|
+ stat(file,&st);
|
|
|
+ return (int)st.st_mtime;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+static hl_code *load_code( const pchar *file, char **error_msg, bool print_errors ) {
|
|
|
hl_code *code;
|
|
|
FILE *f = pfopen(file,"rb");
|
|
|
int pos, size;
|
|
|
char *fdata;
|
|
|
if( f == NULL ) {
|
|
|
- pprintf("File not found '%s'\n",file);
|
|
|
+ if( print_errors ) pprintf("File not found '%s'\n",file);
|
|
|
return NULL;
|
|
|
}
|
|
|
fseek(f, 0, SEEK_END);
|
|
@@ -56,17 +77,30 @@ static hl_code *load_code( const pchar *file ) {
|
|
|
while( pos < size ) {
|
|
|
int r = (int)fread(fdata + pos, 1, size-pos, f);
|
|
|
if( r <= 0 ) {
|
|
|
- pprintf("Failed to read '%s'\n",file);
|
|
|
+ if( print_errors ) pprintf("Failed to read '%s'\n",file);
|
|
|
return NULL;
|
|
|
}
|
|
|
pos += r;
|
|
|
}
|
|
|
fclose(f);
|
|
|
- code = hl_code_read((unsigned char*)fdata, size);
|
|
|
+ code = hl_code_read((unsigned char*)fdata, size, error_msg);
|
|
|
free(fdata);
|
|
|
return code;
|
|
|
}
|
|
|
|
|
|
+static bool check_reload( main_context *m ) {
|
|
|
+ int time = pfiletime(m->file);
|
|
|
+ if( time == m->file_time )
|
|
|
+ return false;
|
|
|
+ char *error_msg = NULL;
|
|
|
+ hl_code *code = load_code(m->file, &error_msg, false);
|
|
|
+ if( code == NULL )
|
|
|
+ return false;
|
|
|
+ m->file_time = time;
|
|
|
+ hl_code_free(code);
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
#ifdef HL_VCC
|
|
|
// this allows some runtime detection to switch to high performance mode
|
|
|
__declspec(dllexport) DWORD NvOptimusEnablement = 1;
|
|
@@ -102,14 +136,11 @@ int wmain(int argc, pchar *argv[]) {
|
|
|
int main(int argc, pchar *argv[]) {
|
|
|
#endif
|
|
|
pchar *file = NULL;
|
|
|
+ char *error_msg = NULL;
|
|
|
int debug_port = -1;
|
|
|
bool debug_wait = false;
|
|
|
- struct {
|
|
|
- hl_code *code;
|
|
|
- hl_module *m;
|
|
|
- vdynamic *ret;
|
|
|
- vclosure c;
|
|
|
- } ctx;
|
|
|
+ bool hot_reload = false;
|
|
|
+ main_context ctx;
|
|
|
bool isExc = false;
|
|
|
int first_boot_arg = -1;
|
|
|
argv++;
|
|
@@ -131,6 +162,10 @@ int main(int argc, pchar *argv[]) {
|
|
|
printf("%d.%d.%d",HL_VERSION>>8,(HL_VERSION>>4)&15,HL_VERSION&15);
|
|
|
return 0;
|
|
|
}
|
|
|
+ if( pcompare(arg,PSTR("--hot-reload")) == 0 ) {
|
|
|
+ hot_reload = true;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
if( *arg == '-' || *arg == '+' ) {
|
|
|
if( first_boot_arg < 0 ) first_boot_arg = argc + 1;
|
|
|
// skip value
|
|
@@ -160,14 +195,21 @@ int main(int argc, pchar *argv[]) {
|
|
|
hl_global_init();
|
|
|
hl_sys_init((void**)argv,argc,file);
|
|
|
hl_register_thread(&ctx);
|
|
|
- ctx.code = load_code(file);
|
|
|
- if( ctx.code == NULL )
|
|
|
+ ctx.file = file;
|
|
|
+ ctx.code = load_code(file, &error_msg, true);
|
|
|
+ if( ctx.code == NULL ) {
|
|
|
+ if( error_msg ) printf("%s\n", error_msg);
|
|
|
return 1;
|
|
|
+ }
|
|
|
ctx.m = hl_module_alloc(ctx.code);
|
|
|
if( ctx.m == NULL )
|
|
|
return 2;
|
|
|
- if( !hl_module_init(ctx.m) )
|
|
|
+ if( !hl_module_init(ctx.m,hot_reload) )
|
|
|
return 3;
|
|
|
+ if( hot_reload ) {
|
|
|
+ ctx.file_time = pfiletime(ctx.file);
|
|
|
+ hl_setup_reload_check(check_reload,&ctx);
|
|
|
+ }
|
|
|
hl_code_free(ctx.code);
|
|
|
if( debug_port > 0 && !hl_module_debug(ctx.m,debug_port,debug_wait) ) {
|
|
|
fprintf(stderr,"Could not start debugger on port %d",debug_port);
|