bcc icon indicating copy to clipboard operation
bcc copied to clipboard

Bcc reflect

Open woollybah opened this issue 9 months ago • 4 comments

woollybah avatar Mar 25 '25 16:03 woollybah

ctranslator diff:

--- <unbenannt>
+++ <unbenannt>
@@ -73,7 +73,7 @@
 		If TULongType( ty ) Return "~q" + p + "y~q"
 		If TLongIntType( ty ) Return "~q" + p + "v~q"
 		If TULongIntType( ty ) Return "~q" + p + "e~q"
-		If TSizeTType( ty ) Return "~q" + p + "z~q"
+		If TSizeTType( ty ) Return "~q" + p + "t~q"
 		If TWParamType( ty ) Return "~q" + p + "w~q"
 		If TLParamType( ty ) Return "~q" + p + "x~q"
 		If TStringType( ty ) Return "~q$~q"
@@ -160,10 +160,39 @@
 		If TLParamType( ty ) Return "x"
 		If TStringType( ty ) Return "t"
 	End Method
+
+	Method TransCifType$(ty:TType)
+		Local p:String = TransSPointer(ty)
+
+		If Not p Then
+			If TByteType( ty ) Return "&ffi_type_uint8"
+			If TShortType( ty ) Return "&ffi_type_uint16"
+			If TIntType( ty ) Return "&ffi_type_sint32"
+			If TUIntType( ty ) Return "&ffi_type_uint32"
+			If TFloatType( ty ) Return "&ffi_type_float"
+			If TDoubleType( ty ) Return "&ffi_type_double"
+			If TLongType( ty ) Return "&ffi_type_sint64"
+			If TULongType( ty ) Return "&ffi_type_uint64"
+			If TSizeTType( ty ) Then
+				If WORD_SIZE = 8 Then
+					Return "&ffi_type_uint32"
+				Else
+					Return "&ffi_type_uint64"
+				End If
+			End If			
+			If TWParamType( ty ) Return "&ffi_type_sint32"
+			If TLParamType( ty ) Return "&ffi_type_sint64"
+		End If
+		' everything else is a pointer...
+		Return "&ffi_type_pointer"
+	End Method
 	
 	Method TransDebugScopeType$(ty:TType)
 		Local p:String = TransSPointer(ty)
-
+		If ty._flags & TType.T_VAR Then
+			p = "&" + p
+		End If
+		
 		If TByteType( ty ) Return p + "b"
 		If TShortType( ty ) Return p + "s"
 		If TIntType( ty ) Return p + "i"
@@ -181,9 +210,9 @@
 		If TFloat128Type( ty ) Return p + "k"
 		If TDouble128Type( ty ) Return p + "m"
 		If TFloat64Type( ty ) Return p + "h"
-		If TStringType( ty ) Return "$"
+		If TStringType( ty ) Return p + "$"
 		If TArrayType( ty ) Then
-			Local s:String = "["
+			Local s:String = p + "["
 			If TArrayType( ty ).isStatic Then
 				s :+ TArrayType( ty ).length
 			Else
@@ -198,7 +227,7 @@
 			If TObjectType( ty ).classdecl.IsStruct() Then
 					Return p + "@" + TObjectType(ty).classDecl.ident
 			Else If Not TObjectType( ty ).classdecl.IsExtern()
-				Return ":" + TObjectType( ty ).classDecl.ident
+				Return p + ":" + TObjectType( ty ).classDecl.ident
 			Else
 				If TObjectType( ty ).classdecl.IsInterface() Then
 					Return p + "*#" + TObjectType(ty).classDecl.ident
@@ -209,7 +238,7 @@
 		End If
 		If TFunctionPtrType( ty ) Then
 			Local func:TFuncDecl = TFunctionPtrType( ty ).func
-			Local s:String = "("
+			Local s:String = p + "("
 			For Local i:Int = 0 Until func.argDecls.length
 				If i Then
 					s :+ ","
@@ -219,7 +248,7 @@
 			Return s + ")" + TransDebugScopeType(func.retType)
 		End If
 		If TEnumType( ty ) Then
-			Return "/" + TEnumType( ty ).decl.ident
+			Return p + "/" + TEnumType( ty ).decl.ident
 		End If
 
 	End Method
@@ -418,6 +447,17 @@
 
 	Method TransRefType$( ty:TType, ident:String )
 		Return TransType( ty, ident )
+	End Method
+
+	Method TransDebugScopeModifiers:String(decl:TDecl)
+		Local modifiers:String
+		If decl.IsAbstract()  Then modifiers :+ "A"
+		If decl.IsFinal()     Then modifiers :+ "F"
+		If decl.IsExtern()    Then modifiers :+ "E"
+		If decl.IsPrivate()   Then modifiers :+ "P"
+		If decl.IsProtected() Then modifiers :+ "R"
+		If modifiers Then modifiers = "'" + modifiers
+		Return modifiers
 	End Method
 
 	Method TransValue$( ty:TType,value$, isStructInit:Int = False )
@@ -1904,6 +1944,8 @@
 		If expr.expr.length = 1 Then
 			If TObjectType(expr.ty) And TObjectType(expr.ty).classdecl.IsStruct() And Not IsPointerType(expr.ty) Then
 				Return "bbArrayNew1DStruct_" + TObjectType(expr.ty).classdecl.munged + Bra(expr.expr[0].Trans())
+			Else If TEnumType(expr.ty) Then
+				Return "bbArrayNew1DEnum" + Bra(TransArrayType(expr.ty) + ", " + expr.expr[0].Trans() + ", " + TEnumType(expr.ty).decl.munged + "_BBEnum_impl")
 			Else
 				Return "bbArrayNew1D" + Bra(TransArrayType(expr.ty) + ", " + expr.expr[0].Trans())
 			End If
