Nicolas Cannasse пре 7 година
родитељ
комит
465a970f23

+ 0 - 38
Makefile

@@ -187,44 +187,6 @@ release_osx:
 	tar -czf hl-$(HL_VER).tgz hl-$(HL_VER)
 	rm -rf hl-$(HL_VER)
 
-OSX_LIBS=/usr/local/opt
-build_package_osx: release
-	rm -rf hl-$(HL_VER)-static
-	tar -xzf hl-$(HL_VER).tgz
-	cp $(OSX_LIBS)/libpng/lib/libpng16.16.dylib hl-$(HL_VER)
-	cp $(OSX_LIBS)/jpeg-turbo/lib/libturbojpeg.0.dylib hl-$(HL_VER)
-	cp $(OSX_LIBS)/libvorbis/lib/libvorbisfile.3.dylib hl-$(HL_VER)
-	cp $(OSX_LIBS)/libvorbis/lib/libvorbis.0.dylib hl-$(HL_VER)
-	cp $(OSX_LIBS)/libogg/lib/libogg.0.dylib hl-$(HL_VER)
-	cp $(OSX_LIBS)/openal-soft/lib/libopenal.1.dylib hl-$(HL_VER)
-	cp $(OSX_LIBS)/sdl2/lib/libSDL2*.dylib hl-$(HL_VER)
-	cp $(OSX_LIBS)/mbedtls/lib/libmbed*.dylib hl-$(HL_VER)
-	cp $(OSX_LIBS)/libuv/lib/libuv.1.dylib hl-$(HL_VER)
-	-cp ../hlsteam/steam.hdll ../hlsteam/native/lib/osx32/libsteam_api.dylib hl-$(HL_VER)
-	mv hl-$(HL_VER) hl-$(HL_VER)-static
-	tar -czf hl-$(HL_VER)-static.tgz hl-$(HL_VER)-static
-	
-# staticaly locked binaries
-LINUX_LIBS=/usr/lib/x86_64-linux-gnu
-build_package_linux: release
-	rm -rf hl-$(HL_VER)-static
-	tar -xzf hl-$(HL_VER).tgz	
-	cp $(LINUX_LIBS)/libpng16.so.16 hl-$(HL_VER)
-	cp $(LINUX_LIBS)/libturbojpeg.so.0 hl-$(HL_VER)
-	cp $(LINUX_LIBS)/libvorbisfile.so.3 hl-$(HL_VER)
-	cp $(LINUX_LIBS)/libvorbis.so.0 hl-$(HL_VER)
-	cp $(LINUX_LIBS)/libogg.so.0 hl-$(HL_VER)
-	cp $(LINUX_LIBS)/libopenal.so.1 hl-$(HL_VER)
-	cp $(LINUX_LIBS)/libSDL2*.so* hl-$(HL_VER)
-	cp $(LINUX_LIBS)/libmbed* hl-$(HL_VER)
-	cp $(LINUX_LIBS)/libuv.so.1 hl-$(HL_VER)
-	cp $(LINUX_LIBS)/libsndio.so* hl-$(HL_VER)
-	cp /lib/x86_64-linux-gnu/libbsd.so.0 hl-$(HL_VER)
-	-cp ../hlsteam/steam.hdll ../hlsteam/native/lib/linux64/libsteam_api.so hl-$(HL_VER)	
-	(cd hl-$(HL_VER) && chmod +x *.so* && find *.hdll hl *.so *.so.* | xargs -L 1 patchelf --set-rpath ./)
-	mv hl-$(HL_VER) hl-$(HL_VER)-static
-	tar -czf hl-$(HL_VER)-static.tgz hl-$(HL_VER)-static
-
 .SUFFIXES : .c .o
 
 .c.o :

+ 12 - 2
README.md

@@ -6,7 +6,7 @@
 HashLink is a virtual machine for Haxe http://hashlink.haxe.org
 
 
-# Building on Linux/OSX
+## Building on Linux/OSX
 
 HashLink is distributed with some graphics libraries allowing to develop various applications, you can manually disable the libraries you want to compile in Makefile. Here's the dependencies that you install in order to compile all the libraries:
 
@@ -24,6 +24,16 @@ And on OSX:
 
 `brew install libpng jpeg-turbo libvorbis sdl2 mbedtls openal-soft libuv`
 
