Kaynağa Gözat

hl_error_msg -> hl_error
prevent potential in hl_error
return before throw in hl_error, to prevent invalid stack report (close #163)

Nicolas Cannasse 7 yıl önce
ebeveyn
işleme
537ba47d23
17 değiştirilmiş dosya ile 110 ekleme ve 93 silme
  1. 2 2
      libs/directx/directx.cpp
  2. 2 2
      libs/fmt/fmt.c
  3. 2 2
      libs/sdl/gl.c
  4. 1 1
      libs/sdl/sdl.c
  5. 4 4
      libs/sqlite/sqlite.c
  6. 1 1
      libs/ssl/ssl.c
  7. 1 1
      src/alloc.c
  8. 4 4
      src/hl.h
  9. 1 1
      src/hlc.h
  10. 3 1
      src/jit.c
  11. 3 3
      src/std/cast.c
  12. 1 1
      src/std/date.c
  13. 16 7
      src/std/error.c
  14. 4 4
      src/std/fun.c
  15. 2 2
      src/std/obj.c
  16. 1 1
      src/std/regexp.c
  17. 62 56
      src/std/ucs2.c

+ 2 - 2
libs/directx/directx.cpp

@@ -48,9 +48,9 @@ static void ReportDxError( HRESULT err, int line ) {
 	}
 	if( err == DXGI_ERROR_DEVICE_REMOVED && driver ){
 		err = driver->device->GetDeviceRemovedReason();
-		hl_error_msg(USTR("DXGI_ERROR_DEVICE_REMOVED reason 0x%X line %d"),(DWORD)err,line);
+		hl_error("DXGI_ERROR_DEVICE_REMOVED reason 0x%X line %d",(DWORD)err,line);
 	}else{
-		hl_error_msg(USTR("DXERROR %X line %d"),(DWORD)err,line);
+		hl_error("DXERROR %X line %d",(DWORD)err,line);
 	}
 }
 

+ 2 - 2
libs/fmt/fmt.c

@@ -236,7 +236,7 @@ HL_PRIM void HL_NAME(zip_flush_mode)( fmt_zip *z, int flush ) {
 		z->flush = Z_BLOCK;
 		break;
 	default:
-		hl_error_msg(USTR("Invalid flush mode %d"),flush);
+		hl_error("Invalid flush mode %d",flush);
 		break;
 	}
 }
@@ -674,7 +674,7 @@ HL_PRIM void HL_NAME(digest)( vbyte *out, vbyte *in, int length, int format ) {
 		break;
 	default:
 		hl_blocking(false);
-		hl_error_msg(USTR("Unknown digest format %d"),format&0xFF);
+		hl_error("Unknown digest format %d",format&0xFF);
 		break;
 	}
 	hl_blocking(false);

+ 2 - 2
libs/sdl/gl.c

@@ -203,7 +203,7 @@ HL_PRIM vdynamic *HL_NAME(gl_get_program_parameter)( vdynamic *p, int param ) {
 		return alloc_i32(ret);
 	}
 	default:
-		hl_error_msg(USTR("Unsupported param %d"),param);
+		hl_error("Unsupported param %d",param);
 	}
 	return NULL;
 }
@@ -266,7 +266,7 @@ HL_PRIM vdynamic *HL_NAME(gl_get_shader_parameter)( vdynamic *s, int param ) {
 		return alloc_i32(ret);
 	}
 	default:
-		hl_error_msg(USTR("Unsupported param %d"), param);
+		hl_error("Unsupported param %d", param);
 	}
 	return NULL;
 }

+ 1 - 1
libs/sdl/sdl.c

