Browse Source

Major low level change to bbArray - is now a c++ 'value' (but still a mx2 reference type) so ctor with bbArray blah{10} etc...

Mark Sibly 9 years ago
parent
commit
ef9a1ef3f9

+ 1 - 1
modules/monkey/native/bbarray.cpp

@@ -1,4 +1,4 @@
 
 
 #include "bbarray.h"
 #include "bbarray.h"
 
 
-void *bb_array_null;
+void *bb_array_kludge;

+ 130 - 140
modules/monkey/native/bbarray.h

@@ -3,119 +3,145 @@
 #define BB_ARRAY_H
 #define BB_ARRAY_H
 
 
 #include "bbgc.h"
 #include "bbgc.h"
-#include "bbdebug.h"
-#include "bbobject.h"
 
 
-extern void *bb_array_null;
+template<class T,int D> struct bbArray{
 
 
-template<class T,int D> class bbArray : public bbGCNode{
-
-	int _sizes[D];
-	T _data[0];
-		
-	bbArray(){
-		memset( _sizes,0,sizeof(_sizes) );
-	}
+	struct Rep : public bbGCNode{
 	
 	
-	bbArray( int sizes[] ){
-		bbGC::beginCtor( this );
+		int _sizes[D];
+		T _data[0];
 		
 		
-		memcpy( _sizes,sizes,D*sizeof(int) );
-		
-		for( int i=0;i<_sizes[D-1];++i ) new( &_data[i] ) T();
-	}
-	
-	~bbArray(){
-		for( int i=0;i<_sizes[D-1];++i ) _data[i].~T();
-	}
-	
-	virtual void gcMark(){
-		for( int i=0;i<_sizes[D-1];++i ) bbGCMark( _data[i] );	
-	}
+		Rep(){
+			memset( _sizes,0,sizeof(_sizes) );
+		}
+			
+		Rep( int sizes[] ){
+			bbGC::beginCtor( this );
+				
+			memcpy( _sizes,sizes,D*sizeof(int) );
+				
+			for( int i=0;i<_sizes[D-1];++i ) new( &_data[i] ) T();
+		}
+			
+		~Rep(){
+			for( int i=0;i<_sizes[D-1];++i ) _data[i].~T();
+		}
 	
 	
-	public:
+		virtual const char *typeName()const{
+			return "bbArray::Rep";
+		}
+			
+		virtual void gcMark(){
+			for( int i=0;i<_sizes[D-1];++i ) bbGCMark( _data[i] );
+		}
+	};
 	
 	
-	virtual const char *typeName()const{
-		return "bbArray";
+	Rep *_rep=nullptr;
+
+	bbArray(){
 	}
 	}
-	
-	template<class...Args> static bbArray *create( Args...args ){
-	
-		int sizes[]{ args... };
-		for( int i=1;i<D;++i ) sizes[i]*=sizes[i-1];
 		
 		
-		if( !sizes[D-1] ) return nullptr;
+	template<class...Args> bbArray( Args...args ){
 		
 		
-		bbGCNode *p=bbGC::alloc( sizeof( bbArray )+sizes[D-1]*sizeof(T) );
-		
-		bbArray *r=new( p ) bbArray( sizes );
-		
-		bbGC::endCtor( r );
-		
-		return r;
-	}
-	
-	template<class...Args> static bbArray *create( std::initializer_list<T> init,Args...args ){
-	
 		int sizes[]{ args... };
 		int sizes[]{ args... };
 		for( int i=1;i<D;++i ) sizes[i]*=sizes[i-1];
 		for( int i=1;i<D;++i ) sizes[i]*=sizes[i-1];
+			
+		if( !sizes[D-1] ) return;
+			
+		bbGCNode *p=bbGC::alloc( sizeof( Rep )+sizes[D-1]*sizeof(T) );
+	
+		_rep=new( p ) Rep( sizes );
+			
+		bbGC::endCtor( _rep );
+	}
 		
 		
-		if( !sizes[D-1] ) return nullptr;
-		
-		bbGCNode *p=bbGC::alloc( sizeof( bbArray )+sizes[D-1]*sizeof(T) );
-		
-		bbArray *r=new( p ) bbArray( sizes );
+	template<class...Args> bbArray( std::initializer_list<T> init,Args...args ){
 		
 		
+		int sizes[]{ args... };
+		for( int i=1;i<D;++i ) sizes[i]*=sizes[i-1];
+			
+		if( !sizes[D-1] ) return;
+			
+		bbGCNode *p=bbGC::alloc( sizeof( Rep )+sizes[D-1]*sizeof(T) );
+			
+		_rep=new( p ) Rep( sizes );
+			
 		int i=0;
 		int i=0;
-		for( auto it=init.begin();it!=init.end();++it ) r->_data[i++]=*it;
-		
-		bbGC::endCtor( r );
-		
-		return r;
+		for( auto it=init.begin();it!=init.end();++it ) _rep->_data[i++]=*it;
+			
+		bbGC::endCtor( _rep );
 	}
 	}
-	
+		
 	T *data(){
 	T *data(){
-		return _data;
+		return _rep->_data;
 	}
 	}
-	
+		
 	const T *data()const{
 	const T *data()const{
-		return _data;
+		return _rep->_data;
 	}
 	}
-	
+		
 	int length()const{
 	int length()const{
-//		return this ? _sizes[D-1] : 0;
-		return this!=bb_array_null ? _sizes[D-1] : 0;
+		return _rep ? _rep->_sizes[D-1] : 0;
 	}
 	}
-	
+		
 	int size( int q )const{
 	int size( int q )const{
-		bbDebugAssert( q<D,"Array dimension out of range" );
+		bbDebugAssert( q>=0 && q<D,"Array dimension out of range" );
+			
+		return _rep ? (q ? _rep->_sizes[q]/_rep->_sizes[q-1] : _rep->_sizes[0]) : 0;
+	}
 		
 		
-//		return this ? (q ? _sizes[q]/_sizes[q-1] : _sizes[0]) : 0;
-		return this!=bb_array_null ? (q ? _sizes[q]/_sizes[q-1] : _sizes[0]) : 0;
+	T &operator[]( int index ){
+		bbDebugAssert( index>=0 && index<length(),"Array index out of range" );
+			
+		return data()[index];
 	}
 	}
 	
 	
-	static int length( bbArray *array ){
-		return array ? array->_sizes[D-1] : 0;
+	T &at( int index ){
+		bbDebugAssert( index>=0 && index<length(),"Array index out of range" );
+				
+		return data()[index];
 	}
 	}
-	
-	static int size( bbArray *array,int q ){
-		bbDebugAssert( q<D,"Array dimension out of range" );
 		
 		
-		return array ? (q ? array->_sizes[q]/array->_sizes[q-1] : array->_sizes[0]) : 0;
+	//slower N-D version
+	template<class...Args> T &at( Args...args ){
+		
+		const int indices[]{args...};
+			
+		int index=indices[0];
+		bbDebugAssert( index>=0 && _rep,"Array index out of range" );
+			
+		for( int i=1;i<D;++i ){
+			bbDebugAssert( indices[i]>=0 && index<_rep->_sizes[i-1],"Array index out of range" );
+				
+			index+=indices[i]*_rep->_sizes[i-1];
+		}
+			
+		bbDebugAssert( index<length(),"Array index out of range" );
+			
+		return data()[index];
+	}
+		
+	operator bool()const{
+		
+		return _rep;
 	}
 	}
+		
+	bbArray<T,1> slice( int from )const{
 	
 	
-	bbArray<T,1> *slice( int from )const{
 		return slice( from,length() );
 		return slice( from,length() );
 	}
 	}
-	
-	bbArray<T,1> *slice( int from,int term )const{
+		
+	bbArray<T,1> slice( int from,int term )const{
+		
 		int length=this->length();
 		int length=this->length();
+			
 		if( from<0 ){
 		if( from<0 ){
 			from+=length;
 			from+=length;
 			if( from<0 ) from=0;
 			if( from<0 ) from=0;
 		}else if( from>length ){
 		}else if( from>length ){
 			from=length;
 			from=length;
 		}
 		}
+			
 		if( term<0 ){
 		if( term<0 ){
 			term+=length;
 			term+=length;
 			if( term<from ) term=from;
 			if( term<from ) term=from;
@@ -124,88 +150,52 @@ template<class T,int D> class bbArray : public bbGCNode{
 		}else if( term>length ){
 		}else if( term>length ){
 			term=length;
 			term=length;
 		}
 		}
+			
 		int newlen=term-from;
 		int newlen=term-from;
-		bbArray<T,1> *r=create( newlen );
-		for( int i=0;i<newlen;++i ) r->data()[i]=data()[from+i];
-		return r;
-	}
-
-	bbArray<T,1> *resize( int newLength )const{
-		bbDebugAssert( newLength>=0,
-			"Array Resize new length must not be negative" );
-			
-		if( newLength<=0 ) newLength=0;
-		int n=this->length();
-		if( n>newLength ) n=newLength;
-		bbArray<T,1> *r=create( newLength );
-		for( int i=0;i<n;++i ) r->data()[i]=data()[i];
+			
+		bbArray<T,1> r{newlen};
+			
+		for( int i=0;i<newlen;++i ) r.data()[i]=data()[from+i];
+			
 		return r;
 		return r;
 	}
 	}
 	
 	
-	void copyTo( bbArray<T,1> *dst,int offset,int dstOffset,int count )const{
-		bbDebugAssert( offset>=0 && dstOffset>=0 && count>=0 && offset+count<=length() && dstOffset+count<=dst->length(),
-			"Array CopyTo parameters out of range" );
-
-		if( dst==this && dstOffset>offset ){
-			for( int i=count-1;i>=0;--i ) dst->data()[dstOffset+i]=data()[offset+i];
-		}else{
-			for( int i=0;i<count;++i ) dst->data()[dstOffset+i]=data()[offset+i];
-		}
-	}
+	bbArray<T,1> resize( int newLength )const{
+		bbDebugAssert( newLength>=0,"Array Resize new length must not be negative" );
+			
+		int ncopy=length();
+		if( ncopy>newLength ) ncopy=newLength;
 	
 	
-	//fast 1D version	
-	T &at( int index ){
-		bbDebugAssert( index>=0 && index<length(),
-			"Array index out of range" );
+		auto r=bbArray<T,1>( newLength );
 			
 			
-		return data()[index];
+		for( int i=0;i<ncopy;++i ) r.data()[i]=data()[i];
+			
+		return r;
 	}
 	}
-	
-	//slower N-D version
-	template<class...Args> T &at( Args...args ){
-	
-		const int indices[]{args...};
 		
 		
-		int index=indices[0];
-		bbDebugAssert( index>=0,"Array index out of range" );
-		
-		for( int i=1;i<D;++i ){
-			bbDebugAssert( indices[i]>=0 && index<_sizes[i-1],"Array index out of range" );
-			index+=indices[i]*_sizes[i-1];
-		}
-		
-		bbDebugAssert( index<length(),"Array index out of range" );
-		return data()[index];
-	}
-	
-	T &get( int index ){
-		if( index<0 || index>=length() ) puts( "Out of range" );
-		return data()[index];
-	}
-	
-	operator bool()const{
-		return length();
-	}
-	
-	void dbEmit(){
-		int n=length();
-		if( n>100 ) n=100;
-		bbString t=bbDBType<T>();
-		for( int i=0;i<n;++i ){
-			bbString e=BB_T("[")+bbString( i )+"]:"+t+"="+bbDBValue( &at(i) );
-			puts( e.c_str() );
+	void copyTo( bbArray<T,1> dst,int offset,int dstOffset,int count )const{
+		bbDebugAssert( offset>=0 && dstOffset>=0 && count>=0 && offset+count<=length() && dstOffset+count<=dst.length(),"Array CopyTo parameters out of range" );
+			
+		if( dst._rep==_rep && dstOffset>offset ){
+			for( int i=count-1;i>=0;--i ) dst.data()[dstOffset+i]=data()[offset+i];
+		}else{
+			for( int i=0;i<count;++i ) dst.data()[dstOffset+i]=data()[offset+i];
 		}
 		}
 	}
 	}
 };
 };
 
 
-template<class T,int N> bbString bbDBType( bbArray<T,N> **p ){
+template<class T,int D> bbString bbDBType( bbArray<T,D> *p ){
 	return bbDBType<T>()+"[]";
 	return bbDBType<T>()+"[]";
 }
 }
 
 
-template<class T,int N> bbString bbDBValue( bbArray<T,N> **p ){
+template<class T,int D> bbString bbDBValue( bbArray<T,D> *p ){
 	char buf[64];
 	char buf[64];
-	sprintf( buf,"@%p",*p );
+	sprintf( buf,"@%p",p->_rep );
 	return buf;
 	return buf;
 }
 }
 
 
+template<class T,int D> void bbGCMark( bbArray<T,D> arr ){
+	bbGC::enqueue( arr._rep );
+}
+
 #endif
 #endif

+ 3 - 3
modules/monkey/native/bbdebug.cpp

@@ -154,17 +154,17 @@ namespace bbDB{
 
 
 	}
 	}
 	
 	