@@ -1922,6 +1964,8 @@
 			If TObjectType(expr.ty) And TObjectType(expr.ty).classdecl.IsStruct() And Not IsPointerType(expr.ty) Then
 				Return "bbArrayNewStruct" + Bra(TransArrayType(expr.ty) + ", sizeof" + Bra(TransObject(TObjectType(expr.ty).classdecl)) + ..
 					", _" + TObjectType(expr.ty).classdecl.munged + "_New, " + expr.expr.length + ", " + s)
+			Else If TEnumType(expr.ty) Then
+				Return "bbArrayNewEnum" + Bra(TransArrayType(expr.ty) + ", " + TEnumType(expr.ty).decl.munged + "_BBEnum_impl" + ", " + expr.expr.length + ", " + s)
 			Else
 				Return "bbArrayNew" + Bra(TransArrayType(expr.ty) + ", " + expr.expr.length + ", " + s)
 			End If
@@ -3015,13 +3059,17 @@
 		Local scopeIndex:Int
 		Local count:Int
 		For Local decl:TDecl = EachIn block.Decls()
-			If TLocalDecl(decl) Then
+			If TLocalDecl(decl) Or TConstDecl(decl) Or TGlobalDecl(decl) Then
 				count :+ 1
 			End If
-			If TGlobalDecl(decl) Then
-				count :+ 1
-			End If
-		Next
+		Next
+		If _app.mainFunc = block Then
+			For Local decl:TDecl = EachIn _app.mainModule.Decls()
+				If TConstDecl(decl) Then
+					count :+ 1
+				End If
+			Next
+		End If
 		
 		' a method also includes "Self" reference back to parent Type
 		If TFuncDecl(block) And TFuncDecl(block).IsMethod() Then
@@ -3045,55 +3093,76 @@
 			End If
 		Else
 			Emit "BBDEBUGSCOPE_LOCALBLOCK,"
-			Emit "0,"
-		End If
-			
+			Emit "(char*)0,"
+		End If
+		
+		Emit "{"
+		
+		If TFuncDecl(block) And TFuncDecl(block).IsMethod() Then
 			Emit "{"
-			
-			If TFuncDecl(block) And TFuncDecl(block).IsMethod() Then
+			Emit "BBDEBUGDECL_LOCAL,"
+			Emit "~qSelf~q,"
+			Emit Enquote(TransDebugScopeType(TClassDecl(block.scope).objectType)) + ","
+			Local prefix:String = "&"
+			If block.ClassScope().IsStruct() Then
+				prefix = ""
+			End If
+			Emit ".var_address=" + prefix + "o,"
+			Emit "(void (*)(void**))0"
+			Emit "},"
+			scopeIndex :+ 1
+		End If
+		
+		' add module consts
+		If _app.mainFunc = block Then
+			' consts
+			For Local cdecl:TConstDecl = EachIn _app.mainModule.Decls()
+				EmitConstDebugScope(cdecl)
+				scopeIndex :+ 1
+			Next
+		End If
+		
+		' block consts and globals
+		' consts
+		For Local cdecl:TConstDecl = EachIn block.Decls()
+			EmitConstDebugScope(cdecl)
+			scopeIndex :+ 1
+		Next
+		' globals
+		For Local gdecl:TGlobalDecl = EachIn block.Decls()
+			EmitGlobalDebugScope(gdecl, scopeIndex)
+			scopeIndex :+ 1
+		Next
+		
+		' iterate through decls and add as appropriate
+		For Local decl:TDecl = EachIn block.Decls()
+			Local ldecl:TLocalDecl = TLocalDecl(decl)
+			If ldecl Then
 				Emit "{"
-				Emit "BBDEBUGDECL_LOCAL,"
-				Emit "~qSelf~q,"
-				Emit Enquote(TransDebugScopeType(TClassDecl(block.scope).objectType)) + ","
-				Local prefix:String = "&"
-				If block.ClassScope().IsStruct() Then
-					prefix = ""
-				End If
-				Emit ".var_address=" + prefix + "o"
+				If ldecl.ty._flags & TType.T_VAR Then
+					Emit "BBDEBUGDECL_VARPARAM,"
+				Else
+					Emit "BBDEBUGDECL_LOCAL,"
+				End If
+				Emit Enquote(ldecl.ident) + ","
+				Emit Enquote(TransDebugScopeType(ldecl.ty)) + ","
+				Emit ".var_address=&" + ldecl.munged + ","
+				Emit "(void (*)(void**))0"
 				Emit "},"
-				scopeIndex:+ 1
-			End If
-			
-			' block globals
-			For Local gdecl:TGlobalDecl = EachIn block.Decls()
-				EmitGlobalDebugScope(gdecl, scopeIndex)
-			Next
-			
-			' iterate through decls and add as appropriate
-			For Local decl:TDecl = EachIn block.Decls()
-				Local ldecl:TLocalDecl = TLocalDecl(decl)
-				If ldecl Then
-					Emit "{"
-					If ldecl.ty._flags & TType.T_VAR Then
-						Emit "BBDEBUGDECL_VARPARAM,"
-					Else
-						Emit "BBDEBUGDECL_LOCAL,"
-					End If
-					Emit Enquote(ldecl.ident) + ","
-					Emit Enquote(TransDebugScopeType(ldecl.ty)) + ","
-					Emit ".var_address=&" + ldecl.munged
-					Emit "},"
-					
-					Continue
-				End If
-			Next
-
-			Emit "{"
-			Emit "BBDEBUGDECL_END"
-			Emit "}"
-			Emit "}"
-			
-			
+				scopeIndex :+ 1
+			End If
+		Next
+		
+		Emit "{"
+		Emit "BBDEBUGDECL_END,"
+		Emit "(char*)0,"
+		Emit "(char*)0,"
+		Emit ".var_address=(void*)0,"
+		Emit "(void (*)(void**))0"
+		Emit "}"
+		Emit "}"
+		
+		
 		Emit "};"
 		
 		' threaded global
