Ver código fonte

Merge pull request #660 from bmx-ng/task/659-null-function-wrappers

Use wrapper functions for Null Function Error function pointers
Brucey 1 ano atrás
pai
commit
05db1e7686
2 arquivos alterados com 118 adições e 39 exclusões
  1. 87 38
      ctranslator.bmx
  2. 31 1
      decl.bmx

+ 87 - 38
ctranslator.bmx

@@ -557,7 +557,7 @@ Type TCTranslator Extends TTranslator
 					End If
 				End If
 			End If
-			If TFunctionPtrType( ty) Return "(&brl_blitz_NullFunctionError)" ' todo ??
+			If TFunctionPtrType( ty) Return "(&" + TransNullFunctionErrorWrapper(TFunctionPtrType(ty)) + ")"
 			If TEnumType( ty ) Then
 				If TEnumType( ty ).decl.isFlags Then
 					Return "0"
@@ -997,7 +997,7 @@ t:+"NULLNULLNULL"
 					End If
 				Else
 					If TFunctionPtrType(gdecl.ty) Then
-						glob :+ "&brl_blitz_NullFunctionError"
+						glob :+ "&" + TransNullFunctionErrorWrapper(TFunctionPtrType(gdecl.ty))
 					Else
 						glob :+ "0"
 					End If
@@ -3538,6 +3538,45 @@ End Rem
 		EndLocalScope
 	End Method
 
+	Method TransFuncDeclArgs:String(decl:TFuncDecl, argCasts:TStack, odecl:TFuncDecl)
+		Local args:String
+
+		' pass object for method
+		If decl.IsMethod() Then
+			args :+ TransObject(decl.scope, True) + " o"
+		End If
+
+		'Local argCasts:TStack =New TStack
+		For Local i:Int=0 Until decl.argDecls.Length
+			Local arg:TArgDecl=decl.argDecls[i]
+			Local oarg:TArgDecl=odecl.argDecls[i]
+			MungDecl arg, True
+			If args args:+","
+			If Not TFunctionPtrType(oarg.ty) Then
+				If Not odecl.castTo Then
+					args:+TransType( oarg.ty, arg.munged )+" "+arg.munged
+					If TArrayType(oarg.ty) And TArrayType(oarg.ty).isStatic Then
+						args :+ "[" + TArrayType(oarg.ty).length + "]"
+					End If
+				Else
+					args:+ oarg.castTo + " " + arg.munged
+				End If
+			Else
+				If Not odecl.castTo Then
+					args:+TransType( oarg.ty, arg.munged )
+				Else
+					args:+ oarg.castTo
+				End If
+			End If
+			If arg.ty.EqualsType( oarg.ty ) Continue
+			Local t$=arg.munged
+			arg.munged=""
+			MungDecl arg
+			argCasts.Push TransType( arg.ty, arg.munged )+" "+arg.munged+"=static_cast<"+TransType(arg.ty, "")+" >"+Bra(t)+";"
+		Next
+
+		Return args
+	End Method
 
 
 	Method EmitFuncDecl( decl:TFuncDecl, proto:Int = False, classFunc:Int = False )
@@ -3587,42 +3626,10 @@ End Rem
 			odecl=odecl.overrides
 		Wend
 
-		'Generate 'args' string and arg casts
-		Local args$
-
-		' pass object for method
-		If decl.IsMethod() Then
-			args :+ TransObject(decl.scope, True) + " o"
-		End If
-
 		Local argCasts:TStack =New TStack
-		For Local i:Int=0 Until decl.argDecls.Length
-			Local arg:TArgDecl=decl.argDecls[i]
-			Local oarg:TArgDecl=odecl.argDecls[i]
-			MungDecl arg, True
-			If args args:+","
-			If Not TFunctionPtrType(oarg.ty) Then
-				If Not odecl.castTo Then
-					args:+TransType( oarg.ty, arg.munged )+" "+arg.munged
-					If TArrayType(oarg.ty) And TArrayType(oarg.ty).isStatic Then
-						args :+ "[" + TArrayType(oarg.ty).length + "]"
-					End If
-				Else
-					args:+ oarg.castTo + " " + arg.munged
-				End If
-			Else
-				If Not odecl.castTo Then
-					args:+TransType( oarg.ty, arg.munged )
-				Else
-					args:+ oarg.castTo
-				End If
-			End If
-			If arg.ty.EqualsType( oarg.ty ) Continue
-			Local t$=arg.munged
-			arg.munged=""
-			MungDecl arg
-			argCasts.Push TransType( arg.ty, arg.munged )+" "+arg.munged+"=static_cast<"+TransType(arg.ty, "")+" >"+Bra(t)+";"
-		Next
+
+		'Generate 'args' string and arg casts
+		Local args:String = TransFuncDeclArgs(decl, argCasts, odecl)
 
 		Local id$=decl.munged
 