-# Documentation
+## Building on Windows
+
+Open `hl.sln` using Visual Studio Code and compile.
+
+To build all of HashLink libraries it is required to download several additional distributions, read each library README file (in hashlink/libs/xxx/README.md) for additional information.
+
+## Debugging
+
+You can debug Haxe/HashLink applications by using the [Visual Studio Code Debugger](https://marketplace.visualstudio.com/items?itemName=HaxeFoundation.haxe-hl)
+
+## Documentation
 
 Read the [Documentation](https://github.com/HaxeFoundation/hashlink/wiki) on the HashLink wiki.

+ 5 - 5
include/pcre/config.h

@@ -1,7 +1,7 @@
 #define COMPILE_PCRE16
-#undef SUPPORT_JIT
+#undef SUPPORT_JIT
 #define PCRE_STATIC
-
+
 #ifdef _MSC_VER
 #	pragma warning(disable:4710) // inline disabled
 #	pragma warning(disable:4711) // inline activated
@@ -15,14 +15,14 @@
    parentheses (of any kind) in a pattern. This limits the amount of system
    stack that is used while compiling a pattern. */
 #define PARENS_NEST_LIMIT 250
-
+
 /* The value of LINK_SIZE determines the number of bytes used to store links
    as offsets within the compiled regex. The default is 2, which allows for
    compiled patterns up to 64K long. This covers the vast majority of cases.
    However, PCRE can also be compiled to use 3 or 4 bytes instead. This allows
    for longer patterns in extreme cases. */
-#define LINK_SIZE 2
-
+#define LINK_SIZE 2
+
 /* This limit is parameterized just in case anybody ever wants to change it.
    Care must be taken if it is increased, because it guards against integer
    overflow caused by enormously large patterns. */

+ 29 - 13
libs/directx/directx.cpp

@@ -1,22 +1,19 @@
 #define HL_NAME(n) directx_##n
 #include <hl.h>
 
+#ifdef HL_WIN_DESKTOP
 #include <dxgi.h>
 #include <d3dcommon.h>
 #include <d3d11.h>
 #include <D3Dcompiler.h>
+#else
+#include <xbo_directx.h>
+#endif
+#include <assert.h>
+#include "directx.h"
 
 #define DXERR(cmd)	{ HRESULT __ret = cmd; if( __ret == E_OUTOFMEMORY ) return NULL; if( __ret != S_OK ) ReportDxError(__ret,__LINE__); }
 
-typedef struct {
-	ID3D11Device *device;
-	ID3D11DeviceContext *context;
-	IDXGISwapChain *swapchain;
-	ID3D11RenderTargetView *renderTarget;
-	D3D_FEATURE_LEVEL feature;
-	int init_flags;
-} dx_driver;
-
 template <typename T> class dx_struct {
 	hl_type *t;
 public:
@@ -67,18 +64,27 @@ HL_PRIM dx_driver *HL_NAME(create)( HWND window, int format, int flags, int rest
 	desc.BufferDesc.Format = (DXGI_FORMAT)format;
 	desc.SampleDesc.Count = 1; // NO AA for now
 	desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
+#ifdef HL_WIN_DESKTOP
 	desc.BufferCount = 1;
 	desc.Windowed = true;
+#else
+	desc.BufferCount = 2;
+	desc.Windowed = false;
+#endif
 	desc.OutputWindow = window;
 	if( restrictLevel >= maxLevels ) restrictLevel = maxLevels - 1;
 	d->init_flags = flags;
 	result = D3D11CreateDeviceAndSwapChain(NULL,D3D_DRIVER_TYPE_HARDWARE,NULL,flags,levels + restrictLevel,maxLevels - restrictLevel,D3D11_SDK_VERSION,&desc,&d->swapchain,&d->device,&d->feature,&d->context);
+
+#ifdef HL_WIN_DESKTOP
 	if( result == DXGI_ERROR_SDK_COMPONENT_MISSING && (flags & D3D11_CREATE_DEVICE_DEBUG) != 0 ) {
 		// no debug driver available, retry
 		flags &= ~D3D11_CREATE_DEVICE_DEBUG;
 		d->init_flags = flags;
 		result = E_INVALIDARG;
 	}
+#endif
+
 	if( result == E_INVALIDARG ) // most likely no DX11.1 support, try again
 		result = D3D11CreateDeviceAndSwapChain(NULL,D3D_DRIVER_TYPE_HARDWARE,NULL,flags,NULL,0,D3D11_SDK_VERSION, &desc, &d->swapchain, &d->device, &d->feature, &d->context);
 
@@ -88,14 +94,23 @@ HL_PRIM dx_driver *HL_NAME(create)( HWND window, int format, int flags, int rest
 	return d;
 }
 
+HL_PRIM dx_driver *HL_NAME(get_driver)(){
+	return driver;
+}
+
 HL_PRIM dx_resource *HL_NAME(get_back_buffer)() {
 	ID3D11Texture2D *backBuffer;
 	DXERR( driver->swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBuffer) );
 	return backBuffer;
 }
 
-HL_PRIM bool HL_NAME(resize)( int width, int height, int format ) {
-	return driver->swapchain->ResizeBuffers(1,width,height,(DXGI_FORMAT)format,0) == S_OK;
+HL_PRIM bool HL_NAME(resize)(int width, int height, int format) {
+#ifdef HL_WIN_DESKTOP
+	HRESULT res = driver->swapchain->ResizeBuffers(1, width, height, (DXGI_FORMAT)format, 0); assert(res == S_OK);
+	return res == S_OK;
+#else
+	return TRUE; //Should not be called if the window is not resized (in the case here it will never happen)
+#endif
 }
 
 HL_PRIM dx_pointer *HL_NAME(create_render_target_view)( dx_resource *r, dx_struct<D3D11_RENDER_TARGET_VIEW_DESC> *desc ) {
@@ -136,7 +151,8 @@ HL_PRIM void HL_NAME(clear_color)( dx_pointer *rt, double r, double g, double b,
 }
 
 HL_PRIM void HL_NAME(present)( int interval, int flags ) {
-	driver->swapchain->Present(interval,flags);
+	HRESULT ret = driver->swapchain->Present(interval, flags);
+	if (ret != S_OK && ret != DXGI_STATUS_OCCLUDED) ReportDxError(ret, __LINE__);
 }
 
 HL_PRIM const uchar *HL_NAME(get_device_name)() {
@@ -319,7 +335,7 @@ HL_PRIM void HL_NAME(om_set_depth_stencil_state)( dx_pointer *s, int ref )  {
 }
 
 HL_PRIM void HL_NAME(clear_depth_stencil_view)( dx_pointer *view, vdynamic *depth, vdynamic *stencil ) {
-	driver->context->ClearDepthStencilView((ID3D11DepthStencilView*)view, (depth?D3D11_CLEAR_DEPTH:0) | (stencil?D3D11_CLEAR_STENCIL:0), depth ? (FLOAT)depth->v.d : 0.f, stencil ? stencil->v.i : 0);
+	driver->context->ClearDepthStencilView((ID3D11DepthStencilView*)view, (depth?D3D11_CLEAR_DEPTH:0) | (stencil?D3D11_CLEAR_STENCIL:0), depth ? (FLOAT)depth->v.d : 0.f, stencil ? (UINT8)stencil->v.i : 0);
 }
 
 HL_PRIM void HL_NAME(om_set_blend_state)( dx_pointer *state, vbyte *factors, int sampleMask ) {

+ 16 - 0
libs/directx/directx.h

@@ -0,0 +1,16 @@
+#pragma once
+#ifndef DIRECTX_H
+#define DIRECTX_H
+
+typedef struct dx_driver_ {
+    ID3D11Device *device;
+    ID3D11DeviceContext *context;
+    IDXGISwapChain *swapchain;
+    ID3D11RenderTargetView *renderTarget;
+    D3D_FEATURE_LEVEL feature;
+    int init_flags;
+} dx_driver;
+
+HL_PRIM dx_driver *directx_get_driver();
+
+#endif

+ 2 - 2
libs/fmt/CMakeLists.txt

@@ -1,7 +1,7 @@
 if(WIN32)
     set(ZLIB_INCLUDE_DIRS ${INCLUDES_BASE_DIR}/zlib)
     set(PNG_INCLUDE_DIRS ${INCLUDES_BASE_DIR}/png)
-    set(OGGVORBIS_INCLUDE_DIR ${INCLUDES_BASE_DIR}/vorbis)
+    set(VORBIS_INCLUDE_DIR ${INCLUDES_BASE_DIR}/vorbis)
 
     if(CMAKE_SIZEOF_VOID_P EQUAL 8)
         set(TurboJPEG_INCLUDE_DIRS ${INCLUDES_BASE_DIR}/turbojpeg ${INCLUDES_BASE_DIR}/turbojpeg/x64)
@@ -133,7 +133,7 @@ target_include_directories(fmt.hdll
     ${ZLIB_INCLUDE_DIRS}
     ${PNG_INCLUDE_DIRS}
     ${TurboJPEG_INCLUDE_DIRS}
-    ${OGGVORBIS_INCLUDE_DIR}
+    ${VORBIS_INCLUDE_DIR}
 )
 
 target_link_libraries(fmt.hdll

+ 2 - 2
libs/fmt/fmt.c

@@ -2,7 +2,7 @@
 #include <png.h>
 #include <hl.h>
 
-#ifdef HL_CONSOLE
+#if defined(HL_CONSOLE) && !defined(HL_XBO)
 extern bool sys_jpg_decode( vbyte *data, int dataLen, vbyte *out, int width, int height, int stride, int format, int flags );
 #else
 #	include <turbojpeg.h>
@@ -18,7 +18,7 @@ typedef struct {
 } pixel;
 
 HL_PRIM bool HL_NAME(jpg_decode)( vbyte *data, int dataLen, vbyte *out, int width, int height, int stride, int format, int flags ) {
-#ifdef HL_CONSOLE
+#if defined(HL_CONSOLE) && !defined(HL_XBO)
 	return sys_jpg_decode(data, dataLen, out, width, height, stride, format, flags);
 #else
 	tjhandle h = tjInitDecompress();

+ 8 - 2
libs/mesa/haxe/System.hx

@@ -36,10 +36,16 @@ class System {
 			throw "Failed to init GL API";
 		return true;
 	}
-	
+
+	public static dynamic function reportError(e:Dynamic) {
+		var stack = haxe.CallStack.toString(haxe.CallStack.exceptionStack());
+		var err = try Std.string(e) catch( _ : Dynamic ) "????";
+		Sys.println(err + stack);
+	}
+
 	@:extern public static inline function beginFrame() {
 	}
-	
+
 	public static function emitEvents(_) {
 		return true;
 	}

+ 1 - 1
libs/sdl/gl.c

@@ -629,7 +629,7 @@ HL_PRIM void HL_NAME(gl_draw_elements_instanced)( int mode, int count, int type,
 	glDrawElementsInstanced(mode,count,type,(void*)(int_val)start,primcount);
 }
 
-HL_PRIM void HL_NAME(gl_draw_arrays_instanced)( int mode, int first, int count, int start, int primcount ) {
+HL_PRIM void HL_NAME(gl_draw_arrays_instanced)( int mode, int first, int count, int primcount ) {
 	GLOG("%d,%d,%d,%d",mode,first,count,primcount);
 	glDrawArraysInstanced(mode,first,count,primcount);
 }

+ 19 - 7
libs/sdl/sdl/GL.hx

@@ -593,8 +593,14 @@ class GL {
 	public static inline var LUMINANCE                      = 0x1909;
 	public static inline var LUMINANCE_ALPHA                = 0x190A;
 
-	public static inline var BGRA							= 0x80E1;
-	public static inline var RGBA8							= 0x8058;
+	public static inline var BGRA                           = 0x80E1;
+	public static inline var RGBA8                          = 0x8058;
+	public static inline var RGB10_A2                       = 0x8059;
+
+	public static inline var RG16                           = 0x822C;
+	public static inline var RG16UI                         = 0x823A;
+	public static inline var RG16F                          = 0x822F;
+	public static inline var RG32F                          = 0x8230;
 
 	/* PixelType */
 	/*      UNSIGNED_BYTE */
@@ -602,11 +608,11 @@ class GL {
 	public static inline var UNSIGNED_SHORT_5_5_5_1         = 0x8034;
 	public static inline var UNSIGNED_SHORT_5_6_5           = 0x8363;
 
-	public static inline var SRGB							= 0x8C40;
-	public static inline var SRGB8							= 0x8C41;
-	public static inline var SRGB_ALPHA						= 0x8C42;
-	public static inline var SRGB8_ALPHA					= 0x8C43;
-	public static inline var FRAMEBUFFER_SRGB				= 0x8DB9;
+	public static inline var SRGB                           = 0x8C40;
+	public static inline var SRGB8                          = 0x8C41;
+	public static inline var SRGB_ALPHA                     = 0x8C42;
+	public static inline var SRGB8_ALPHA                    = 0x8C43;
+	public static inline var FRAMEBUFFER_SRGB               = 0x8DB9;
 
 	public static inline var RGBA32F                        = 0x8814;
 	public static inline var RGB32F                         = 0x8815;
@@ -678,8 +684,14 @@ class GL {
 	/* TextureParameterName */
 	public static inline var TEXTURE_MAG_FILTER             = 0x2800;
 	public static inline var TEXTURE_MIN_FILTER             = 0x2801;
+	public static inline var TEXTURE_WRAP_R                 = 0x8072;
 	public static inline var TEXTURE_WRAP_S                 = 0x2802;
 	public static inline var TEXTURE_WRAP_T                 = 0x2803;
+	public static inline var TEXTURE_LOD_BIAS               = 0x8501;
+	public static inline var TEXTURE_MAX_ANISOTROPY         = 0x84FE;
+	public static inline var TEXTURE_COMPARE_MODE           = 0x884C;
+	public static inline var TEXTURE_COMPARE_FUNC           = 0x884D;
+	public static inline var COMPARE_REF_TO_TEXTURE         = 0x884E;
 
 	/* TextureTarget */
 	public static inline var TEXTURE_2D                     = 0x0DE1;

+ 5 - 0
libs/sdl/sdl/Sdl.hx

@@ -38,6 +38,11 @@ class Sdl {
 		Sys.exit( -1);
 	}
 
+	public static inline var DOUBLE_BUFFER            = 1 << 0;
+	public static inline var GL_CORE_PROFILE          = 1 << 1;
+	public static inline var GL_COMPATIBILITY_PROFILE = 1 << 2;
+	public static inline var GL_ES                    = 1 << 3;
+
 	static function glOptions( major : Int, minor : Int, depth : Int, stencil : Int, flags : Int, samples : Int ) {}
 
 	static function initOnce() return false;

+ 2 - 0
libs/ui/ui_stub.c

@@ -1,6 +1,8 @@
 #define HL_NAME(n) ui_##n
 #include <hl.h>
+#ifndef HL_WIN
 #include <unistd.h>
+#endif
 
 #define wref void
 #define vsentinel void

+ 2 - 1
other/cmake/FindOggVorbis.cmake

@@ -3,7 +3,8 @@
 #
 #  OGGVORBIS_FOUND - system has OggVorbis
 #  OGGVORBIS_VERSION - set either to 1 or 2
-#  OGGVORBIS_INCLUDE_DIR - the OggVorbis include directory
+#  VORBIS_INCLUDE_DIR - the vorbisfile.h include directory
+#  OGG_INCLUDE_DIR - the ogg.h include directory
 #  OGGVORBIS_LIBRARIES - The libraries needed to use OggVorbis
 #  OGG_LIBRARY         - The Ogg library
 #  VORBIS_LIBRARY      - The Vorbis library

+ 3 - 0
other/memory/memory.hxml

@@ -0,0 +1,3 @@
+-lib format
+-main Memory
+-hl memory.hl

+ 30 - 3
src/alloc.c

@@ -69,7 +69,18 @@ static inline unsigned int TRAILING_ZEROES( unsigned int x ) {
 // we should instead have some special handling for them
 // in x86-64 user space grows up to 0x8000-00000000 (16 bits base + 31 bits page id)
 
+#ifdef HL_WIN
 #	define gc_hash(ptr)			((int_val)(ptr)&0x0000000FFFFFFFFF)
+#else
+// Linux gives addresses using the following patterns (X=any,Y=small value - can be 0): 
+//		0x0000000YXXX0000
+//		0x0007FY0YXXX0000
+static int_val gc_hash( void *ptr ) {
+	int_val v = (int_val)ptr;
+	return (v ^ ((v >> 33) << 28)) & 0x0000000FFFFFFFFF;
+}
+#endif
+
 #endif
 
 #define GC_MASK_BITS		16
@@ -82,6 +93,7 @@ static inline unsigned int TRAILING_ZEROES( unsigned int x ) {
 
 #ifdef HL_DEBUG
 #	define GC_DEBUG
+#	define GC_MEMCHK
 #endif
 
 #define out_of_memory(reason)		hl_fatal("Out of Memory (" reason ")")
@@ -678,6 +690,9 @@ void *hl_gc_alloc_gen( hl_type *t, int size, int flags ) {
 	int allocated = 0;
 	gc_global_lock(true);
 	gc_check_mark();
+#	ifdef GC_MEMCHK
+	size += HL_WSIZE;
+#	endif
 	if( gc_flags & GC_PROFILE ) time = TIMESTAMP();
 	ptr = gc_alloc_gen(size, flags, &allocated);
 	if( gc_flags & GC_PROFILE ) gc_stats.alloc_time += TIMESTAMP() - time;
@@ -691,6 +706,9 @@ void *hl_gc_alloc_gen( hl_type *t, int size, int flags ) {
 	gc_global_lock(false);
 	if( (gc_flags & GC_TRACK) && gc_track_callback )
 		((void (*)(hl_type *,int,int,void*))gc_track_callback)(t,size,flags,ptr);
+#	ifdef GC_MEMCHK
+	memset((char*)ptr+(allocated - HL_WSIZE),0xEE,HL_WSIZE);
+#	endif
 	return ptr;
 }
 
@@ -812,10 +830,19 @@ static void gc_clear_unmarked_mem() {
 			int bid;
 			for(bid=p->first_block;bid<p->max_blocks;bid++) {
 				if( p->sizes && !p->sizes[bid] ) continue;
+				int size = p->sizes ? p->sizes[bid] * p->block_size : p->block_size;
+				unsigned char *ptr = (unsigned char*)p + bid * p->block_size;
+				if( bid * p->block_size + size > p->page_size ) hl_fatal("invalid block size");
+#				ifdef GC_MEMCHK
+				int_val eob = *(int_val*)(ptr + size - HL_WSIZE);
+#				ifdef HL_64
+				if( eob != 0xEEEEEEEEEEEEEEEE && eob != 0xDDDDDDDDDDDDDDDD )
+#				else
+				if( eob != 0xEEEEEEEE && eob != 0xDDDDDDDD )
+#				endif
+					hl_fatal("Block written out of bounds");
+#				endif
 				if( (p->bmp[bid>>3] & (1<<(bid&7))) == 0 ) {
-					int size = p->sizes ? p->sizes[bid] * p->block_size : p->block_size;
-					unsigned char *ptr = (unsigned char*)p + bid * p->block_size;
-					if( bid * p->block_size + size > p->page_size ) hl_fatal("invalid block size");
 					memset(ptr,0xDD,size);
 					if( p->sizes ) p->sizes[bid] = 0;
 				}

+ 13 - 1
src/code.c

@@ -434,7 +434,7 @@ hl_code *hl_code_read( const unsigned char *data, int size ) {
 		EXIT("Invalid header");
 	r->code = c;
 	c->version = READ();
-	if( c->version <= 1 || c->version > 3 ) {
+	if( c->version <= 1 || c->version > 4 ) {
 		printf("VER=%d\n",c->version);
 		EXIT("Unsupported bytecode version");
 	}
@@ -446,6 +446,7 @@ hl_code *hl_code_read( const unsigned char *data, int size ) {
 	c->nglobals = UINDEX();
 	c->nnatives = UINDEX();
 	c->nfunctions = UINDEX();
+	c->nconstants = c->version >= 4 ? UINDEX() : 0;
 	c->entrypoint = UINDEX();	
 	c->hasdebug = flags & 1;
 	CHK_ERROR();
@@ -501,6 +502,17 @@ hl_code *hl_code_read( const unsigned char *data, int size ) {
 		}
 	}
 	CHK_ERROR();
+	ALLOC(c->constants, hl_constant, c->nconstants);
+	for (i = 0; i < c->nconstants; i++) {
+		int j;
+		hl_constant *k = c->constants + i;
+		k->global = UINDEX();
+		k->nfields = UINDEX();
+		ALLOC(k->fields, int, k->nfields);
+		for (j = 0; j < k->nfields; j++)
+			k->fields[j] = UINDEX();
+		CHK_ERROR();
+	}
 	return c;
 }
 

+ 24 - 5
src/hl.h

@@ -29,8 +29,11 @@
 
 #define HL_VERSION	0x150
 
-#ifdef _WIN32
+#if defined(_WIN32)
 #	define HL_WIN
+#	ifndef _DURANGO
+#		define HL_WIN_DESKTOP
+#	endif
 #endif
 
 #if defined(__APPLE__) || defined(__MACH__) || defined(macintosh)
@@ -65,7 +68,11 @@
 #	define HL_NX
 #endif
 
-#if defined(HL_PS) || defined(HL_NX)
+#ifdef _DURANGO
+#	define HL_XBO
+#endif
+
+#if defined(HL_PS) || defined(HL_NX) || defined(HL_XBO)
 #	define HL_CONSOLE
 #endif
 
@@ -194,7 +201,11 @@ typedef unsigned long long uint64;
 // -------------- UNICODE -----------------------------------
 
 #if defined(HL_WIN) && !defined(HL_LLVM)
-#	include <windows.h>
+#ifdef HL_WIN_DESKTOP
+#	include <Windows.h>
+#else
+#	include <xdk.h>
+#endif
 #	include <wchar.h>
 typedef wchar_t	uchar;
 #	define USTR(str)	L##str
@@ -243,8 +254,12 @@ C_FUNCTION_END
 
 #if defined(HL_VCC)
 #	define hl_debug_break()	if( IsDebuggerPresent() ) __debugbreak()
-#elif defined(HL_PS)
+#elif defined(HL_PS) && defined(_DEBUG)
 #	define hl_debug_break()	__debugbreak()
+#elif defined(HL_NX)
+C_FUNCTION_BEGIN
+HL_API void hl_debug_break( void );
+C_FUNCTION_END
 #elif defined(HL_LINUX) && defined(__i386__)
 #	ifdef HL_64
 #	define hl_debug_break() \
@@ -737,7 +752,11 @@ typedef struct {
 #		define DEFINE_PRIM_WITH_NAME(t,name,args,realName)
 #	endif
 #elif defined(LIBHL_STATIC)
-#define	HL_PRIM
+#	ifdef __cplusplus
+#		define	HL_PRIM				extern "C" 
+#	else
+#		define	HL_PRIM				
+#	endif
 #define DEFINE_PRIM_WITH_NAME(t,name,args,realName)
 #else
 #	ifdef __cplusplus

+ 13 - 9
src/hlc.h

@@ -44,17 +44,21 @@
 #undef STRICT
 
 // disable some warnings triggered by HLC code generator
-
+
 #ifdef HL_VCC
-#	pragma warning(disable:4702) // unreachable code
-#	pragma warning(disable:4100) // unreferenced param
-#	pragma warning(disable:4101) // unreferenced local var
-#	pragma warning(disable:4102) // unreferenced label
-#	pragma warning(disable:4700) // uninitialized local variable used
+#	pragma warning(disable:4100) // unreferenced param
+#	pragma warning(disable:4101) // unreferenced local var
+#	pragma warning(disable:4102) // unreferenced label
+#	pragma warning(disable:4204) // nonstandard extension
+#	pragma warning(disable:4221) // nonstandard extension
+#	pragma warning(disable:4244) // possible loss of data
+#	pragma warning(disable:4700) // uninitialized local variable used
+#	pragma warning(disable:4701) // potentially uninitialized local variable
+#	pragma warning(disable:4702) // unreachable code
 #	pragma warning(disable:4703) // potentially uninitialized local
-#	pragma warning(disable:4723) // potential divide by 0
-#	pragma warning(disable:4715) // control paths must return a value
-#	pragma warning(disable:4716) // must return a value (ends with throw)
+#	pragma warning(disable:4715) // control paths must return a value
+#	pragma warning(disable:4716) // must return a value (ends with throw)
+#	pragma warning(disable:4723) // potential divide by 0
 #else
 #	pragma GCC diagnostic ignored "-Wunused-variable"
 #	pragma GCC diagnostic ignored "-Wunused-function"

+ 11 - 5
src/hlc_main.c

@@ -25,10 +25,12 @@
 #   include <SDL_main.h>
 #endif
 
-#ifdef _WIN32
+#ifdef HL_WIN_DESKTOP
+#	define CONST
 #	pragma warning(disable:4091)
 #	include <DbgHelp.h>
 #	pragma comment(lib, "Dbghelp.lib")
+#	undef CONST
 #endif
 
 #ifdef HL_CONSOLE
@@ -45,7 +47,7 @@ extern void sys_global_exit();
 #endif
 
 static uchar *hlc_resolve_symbol( void *addr, uchar *out, int *outSize ) {
-#ifdef _WIN32
+#ifdef HL_WIN_DESKTOP
 	static HANDLE stack_process_handle = NULL;
 	DWORD64 index;
 	IMAGEHLP_LINEW64 line;
@@ -75,25 +77,29 @@ static uchar *hlc_resolve_symbol( void *addr, uchar *out, int *outSize ) {
 
 static int hlc_capture_stack( void **stack, int size ) {
 	int count = 0;
-#	ifdef _WIN32
+#	ifdef HL_WIN_DESKTOP
 	count = CaptureStackBackTrace(2, size, stack, NULL) - 8; // 8 startup
 	if( count < 0 ) count = 0;
 #	endif
 	return count;
 }
 
-#ifdef HL_VCC
+#if defined( HL_VCC )
 static int throw_handler( int code ) {
+	#if !defined(HL_XBO)
 	switch( code ) {
 	case EXCEPTION_ACCESS_VIOLATION: hl_error("Access violation");
 	case EXCEPTION_STACK_OVERFLOW: hl_error("Stack overflow");
 	default: hl_error("Unknown runtime error");
 	}
 	return EXCEPTION_CONTINUE_SEARCH;
+	#else
+	return 0;
+	#endif
 }
 #endif
 
-#ifdef HL_WIN
+#ifdef HL_WIN_DESKTOP
 int wmain(int argc, uchar *argv[]) {
 #else
 int main(int argc, char *argv[]) {

+ 8 - 0
src/hlmodule.h

@@ -50,6 +50,12 @@ typedef struct {
 	const uchar *field;
 } hl_function;
 
+typedef struct {
+	int global;
+	int nfields;
+	int *fields;
+} hl_constant;
+
 typedef struct {
 	int version;
 	int nints;
@@ -59,6 +65,7 @@ typedef struct {
 	int nglobals;
 	int nnatives;
 	int nfunctions;
+	int nconstants;
 	int entrypoint;
 	int ndebugfiles;
 	bool hasdebug;
@@ -73,6 +80,7 @@ typedef struct {
 	hl_type**	globals;
 	hl_native*	natives;
 	hl_function*functions;
+	hl_constant*constants;
 	hl_alloc	alloc;
 	hl_alloc	falloc;
 } hl_code;

+ 1 - 1
src/main.c

@@ -135,7 +135,7 @@ int main(int argc, pchar *argv[]) {
 		file = PSTR("hlboot.dat");
 		fchk = pfopen(file,"rb");
 		if( fchk == NULL ) {
-			printf("HL/JIT %d.%d.%d (c)2015-2017 Haxe Foundation\n  Usage : hl [--debug <port>] <file>\n",HL_VERSION>>8,(HL_VERSION>>4)&15,HL_VERSION&15);
+			printf("HL/JIT %d.%d.%d (c)2015-2018 Haxe Foundation\n  Usage : hl [--debug <port>] [--debug-wait] <file>\n",HL_VERSION>>8,(HL_VERSION>>4)&15,HL_VERSION&15);
 			return 1;
 		}
 		fclose(fchk);

+ 61 - 0
src/module.c

@@ -216,10 +216,26 @@ static void append_type( char **p, hl_type *t ) {
 	}
 }
 
+#define DISABLED_LIB_PTR ((void*)(int_val)2)
+
 static void *resolve_library( const char *lib ) {
 	char tmp[256];	
 	void *h;
 
+#	ifndef HL_CONSOLE
+	static char *DISABLED_LIBS = NULL;
+	if( !DISABLED_LIBS ) {
+		DISABLED_LIBS = getenv("HL_DISABLED_LIBS");
+		if( !DISABLED_LIBS ) DISABLED_LIBS = "";
+	}
+	char *disPart = strstr(DISABLED_LIBS, lib);
+	if( disPart ) {
+		disPart += strlen(lib);
+		if( *disPart == 0 || *disPart == ',' )
+			return DISABLED_LIB_PTR;
+	}
+#	endif
+
 	if( strcmp(lib,"builtin") == 0 )
 		return dlopen(NULL,RTLD_LAZY);
 
@@ -253,6 +269,10 @@ static void *resolve_library( const char *lib ) {
 	return h;
 }
 
+static void disabled_primitive() {
+	hl_error("This library primitive has been disabled");
+}
+
 int hl_module_init( hl_module *m ) {
 	int i;
 	jit_ctx *ctx;
@@ -276,6 +296,11 @@ int hl_module_init( hl_module *m ) {
 				curlib = n->lib;
 				libHandler = resolve_library(n->lib);
 			}
+			if( libHandler == DISABLED_LIB_PTR ) {
+				m->functions_ptrs[n->findex] = disabled_primitive;
+				continue;
+			}
+
 			strcpy(p,"hlp_");
 			p += 4;
 			strcpy(p,n->name);
@@ -366,6 +391,42 @@ int hl_module_init( hl_module *m ) {
 		hl_function *f = m->code->functions + i;
 		m->functions_ptrs[f->findex] = ((unsigned char*)m->jit_code) + ((int_val)m->functions_ptrs[f->findex]);
 	}
+	// INIT constants
+	for (i = 0; i<m->code->nconstants; i++) {
+		int j;
+		hl_constant *c = m->code->constants + i;
+		hl_type *t = m->code->globals[c->global];
+		hl_runtime_obj *rt;
+		vdynamic **global = (vdynamic**)(m->globals_data + m->globals_indexes[c->global]);
+		vdynamic *v = NULL;
+		switch (t->kind) {
+		case HOBJ:
+			rt = hl_get_obj_rt(t);
+			v = (vdynamic*)malloc(rt->size);
+			v->t = t;
+			for (j = 0; j<c->nfields; j++) {
+				int idx = c->fields[j];
+				hl_type *ft = t->obj->fields[j].t;
+				void *addr = (char*)v + rt->fields_indexes[j];
+				switch (ft->kind) {
+				case HI32:
+					*(int*)addr = m->code->ints[idx];
+					break;
+				case HBYTES:
+					*(const void**)addr = hl_get_ustring(m->code, idx);
+					break;
+				default:
+					hl_fatal("assert");
+				}
+			}
+			break;
+		default:
+			hl_fatal("assert");
+		}
+		*global = v;
+		hl_remove_root(global);
+	}
+	// DONE
 	cur_module = m;
 	hl_setup_exception(module_resolve_symbol, module_capture_stack);
 	hl_gc_set_dump_types(hl_module_types_dump);

+ 6 - 0
src/std/debug.c

@@ -117,6 +117,12 @@ HL_API int hl_debug_wait( int pid, int *thread, int timeout ) {
 		case EXCEPTION_SINGLE_STEP:
 		case 0x4000001E: // STATUS_WX86_SINGLE_STEP
 			return 2;
+		case 0x406D1388: // MS_VC_EXCEPTION (see SetThreadName)
+			ContinueDebugEvent(e.dwProcessId, e.dwThreadId, DBG_CONTINUE);
+			break;
+		case 0xE06D7363: // C++ EH EXCEPTION
+			ContinueDebugEvent(e.dwProcessId, e.dwThreadId, DBG_EXCEPTION_NOT_HANDLED);
+			break;
 		default:
 			return 3;
 		}

+ 10 - 6
src/std/error.c

@@ -23,17 +23,22 @@
 #include <stdarg.h>
 #include <string.h>
 
+#ifdef HL_CONSOLE
+#include <posix/posix.h>
+#endif
+
 HL_PRIM hl_trap_ctx *hl_current_trap = NULL;
 HL_PRIM vdynamic *hl_current_exc = NULL;
 HL_PRIM vdynamic **hl_debug_exc = NULL;
-
+HL_PRIM bool hl_debug_catch_all = false;
+static hl_trap_ctx *hl_trap_root = NULL;
 static void *stack_trace[0x1000];
 static int stack_count = 0;
 static bool exc_rethrow = false;
 
 HL_PRIM void *hl_fatal_error( const char *msg, const char *file, int line ) {
 	hl_blocking(true);
-#	ifdef _WIN32
+#	ifdef HL_WIN_DESKTOP
     HWND consoleWnd = GetConsoleWindow();
     DWORD pid;
     GetWindowThreadProcessId(consoleWnd, &pid);
@@ -73,13 +78,13 @@ HL_PRIM void hl_setup_exception( void *resolve_symbol, void *capture_stack ) {
 }
 
 HL_PRIM void hl_set_error_handler( vclosure *d ) {
+	hl_trap_root = hl_current_trap;
 	if( d == hl_error_handler )
 		return;
 	hl_error_handler = d;
+	hl_remove_root(&hl_error_handler);
 	if( d )
 		hl_add_root(&hl_error_handler);
-	else
-		hl_remove_root(&hl_error_handler);
 }
 
 HL_PRIM void hl_throw( vdynamic *v ) {
@@ -90,7 +95,7 @@ HL_PRIM void hl_throw( vdynamic *v ) {
 		stack_count = capture_stack_func(stack_trace, 0x1000);
 	hl_current_exc = v;
 	hl_current_trap = t->prev;
-	if( hl_current_trap == NULL ) {
+	if( t == hl_trap_root || hl_current_trap == NULL || hl_debug_catch_all ) {
 		hl_debug_exc = &v;
 		hl_debug_break();
 		hl_debug_exc = NULL;
@@ -118,7 +123,6 @@ HL_PRIM void hl_dump_stack() {
 	}
 }
 
-
 HL_PRIM varray *hl_exception_stack() {
 	varray *a = hl_alloc_array(&hlt_bytes, stack_count);
 	int i;

+ 4 - 0
src/std/file.c

@@ -25,7 +25,11 @@
 #	include <posix/posix.h>
 #endif
 #ifdef HL_WIN
+#ifdef HL_WIN_DESKTOP
 #	include <windows.h>
+#else
+#	include<xdk.h>
+#endif
 #	define fopen(name,mode) _wfopen(name,mode)
 #	define HL_UFOPEN
 #endif

+ 2 - 0
src/std/maps.h

@@ -72,6 +72,8 @@ static void _MNAME(resize)( t_map *m ) {
 	// save
 	t_map old = *m;
 
+	if( m->nentries != m->maxentries ) hl_error("assert");
+
 	// resize
 	int i = 0;
 	int nentries = m->maxentries ? ((m->maxentries * 3) + 1) >> 1 : H_SIZE_INIT;

+ 5 - 1
src/std/math.c

@@ -36,7 +36,11 @@ HL_PRIM double hl_math_abs( double a ) {
 }
 
 HL_PRIM bool hl_math_isnan( double a ) {
-	return a != a;
+#ifdef HL_WIN
+	return isnan(a);
+#else
+	return a != a; //does not work on some platforms
+#endif
 }
 
 typedef union {

+ 17 - 7
src/std/obj.c

@@ -552,10 +552,6 @@ static void hl_dynobj_delete_field( vdynobj *o, hl_field_lookup *f ) {
 		// no erase needed, compaction will be performed on next add
 	}
 
-	int field = (int)(f - o->lookup);
-	memmove(o->lookup + field, o->lookup + field + 1, (o->nfields - (field + 1)) * sizeof(hl_field_lookup));
-	o->nfields--;
-
 	// remove from virtuals
 	vvirtual *v = o->virtuals;
 	while( v ) {
@@ -563,6 +559,11 @@ static void hl_dynobj_delete_field( vdynobj *o, hl_field_lookup *f ) {
 		if( vf ) hl_vfields(v)[vf->field_index] = NULL;
 		v = v->next;
 	}
+
+	// remove from lookup
+	int field = (int)(f - o->lookup);
+	memmove(o->lookup + field, o->lookup + field + 1, (o->nfields - (field + 1)) * sizeof(hl_field_lookup));
+	o->nfields--;
 }
 
 static hl_field_lookup *hl_dynobj_add_field( vdynobj *o, int hfield, hl_type *t ) {
@@ -702,7 +703,10 @@ static vdynamic *hl_obj_lookup_extra( vdynamic *d, int hfield ) {
 HL_PRIM int hl_dyn_geti( vdynamic *d, int hfield, hl_type *t ) {
 	hl_type *ft;
 	void *addr = hl_obj_lookup(d,hfield,&ft);
-	if( !addr ) return 0;
+	if( !addr ) {
+		d = hl_obj_lookup_extra(d,hfield);
+		return d == NULL ? 0 : hl_dyn_casti(&d,&hlt_dyn,t);
+	}
 	switch( ft->kind ) {
 	case HUI8:
 		return *(unsigned char*)addr;
@@ -724,14 +728,20 @@ HL_PRIM int hl_dyn_geti( vdynamic *d, int hfield, hl_type *t ) {
 HL_PRIM float hl_dyn_getf( vdynamic *d, int hfield ) {
 	hl_type *ft;
 	void *addr = hl_obj_lookup(d,hfield,&ft);
-	if( !addr ) return 0.;
+	if( !addr ) {
+		d = hl_obj_lookup_extra(d,hfield);
+		return d == NULL ? 0.f : hl_dyn_castf(&d,&hlt_dyn);
+	}
 	return ft->kind == HF32 ? *(float*)addr : hl_dyn_castf(addr,ft);
 }
 
 HL_PRIM double hl_dyn_getd( vdynamic *d, int hfield ) {
 	hl_type *ft;
 	void *addr = hl_obj_lookup(d,hfield,&ft);
-	if( !addr ) return 0.;
+	if( !addr ) {
+		d = hl_obj_lookup_extra(d,hfield);
+		return d == NULL ? 0. : hl_dyn_castd(&d,&hlt_dyn);
+	}
 	return ft->kind == HF64 ? *(double*)addr : hl_dyn_castd(addr,ft);
 }
 

+ 1 - 1
src/std/random.c

@@ -22,7 +22,7 @@
 #include <hl.h>
 #include <time.h>
 #include <string.h>
-#if defined(HL_WIN)
+#if defined(HL_WIN_DESKTOP)
 #	include <windows.h>
 #	include <process.h>
 #elif defined(HL_CONSOLE)

+ 1 - 1
src/std/regexp.c

@@ -47,7 +47,7 @@ HL_PRIM ereg *hl_regexp_new_options( vbyte *str, vbyte *opts ) {
 	int errorcode;
 	pcre16 *p;
 	uchar *o = (uchar*)opts;
-	int options = 0;
+	int options = PCRE_JAVASCRIPT_COMPAT;
 	while( *o ) {
 		switch( *o++ ) {
 		case 'i':

+ 15 - 0
src/std/string.c

@@ -38,6 +38,21 @@ HL_PRIM vbyte *hl_ftos( double d, int *len ) {
 	// don't use the last digit (eg 5.1 = 5.09999..996)
 	// also cut one more digit for some numbers (eg 86.57 and 85.18) <- to fix since we lose one PI digit
 	k = (int)usprintf(tmp,24,USTR("%.15g"),d);
+#	if defined(HL_WIN) && _MSC_VER <= 1800
+	// fix for window : 1e-5 is printed as 1e-005 whereas it's 1e-05 on other platforms
+	// note : this is VS2013 std bug, VS2015 works correctly
+	{
+		int i;
+		for(i=0;i<k;i++)
+			if( tmp[i] == 'e' ) {
+				if( tmp[i+1] == '+' || tmp[i+1] == '-' ) i++;
+				if( tmp[i+1] != '0' || tmp[i+2] != '0' ) break;
+				memmove(tmp+i+1,tmp+i+2,(k-(i+1))*2);
+				k--;
+				break;
+			}
+	}
+#	endif
 	*len = k;
 	return hl_copy_bytes((vbyte*)tmp,(k + 1) << 1);
 }

+ 13 - 9
src/std/sys.c

@@ -23,8 +23,8 @@
 
 #ifdef HL_CONSOLE
 #	include <posix/posix.h>
-#else
-
+#endif
+#if !defined(HL_CONSOLE) || defined(HL_WIN)
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
@@ -101,7 +101,9 @@ HL_PRIM bool hl_sys_utf8_path() {
 }
 
 HL_PRIM vbyte *hl_sys_string() {
-#if defined(HL_WIN) || defined(HL_CYGWIN) || defined(HL_MINGW)
+#if defined(HL_CONSOLE)
+	return (vbyte*)sys_platform_name();
+#elif defined(HL_WIN) || defined(HL_CYGWIN) || defined(HL_MINGW)
 	return (vbyte*)USTR("Windows");
 #elif defined(HL_GNUKBSD)
 	return (vbyte*)USTR("GNU/kFreeBSD");
@@ -111,8 +113,6 @@ HL_PRIM vbyte *hl_sys_string() {
 	return (vbyte*)USTR("BSD");
 #elif defined(HL_MAC)
 	return (vbyte*)USTR("Mac");
-#elif defined(HL_CONSOLE)
-	return (vbyte*)sys_platform_name();
 #elif defined(HL_IOS)
 	return (vbyte*)USTR("iOS");
 #elif defined(HL_TVOS)
@@ -125,7 +125,7 @@ HL_PRIM vbyte *hl_sys_string() {
 }
 
 HL_PRIM vbyte *hl_sys_locale() {
-#ifdef HL_WIN
+#ifdef HL_WIN_DESKTOP
 	wchar_t loc[LOCALE_NAME_MAX_LENGTH];
 	int len = GetSystemDefaultLocaleName(loc,LOCALE_NAME_MAX_LENGTH);
 	return len == 0 ? NULL : hl_copy_bytes((vbyte*)loc,(len+1)*2);
@@ -136,7 +136,11 @@ HL_PRIM vbyte *hl_sys_locale() {
 
 HL_PRIM void hl_sys_print( vbyte *msg ) {
 	hl_blocking(true);
+#	ifdef HL_XBO
+	OutputDebugStringW((LPCWSTR)msg);
+#	else
 	uprintf(USTR("%s"),(uchar*)msg);
+#	endif
 	hl_blocking(false);
 }
 
@@ -183,7 +187,7 @@ HL_PRIM bool hl_sys_put_env( vbyte *e, vbyte *v ) {
 #	define environ (*_NSGetEnviron())
 #endif
 
-#ifdef HL_WIN
+#ifdef HL_WIN_DESKTOP
 #	undef environ
 #	define environ _wenviron
 #else
@@ -529,7 +533,7 @@ HL_PRIM vbyte *hl_sys_exe_path() {
 		return NULL;
 	return (vbyte*)pstrdup(path,-1);
 #elif defined(HL_CONSOLE)
-	return (vbyte*)sys_exe_path();
+	return sys_exe_path();
 #else
 	const pchar *p = getenv("_");
 	if( p != NULL )
@@ -546,7 +550,7 @@ HL_PRIM vbyte *hl_sys_exe_path() {
 }
 
 HL_PRIM int hl_sys_get_char( bool b ) {
-#	if defined(HL_WIN)
+#	if defined(HL_WIN_DESKTOP)
 	return b?getche():getch();
 #	elif defined(HL_CONSOLE)
 	return -1;