@@ -3579,7 +3648,7 @@
 
 
 
-	Method EmitFuncDecl( decl:TFuncDecl, proto:Int = False, classFunc:Int = False )
+	Method EmitFuncDecl( decl:TFuncDecl, proto:Int = False, classFunc:Int = False, createReflectionWrapper:Int = True )
 		'If Not proto And decl.IsAbstract() Return
 
 		Local tmpDebug:Int = opt_debug
@@ -3674,7 +3743,7 @@
 				id = id
 			End If
 		End If
-
+		
 		Local iterations:Int = 1
 		If decl.attrs & DECL_INLINE Then
 			iterations = 2
@@ -3803,7 +3872,7 @@
 		If decl.attrs & DECL_INLINE Then
 			Emit "#endif"
 		End If
-
+		
 		' reset label ids
 		contLabelId = 0
 		exitLabelId = 0
@@ -3813,6 +3882,69 @@
 		
 		opt_debug = tmpDebug
 		
+		' wrapper function for invocation via reflection
+		If createReflectionWrapper And Not proto Then EmitReflectionWrapper Null, decl
+		
+	End Method
+	
+	Method EmitReflectionWrapper(classDecl:TClassDecl, decl:TFuncDecl)
+		' classDecl is only required for constructors
+		Local funcName:String
+		If decl.IsCTor() Then
+			funcName = MungedConstructorName(classDecl, decl)
+		Else If decl.IsMethod() Then 
+			funcName = "_" + decl.munged
+		Else
+			funcName = decl.munged
+		End If
+		
+		' wrapper signature
+		Emit "void " + funcName + "_ReflectionWrapper(void** buf){"
+		Local offsetStr:String
+		
+		' call to original method/function
+		If TVoidType(decl.retType) Or decl.IsCTor() Then 
+			Emit funcName + "("
+		Else
+			offsetStr = Bra(ArgSizeStr(TransType(decl.retType, "")))
+			Emit "*" + Bra(TransType(TType.MapToPointerType(decl.retType.Copy()), "")) + "(buf) = " + funcName + "("
+		End If
+		
+		' arguments for call
+		Local startIndex:Int = 0
+		If decl.IsMethod() Or decl.IsCTor() Then startIndex = -1 ' add Self argument
+		For Local a:Int = startIndex Until decl.argDecls.Length
+			Local argTypeStr:String
+			Local argPtrTypeStr:String
+			If a = -1 Then
+				If decl.IsCTor() Then argTypeStr = TransObject(classDecl, True) Else argTypeStr = TransObject(decl.scope, True)
+				argPtrTypeStr = argTypeStr + "*"
+			Else
+				argTypeStr = TransType(decl.argDecls[a].ty, "")
+				argPtrTypeStr = TransType(TType.MapToPointerType(decl.argDecls[a].ty.Copy()), "")
+			End If
+			
+			Local argStr:String = "~t*" + Bra(argPtrTypeStr)
+			If offsetStr Then
+				argStr :+ Bra("buf + " + Bra(offsetStr))
+				offsetStr :+ " + "
+			Else
+				argStr :+ Bra("buf")
+			End If
+			offsetStr :+ Bra(ArgSizeStr(argTypeStr))
+			
+			If a <> decl.argDecls.Length - 1 Then argStr :+ ","
+			Emit argStr
+		Next
+		
+		Emit ");"
+		Emit "}"
+		
+		Function ArgSizeStr:String(typeStr:String)
+			' rounds up to pointer size
+			Local size:String = "sizeof(" + typeStr + ")"
+			Return "((" + size + " - 1) * (" + size + " != 0)) / sizeof(void*) + 1"
+		End Function
 	End Method
 	
 	Method EmitLocalDeclarations(decl:TScopeDecl, ignoreVar:TValDecl = Null)
@@ -3887,7 +4019,7 @@
 		Local fdecls:TFuncDecl[] = classDecl.GetAllFuncDecls()
 
 		For Local decl:TFuncDecl=EachIn fdecls
-
+		
 			If Not decl.IsSemanted()
 				decl.Semant()
 			End If
@@ -3932,19 +4064,19 @@
 		If emitFuncProtos Then
 			EmitClassDeclNewListProto(classDecl)
 
-			If classHierarchyHasFunction(classDecl, "Delete") Then
+			If classHierarchyGetFunction(classDecl, "Delete") Then
 				Emit "void _" + classid + "_Delete" + Bra(TransObject(classdecl) + " o") + ";"
 			End If
 	
-			If classHasFunction(classDecl, "ToString") Then
+			If classGetFunction(classDecl, "ToString") Then
 				Emit "BBSTRING _" + classid + "_ToString" + Bra(TransObject(classdecl) + " o") + ";"
 			End If
 	
-			If classHasFunction(classDecl, "Compare") Then
+			If classGetFunction(classDecl, "Compare") Then
 				Emit "BBINT _" + classid + "_Compare(" + TransObject(classdecl) + " o, BBOBJECT otherObject);"
 			End If
 	
-			If classHasFunction(classDecl, "SendMessage") Then
+			If classGetFunction(classDecl, "SendMessage") Then
 				Emit "BBOBJECT _" + classid + "_SendMessage(" + TransObject(classdecl) + " o, BBOBJECT message, BBOBJECT source);"
 			End If
 
@@ -3987,17 +4119,17 @@
 		Emit "unsigned int instance_size;"
 		Emit "void      (*ctor)( BBOBJECT o );"
 		Emit "void      (*dtor)( BBOBJECT o );"
-		If classHierarchyHasFunction(classDecl, "ToString") Then
+		If classHierarchyGetFunction(classDecl, "ToString") Then
 			Emit "BBSTRING  (*ToString)( struct " + classidForFunction(classDecl, "ToString") + "_obj* x );"
 		Else
 			Emit "BBSTRING  (*ToString)( BBOBJECT x );"
 		End If