@@ -84,7 +84,7 @@ typedef struct {
 HL_PRIM bool HL_NAME(init_once)() {
 	SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1");
 	if( SDL_Init(SDL_INIT_EVERYTHING) != 0 ) {
-		hl_error_msg(USTR("SDL_Init failed: %s"), hl_to_utf16(SDL_GetError()));
+		hl_error("SDL_Init failed: %s", hl_to_utf16(SDL_GetError()));
 		return false;
 	}
 #	ifdef _WIN32

+ 4 - 4
libs/sqlite/sqlite.c

@@ -40,7 +40,7 @@ static void HL_NAME(error)( sqlite3 *db, bool close ) {
 	hl_buffer_str(b, sqlite3_errmsg16(db));
 	if ( close )
 		sqlite3_close(db);
-	hl_error_msg(hl_buffer_content(b, NULL));
+	hl_error("%s",hl_buffer_content(b,NULL));
 }
 
 static void HL_NAME(finalize_request)(sqlite_result *r, bool exc ) {
@@ -141,7 +141,7 @@ HL_PRIM sqlite_result *HL_NAME(request)(sqlite_database *db, vbyte *sql ) {
 					hl_buffer_str(b, USTR("SQLite error: Same field is two times in the request: "));
 					hl_buffer_str(b, (uchar*)sql);
 
-					hl_error_msg(hl_buffer_content(b, NULL));
+					hl_error("%s",hl_buffer_content(b, NULL));
 				} else {
 					hl_buffer *b = hl_alloc_buffer();
 					hl_buffer_str(b, USTR("SQLite error: Same field ids for: "));
@@ -150,7 +150,7 @@ HL_PRIM sqlite_result *HL_NAME(request)(sqlite_database *db, vbyte *sql ) {
 					hl_buffer_str(b, sqlite3_column_name16(r->r,j));
 					
 					sqlite3_finalize(r->r);
-					hl_error_msg(hl_buffer_content(b, NULL));
+					hl_error("%s",hl_buffer_content(b, NULL));
 				}
 			}
 		r->names[i] = id;
@@ -245,7 +245,7 @@ HL_PRIM varray *HL_NAME(result_next)( sqlite_result *r ) {
 				break;
 			}
 			default:
-				hl_error_msg(USTR("SQLite error: Unknown type #%d"), sqlite3_column_type(r->r,i));
+				hl_error("SQLite error: Unknown type #%d", sqlite3_column_type(r->r,i));
 			}
 			hl_aptr(a, vdynamic*)[i] = v;
 		}

+ 1 - 1
libs/ssl/ssl.c

@@ -87,7 +87,7 @@ static int ssl_error(int ret) {
 	uchar buf16[128];
 	mbedtls_strerror(ret, buf, sizeof(buf));
 	hl_from_utf8(buf16, (int)strlen(buf), buf);
-	hl_error_msg(buf16);
+	hl_error("%s",buf16);
 	return ret;
 }
 

+ 1 - 1
src/alloc.c

@@ -414,7 +414,7 @@ retry:
 		// big block : report stack trace - we should manage to handle it
 		if( size >= (8 << 20) ) {
 			gc_global_lock(false);
-			hl_error_msg(USTR("Failed to alloc %d KB"),size>>10);
+			hl_error("Failed to alloc %d KB",size>>10);
 		}
 		if( gc_flags & GC_DUMP_MEM ) hl_gc_dump_memory("hlmemory.dump");
 		out_of_memory("pages");

+ 4 - 4
src/hl.h

@@ -217,7 +217,7 @@ typedef wchar_t	uchar;
 #	define uprintf		wprintf
 #	define ustrlen		wcslen
 #	define ustrdup		_wcsdup
-#	define uvsprintf	wvsprintf
+HL_API int uvszprintf( uchar *out, int out_size, const uchar *fmt, va_list arglist );
 #	define utod(s,end)	wcstod(s,end)
 #	define utoi(s,end)	wcstol(s,end,10)
 #	define ucmp(a,b)	wcscmp(a,b)
@@ -250,7 +250,7 @@ HL_API int utoi( const uchar *str, uchar **end );
 HL_API int ucmp( const uchar *a, const uchar *b );
 HL_API int utostr( char *out, int out_size, const uchar *str );
 HL_API int usprintf( uchar *out, int out_size, const uchar *fmt, ... );
-HL_API int uvsprintf( uchar *out, const uchar *fmt, va_list arglist );
+HL_API int uvszprintf( uchar *out, int out_size, const uchar *fmt, va_list arglist );
 HL_API void uprintf( const uchar *fmt, const uchar *str );
 C_FUNCTION_END
 #endif
@@ -566,8 +566,8 @@ HL_API int hl_hash_utf8( const char *str ); // no cache
 HL_API int hl_hash_gen( const uchar *name, bool cache_name );
 HL_API const uchar *hl_field_name( int hash );
 
-#define hl_error(msg)	hl_error_msg(USTR(msg))
-HL_API void hl_error_msg( const uchar *msg, ... );
+#define hl_error(msg, ...) hl_throw(hl_alloc_strbytes(USTR(msg), __VA_ARGS__))
+HL_API vdynamic *hl_alloc_strbytes( const uchar *msg, ... );
 HL_API void hl_assert( void );
 HL_API void hl_throw( vdynamic *v );
 HL_API void hl_rethrow( vdynamic *v );

+ 1 - 1
src/hlc.h

@@ -75,7 +75,7 @@
 #endif
 
 static void hl_null_access() {
-	hl_error_msg(USTR("Null access"));
+	hl_error("Null access");
 }
 
 #endif

+ 3 - 1
src/jit.c

@@ -1450,7 +1450,9 @@ static int prepare_call_args( jit_ctx *ctx, int count, int *args, vreg *vregs, i
 #	pragma optimize( "", off )
 #endif
 HL_NO_OPT static void hl_null_access() {
-	hl_error_msg(USTR("Null access"));
+	vdynamic *d = hl_alloc_dynamic(&hlt_bytes);
+	d->v.ptr = USTR("Null access");
+	hl_throw(d);
 }
 #ifdef HL_VCC
 #	pragma optimize( "", on )

+ 3 - 3
src/std/cast.c

@@ -25,7 +25,7 @@
 #define TK2(a,b)		((a) | ((b)<<5))
 
 static void invalid_cast( hl_type *from, hl_type *to ) {
-	hl_error_msg(USTR("Can't cast %s to %s"),hl_type_str(from),hl_type_str(to));
+	hl_error("Can't cast %s to %s",hl_type_str(from),hl_type_str(to));
 }
 
 HL_PRIM vdynamic *hl_make_dyn( void *data, hl_type *t ) {
@@ -441,7 +441,7 @@ static bool is_number( hl_type *t ) {
 
 HL_PRIM vdynamic *hl_dyn_op( int op, vdynamic *a, vdynamic *b ) {
 	static uchar *op_names[] = { USTR("+"), USTR("-"), USTR("*"), USTR("%"), USTR("/"), USTR("<<"), USTR(">>"), USTR(">>>"), USTR("&"), USTR("|"), USTR("^") };
-	if( op < 0 || op >= OpLast ) hl_error_msg(USTR("Invalid op %d"),op);
+	if( op < 0 || op >= OpLast ) hl_error("Invalid op %d",op);
 	if( !a && !b ) return op == OP_DIV || op == OP_MOD ? hl_dynf64(hl_nan()) : NULL;
 	if( (!a || is_number(a->t)) && (!b || is_number(b->t)) ) {
 		switch( op ) {
@@ -466,7 +466,7 @@ HL_PRIM vdynamic *hl_dyn_op( int op, vdynamic *a, vdynamic *b ) {
 		case OP_XOR: IOP(^);
 		}
 	}
-	hl_error_msg(USTR("Can't perform dyn op %s %s %s"),hl_type_str(a->t),op_names[op],hl_type_str(b->t));
+	hl_error("Can't perform dyn op %s %s %s",hl_type_str(a->t),op_names[op],hl_type_str(b->t));
 	return NULL;
 }
 

+ 1 - 1
src/std/date.c

@@ -56,7 +56,7 @@ HL_PRIM vbyte *hl_date_to_string( int date, int *len ) {
 	int size;
 	uchar *out;
 	if( !localtime_r(&d,&t) )
-		hl_error("invalid date");
+		hl_error("Invalid date");
 	size = (int)strftime(buf,127,"%Y-%m-%d %H:%M:%S",&t);
 	out = (uchar*)hl_gc_alloc_noptr((size + 1) << 1);
 	hl_from_utf8(out,size,buf);

+ 16 - 7
src/std/error.c

@@ -135,17 +135,26 @@ HL_PRIM void hl_rethrow( vdynamic *v ) {
 	hl_throw(v);
 }
 
-HL_PRIM void hl_error_msg( const uchar *fmt, ... ) {
-	uchar buf[256];
+HL_PRIM vdynamic *hl_alloc_strbytes( const uchar *fmt, ... ) {
+	uchar _buf[256];
 	vdynamic *d;
 	int len;
+	uchar *buf = _buf;
+	int bsize = sizeof(_buf);
 	va_list args;
-	va_start(args, fmt);
-	len = uvsprintf(buf,fmt,args);
-	va_end(args);
+	while( true ) {
+		va_start(args, fmt);
+		len = uvszprintf(buf,bsize,fmt,args);
+		va_end(args);
+		if( (len + 2) << 1 < bsize ) break;
+		if( buf != _buf ) free(buf);
+		bsize <<= 1;
+		buf = (uchar*)malloc(bsize);
+	}
 	d = hl_alloc_dynamic(&hlt_bytes);
 	d->v.ptr = hl_copy_bytes((vbyte*)buf,(len + 1) << 1);
-	hl_throw(d);
+	if( buf != _buf ) free(buf);
+	return d;
 }
 
 HL_PRIM void hl_fatal_fmt( const char *file, int line, const char *fmt, ...) {
@@ -196,7 +205,7 @@ HL_PRIM bool hl_detect_debugger() {
 #endif
 HL_PRIM HL_NO_OPT void hl_assert() {
 	hl_debug_break();
-	hl_error("Assert");
+	hl_error("assert");
 }
 #ifdef HL_VCC
 #	pragma optimize( "", on )

+ 4 - 4
src/std/fun.c

@@ -140,7 +140,7 @@ HL_PRIM vdynamic* hl_call_method( vdynamic *c, varray *args ) {
 		hl_error("Can't call closure with value");
 	}
 	if( args->size < cl->t->fun->nargs )
-		hl_error_msg(USTR("Missing arguments : %d expected but %d passed"),cl->t->fun->nargs, args->size);
+		hl_error("Missing arguments : %d expected but %d passed",cl->t->fun->nargs, args->size);
 	for(i=0;i<cl->t->fun->nargs;i++) {
 		vdynamic *v = vargs[i];
 		hl_type *t = cl->t->fun->args[i];
@@ -310,7 +310,7 @@ HL_PRIM void *hl_dyn_call_obj( vdynamic *o, hl_type *ft, int hfield, void **args
 			vdynobj *d = (vdynobj*)o;
 			hl_field_lookup *l = hl_lookup_find(d->lookup,d->nfields, hfield);
 			if( l != NULL && l->t->kind != HFUN )
-				hl_error_msg(USTR("Field %s is of type %s and cannot be called"), hl_field_name(hfield), hl_type_str(l->t));
+				hl_error("Field %s is of type %s and cannot be called", hl_field_name(hfield), hl_type_str(l->t));
 			vclosure *tmp = (vclosure*)d->values[l->field_index];
 			if( tmp ) {
 				vclosure_wrapper w;
@@ -321,7 +321,7 @@ HL_PRIM void *hl_dyn_call_obj( vdynamic *o, hl_type *ft, int hfield, void **args
 				w.wrappedFun = tmp;
 				return hl_wrapper_call(&w,args,ret);
 			}
-			hl_error_msg(USTR("%s has no method %s"),hl_type_str(o->t),hl_field_name(hfield));
+			hl_error("%s has no method %s",hl_type_str(o->t),hl_field_name(hfield));
 		}
 		break;
 	case HOBJ:
@@ -346,7 +346,7 @@ HL_PRIM void *hl_dyn_call_obj( vdynamic *o, hl_type *ft, int hfield, void **args
 				rt = rt->parent;
 				if( rt == NULL ) break;
 			}
-			hl_error_msg(USTR("%s has no method %s"),o->t->obj->name,hl_field_name(hfield));
+			hl_error("%s has no method %s",o->t->obj->name,hl_field_name(hfield));
 		}
 		break;
 	default:

+ 2 - 2
src/std/obj.c

@@ -517,7 +517,7 @@ vvirtual *hl_to_virtual( hl_type *vt, vdynamic *obj ) {
 		if( hl_safe_cast(obj->t, vt) ) return (vvirtual*)obj;
 		return hl_to_virtual(vt,hl_virtual_make_value((vvirtual*)obj));
 	default:
-		hl_error_msg(USTR("Can't cast %s to %s"), hl_type_str(obj->t), hl_type_str(vt));
+		hl_error("Can't cast %s to %s", hl_type_str(obj->t), hl_type_str(vt));
 		break;
 	}
 	return v;
@@ -796,7 +796,7 @@ static void *hl_obj_lookup_set( vdynamic *d, int hfield, hl_type *t, hl_type **f
 	case HOBJ:
 		{
 			hl_field_lookup *f = obj_resolve_field(d->t->obj,hfield);
-			if( f == NULL || f->field_index < 0 ) hl_error_msg(USTR("%s does not have field %s"),d->t->obj->name,hl_field_name(hfield));
+			if( f == NULL || f->field_index < 0 ) hl_error("%s does not have field %s",d->t->obj->name,hl_field_name(hfield));
 			*ft = f->t;
 			return (char*)d + f->field_index;
 		}

+ 1 - 1
src/std/regexp.c

@@ -98,7 +98,7 @@ HL_PRIM int hl_regexp_matched_pos( ereg *e, int m, int *len ) {
 	if( !e->matched )
 		hl_error("Calling matchedPos() on an unmatched regexp"); 
 	if( m < 0 || m >= e->nmatches )
-		hl_error_msg(USTR("Matched index %d outside bounds"),m);
+		hl_error("Matched index %d outside bounds",m);
 	start = e->matches[m*2];
 	if( len ) *len = e->matches[m*2+1] - start;
 	return start;

+ 62 - 56
src/std/ucs2.c

@@ -109,14 +109,74 @@ int ucmp( const uchar *a, const uchar *b ) {
 	}
 }
 
-int uvsprintf( uchar *out, const uchar *fmt, va_list arglist ) {
+int usprintf( uchar *out, int out_size, const uchar *fmt, ... ) {
+	va_list args;
+	int ret;
+	va_start(args, fmt);
+	ret = uvsprintf(out, fmt, args);
+	va_end(args);
+	return ret;
+}
+
+// USE UTF-8 encoding
+int utostr( char *out, int out_size, const uchar *str ) {
+	char *start = out;
+	char *end = out + out_size - 1; // final 0
+	if( out_size <= 0 ) return 0;
+	while( out < end ) {
+		unsigned int c = *str++;
+		if( c == 0 ) break;
+		if( c < 0x80 )
+			*out++ = (char)c;
+		else if( c < 0x800 ) {
+			if( out + 2 > end ) break;
+			*out++ = (char)(0xC0|(c>>6));
+			*out++ = 0x80|(c&63);
+		} else {
+			if( out + 3 > end ) break;
+			*out++ = (char)(0xE0|(c>>12));
+			*out++ = 0x80|((c>>6)&63);
+			*out++ = 0x80|(c&63);
+		}
+	}
+	*out = 0;
+	return (int)(out - start);
+}
+
+static char *utos( const uchar *s ) {
+	int len = ustrlen_utf8(s);
+	char *out = (char*)malloc(len + 1);
+	if( utostr(out,len+1,s) < 0 )
+		*out = 0;
+	return out;
+}
+
+void uprintf( const uchar *fmt, const uchar *str ) {
+	char *cfmt = utos(fmt);
+	char *cstr = utos(str);
+#ifdef HL_ANDROID
+	LOG_ANDROID(cfmt,cstr);
+#else
+	printf(cfmt,cstr);
+#endif
+	free(cfmt);
+	free(cstr);
+}
+
+#endif
+
+#if !defined(HL_NATIVE_UCHAR_FUN) || defined(HL_WIN)
+
+HL_PRIM int uvszprintf( uchar *out, int out_size, const uchar *fmt, va_list arglist ) {
 	uchar *start = out;
+	uchar *end = out + (out_size >> 1) - 1;
 	char cfmt[20];
 	char tmp[32];
 	uchar c;
 	while(true) {
 sprintf_loop:
 		c = *fmt++;
+		if( out == end ) c = 0;
 		switch( c ) {
 		case 0:
 			*out = 0;
@@ -178,7 +238,7 @@ sprintf_loop:
 sprintf_add:
 				// copy from c string to u string
 				i = 0;
-				while( i < size )
+				while( i < size && out < end )
 					*out++ = tmp[i++];
 			}
 			break;
@@ -190,58 +250,4 @@ sprintf_add:
 	return 0;
 }
 
-int usprintf( uchar *out, int out_size, const uchar *fmt, ... ) {
-	va_list args;
-	int ret;
-	va_start(args, fmt);
-	ret = uvsprintf(out, fmt, args);
-	va_end(args);
-	return ret;
-}
-
-// USE UTF-8 encoding
-int utostr( char *out, int out_size, const uchar *str ) {
-	char *start = out;
-	char *end = out + out_size - 1; // final 0
-	if( out_size <= 0 ) return 0;
-	while( out < end ) {
-		unsigned int c = *str++;
-		if( c == 0 ) break;
-		if( c < 0x80 )
-			*out++ = (char)c;
-		else if( c < 0x800 ) {
-			if( out + 2 > end ) break;
-			*out++ = (char)(0xC0|(c>>6));
-			*out++ = 0x80|(c&63);
-		} else {
-			if( out + 3 > end ) break;
-			*out++ = (char)(0xE0|(c>>12));
-			*out++ = 0x80|((c>>6)&63);
-			*out++ = 0x80|(c&63);
-		}
-	}
-	*out = 0;
-	return (int)(out - start);
-}
-
-static char *utos( const uchar *s ) {
-	int len = ustrlen_utf8(s);
-	char *out = (char*)malloc(len + 1);
-	if( utostr(out,len+1,s) < 0 )
-		*out = 0;
-	return out;
-}
-
-void uprintf( const uchar *fmt, const uchar *str ) {
-	char *cfmt = utos(fmt);
-	char *cstr = utos(str);
-#ifdef HL_ANDROID
-	LOG_ANDROID(cfmt,cstr);
-#else
-	printf(cfmt,cstr);
-#endif
-	free(cfmt);
-	free(cstr);
-}
-
 #endif