Skip to content
Open
Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion src/OneScript.Core/Exceptions/IExceptionInfoFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace OneScript.Exceptions
/// </summary>
public interface IExceptionInfoFactory
{
BslObjectValue GetExceptionInfo(Exception exception);
BslValue GetExceptionInfo(Exception exception);

string GetExceptionDescription(IRuntimeContextInstance exceptionInfo);

Expand Down
8 changes: 1 addition & 7 deletions src/OneScript.Native/Compiler/ExpressionHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -595,18 +595,12 @@ public static Expression CallOfInstanceMethod(Expression instance, string name,

public static Expression AccessModuleVariable(ParameterExpression thisArg, int variableIndex)
{
var contextProperty = PropertiesCache.GetOrAdd(
typeof(NativeClassInstanceWrapper),
nameof(NativeClassInstanceWrapper.Context),
BindingFlags.Instance | BindingFlags.Public);

var contextAccess = Expression.Property(thisArg, contextProperty);
var getVariableMethod = OperationsCache.GetOrAdd(
typeof(IAttachableContext),
nameof(IAttachableContext.GetVariable),
BindingFlags.Instance | BindingFlags.Public);

var iVariable = Expression.Call(contextAccess, getVariableMethod, Expression.Constant(variableIndex));
var iVariable = Expression.Call(thisArg, getVariableMethod, Expression.Constant(variableIndex));
var valueProperty = PropertiesCache.GetOrAdd(
typeof(IValueReference),
nameof(IValueReference.BslValue),
Expand Down
112 changes: 39 additions & 73 deletions src/OneScript.Native/Compiler/MethodCompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ private void CompileFragment(BslSyntaxNode node, Action<BslSyntaxNode> visitor)
private void FillParameterVariables()
{
_declaredParameters = _method.GetBslParameters();
_thisParameter = _method.IsInstance ? Expression.Parameter(typeof(NativeClassInstanceWrapper), "$this") : null;
_thisParameter = _method.IsInstance ? Expression.Parameter(typeof(IAttachableContext), "$this") : null;

var localScope = Symbols.GetScope(Symbols.ScopeCount-1);
foreach (var parameter in _declaredParameters)
Expand Down Expand Up @@ -1107,56 +1107,13 @@ private static bool InjectedProcessNeeded(MethodInfo methodInfo)
}

protected override void VisitObjectProcedureCall(BslSyntaxNode node)
{
var target = _statementBuildParts.Pop();
var call = (CallNode) node;

var targetType = target.Type;
var name = call.Identifier.GetIdentifier();
if (targetType.IsObjectValue())
{
var methodInfo = FindMethodOfType(node, targetType, name);
var injectProcess = InjectedProcessNeeded(methodInfo);
var args = PrepareCallArguments(call.ArgumentList, methodInfo.GetParameters(), injectProcess);

_blocks.Add(Expression.Call(target, methodInfo, args));
}
else if (targetType.IsContext())
{
var contextCall = ExpressionHelpers.CallContextMethod(target, name, _processParameter,
PrepareDynamicCallArguments(call.ArgumentList));
_blocks.Add(contextCall);
}
else if (targetType.IsValue())
{
var contextCall = ExpressionHelpers.TryCallContextMethod(target, name, _processParameter,
PrepareDynamicCallArguments(call.ArgumentList));
_blocks.Add(contextCall);
}
else if (target is DynamicExpression)
{
var args = new List<Expression>();
args.Add(target);
args.AddRange(PrepareDynamicCallArguments(call.ArgumentList));

var csharpArgs = new List<CSharpArgumentInfo>();
csharpArgs.Add(CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, default));
csharpArgs.AddRange(args.Select(x => CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, default)));

var binder = Microsoft.CSharp.RuntimeBinder.Binder.InvokeMember(
CSharpBinderFlags.InvokeSimpleName,
name,
null,
typeof(BslObjectValue),
csharpArgs);
{
_blocks.Add(CreateObjectMethodCall(node));
}

var objectExpr = Expression.Dynamic(binder, typeof(object), args);
_blocks.Add(ExpressionHelpers.ConvertToType(objectExpr, typeof(BslValue)));
}
else
{
AddError(NativeCompilerErrors.TypeIsNotAnObjectType(targetType), node.Location);
}
protected override void VisitObjectFunctionCall(BslSyntaxNode node)
{
_statementBuildParts.Push(CreateObjectMethodCall(node, true));
}

private IEnumerable<Expression> PrepareDynamicCallArguments(BslSyntaxNode argList)
Expand All @@ -1167,44 +1124,48 @@ private IEnumerable<Expression> PrepareDynamicCallArguments(BslSyntaxNode argLis
: Expression.Constant(BslSkippedParameterValue.Instance));
}

protected override void VisitObjectFunctionCall(BslSyntaxNode node)
{
private Expression CreateObjectMethodCall(BslSyntaxNode node, bool asFunction = false)
{
var target = _statementBuildParts.Pop();
var call = (CallNode) node;

var call = (CallNode)node;
var targetType = target.Type;
var name = call.Identifier.GetIdentifier();

if (targetType.IsObjectValue())
{
var methodInfo = FindMethodOfType(node, targetType, name);
if (methodInfo.ReturnType == typeof(void))
if (asFunction && methodInfo.ReturnType == typeof(void))
{
throw new NativeCompilerException(BilingualString.Localize(
$"Метод {targetType}.{name} не является функцией",
$"Method {targetType}.{name} is not a function"), ToCodePosition(node.Location));
}

var args = PrepareCallArguments(call.ArgumentList, methodInfo.GetParameters(), InjectedProcessNeeded(methodInfo));
_statementBuildParts.Push(Expression.Call(target, methodInfo, args));
return Expression.Call(target, methodInfo, args);
}
else if (targetType.IsContext())
{
_statementBuildParts.Push(ExpressionHelpers.CallContextMethod(target, name, _processParameter, PrepareDynamicCallArguments(call.ArgumentList)));
return ExpressionHelpers.CallContextMethod(target, name, _processParameter,
PrepareDynamicCallArguments(call.ArgumentList));
}
else if (targetType.IsValue())
{
var contextCall = ExpressionHelpers.TryCallContextMethod(target, name, _processParameter,
return ExpressionHelpers.TryCallContextMethod(target, name, _processParameter,
PrepareDynamicCallArguments(call.ArgumentList));
_statementBuildParts.Push(contextCall);
}
else if (target is DynamicExpression)
{
var args = new List<Expression>();
args.Add(target);
var args = new List<Expression>
{
target
};
args.AddRange(PrepareDynamicCallArguments(call.ArgumentList));

var csharpArgs = new List<CSharpArgumentInfo>();
csharpArgs.Add(CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, default));
var csharpArgs = new List<CSharpArgumentInfo>
{
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, default)
};
csharpArgs.AddRange(args.Select(x => CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, default)));

var binder = Microsoft.CSharp.RuntimeBinder.Binder.InvokeMember(
Expand All @@ -1215,12 +1176,11 @@ protected override void VisitObjectFunctionCall(BslSyntaxNode node)
csharpArgs);

var objectExpr = Expression.Dynamic(binder, typeof(object), args);
_statementBuildParts.Push(ExpressionHelpers.ConvertToType(objectExpr, typeof(BslValue)));
}
else
{
AddError(NativeCompilerErrors.TypeIsNotAnObjectType(targetType), node.Location);
return ExpressionHelpers.ConvertToType(objectExpr, typeof(BslValue));
}

AddError(NativeCompilerErrors.TypeIsNotAnObjectType(targetType), node.Location);
return null;
}

private MethodInfo FindMethodOfType(BslSyntaxNode node, Type targetType, string name)
Expand Down Expand Up @@ -1286,10 +1246,15 @@ private Expression CreateMethodCall(CallNode node)
var methodInfo = symbol.Method;
if (methodInfo is ContextMethodInfo contextMethod)
{
return DirectClrCall(
var call = DirectClrCall(
GetMethodBinding(binding, symbol),
contextMethod.GetWrappedMethod(),
args);

if (call.Type == typeof(IValue))
return Expression.TypeAs(call, typeof(BslValue));

return call;
}

if (methodInfo is BslNativeMethodInfo nativeMethod)
Expand Down Expand Up @@ -1328,9 +1293,8 @@ private Expression CreateBuiltInFunctionCall(CallNode node)
result = DirectConversionCall(node, typeof(DateTime));
break;
case Token.Type:
CheckArgumentsCount(node.ArgumentList, 1);
result = ExpressionHelpers.TypeByNameCall(CurrentTypeManager,
ConvertToExpressionTree(node.ArgumentList.Children[0].Children[0]));
var strType = DirectConversionCall(node, typeof(string));
result = ExpressionHelpers.TypeByNameCall(CurrentTypeManager, strType);
break;
case Token.ExceptionInfo:
CheckArgumentsCount(node.ArgumentList, 0);
Expand Down Expand Up @@ -1364,7 +1328,9 @@ private Expression GetRuntimeExceptionDescription()
var excVariable = _blocks.GetCurrentBlock().CurrentException;
Expression factoryArgument;
// нас вызвали вне попытки-исключения
factoryArgument = excVariable == null ? Expression.Constant(null, typeof(IRuntimeContextInstance)) : GetRuntimeExceptionObject();
//factoryArgument = excVariable == null ? Expression.Constant(null, typeof(IRuntimeContextInstance)) : GetRuntimeExceptionObject();
factoryArgument = excVariable == null ? Expression.Constant(null, typeof(IRuntimeContextInstance))
: ExpressionHelpers.ConvertToType(GetRuntimeExceptionObject(), typeof(IRuntimeContextInstance));

var factory = Expression.Constant(ExceptionInfoFactory);
return ExpressionHelpers.CallOfInstanceMethod(
Expand Down
19 changes: 6 additions & 13 deletions src/OneScript.Native/Runtime/CallableMethod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ internal class CallableMethod
{
private readonly BslNativeMethodInfo _method;

private delegate BslValue NativeCallable(NativeClassInstanceWrapper target, BslValue[] args, IBslProcess process);
private delegate BslValue NativeCallable(IAttachableContext target, BslValue[] args, IBslProcess process);

private NativeCallable _delegate;

Expand All @@ -47,23 +47,16 @@ public BslValue Invoke(IBslProcess process, object target, BslValue[] args)
return _delegate.Invoke(callableWrapper, args, process);
}

private NativeClassInstanceWrapper GetCallableWrapper(object obj)
private IAttachableContext GetCallableWrapper(object obj)
{
NativeClassInstanceWrapper callableWrapper;
IAttachableContext callableWrapper;
if (_method.IsInstance)
{
if (obj == null)
throw new InvalidOperationException($"Method {_method.Name} is not static and requires target");
if (obj is NativeClassInstanceWrapper w)
if (obj is IAttachableContext context)
{
callableWrapper = w;
}
else if (obj is IAttachableContext context)
{
callableWrapper = new NativeClassInstanceWrapper
{
Context = context
};
callableWrapper = context;
}
else
{
Expand All @@ -86,7 +79,7 @@ private static NativeCallable CreateDelegate(BslNativeMethodInfo method)
if (method.Implementation == default)
throw new InvalidOperationException("Method has no implementation");

var targetParam = Expression.Parameter(typeof(NativeClassInstanceWrapper));
var targetParam = Expression.Parameter(typeof(IAttachableContext));
var arrayOfValuesParam = Expression.Parameter(typeof(BslValue[]));
var processParam = Expression.Parameter(typeof(IBslProcess));
var convertedAccessList = new List<Expression>();
Expand Down
2 changes: 1 addition & 1 deletion src/OneScript.Native/Runtime/DynamicOperations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public static T StrictConstructorCall<T>(ITypeManager typeManager, IServiceConta
where T : BslValue
=> (T)ConstructorCall(typeManager, services, typeName, process, args);

public static BslObjectValue GetExceptionInfo(IExceptionInfoFactory factory, Exception e)
public static BslValue GetExceptionInfo(IExceptionInfoFactory factory, Exception e)
=> factory.GetExceptionInfo(e);

public static BslTypeValue GetTypeByName(ITypeManager manager, string name)
Expand Down
20 changes: 0 additions & 20 deletions src/OneScript.Native/Runtime/NativeClassInstanceWrapper.cs

This file was deleted.

2 changes: 1 addition & 1 deletion src/ScriptEngine/Machine/ExceptionInfoFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public ExceptionInfoFactory(IBslProcessFactory processFactory)
_processFactory = processFactory;
}

public BslObjectValue GetExceptionInfo(Exception exception)
public BslValue GetExceptionInfo(Exception exception)
{
if (exception == null)
{
Expand Down