-		If classHierarchyHasFunction(classDecl, "Compare") Then
+		If classHierarchyGetFunction(classDecl, "Compare") Then
 			Emit "BBINT     (*Compare)( struct " + classidForFunction(classDecl, "Compare") + "_obj* x, BBOBJECT y );"
 		Else
 			Emit "int       (*Compare)( BBOBJECT x,BBOBJECT y );"
 		End If
-		If classHierarchyHasFunction(classDecl, "SendMessage") Then
+		If classHierarchyGetFunction(classDecl, "SendMessage") Then
 			Emit "BBOBJECT  (*SendMessage)( struct " + classidForFunction(classDecl, "SendMessage") + "_obj* x, BBOBJECT m, BBOBJECT s );"
 		Else
 			Emit "BBOBJECT  (*SendMessage)( BBOBJECT o,BBOBJECT m,BBOBJECT s );"
@@ -4186,29 +4318,30 @@
 
 	End Method
 
-	Method classHasFunction:Int(classDecl:TClassDecl, func:String)
+	Method classGetFunction:TDecl(classDecl:TClassDecl, func:String)
 		Local f:String = func.ToLower()
 		For Local decl:TFuncDecl = EachIn classDecl.Decls()
 			If Not decl.IsSemanted() Then
 				decl.Semant
 			End If
 			If decl.IdentLower() = f And equalsBuiltInFunc(classDecl.superClass, decl) Then
-				Return True
-			End If
-		Next
-		Return False
-	End Method
-
-	Method classHierarchyHasFunction:Int(classDecl:TClassDecl, func:String)
-		If classHasFunction(classDecl, func) Return True
+				Return decl
+			End If
+		Next
+		Return Null
+	End Method
+
+	Method classHierarchyGetFunction:TDecl(classDecl:TClassDecl, func:String)
+		Local decl:TDecl = classGetFunction(classDecl, func)
+		If decl Then Return decl
 		If classDecl.superClass And classDecl.superClass.munged <> "bbObjectClass" Then
-			Return classHierarchyHasFunction(classDecl.superClass, func)
-		End If
-		Return False
+			Return classHierarchyGetFunction(classDecl.superClass, func)
+		End If
+		Return Null
 	End Method
 
 	Method classidForFunction:String(classDecl:TClassDecl, func:String)
-		If classHasFunction(classDecl, func) Return classDecl.munged
+		If classGetFunction(classDecl, func) Return classDecl.munged
 		If classDecl.superClass And classDecl.superClass.munged <> "bbObjectClass" Then
 			Return classidForFunction(classDecl.superClass, func)
 		End If
@@ -4250,11 +4383,12 @@
 		Emit "{"
 		Emit "BBDEBUGDECL_CONST,"
 		Emit Enquote(decl.ident) + ","
-		Emit Enquote(TransDebugScopeType(decl.ty) + TransDebugMetaData(decl.metadata.metadataString)) + ","
+		Emit Enquote(TransDebugScopeType(decl.ty) + TransDebugScopeModifiers(decl) + TransDebugMetaData(decl.metadata.metadataString)) + ","
 		
 		_appInstance.mapStringConsts(decl.value)
 		
-		Emit ".const_value=(BBString*)&" + StringConstId(decl.value)
+		Emit ".const_value=(BBString*)&" + StringConstId(decl.value) + ","
+		Emit "(void (*)(void**))0"
 		Emit "},"
 
 	End Method
@@ -4270,7 +4404,7 @@
 			Emit "{"
 			Emit "BBDEBUGDECL_FIELD,"
 			Emit Enquote(decl.ident) + ","
-			Emit Enquote(TransDebugScopeType(decl.ty) + TransDebugMetaData(decl.metadata.metadataString)) + ","
+			Emit Enquote(TransDebugScopeType(decl.ty) + TransDebugScopeModifiers(decl) + TransDebugMetaData(decl.metadata.metadataString)) + ","
 
 			Local offset:String = ".field_offset=offsetof"
 			
@@ -4282,7 +4416,8 @@
 '			If WORD_SIZE = 8 Then
 '				Emit Bra("BBLONG") + offset
 '			Else
-			Emit offset
+			Emit offset + ","
+			Emit "(void (*)(void**))0"
 '			End If
 			'If Not TFunctionPtrType(decl.ty) Then
 			'	Emit TransType(decl.ty, classDecl.actual.munged) + " _" + classDecl.actual.munged.ToLower() + "_" + decl.ident.ToLower() + ";"
@@ -4299,12 +4434,13 @@
 	End Method
 	
 	Method EmitClassStandardMethodDebugScope(ident:String, ty:String, munged:String)
-			Emit "{"
-			Emit "BBDEBUGDECL_TYPEMETHOD,"
-			Emit Enquote(ident) + ","
-			Emit Enquote(ty) + ","
-			Emit ".func_ptr=(BBFuncPtr)&" + munged
-			Emit "},"
+		Emit "{"
+		Emit "BBDEBUGDECL_TYPEMETHOD,"
+		Emit Enquote(ident) + ","
+		Emit Enquote(ty) + ","
+		Emit ".func_ptr=(BBFuncPtr)&" + munged + ","
+		Emit "&" + munged + "_ReflectionWrapper"
+		Emit "},"
 	End Method
 	
 	Method TransDebugMetaData:String(meta:String)
@@ -4313,76 +4449,77 @@
 		End If
 	End Method
 