-	bbArray<bbString> *stack(){
+	bbArray<bbString> stack(){
 	
 	
 		int n=0;
 		int n=0;
 		for( bbDBFrame *frame=currentContext->frames;frame;frame=frame->succ ) ++n;
 		for( bbDBFrame *frame=currentContext->frames;frame;frame=frame->succ ) ++n;
 		
 		
 		//TODO: Fix GC issues! Can't have a free local like this in case bbString ctors cause gc sweep!!!!
 		//TODO: Fix GC issues! Can't have a free local like this in case bbString ctors cause gc sweep!!!!
-		bbArray<bbString> *st=bbArray<bbString>::create( n );
+		bbArray<bbString> st=bbArray<bbString>( n );
 		
 		
 		int i=0;
 		int i=0;
 		for( bbDBFrame *frame=currentContext->frames;frame;frame=frame->succ ){
 		for( bbDBFrame *frame=currentContext->frames;frame;frame=frame->succ ){
-			st->at( i++ )=BB_T( frame->srcFile )+" ["+bbString( frame->srcPos>>12 )+"] "+frame->decl;
+			st[i++]=BB_T( frame->srcFile )+" ["+bbString( frame->srcPos>>12 )+"] "+frame->decl;
 		}
 		}
 		
 		
 		return st;
 		return st;

+ 1 - 1
modules/monkey/native/bbdebug.h

@@ -100,7 +100,7 @@ namespace bbDB{
 	
 	
 	void error( bbString err );
 	void error( bbString err );
 	
 	
-	bbArray<bbString> *stack();
+	bbArray<bbString> stack();
 	
 	
 	void emitStack();
 	void emitStack();
 }
 }

+ 6 - 18
modules/monkey/native/bbgc.h

@@ -258,41 +258,29 @@ template<class T> struct bbGCVar{
 	}
 	}
 };
 };
 
 
