Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 58 additions & 39 deletions Basis/Packages/com.cnlohr.cilbox/Cilbox.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ public class CilboxHeapInstance

public class CilboxMethod
{
private static readonly ArrayPool<StackElement> stackPool = ArrayPool<StackElement>.Create();

public CilboxClass parentClass;
public int MaxStackSize;
public String methodName;
Expand Down Expand Up @@ -154,40 +156,48 @@ public object Interpret( CilboxProxy ths, object [] parametersIn )

int plen = parametersIn?.Length ?? 0;
int thisOffset = isStatic ? 0 : 1;
int parameterCount = plen + thisOffset;
StackElement [] paramStackArray = stackPool.Rent(parameterCount + Cilbox.defaultStackSize);
ArraySegment<StackElement> parameters = new (paramStackArray, 0, parameterCount);
ArraySegment<StackElement> stackBuffer = new (paramStackArray, parameterCount, Cilbox.defaultStackSize);

StackElement [] parameters = new StackElement[plen+thisOffset];
StackElement [] stackBuffer = new StackElement[Cilbox.defaultStackSize];

if( isStatic )
{
for( int p = 0; p < plen; p++ )
parameters[p].Load( parametersIn[p] );
}
else
{
parameters[0].Load( ths );
for( int p = 0; p < plen; p++ )
parameters[p+1].Load( parametersIn[p] );
plen++;
}

object ret = null;
if( !parentClass.box.InterpreterEntry(this) ) return null;
try
{
ret = InterpretInner( stackBuffer, parameters ).AsObject();
if( isStatic )
{
for( int p = 0; p < plen; p++ )
paramStackArray[p].Load( parametersIn[p] );
}
else
{
paramStackArray[0].Load( ths );
for( int p = 0; p < plen; p++ )
paramStackArray[p+1].Load( parametersIn[p] );
plen++;
}

object ret = null;
if( !parentClass.box.InterpreterEntry(this) ) return null;
try
{
ret = InterpretInner( stackBuffer, parameters ).AsObject();
}
catch( Exception e )
{
parentClass.box.InterpreterExit();
if( ths != null ) ths.DisableProxy();
else parentClass.box.DisableWithReason(e.ToString());
if( e is CilboxUnhandledInterpretedException uhe && uhe.Throwee is System.Exception te ) throw te;
throw;
}
parentClass.box.InterpreterExit();

return ret;
}
catch( Exception e )
finally
{
parentClass.box.InterpreterExit();
if( ths != null ) ths.DisableProxy();
else parentClass.box.DisableWithReason(e.ToString());
if( e is CilboxUnhandledInterpretedException uhe && uhe.Throwee is System.Exception te ) throw te;
throw;
stackPool.Return(paramStackArray, clearArray: true);
}
parentClass.box.InterpreterExit();

return ret;
}

private StackElement InterpretInner( ArraySegment<StackElement> stackBufferIn, ArraySegment<StackElement> parametersIn )
Expand Down Expand Up @@ -446,13 +456,17 @@ private StackElement InterpretInner( ArraySegment<StackElement> stackBufferIn, A
Type[] paTypes = dt.nativeParameterTypes;
int numFields = paTypes.Length;
object [] callpar = new object[numFields];
StackElement [] callpar_se = new StackElement[numFields];
StackElement [] callpar_se = null;

int ik;
for( ik = 0; ik < numFields; ik++ )
{
StackElement se = stackBuffer[sp--];
callpar_se[numFields-ik-1] = se;
if( se.type == StackType.Address || se.type == StackType.NativeHandle )
{
callpar_se ??= new StackElement[numFields];
callpar_se[numFields-ik-1] = se;
}
object o = se.AsObject(box);
Type t = paTypes[numFields-ik-1];

Expand Down Expand Up @@ -599,17 +613,22 @@ private StackElement InterpretInner( ArraySegment<StackElement> stackBufferIn, A
}
}

// Possibly copy back any references.
for( ik = 0; ik < numFields; ik++ )
// Possibly copy back any references. Most native calls have no by-ref
// operands, so avoid allocating a parallel StackElement[] unless one
// was actually observed while popping arguments.
if( callpar_se != null )
{
StackElement se = callpar_se[ik];
if (se.type == StackType.Address)
{
callpar_se[ik].DereferenceLoadAddress( callpar[ik] );
}
else if ( se.type == StackType.NativeHandle )
for( ik = 0; ik < numFields; ik++ )
{
callpar_se[ik].DereferenceLoadNativeHandle( box, callpar[ik] );
StackElement se = callpar_se[ik];
if (se.type == StackType.Address)
{
callpar_se[ik].DereferenceLoadAddress( callpar[ik] );
}
else if ( se.type == StackType.NativeHandle )
{
callpar_se[ik].DereferenceLoadNativeHandle( box, callpar[ik] );
}
}
}

Expand Down
Loading