-	Method EmitBBClassFuncsDebugScope(decl:TFuncDecl)
-
-			Emit "{"
-			If decl.IsMethod() Then
-				Emit "BBDEBUGDECL_TYPEMETHOD,"
-			Else
-				Emit "BBDEBUGDECL_TYPEFUNCTION,"
-			End If
-			Emit Enquote(decl.ident) + ","
-			
-			Local s:String = "("
-			For Local i:Int = 0 Until decl.argDecls.length
-				If i Then
-					s:+ ","
-				End If
-				s:+ TransDebugScopeType(decl.argDecls[i].ty)
-			Next
-			s:+ ")"
-
-			If decl.retType Then
-				s:+ TransDebugScopeType(decl.retType)
-			End If
-
-			s:+ TransDebugMetaData(decl.metadata.metadataString)
-
-			Emit Enquote(s) + ","
-			If decl.IsMethod() Or decl.IsCTor() Then 
-				Emit ".func_ptr=(BBFuncPtr)&_" + decl.munged
-			Else
-				Emit ".func_ptr=(BBFuncPtr)&" + decl.munged
-			End If
-			Emit "},"
+	Method EmitBBClassFuncsDebugScope(classDecl:TClassDecl, decl:TFuncDecl)
+		Emit "{"
+		If decl.IsMethod() Or decl.IsCTor() Then
+			Emit "BBDEBUGDECL_TYPEMETHOD,"
+		Else
+			Emit "BBDEBUGDECL_TYPEFUNCTION,"
+		End If
+		Emit Enquote(decl.ident) + ","
+		
+		Local s:String = "("
+		For Local i:Int = 0 Until decl.argDecls.length
+			If i Then
+				s:+ ","
+			End If
+			s:+ TransDebugScopeType(decl.argDecls[i].ty)
+		Next
+		s:+ ")"
+
+		If decl.retType And Not decl.IsCTor() Then
+			s:+ TransDebugScopeType(decl.retType)
+		End If
+
+		s:+ TransDebugScopeModifiers(decl) + TransDebugMetaData(decl.metadata.metadataString)
+
+		Emit Enquote(s) + ","
+		Local funcname:String
+		If decl.IsCTor() Then
+			' only parameterized constructors here
+			' the default constructor is handled as a special case in EmitClassFuncsDebugScope
+			funcname = MungedConstructorName(classDecl, decl)
+		Else If decl.IsMethod() Then 
+			funcname = "_" + decl.munged
+		Else
+			funcname = decl.munged
+		End If
+		Emit ".func_ptr=(BBFuncPtr)&" + funcname + ","
+		Emit "&" + funcname + "_ReflectionWrapper"
+		Emit "},"
 	End Method
 
 	Method BBClassClassFuncsDebugScopeBuildList(classDecl:TClassDecl, list:TList)
 		'Local reserved:String = ",New,Delete,ToString,Compare,SendMessage,_reserved1_,_reserved2_,_reserved3_,".ToLower()
-
-		For Local decl:TDecl=EachIn classDecl.GetAllFuncDecls(Null, False)
-			Local fdecl:TFuncDecl =TFuncDecl( decl )
-			If fdecl
-				If Not fdecl.IsSemanted()
-					fdecl.Semant()
-				End If
-				If Not classDecl.IsInterface() And fdecl.IsAbstract() Then
-					Continue
-				End If
-
-				If Not equalsBuiltInFunc(classDecl, fdecl) Then
-				
-					Local ignore:Int
-					Local link:TLink=list._head._succ
-					While link<>list._head
-						Local ofdecl:TFuncDecl = TFuncDecl(link._value)
-						If fdecl.ident = ofdecl.ident And fdecl.EqualsArgs(ofdecl) And fdecl.scope <> ofdecl.scope Then
-							If fdecl.overrides Then
-								link._value = fdecl
-								ignore = True
-								Exit
-							End If
-						EndIf
-						link = link._succ
-					Wend
-
-					If Not ignore Then
-						list.AddLast(fdecl)
-					End If
-				
-					Continue
-				End If
-			EndIf
+		
+		Local funcDecls:TFuncDecl[] = classDecl.GetAllFuncDecls(Null, False)
+		
+		For Local fdecl:TFuncDecl = EachIn funcDecls
+			If Not fdecl.IsSemanted()
+				fdecl.Semant()
+			End If
+			
+			If Not equalsBuiltInFunc(classDecl, fdecl) Then
+				Local ignore:Int
+				Local link:TLink=list._head._succ
+				While link<>list._head
+					Local ofdecl:TFuncDecl = TFuncDecl(link._value)
+					If fdecl.ident = ofdecl.ident And fdecl.EqualsArgs(ofdecl) And fdecl.scope <> ofdecl.scope Then
+						If fdecl.overrides Then
+							link._value = fdecl
+							ignore = True
+							Exit
+						End If
+					EndIf
+					link = link._succ
+				Wend
+
+				If Not ignore Then
+					list.AddLast(fdecl)
+				End If
+			
+				Continue
+			End If
 		Next
 	End Method
 	
@@ -4392,9 +4529,9 @@
 		Local list:TList = New TList
 		
 		BBClassClassFuncsDebugScopeBuildList(classDecl, list)
-	
+		
 		For Local fdecl:TFuncDecl = EachIn list
-			EmitBBClassFuncsDebugScope( fdecl )
+			EmitBBClassFuncsDebugScope(classDecl, fdecl)
 		Next
 
 	End Method
@@ -4414,27 +4551,79 @@
 			ret = "()"
 		End If
 		
-		If Not classDecl.IsInterface() Then
-			EmitClassStandardMethodDebugScope("New", ret, "_" + classid + "_New")
-		End If
-	
-		If classHasFunction(classDecl, "ToString") Then
-			EmitClassStandardMethodDebugScope("ToString", "()$", "_" + classidForFunction(classDecl, "ToString") + "_ToString")
+		If Not classDecl.IsInterface() And Not classDecl.IsStruct() Then
+			Local newDecl:TDecl = classGetFunction(classDecl, "New")
+			If newDecl Then
+				EmitClassStandardMethodDebugScope("New", ret + TransDebugScopeModifiers(newDecl) , "_" + classid + "_New")
+			Else
+				EmitClassStandardMethodDebugScope("New", ret, "_" + classid + "_New")
+			End If
+		End If
+	
+		Local toStringDecl:TDecl = classGetFunction(classDecl, "ToString")
+		If toStringDecl Then
+			EmitClassStandardMethodDebugScope("ToString", "()$" + TransDebugScopeModifiers(toStringDecl), "_" + classidForFunction(classDecl, "ToString") + "_ToString")
 			'Emit "_" + classid + "_ToString,"
 		End If
 
