소스 검색

added hl_is_prim_loaded, allow ?libname for optional library

Nicolas Cannasse 5 년 전
부모
커밋
71053468d3
2개의 변경된 파일26개의 추가작업 그리고 8개의 파일을 삭제
  1. 17 7
      src/module.c
  2. 9 1
      src/std/fun.c

+ 17 - 7
src/module.c

@@ -33,6 +33,8 @@ EXTERN_C IMAGE_DOS_HEADER __ImageBase;
 
 
 #define HOT_RELOAD_EXTRA_GLOBALS	4096
 #define HOT_RELOAD_EXTRA_GLOBALS	4096
 
 
+HL_API void hl_prim_not_loaded( const uchar *err );
+
 static hl_module **cur_modules = NULL;
 static hl_module **cur_modules = NULL;
 static int modules_count = 0;
 static int modules_count = 0;
 
 
@@ -302,7 +304,7 @@ static void append_type( char **p, hl_type *t ) {
 
 
 #define DISABLED_LIB_PTR ((void*)(int_val)2)
 #define DISABLED_LIB_PTR ((void*)(int_val)2)
 
 
-static void *resolve_library( const char *lib ) {
+static void *resolve_library( const char *lib, bool is_opt ) {
 	char tmp[256];	
 	char tmp[256];	
 	void *h;
 	void *h;
 
 
@@ -331,7 +333,7 @@ static void *resolve_library( const char *lib ) {
 #		else
 #		else
 		h = dlopen("libhl.dll",RTLD_LAZY);
 		h = dlopen("libhl.dll",RTLD_LAZY);
 #		endif
 #		endif
-		if( h == NULL ) hl_fatal1("Failed to load library %s","libhl.dll");
+		if( h == NULL && !is_opt ) hl_fatal1("Failed to load library %s","libhl.dll");
 		return h;
 		return h;
 #	else
 #	else
 		return RTLD_DEFAULT;
 		return RTLD_DEFAULT;
@@ -348,7 +350,7 @@ static void *resolve_library( const char *lib ) {
 	
 	
 	strcpy(tmp+strlen(lib),".hdll");
 	strcpy(tmp+strlen(lib),".hdll");
 	h = dlopen(tmp,RTLD_LAZY);
 	h = dlopen(tmp,RTLD_LAZY);
-	if( h == NULL )
+	if( h == NULL && !is_opt )
 		hl_fatal1("Failed to load library %s",tmp);
 		hl_fatal1("Failed to load library %s",tmp);
 	return h;
 	return h;
 }
 }
@@ -452,11 +454,14 @@ static void hl_module_init_natives( hl_module *m ) {
 	const char *curlib = NULL, *sign;
 	const char *curlib = NULL, *sign;
 	for(i=0;i<m->code->nnatives;i++) {
 	for(i=0;i<m->code->nnatives;i++) {
 		hl_native *n = m->code->natives + i;
 		hl_native *n = m->code->natives + i;
+		const char *lib = n->lib;
+		bool is_opt = *lib == '?';
 		char *p = tmp;
 		char *p = tmp;
 		void *f;
 		void *f;
-		if( curlib != n->lib ) {
-			curlib = n->lib;
-			libHandler = resolve_library(n->lib);
+		if( is_opt ) lib++;
+		if( curlib != lib ) {
+			curlib = lib;
+			libHandler = resolve_library(lib, is_opt);
 		}
 		}
 		if( libHandler == DISABLED_LIB_PTR ) {
 		if( libHandler == DISABLED_LIB_PTR ) {
 			m->functions_ptrs[n->findex] = disabled_primitive;
 			m->functions_ptrs[n->findex] = disabled_primitive;
@@ -468,8 +473,13 @@ static void hl_module_init_natives( hl_module *m ) {
 		p += strlen(n->name);
 		p += strlen(n->name);
 		*p++ = 0;
 		*p++ = 0;
 		f = dlsym(libHandler,tmp);
 		f = dlsym(libHandler,tmp);
-		if( f == NULL )
+		if( f == NULL ) {
+			if( is_opt ) {
+				m->functions_ptrs[n->findex] = hl_prim_not_loaded;
+				continue;
+			}
 			hl_fatal2("Failed to load function %s@%s",n->lib,n->name);
 			hl_fatal2("Failed to load function %s@%s",n->lib,n->name);
+		}
 		m->functions_ptrs[n->findex] = ((void *(*)( const char **p ))f)(&sign);
 		m->functions_ptrs[n->findex] = ((void *(*)( const char **p ))f)(&sign);
 		p = tmp;
 		p = tmp;
 		append_type(&p,n->t);
 		append_type(&p,n->t);

+ 9 - 1
src/std/fun.c

@@ -392,13 +392,21 @@ HL_PRIM vdynamic *hl_make_var_args( vclosure *c ) {
 	return (vdynamic*)hl_alloc_closure_ptr(&hlt_var_args,fun_var_args,c);
 	return (vdynamic*)hl_alloc_closure_ptr(&hlt_var_args,fun_var_args,c);
 }
 }
 
 
+HL_PRIM void hl_prim_not_loaded() {
+	hl_error("Primitive or library is missing");
+}
+
+HL_PRIM bool hl_is_prim_loaded( vdynamic *f ) {
+	return f && f->t->kind == HFUN && ((vclosure*)f)->fun != hl_prim_not_loaded;
+}
+
 DEFINE_PRIM(_DYN, no_closure, _DYN);
 DEFINE_PRIM(_DYN, no_closure, _DYN);
 DEFINE_PRIM(_DYN, make_closure, _DYN _DYN);
 DEFINE_PRIM(_DYN, make_closure, _DYN _DYN);
 DEFINE_PRIM(_DYN, get_closure_value, _DYN);
 DEFINE_PRIM(_DYN, get_closure_value, _DYN);
 DEFINE_PRIM(_BOOL, fun_compare, _DYN _DYN);
 DEFINE_PRIM(_BOOL, fun_compare, _DYN _DYN);
 DEFINE_PRIM(_DYN, make_var_args, _FUN(_DYN,_ARR));
 DEFINE_PRIM(_DYN, make_var_args, _FUN(_DYN,_ARR));
 DEFINE_PRIM(_DYN, call_method, _DYN _ARR);
 DEFINE_PRIM(_DYN, call_method, _DYN _ARR);
-
+DEFINE_PRIM(_BOOL, is_prim_loaded, _DYN);
 
 
 #if defined(HL_VCC) && !defined(HL_XBO)
 #if defined(HL_VCC) && !defined(HL_XBO)
 static int throw_handler( int code ) {
 static int throw_handler( int code ) {