+/*
 template<class T> struct bbGCRootVar : public bbGCVar<T>,public bbGCRoot{
 template<class T> struct bbGCRootVar : public bbGCVar<T>,public bbGCRoot{
 	
 	
-	using bbGCVar<T>::_ptr;
-	using bbGCVar<T>::enqueue;
+	using bbGCVar<T>::operator=;
 
 
 	bbGCRootVar(){
 	bbGCRootVar(){
 	}
 	}
 	
 	
 	bbGCRootVar( T *p ){
 	bbGCRootVar( T *p ){
-		_ptr=p;
+		this->_ptr=p;
 		enqueue();
 		enqueue();
 	}
 	}
 	
 	
 	bbGCRootVar( const bbGCVar<T> &p ){
 	bbGCRootVar( const bbGCVar<T> &p ){
-		_ptr=p._ptr;
+		this->_ptr=p._ptr;
 		enqueue();
 		enqueue();
 	}
 	}
-	
 
 
-	bbGCRootVar &operator=( T *p ){
-		_ptr=p;
-		enqueue();
-		return *this;
-	}
-	
-	bbGCRootVar &operator=( const bbGCVar<T> &p ){
-		_ptr=p._ptr;
-		enqueue();
-		return *this;
-	}
-	
-	virtual void gcMark(){
+	void gcMark(){
 		bbGC::enqueue( dynamic_cast<bbGCNode*>( _ptr ) );
 		bbGC::enqueue( dynamic_cast<bbGCNode*>( _ptr ) );
 	}
 	}
 };
 };
+*/
 
 
 template<class T> void bbGCMark( const T &t ){}
 template<class T> void bbGCMark( const T &t ){}
 
 