-		If classHasFunction(classDecl, "Compare") Then
-			EmitClassStandardMethodDebugScope("Compare", "(:Object)i", "_" + classidForFunction(classDecl, "Compare") + "_Compare")
+		Local compareDecl:TDecl = classGetFunction(classDecl, "Compare")
+		If compareDecl Then
+			EmitClassStandardMethodDebugScope("Compare", "(:Object)i" + TransDebugScopeModifiers(compareDecl), "_" + classidForFunction(classDecl, "Compare") + "_Compare")
 			'Emit "_" + classid + "_ObjectCompare,"
 		End If
 
-		If classHasFunction(classDecl, "SendMessage") Then
-			EmitClassStandardMethodDebugScope("SendMessage", "(:Object, :Object):Object", "_" + classidForFunction(classDecl, "SendMessage") + "_SendMessage")
+		Local sendMessageDecl:TDecl = classGetFunction(classDecl, "SendMessage")
+		If sendMessageDecl Then
+			EmitClassStandardMethodDebugScope("SendMessage", "(:Object, :Object):Object" + TransDebugScopeModifiers(sendMessageDecl), "_" + classidForFunction(classDecl, "SendMessage") + "_SendMessage")
 			'Emit "_" + classid + "_SendMessage,"
 		End If
 
 		EmitBBClassClassFuncsDebugScope(classDecl)
 
+	End Method
+	
+	Method EmitClassFuncsDebugScopeCifs(classDecl:TClassDecl)
+		
+		If classDecl.IsExtern() Return
+		
+		Local classid$=classDecl.munged
+		Local superid$
+		If classDecl.superClass Then
+			superid = classDecl.superClass.actual.munged
+		End If
+		
+		Local list:TList = New TList
+		
+		BBClassClassFuncsDebugScopeBuildList(classDecl, list)
+		
+		For Local func:TFuncDecl = EachIn list
+			Local s:String
+			If func.IsMethod() Or func.IsCTor() Then
+				s :+ "&ffi_type_pointer"
+			End If
+			For Local i:Int = 0 Until func.argDecls.length
+				If s Then
+					s :+ ","
+				End If
+				s :+ TransCifType(func.argDecls[i].ty)
+			Next
+			Emit "ffi_type * bbCif_" + func.munged + "_arg_types[] = [" + s + "];"
+			
+			Emit "BBCif bbCif_" + func.munged + " = {"
+			Emit "FFI_DEFAULT_ABI,"
+			Local count:Int
+			If func.IsMethod() Then
+				count = 1
+			End If
+			Emit count + func.argDecls.length + ","
+			If TVoidType(func.retType) Then
+				Emit "&ffi_type_void,"
+			Else
+				Emit TransCifType(func.retType) + ","
+			End If
+			Emit "bbCif_" + func.munged + "_arg_types"
+			Emit "};"
+		Next
 	End Method
 	
 	Method EmitClassGlobalDebugScope( classDecl:TClassDecl, scopeIndex:Int Var )
@@ -4448,13 +4637,14 @@
 		Emit "{"
 		Emit "BBDEBUGDECL_GLOBAL,"
 		Emit Enquote(decl.ident) + ","
-		Emit Enquote(TransDebugScopeType(decl.ty) + TransDebugMetaData(decl.metadata.metadataString)) + ","
+		Emit Enquote(TransDebugScopeType(decl.ty) + TransDebugScopeModifiers(decl) + TransDebugMetaData(decl.metadata.metadataString)) + ","
 		If decl.IsThreaded() Then
-			Emit ".var_address=0"
+			Emit ".var_address=0,"
 			decl.scopeIndex = scopeIndex
 		Else
-			Emit ".var_address=(void*)&" + decl.munged
-		End If
+			Emit ".var_address=(void*)&" + decl.munged + ","
+		End If
+		Emit "(void (*)(void**))0"
 		Emit "},"
 	End Method
 
@@ -4463,9 +4653,6 @@
 		For Local decl:TDecl=EachIn classDecl.GetAllFuncDecls(Null, False)
 			Local fdecl:TFuncDecl =TFuncDecl( decl )
 			If fdecl
-				If Not classDecl.IsInterface() And fdecl.IsAbstract() Then
-					Continue
-				End If
 
 				If Not equalsBuiltInFunc(classDecl, fdecl) Then
 					count :+ 1
@@ -4491,27 +4678,30 @@
 	Method DebugScopeDeclCount:Int(classDecl:TClassDecl)
 		Local count:Int = 2 ' "New" counts as first one
 		
-		' but we don't use "New" for interfaces...
+		' but we don't use "New" for interfaces or for extern structs...
 		If classDecl.IsInterface() Or (classDecl.IsExtern() And classDecl.IsStruct()) Then
 			count :- 1
-		End If
-
-		' consts		
+		' ...or for regular structs, because GetAllFuncDecls returns New() but equalsBuiltInFunc returns False for it
+		Else If classDecl.IsStruct() Then
+			count :- 1
+		End If
+		
+		' consts
 		CountClassConstsDebugScope(classDecl, count)
 
 		' fields
 		CountClassFieldsDebugScope(classDecl, count)
 		
 		' standard methods
-		If classHasFunction(classDecl, "ToString") Then
+		If classGetFunction(classDecl, "ToString") Then
 			count :+ 1
 		End If
 