@@ -5178,7 +5185,7 @@ End Rem
 							fld :+ "= &bbNullObject;"
 						End If
 					Else If TFunctionPtrType(decl.ty) Then
-						fld :+ "= &brl_blitz_NullFunctionError;"
+						fld :+ "= &" + TransNullFunctionErrorWrapper(TFunctionPtrType(decl.ty)) + ";"
 					Else If TStringType(decl.ty) Then
 						fld :+ "= &bbEmptyString;"
 					Else If TArrayType(decl.ty) Then
@@ -5213,6 +5220,27 @@ End Rem
 		Emit "}"
 	End Method
 
+	Method TransNullFunctionErrorWrapper:String(fptr:TFunctionPtrType)
+
+		Local odecl:TFuncDecl=fptr.func
+		While odecl.overrides
+			odecl=odecl.overrides
+		Wend
+		Local argCasts:TStack =New TStack
+
+		Local id:String = fptr.ToString()
+
+		Local args:String = TransFuncDeclArgs(fptr.func, argCasts, odecl)
+
+		_appInstance.MapFuncErrorPtrWrapper(args, fptr)
+
+		Local fp:TFuncErrorPtrWrapper = TFuncErrorPtrWrapper(_app.funcErrorPtrWrappers.ValueForKey(id))
+		fp.used = 1
+
+		Return fp.id
+
+	End Method
+
 	Method EmitClassDeclNewList( classDecl:TClassDecl )
 		Local classid$=classDecl.munged
 
@@ -6929,6 +6957,27 @@ End If
 				End If
 			End If
 		Next
+
+		' function ptr wrappers
+		For Local f:String = EachIn app.funcErrorPtrWrappers.Keys()
+			Local wrapper:TFuncErrorPtrWrapper = TFuncErrorPtrWrapper(app.funcErrorPtrWrappers.ValueForKey(f))
+			
+			If wrapper Then
+				Local odecl:TFuncDecl=wrapper.fptr.func
+				While odecl.overrides
+					odecl=odecl.overrides
+				Wend
+
+				Local argCasts:TStack =New TStack
+				
+				Emit "static " + TransType(wrapper.fptr.func.retType, "") + " " + wrapper.id + "(" + TransFuncDeclArgs(wrapper.fptr.func, argCasts, odecl) + ") {"
+				Emit "brl_blitz_NullFunctionError();"
+				If wrapper.fptr.func.retType And Not TVoidType(wrapper.fptr.func.retType) Then
+					Emit "return " + TransValue(wrapper.fptr.func.retType, Null) + ";"
+				End If
+				Emit "}"
+			End If
+		Next
 		
 		' scope defs
 		If Not app.scopedefs.IsEmpty() Then

+ 31 - 1
decl.bmx

@@ -4265,6 +4265,9 @@ Type TAppDecl Extends TScopeDecl
 	
 	Field stringConsts:TMap = New TMap
 	Field stringConstCount:Int
+
+	Field funcErrorPtrWrappers:TMap = New TMap
+	Field funcErrorPtrWrapperCount:Int
 	
 	Field incbins:TList = New TList
 	Field genIncBinHeader:Int = False
@@ -4447,7 +4450,27 @@ Type TAppDecl Extends TScopeDecl
 			End If
 		Next
 	End Method
-	
+
+	Method MapFuncErrorPtrWrapper(id:String, fptr:TFunctionPtrType)
+
+		Local value:String = fptr.ToString()
+
+		Local fp:TFuncErrorPtrWrapper = TFuncErrorPtrWrapper(funcErrorPtrWrappers.ValueForKey(value))
+		
+		If Not fp Then
+			Local fp:TFuncErrorPtrWrapper = New TFuncErrorPtrWrapper
+			fp.fptr = fptr
+			fp.count = 1
+			fp.id = "_fpw" + funcErrorPtrWrapperCount
+
+			funcErrorPtrWrappers.Insert(value, fp)
+
+			funcErrorPtrWrapperCount:+ 1
+		Else
+			fp.count :+ 1
+		End If
+	End Method
+
 End Type
 
 Type TStringConst
@@ -4458,6 +4481,13 @@ Type TStringConst
 
 End Type
 
+Type TFuncErrorPtrWrapper
+	Field fptr:TFunctionPtrType
+	Field id:String
+	Field count:Int
+	Field used:Int
+End Type
+
 Type TTemplateDets
 
 	Field instArgs:TType[]