+ 15 - 15
modules/monkey/native/bbstring.cpp

@@ -218,12 +218,12 @@ bbString bbString::fromUtf8Data( const void *data,int size ){
 }
 }
 
 
 
 
-bbArray<bbString> *bbString::split( bbString sep )const{
+bbArray<bbString> bbString::split( bbString sep )const{
 
 
 	if( !sep.length() ){
 	if( !sep.length() ){
-		bbArray<bbString> *bits=bbArray<bbString>::create( length() );
+		bbArray<bbString> bits=bbArray<bbString>( length() );
 		for( int i=0;i<length();++i ){
 		for( int i=0;i<length();++i ){
-			bits->at(i)=bbString( &data()[i],1 );
+			bits[i]=bbString( &data()[i],1 );
 		}
 		}
 		return bits;
 		return bits;
 	}
 	}
@@ -233,36 +233,36 @@ bbArray<bbString> *bbString::split( bbString sep )const{
 		++n;
 		++n;
 		i=i2+sep.length();
 		i=i2+sep.length();
 	}
 	}
-	bbArray<bbString> *bits=bbArray<bbString>::create( n );
+	bbArray<bbString> bits=bbArray<bbString>( n );
 	if( n==1 ){
 	if( n==1 ){
-		bits->at(0)=*this;
+		bits[0]=*this;
 		return bits;
 		return bits;
 	}
 	}
 	i=0;n=0;
 	i=0;n=0;
 	while( (i2=find( sep,i ))!=-1 ){
 	while( (i2=find( sep,i ))!=-1 ){
-		bits->at(n++)=slice( i,i2 );
+		bits[n++]=slice( i,i2 );
 		i=i2+sep.length();
 		i=i2+sep.length();
 	}
 	}
-	bits->at(n)=slice( i );
+	bits[n]=slice( i );
 	return bits;
 	return bits;
 }
 }
 
 