-		If classHasFunction(classDecl, "Compare") Then
+		If classGetFunction(classDecl, "Compare") Then
 			count :+ 1
 		End If
 
-		If classHasFunction(classDecl, "SendMessage") Then
+		If classGetFunction(classDecl, "SendMessage") Then
 			count :+ 1
 		End If
 		
@@ -4593,7 +4783,7 @@
 					Next
 				End If
 		
-				If classHierarchyHasFunction(classDecl, "Delete") Then
+				If classHierarchyGetFunction(classDecl, "Delete") Then
 					EmitClassDeclDelete(classDecl)
 				End If
 			End If
@@ -4662,6 +4852,8 @@
 
 		End If
 
+		' cif defs
+		'EmitClassFuncsDebugScopeCifs(classDecl)
 			
 		'Emit "struct _" + classid + "_DebugScope{"
 		'Emit "int kind;"
@@ -4685,7 +4877,7 @@
 		Else
 			Emit "BBDEBUGSCOPE_USERTYPE,"
 		End If
-		Emit EnQuote(classDecl.ident + TransDebugMetaData(classDecl.metadata.metadataString)) + ","
+		Emit Enquote(classDecl.ident + TransDebugScopeModifiers(classDecl) + TransDebugMetaData(classDecl.metadata.metadataString)) + ","
 
 		Emit "{"
 		
@@ -4703,9 +4895,23 @@
 		' debug func decls
 		EmitClassFuncsDebugScope(classDecl)
 		
-		Emit "{"
-		Emit "BBDEBUGDECL_END"
-		Emit "}"
+		If classDecl.IsStruct() Then
+			Emit "{"
+			Emit "BBDEBUGDECL_END,"
+			Emit "(char*)0,"
+			Emit "(char*)0,"
+			Emit ".struct_size=sizeof(struct " + classid + "),"
+			Emit "(void (*)(void**))0"
+			Emit "}"
+		Else
+			Emit "{"
+			Emit "BBDEBUGDECL_END,"
+			Emit "(char*)0,"
+			Emit "(char*)0,"
+			Emit ".var_address=(void*)0,"
+			Emit "(void (*)(void**))0"
+			Emit "}"
+		End If
 		Emit "}"
 
 		Emit "};"
@@ -4713,11 +4919,11 @@
 		Local fdecls:TFuncDecl[] = classDecl.GetAllFuncDecls()
 		Local implementedInterfaces:TMap = classDecl.GetInterfaces()
 		Local ifcCount:Int
-
+		
 		If Not classDecl.IsStruct() Then
 
 			' interface class implementation
-			If Not classDecl.IsInterface()
+			'If Not classDecl.IsInterface()
 				If Not implementedInterfaces.IsEmpty() Then
 					Emit "struct " + classid + "_vdef {"
 					For Local ifc:TClassDecl = EachIn implementedInterfaces.Values()
@@ -4777,7 +4983,7 @@
 					Emit ifcCount
 					Emit "};~n"
 				End If
-			End If
+			'End If
 			
 			Emit "struct BBClass_" + classid + " " + classid + "={"
 	
@@ -4792,25 +4998,25 @@
 			' standard methods
 			Emit "(void (*)(BBOBJECT))_" + classid + "_New,"
 	
-			If Not classHierarchyHasFunction(classDecl, "Delete") Then
+			If Not classHierarchyGetFunction(classDecl, "Delete") Then
 				Emit "bbObjectDtor,"
 			Else
 				Emit "(void (*)(BBOBJECT))_" + classid + "_Delete,"
 			End If
 	
-			If classHierarchyHasFunction(classDecl, "ToString") Then
+			If classHierarchyGetFunction(classDecl, "ToString") Then
 				Emit "_" + classidForFunction(classDecl, "ToString") + "_ToString,"
 			Else
 				Emit "bbObjectToString,"
 			End If
 	
-			If classHierarchyHasFunction(classDecl, "Compare") Then
+			If classHierarchyGetFunction(classDecl, "Compare") Then
 				Emit "_" + classidForFunction(classDecl, "Compare") + "_Compare,"
 			Else
 				Emit "bbObjectCompare,"
 			End If
 	
-			If classHierarchyHasFunction(classDecl, "SendMessage") Then
+			If classHierarchyGetFunction(classDecl, "SendMessage") Then
 				Emit "_" + classidForFunction(classDecl, "SendMessage") + "_SendMessage,"
 			Else
 				Emit "bbObjectSendMessage,"
@@ -4845,11 +5051,11 @@
 			'		Continue
 			'	EndIf
 			'Next
-	
+			
 			'gc mark
 			'Emit "void mark();"
-	
-			If classDecl.IsInterface() Or implementedInterfaces.IsEmpty() Then
+			
+			If implementedInterfaces.IsEmpty() Then
 				' itable
 				Emit "0,"
 				' extra pointer
@@ -4859,7 +5065,7 @@
 				' extra pointer
 				Emit "0,"
 			End If
-	
+			
 			' obj_size
 			Emit TransObjectSize(classDecl)
 			' instance_count
@@ -4967,7 +5173,7 @@
 
 		For Local value:TEnumValueDecl = EachIn decl.values
 			Emit "{"
-			Emit "BBDEBUGDECL_GLOBAL,"
+			Emit "BBDEBUGDECL_CONST,"
 			Emit Enquote(value.ident) + ","
 			Emit Enquote(TransDebugScopeType(ty) + TransDebugMetaData(decl.metadata.metadataString)) + ","
 
@@ -4979,7 +5185,11 @@
 		Next
 		
 		Emit "{"
-		Emit "BBDEBUGDECL_END"
+		Emit "BBDEBUGDECL_END,"
+		Emit "(char*)0,"
+		Emit Enquote(TransDebugScopeType(decl.ty)) + ","
+		Emit ".is_flags_enum=" + decl.isFlags + ","
+		Emit "(void (*)(void**))0"
 		Emit "}"
 		Emit "}"
 