-bbString bbString::join( bbArray<bbString> *bits )const{
+bbString bbString::join( bbArray<bbString> bits )const{
 
 
-	if( bits->length()==0 ) return bbString();
-	if( bits->length()==1 ) return bits->at(0);
+	if( bits.length()==0 ) return bbString();
+	if( bits.length()==1 ) return bits[0];
 	
 	
-	int len=length() * (bits->length()-1);
-	for( int i=0;i<bits->length();++i ) len+=bits->at(i).length();
+	int len=length() * (bits.length()-1);
+	for( int i=0;i<bits.length();++i ) len+=bits[i].length();
 	
 	
 	Rep *rep=Rep::alloc( len );
 	Rep *rep=Rep::alloc( len );
 	bbChar *p=rep->data;
 	bbChar *p=rep->data;
 
 
-	p=t_memcpy( p,bits->at(0).data(),bits->at(0).length() );
+	p=t_memcpy( p,bits[0].data(),bits[0].length() );
 	
 	
-	for( int i=1;i<bits->length();++i ){
+	for( int i=1;i<bits.length();++i ){
 		p=t_memcpy( p,data(),length() );
 		p=t_memcpy( p,data(),length() );
-		p=t_memcpy( p,bits->at(i).data(),bits->at(i).length() );
+		p=t_memcpy( p,bits[i].data(),bits[i].length() );
 	}
 	}
 	
 	
 	return rep;
 	return rep;

+ 2 - 2
modules/monkey/native/bbstring.h

@@ -350,9 +350,9 @@ class bbString{
 		return rep;
 		return rep;
 	}
 	}
 	
 	
-	bbArray<bbString> *split( bbString sep )const;
+	bbArray<bbString> split( bbString sep )const;
 	
 	
-	bbString join( bbArray<bbString> *bits )const;
+	bbString join( bbArray<bbString> bits )const;
 	
 	
 	int compare( const bbString &t )const{
 	int compare( const bbString &t )const{
 		int len=length()<t.length() ? length() : t.length();
 		int len=length()<t.length() ? length() : t.length();

+ 4 - 4
modules/std/filesystem/native/filesystem.cpp

@@ -39,7 +39,7 @@ namespace bbFileSystem{
 
 
 	bbString _appDir;
 	bbString _appDir;
 	bbString _appPath;
 	bbString _appPath;
-	bbArray<bbString> *_appArgs;
+	bbArray<bbString> _appArgs;
 	
 	
 	struct GCRoot : public bbGCRoot{
 	struct GCRoot : public bbGCRoot{
 		void gcMark(){
 		void gcMark(){
@@ -55,9 +55,9 @@ namespace bbFileSystem{
 		if( done ) return;
 		if( done ) return;
 		done=true;
 		done=true;
 		
 		
-		_appArgs=bbArray<bbString>::create( bb_argc );
+		_appArgs=bbArray<bbString>( bb_argc );
 		
 		
-		for( int i=0;i<bb_argc;++i ) _appArgs->at(i)=bbString( bb_argv[i] );
+		for( int i=0;i<bb_argc;++i ) _appArgs[i]=bbString( bb_argv[i] );
 		
 		
 		#if _WIN32
 		#if _WIN32
 	
 	
@@ -117,7 +117,7 @@ namespace bbFileSystem{
 		return _appPath;
 		return _appPath;
 	}
 	}
 	
 	
-	bbArray<bbString> *appArgs(){
+	bbArray<bbString> appArgs(){
 		init();
 		init();
 		return _appArgs;
 		return _appArgs;
 	}
 	}

+ 1 - 1
modules/std/filesystem/native/filesystem.h

@@ -10,7 +10,7 @@ namespace bbFileSystem{
 	
 	
 	bbString appPath();
 	bbString appPath();
 	
 	
-	bbArray<bbString> *appArgs();
+	bbArray<bbString> appArgs();
 	
 	
 	bbBool copyFile( bbString srcPath,bbString dstPath );
 	bbBool copyFile( bbString srcPath,bbString dstPath );
 }
 }

+ 7 - 17
src/mx2cc/translator.monkey2

@@ -28,16 +28,11 @@ Function IsGCType:Bool( type:Type )
 	Return False
 	Return False
 End
 End
 
 
-
 Function IsGCPtrType:Bool( type:Type )
 Function IsGCPtrType:Bool( type:Type )
 
 
 	Local ctype:=TCast<ClassType>( type )
 	Local ctype:=TCast<ClassType>( type )
-	If ctype Return Not ctype.ExtendsVoid And Not ctype.IsStruct
-	
-	Local atype:=TCast<ArrayType>( type )
-	If atype Return True
 	
 	
-	Return False
+	Return ctype And Not ctype.ExtendsVoid And (ctype.IsClass Or ctype.IsInterface)
 End
 End
 
 
 'Visitor that looks for gc params on LHS of an assignment.
 'Visitor that looks for gc params on LHS of an assignment.
@@ -212,7 +207,6 @@ Class Translator
 				Else
 				Else
 					Emit( "bbGCMark("+VarName( vvar )+");" )
 					Emit( "bbGCMark("+VarName( vvar )+");" )
 				Endif
 				Endif
-'				Emit( "bbGCMark("+VarName( vvar )+");" )
 			Next
 			Next
 			
 			
 			For Local tmp:=Eachin _gcframe.tmps
 			For Local tmp:=Eachin _gcframe.tmps
@@ -222,7 +216,6 @@ Class Translator
 				Else
 				Else
 					Emit( "bbGCMark("+tmp.ident+");" )
 					Emit( "bbGCMark("+tmp.ident+");" )
 				Endif
 				Endif
-'				Emit( "bbGCMark("+tmp.ident+");" )
 			Next
 			Next
 			
 			
 			Emit( "}" )
 			Emit( "}" )
@@ -326,7 +319,7 @@ Class Translator
 				
 				
 				If debug And Not ctype.cdecl.IsExtern
 				If debug And Not ctype.cdecl.IsExtern
 					Local tname:=cname
 					Local tname:=cname
-					If Not IsStruct( ctype ) tname+="*"
+					If Not ctype.IsStruct tname+="*"
 					Emit( "bbString bbDBType("+tname+"*);" )
 					Emit( "bbString bbDBType("+tname+"*);" )
 					Emit( "bbString bbDBValue("+tname+"*);" )
 					Emit( "bbString bbDBValue("+tname+"*);" )
 				Endif
 				Endif
@@ -415,7 +408,7 @@ Class Translator
 		Local ctype:=TCast<ClassType>( type )
 		Local ctype:=TCast<ClassType>( type )
 		If ctype
 		If ctype
 			If ctype.cdecl.IsExtern Uses( ctype.transFile ) ; return
 			If ctype.cdecl.IsExtern Uses( ctype.transFile ) ; return
-			If IsStruct( ctype ) Uses( ctype ) ; Return
+			If ctype.IsStruct Uses( ctype ) ; Return
 			If AddRef( ctype ) Return
 			If AddRef( ctype ) Return
 			_refsTypes.Push( ctype )
 			_refsTypes.Push( ctype )
 			Return
 			Return
@@ -479,15 +472,12 @@ Class Translator
 	
 	
 	'***** MISC *****
 	'***** MISC *****
 
 
-	Method IsStruct:Bool( type:Type )
-
-		Local ctype:=TCast<ClassType>( type )
-		Return ctype And ctype.cdecl.kind="struct"
-	End
+	Method IsCValueType:Bool( type:Type )
 	
 	
-	Method IsValue:Bool( type:Type )
+		Local ctype:=TCast<ClassType>( type )
+		If ctype And ctype.IsStruct Return True
 	
 	
-		Return TCast<PrimType>( type ) Or TCast<FuncType>( type ) Or IsStruct( type )
+		Return TCast<PrimType>( type ) Or TCast<FuncType>( type ) Or TCast<ArrayType>( type )
 	End
 	End
 	
 	
 	Method CFuncType:String( type:FuncType )
 	Method CFuncType:String( type:FuncType )

+ 86 - 27
src/mx2cc/translator_cpp.monkey2

@@ -126,13 +126,33 @@ Class Translator_CPP Extends Translator
 	
 	
 	'***** Decls *****
 	'***** Decls *****
 	
 	
+	Method HeapVarType:String( type:Type )
+	
+		If IsGCPtrType( type ) Return "bbGCVar<"+ClassName( TCast<ClassType>( type ) )+">"
+		
+		Return TransType( type )
+	End
+	
+	Method VarType:String( vvar:VarValue )
+	
+		Local type:=vvar.type
+		
+		Select vvar.vdecl.kind
+		Case "const","global","field"
+			Return HeapVarType( type )
+		End
+		
+		Return TransType( type )
+	End
+
+#rem		
 	Method GCVarTypeName:String( type:Type )
 	Method GCVarTypeName:String( type:Type )
 	
 	
 		Local ctype:=TCast<ClassType>( type )
 		Local ctype:=TCast<ClassType>( type )
 		If ctype And Not ctype.ExtendsVoid And (ctype.cdecl.kind="class" Or ctype.cdecl.kind="interface") Return ClassName( ctype )
 		If ctype And Not ctype.ExtendsVoid And (ctype.cdecl.kind="class" Or ctype.cdecl.kind="interface") Return ClassName( ctype )
 		
 		
-		Local atype:=TCast<ArrayType>( type )
-		If atype Return ArrayName( atype )
+'		Local atype:=TCast<ArrayType>( type )
+'		If atype Return ArrayName( atype )
 		
 		
 		Return ""
 		Return ""
 	End
 	End
@@ -158,12 +178,14 @@ Class Translator_CPP Extends Translator
 		Case "field"
 		Case "field"
 			Return "bbGCVar<"+name+">"
 			Return "bbGCVar<"+name+">"
 		Case "global","const"
 		Case "global","const"
-			Return "bbGCRootVar<"+name+">"
+			Return "bbGCVar<"+name+">"
+'			Return "bbGCRootVar<"+name+">"
 		End
 		End
 		
 		
 		TransError( "Translator.VarType()" )
 		TransError( "Translator.VarType()" )
 		Return ""
 		Return ""
 	End
 	End
+#end
 
 
 	Method VarProto:String( vvar:VarValue ) Override
 	Method VarProto:String( vvar:VarValue ) Override
 	
 	
@@ -220,21 +242,35 @@ Class Translator_CPP Extends Translator
 	Method EmitGlobalInits( fdecl:FileDecl )
 	Method EmitGlobalInits( fdecl:FileDecl )
 	
 	
 		EmitBr()
 		EmitBr()
-		Emit( "void mx2_"+fdecl.ident+"_init(){" )
+		Emit( "void mx2_"+fdecl.ident+"_init_f(){" )
 		BeginGCFrame()
 		BeginGCFrame()
+		
 		Emit( "static bool done;" )
 		Emit( "static bool done;" )
 		Emit( "if(done) return;" )
 		Emit( "if(done) return;" )
 		Emit( "done=true;")
 		Emit( "done=true;")
 		
 		
+		Local gc:=False
 		For Local vvar:=Eachin fdecl.globals
 		For Local vvar:=Eachin fdecl.globals
 			If vvar.init Emit( Trans( vvar )+"="+Trans( vvar.init )+";" )
 			If vvar.init Emit( Trans( vvar )+"="+Trans( vvar.init )+";" )
+			If IsGCType( vvar.type ) gc=True
 		Next
 		Next
 		
 		
 		EndGCFrame()
 		EndGCFrame()
 		Emit( "}" )
 		Emit( "}" )
 		
 		
+		If gc
+			EmitBr()
+			Emit( "struct mx2_"+fdecl.ident+"_roots_t : bbGCRoot{" )
+			Emit( "void gcMark(){" )
+			For Local vvar:=Eachin fdecl.globals
+				If IsGCType( vvar.type ) Emit( "bbGCMark("+Trans(vvar)+");" )
+			Next
+			Emit( "}" )
+			Emit( "}mx2_"+fdecl.ident+"_roots;" )
+		Endif
+		
 		EmitBr()
 		EmitBr()
-		Emit( "bbInit mx2_"+fdecl.ident+"_init_v(~q"+fdecl.ident+"~q,&mx2_"+fdecl.ident+"_init);" )
+		Emit( "bbInit mx2_"+fdecl.ident+"_init(~q"+fdecl.ident+"~q,&mx2_"+fdecl.ident+"_init_f);" )
 	
 	
 	End
 	End
 	
 	
@@ -439,13 +475,12 @@ Class Translator_CPP Extends Translator
 		
 		
 		If debug
 		If debug
 			Local tname:=cname
 			Local tname:=cname
-			If Not IsStruct( ctype ) tname+="*"
+			If Not ctype.IsStruct tname+="*"
 			Emit( "bbString bbDBType("+tname+"*);" )
 			Emit( "bbString bbDBType("+tname+"*);" )
 			Emit( "bbString bbDBValue("+tname+"*);" )
 			Emit( "bbString bbDBValue("+tname+"*);" )
 		Endif
 		Endif
 		
 		
-		If IsStruct( ctype )
-
+		If ctype.IsStruct
 			EmitBr()
 			EmitBr()
 			If hasCmp
 			If hasCmp
 				Emit( "inline int bbCompare(const "+cname+"&x,const "+cname+"&y){return x.m__cmp(y);}" )
 				Emit( "inline int bbCompare(const "+cname+"&x,const "+cname+"&y){return x.m__cmp(y);}" )
@@ -581,7 +616,7 @@ Class Translator_CPP Extends Translator
 		
 		
 		If debug
 		If debug
 			Local tname:=cname
 			Local tname:=cname
-			If Not IsStruct( ctype ) tname+="*"
+			If Not ctype.IsStruct tname+="*"
 			
 			
 			Emit( "bbString bbDBType("+tname+"*){" )
 			Emit( "bbString bbDBType("+tname+"*){" )
 			Emit( "return ~q"+ctype.Name+"~q;" )
 			Emit( "return ~q"+ctype.Name+"~q;" )
@@ -613,8 +648,7 @@ Class Translator_CPP Extends Translator
 
 
 		'Emit static struct methods
 		'Emit static struct methods
 		'
 		'
-		If IsStruct( ctype ) 
-
+		If ctype.IsStruct
 			If Not hasCmp
 			If Not hasCmp
 				EmitBr()
 				EmitBr()
 				Emit( "int bbCompare(const "+cname+"&x,const "+cname+"&y){" )
 				Emit( "int bbCompare(const "+cname+"&x,const "+cname+"&y){" )
@@ -946,6 +980,12 @@ Class Translator_CPP Extends Translator
 			
 			
 			Emit( type+" "+tvar+init+";" )
 			Emit( type+" "+tvar+init+";" )
 			
 			
+			If (vdecl.kind="global" Or vdecl.kind="const") And IsGCType( vvar.type )
+				Emit( "static struct _"+tvar+"_t:bbGCRoot{" )
+				Emit( "void gcMark(){ bbGCMark("+tvar+");}" )
+				Emit( "}_"+tvar+";" )
+			Endif
+			
 		Endif
 		Endif
 		
 		
 		If debug And vdecl.kind="local" Emit( "bbDBLocal(~q"+vvar.vdecl.ident+"~q,&"+tvar+");" )
 		If debug And vdecl.kind="local" Emit( "bbDBLocal(~q"+vvar.vdecl.ident+"~q,&"+tvar+");" )
@@ -1205,7 +1245,7 @@ Class Translator_CPP Extends Translator
 
 
 		Local t:="("+Trans( value.value )+")"
 		Local t:="("+Trans( value.value )+")"
 		
 		
-		If IsValue( value.type ) Return TransType( value.type )+t
+		If IsCValueType( value.type ) Return TransType( value.type )+t
 
 
 		Return "(("+TransType( value.type )+")"+t+")"
 		Return "(("+TransType( value.type )+")"+t+")"
 	End
 	End
@@ -1222,7 +1262,7 @@ Class Translator_CPP Extends Translator
 		
 		
 		Local t:="("+Trans( value.value )+")"
 		Local t:="("+Trans( value.value )+")"
 		
 		
-		If IsValue( value.type ) Return TransType( value.type )+t
+		If IsCValueType( value.type ) Return TransType( value.type )+t
 
 
 		Return "(("+TransType( value.type )+")"+t+")"
 		Return "(("+TransType( value.type )+")"+t+")"
 	End
 	End
@@ -1242,7 +1282,10 @@ Class Translator_CPP Extends Translator
 		Local etype:=TCast<EnumType>( type )
 		Local etype:=TCast<EnumType>( type )
 		If etype Return EnumName( etype )+"(0)"
 		If etype Return EnumName( etype )+"(0)"
 
 
-		If IsValue( type ) Return TransType( type )+"{}"
+		If IsCValueType( type ) 
+			Uses( type )
+			Return TransType( type )+"{}"
+		Endif
 		
 		
 		Return "(("+TransType( type )+")0)"
 		Return "(("+TransType( type )+")0)"
 	End
 	End
@@ -1287,7 +1330,7 @@ Class Translator_CPP Extends Translator
 		
 		
 		Local cname:=ClassName( value.ctype )
 		Local cname:=ClassName( value.ctype )
 		
 		
-		If IsStruct( value.ctype ) Return "(*static_cast<"+cname+"*>(this))"
+		If value.ctype.IsStruct Return "(*static_cast<"+cname+"*>(this))"
 		
 		
 		Return "static_cast<"+cname+"*>(this)"
 		Return "static_cast<"+cname+"*>(this)"
 	End
 	End
@@ -1301,12 +1344,17 @@ Class Translator_CPP Extends Translator
 		
 		
 		Local tinst:=Trans( instance )
 		Local tinst:=Trans( instance )
 		Local tmember:=Trans( member )
 		Local tmember:=Trans( member )
-
-		If IsValue( instance.type ) Return tinst+"."+tmember
 		
 		
 		If Cast<FuncValue>( member ) And IsVolatile( instance ) tinst="("+AllocGCTmp( instance.type )+"="+tinst+")"
 		If Cast<FuncValue>( member ) And IsVolatile( instance ) tinst="("+AllocGCTmp( instance.type )+"="+tinst+")"
+
+		If IsCValueType( instance.type ) Return tinst+"."+tmember
 		
 		
 		Return tinst+"->"+tmember
 		Return tinst+"->"+tmember
+		
+		'have to do this for arrays too?
+'		If Cast<FuncValue>( member ) And IsVolatile( instance ) tinst="("+AllocGCTmp( instance.type )+"="+tinst+")"
+		
+'		Return tinst+"->"+tmember
 	End
 	End
 	
 	
 	Method TransInvokeMember:String( instance:Value,member:FuncValue,args:Value[] )
 	Method TransInvokeMember:String( instance:Value,member:FuncValue,args:Value[] )
@@ -1367,7 +1415,7 @@ Class Translator_CPP Extends Translator
 			Return "new "+cname+"("+TransArgs( value.args )+")"
 			Return "new "+cname+"("+TransArgs( value.args )+")"
 		Endif
 		Endif
 		
 		
-		If IsStruct( ctype )
+		If ctype.IsStruct
 			If Not value.args Return cname+"(bbNullCtor)"
 			If Not value.args Return cname+"(bbNullCtor)"
 			If value.args[0].type.Equals( ctype ) Return cname+"("+TransArgs( value.args )+",bbNullCtor)"
 			If value.args[0].type.Equals( ctype ) Return cname+"("+TransArgs( value.args )+",bbNullCtor)"
 			Return cname+"("+TransArgs( value.args )+")"
 			Return cname+"("+TransArgs( value.args )+")"
@@ -1380,14 +1428,21 @@ Class Translator_CPP Extends Translator
 	
 	
 		Local atype:=value.atype
 		Local atype:=value.atype
 		Uses( atype )
 		Uses( atype )
+		
+		If value.inits Return ArrayName( atype )+"({"+TransArgs( value.inits )+"},"+value.inits.Length+")"
+		
+		Return ArrayName( atype )+"("+TransArgs( value.sizes )+")"
 	
 	
-		If value.inits Return ArrayName( atype )+"::create({"+TransArgs( value.inits )+"},"+value.inits.Length+")"
+'		If value.inits Return ArrayName( atype )+"::create({"+TransArgs( value.inits )+"},"+value.inits.Length+")"
 		
 		
-		Return ArrayName( atype )+"::create("+TransArgs( value.sizes )+")"
+'		Return ArrayName( atype )+"::create("+TransArgs( value.sizes )+")"
 	End
 	End
 	
 	
 	Method Trans:String( value:ArrayIndexValue )
 	Method Trans:String( value:ArrayIndexValue )
-		Return Trans( value.value )+"->at("+TransArgs( value.args )+")"
+		If value.args.Length=1 Return Trans( value.value )+"["+TransArgs( value.args )+"]"
+		Return Trans( value.value )+".at("+TransArgs( value.args )+")"
+		
+'		Return Trans( value.value )+"->at("+TransArgs( value.args )+")"
 	End
 	End
 	
 	
 	Method Trans:String( value:StringIndexValue )
 	Method Trans:String( value:StringIndexValue )
@@ -1428,7 +1483,11 @@ Class Translator_CPP Extends Translator
 		
 		
 			If op="=" op="==" Else If op="<>" op="!="
 			If op="=" op="==" Else If op="<>" op="!="
 			
 			
-			If IsStruct( value.lhs.type ) Or (TCast<FuncType>( value.lhs.type ) And op<>"==" And op<>"!=" )
+			Local ctype:=TCast<ClassType>( value.lhs.type )
+			Local ftype:=TCast<FuncType>( value.lhs.type )
+			
+			If (ctype And ctype.IsStruct) Or (ftype And op<>"==" And op<>"!=" )
+'			If IsStruct( value.lhs.type ) Or (TCast<FuncType>( value.lhs.type ) And op<>"==" And op<>"!=" )
 				Return "(bbCompare("+Trans( value.lhs )+","+Trans( value.rhs )+")"+op+"0)"
 				Return "(bbCompare("+Trans( value.lhs )+","+Trans( value.rhs )+")"+op+"0)"
 			Endif
 			Endif
 			
 			
@@ -1554,7 +1613,7 @@ Class Translator_CPP Extends Translator
 	End
 	End
 	
 	
 	Method TransType:String( type:ClassType )
 	Method TransType:String( type:ClassType )
-		If IsStruct( type ) Return ClassName( type )
+		If type.IsStruct Return ClassName( type )
 		Return ClassName( type )+"*"
 		Return ClassName( type )+"*"
 	End
 	End
 	
 	
@@ -1571,7 +1630,7 @@ Class Translator_CPP Extends Translator
 	End
 	End
 	
 	
 	Method TransType:String( type:ArrayType )
 	Method TransType:String( type:ArrayType )
-		Return ArrayName( type )+"*"
+		Return ArrayName( type )
 	End
 	End
 	
 	
 	Method TransType:String( type:PointerType )
 	Method TransType:String( type:PointerType )
@@ -1583,9 +1642,9 @@ Class Translator_CPP Extends Translator
 	End
 	End
 	
 	
 	Method ArrayName:String( type:ArrayType )
 	Method ArrayName:String( type:ArrayType )
-		Refs( type )
-		If type.rank=1 Return "bbArray<"+ElementType( type.elemType )+">"
-		Return "bbArray<"+ElementType( type.elemType )+","+type.rank+">"
+'		Refs( type )
+		If type.rank=1 Return "bbArray<"+HeapVarType( type.elemType )+">"
+		Return "bbArray<"+HeapVarType( type.elemType )+","+type.rank+">"
 	End
 	End
 	
 	
 End
 End