@@ -5091,25 +5301,27 @@
 		Return t
 	End Method
 	
+	Method MungedConstructorName:String( classDecl:TClassDecl, fdecl:TFuncDecl )
+		If fdecl.argDecls.Length Then
+			If classDecl = fdecl.scope Then
+				Return "_" + fdecl.munged
+			Else
+				Return "_" + classDecl.munged + "_" + fdecl.ident + MangleMethod(fdecl)
+			End If
+		Else
+			Return "_" + classDecl.munged + "_New"
+		End If
+	End Method
+	
 	Method EmitClassDeclNew( classDecl:TClassDecl, fdecl:TFuncDecl )
+		Local id:String = MungedConstructorName(classDecl, fdecl)
+		
 		Local classid$=classDecl.munged
 		Local superid$
 		If classDecl.superClass Then
 			superid = classDecl.superClass.actual.munged
 		End If
-
-		Local t:String = "void _" 
-		
-		If fdecl.argDecls.Length Then
-			If classDecl = fdecl.scope Then
-				t :+ fdecl.munged
-			Else
-				t :+ classDecl.munged + "_" + fdecl.ident + MangleMethod(fdecl)
-			End If
-		Else
-			t :+ classid + "_New"
-		End If
-
+		
 		'Find decl we override
 		Local odecl:TFuncDecl=fdecl
 
@@ -5144,7 +5356,7 @@
 			If arg.ty.EqualsType( oarg.ty ) Continue
 		Next
 		
-		Emit t + Bra(args) + " {"
+		Emit "void " + id + Bra(args) + " {"
 		
 		Local newDecl:TNewDecl = TNewDecl(fdecl)
 		
@@ -5159,7 +5371,7 @@
 					Emit "bbObjectCtor((BBOBJECT)o);"
 				Else
 					If fdecl And fdecl.scope <> classDecl And fdecl.argDecls.Length Then
-						t = "o"
+						Local t:String = "o"
 						For Local i:Int=0 Until fdecl.argDecls.Length
 							Local arg:TArgDecl=fdecl.argDecls[i]
 							t :+ ", " + arg.munged
@@ -5273,6 +5485,7 @@
 
 		'
 		Emit "}"
+		EmitReflectionWrapper classDecl, fdecl
 	End Method
 
 	Method EmitClassDeclNewList( classDecl:TClassDecl )
@@ -5566,7 +5779,7 @@
 	Method EmitClassDeclDeleteDtor( classDecl:TClassDecl )
 		Local superid$=classDecl.superClass.actual.munged
 		
-		If classDecl.superClass.ident = "Object" Or Not classHierarchyHasFunction(classDecl.superClass, "Delete") Then
+		If classDecl.superClass.ident = "Object" Or Not classHierarchyGetFunction(classDecl.superClass, "Delete") Then
 			Emit "bbObjectDtor((BBOBJECT)o);"
 		Else
 			Emit "_" + superid + "_Delete((" + TransObject(TScopeDecl(classDecl.superClass.actual)) + ")o);"
@@ -5951,7 +6164,7 @@
 				EmitIfcConstDecl(cDecl)
 			Next
 	
-				' global
+			' global
 			For Local gDecl:TGlobalDecl = EachIn classDecl.Decls()
 				gDecl.Semant()
 	
@@ -5959,7 +6172,7 @@
 			Next
 	
 	
-				' field
+			' field
 			For Local fDecl:TFieldDecl = EachIn classDecl.Decls()
 				fDecl.Semant()
 	
@@ -5973,11 +6186,11 @@
 		
 			If Not classDecl.templateSource Then
 
-				If Not (classDecl.attrs & CLASS_INTERFACE) And Not classDecl.IsStruct() And Not classHierarchyHasFunction(classDecl, "New") Then
+				If Not (classDecl.attrs & CLASS_INTERFACE) And Not classDecl.IsStruct() And Not classHierarchyGetFunction(classDecl, "New") Then
 					Emit "-New()=" + Enquote("_" + classDecl.munged + "_New")
 				End If
 
-				If classHierarchyHasFunction(classDecl, "Delete") Then
+				If classHierarchyGetFunction(classDecl, "Delete") Then
 					Emit "-Delete()=" + Enquote("_" + classDecl.munged + "_Delete")
 				End If
 	
@@ -6946,15 +7159,15 @@
 
 		' strings
 		' generate sized structs
-		Local sizes:TIntMap = New TIntMap
+		Local sizes:TMap = New TMap
 		For Local s:String = EachIn app.stringConsts.Keys()
 			If s Then
 				Local key:TStringConst = TStringConst(app.stringConsts.ValueForKey(s))
 
 				If key.used > 0 Then
-					If Not sizes.Contains(s.length) Then
+					If Not sizes.Contains(String s.length) Then
 						Emit "struct BBString_" + s.length + "{BBClass_String* clas;BBULONG hash;int length;BBChar buf[" + s.length + "];};"
-						sizes.Insert(s.length, "")
+						sizes.Insert(String s.length, "")
 					End If
 				End If
 			End If
@@ -7300,4 +7513,3 @@
 	End Method
 	
 End Type
-

GWRon avatar Mar 25 '25 16:03 GWRon

There's a "hide whitespace" option if you click on the gear icon... :)

woollybah avatar Mar 25 '25 16:03 woollybah

There's a "hide whitespace" option if you click on the gear icon... :)

Good point - for me the browser page did not respond after trying to "load diff" - it showed the content (all green) but the "..." did not lead to a reaction (guess file too big, browser tab enjoying the load...).

GWRon avatar Mar 25 '25 16:03 GWRon

How can we assist you for the PR (bcc and brl) -- assuming you are already writing some "(unit)test" ?

GWRon avatar Mar 25 '25 16:03 GWRon