Skip to content

Commit

Permalink
ClearScript 5.2: Revamped error handling, host member type restrictio…
Browse files Browse the repository at this point in the history
…n, V8Update improvements, bug fixes, test fixes.
  • Loading branch information
ClearScriptLib committed Mar 27, 2013
1 parent 645a752 commit 6a0f089
Show file tree
Hide file tree
Showing 78 changed files with 2,502 additions and 914 deletions.
1 change: 1 addition & 0 deletions ClearScript.NoV8.sln.DotSettings
Expand Up @@ -14,6 +14,7 @@
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INITIALIZER_BRACES/@EntryValue">NEXT_LINE</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_AFTER_TYPECAST_PARENTHESES/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_AROUND_MULTIPLICATIVE_OP/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_BEFORE_SIZEOF_PARENTHESES/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_BEFORE_TYPEOF_PARENTHESES/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_WITHIN_SINGLE_LINE_ARRAY_INITIALIZER_BRACES/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_LINES/@EntryValue">False</s:Boolean>
Expand Down
1 change: 1 addition & 0 deletions ClearScript.sln.DotSettings
Expand Up @@ -14,6 +14,7 @@
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INITIALIZER_BRACES/@EntryValue">NEXT_LINE</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_AFTER_TYPECAST_PARENTHESES/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_AROUND_MULTIPLICATIVE_OP/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_BEFORE_SIZEOF_PARENTHESES/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_BEFORE_TYPEOF_PARENTHESES/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_WITHIN_SINGLE_LINE_ARRAY_INITIALIZER_BRACES/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_LINES/@EntryValue">False</s:Boolean>
Expand Down
4 changes: 4 additions & 0 deletions ClearScript/ClearScript.csproj
Expand Up @@ -60,13 +60,17 @@
<Compile Include="HostTargetFlags.cs" />
<Compile Include="IScriptableObject.cs" />
<Compile Include="BindSignature.cs" />
<Compile Include="IScriptEngineException.cs" />
<Compile Include="NoScriptAccessAttribute.cs" />
<Compile Include="Properties\AssemblyInfo.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>AssemblyInfo.tt</DependentUpon>
</Compile>
<Compile Include="ScriptAccess.cs" />
<Compile Include="ScriptEngineException.cs" />
<Compile Include="ScriptInterruptedException.cs" />
<Compile Include="ScriptMemberFlags.cs" />
<Compile Include="ScriptMethod.cs" />
<Compile Include="ScriptMemberAttribute.cs" />
<Compile Include="ScriptUsageAttribute.cs" />
Expand Down
2 changes: 1 addition & 1 deletion ClearScript/HostFunctions.cs
Expand Up @@ -173,7 +173,7 @@ public T newObj<T>(params object[] args)
/// </code>
/// </example>
/// <seealso cref="ExtendedHostFunctions.type(string, object[])"/>
public Array newArr<T>(params int[] lengths)
public object newArr<T>(params int[] lengths)
{
return Array.CreateInstance(typeof(T), lengths);
}
Expand Down
35 changes: 23 additions & 12 deletions ClearScript/HostItem.Invoke.cs
Expand Up @@ -153,7 +153,7 @@ private MethodBindResult BindMethod(string name, Type[] typeArgs, object[] args,
{
if (result is MethodBindSuccess)
{
result = new MethodBindFailure(new MissingMemberException(MiscHelpers.FormatInvariant("Object has no method named '{0}' that matches the specified arguments", name)));
result = new MethodBindFailure(() => new MissingMemberException(MiscHelpers.FormatInvariant("Object has no method named '{0}' that matches the specified arguments", name)));
}

foreach (var altName in GetAltMethodNames(name))
Expand Down Expand Up @@ -254,13 +254,13 @@ public static MethodBindResult Create(string name, object rawResult, HostTarget
{
if ((method.IsStatic) && !hostTarget.Flags.HasFlag(HostTargetFlags.AllowStaticMembers))
{
return new MethodBindFailure(new InvalidOperationException(MiscHelpers.FormatInvariant("Cannot access static method '{0}' in non-static context", method.Name)));
return new MethodBindFailure(() => new InvalidOperationException(MiscHelpers.FormatInvariant("Cannot access static method '{0}' in non-static context", method.Name)));
}

return new MethodBindSuccess(hostTarget, method, args);
}

return new MethodBindFailure((rawResult as Exception) ?? new NotSupportedException(MiscHelpers.FormatInvariant("Invocation of method '{0}' failed (unrecognized binding)", name)));
return new MethodBindFailure((rawResult as Func<Exception>) ?? (() => new NotSupportedException(MiscHelpers.FormatInvariant("Invocation of method '{0}' failed (unrecognized binding)", name))));
}

public abstract object RawResult { get; }
Expand Down Expand Up @@ -327,18 +327,18 @@ public override object Invoke(ScriptEngine engine)

private class MethodBindFailure : MethodBindResult
{
private readonly Exception exception;
private readonly Func<Exception> exceptionFactory;

public MethodBindFailure(Exception exception)
public MethodBindFailure(Func<Exception> exceptionFactory)
{
this.exception = exception;
this.exceptionFactory = exceptionFactory;
}

#region MethodBindResult overrides

public override object RawResult
{
get { return exception; }
get { return exceptionFactory; }
}

public override bool IsPreferredMethod(string name)
Expand All @@ -350,9 +350,10 @@ public override bool IsUnblockedMethod()
{
return false;
}

public override object Invoke(ScriptEngine engine)
{
throw exception;
throw exceptionFactory();
}

#endregion
Expand All @@ -377,7 +378,7 @@ public MethodBindingVisitor(object target, string name, Expression expression)
if (results.Count != 1)
{
results.Clear();
results.Add(new NotSupportedException(MiscHelpers.FormatInvariant("Invocation of method '{0}' failed (unrecognized binding)", name)));
AddResult(() => new NotSupportedException(MiscHelpers.FormatInvariant("Invocation of method '{0}' failed (unrecognized binding)", name)));
}
else
{
Expand All @@ -398,7 +399,7 @@ protected override Expression VisitMethodCall(MethodCallExpression node)
{
if (node.Method.Name == name)
{
results.Add(node.Method);
AddResult(node.Method);
}

return base.VisitMethodCall(node);
Expand All @@ -412,7 +413,7 @@ protected override Expression VisitInvocation(InvocationExpression node)
var del = DynamicHelpers.InvokeExpression(node.Expression) as Delegate;
if (del == targetDelegate)
{
results.Add(del.GetType().GetMethod("Invoke"));
AddResult(del.GetType().GetMethod("Invoke"));
}
}

Expand All @@ -426,12 +427,22 @@ protected override Expression VisitUnary(UnaryExpression node)
var exception = DynamicHelpers.InvokeExpression(node.Operand) as Exception;
if (exception != null)
{
results.Add(exception);
AddResult(() => (Exception)DynamicHelpers.InvokeExpression(node.Operand));
}
}

return base.VisitUnary(node);
}

private void AddResult(MethodInfo method)
{
results.Add(method);
}

private void AddResult(Func<Exception> exceptionFactory)
{
results.Add(exceptionFactory);
}
}

#endregion
Expand Down
33 changes: 14 additions & 19 deletions ClearScript/HostItem.cs
Expand Up @@ -66,7 +66,6 @@
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Expando;
using Microsoft.ClearScript.Util;

Expand Down Expand Up @@ -499,14 +498,11 @@ private object InvokeDynamicMember(string name, BindingFlags invokeFlags, object
{
return targetDynamic.Invoke(args, false);
}
catch (Exception exception)
catch (Exception)
{
if ((exception is NotSupportedException) || (exception is InvalidOperationException) || (exception is ExternalException))
if (invokeFlags.HasFlag(BindingFlags.GetField) && (args.Length < 1))
{
if (invokeFlags.HasFlag(BindingFlags.GetField))
{
return targetDynamic;
}
return targetDynamic;
}

throw;
Expand All @@ -517,14 +513,11 @@ private object InvokeDynamicMember(string name, BindingFlags invokeFlags, object
{
return targetDynamic.InvokeMethod(name, args);
}
catch (Exception exception)
catch (Exception)
{
if ((exception is MissingMemberException) || (exception is NotSupportedException) || (exception is InvalidOperationException) || (exception is ExternalException))
if (invokeFlags.HasFlag(BindingFlags.GetField) && (args.Length < 1))
{
if (invokeFlags.HasFlag(BindingFlags.GetField))
{
return targetDynamic.GetProperty(name);
}
return targetDynamic.GetProperty(name);
}

throw;
Expand Down Expand Up @@ -552,7 +545,7 @@ private object InvokePropertyBagMember(string name, BindingFlags invokeFlags, ob
{
if (name == SpecialMemberNames.Default)
{
if (invokeFlags.HasFlag(BindingFlags.GetField))
if (invokeFlags.HasFlag(BindingFlags.GetField) && (args.Length < 1))
{
return targetPropertyBag;
}
Expand All @@ -572,7 +565,7 @@ private object InvokePropertyBagMember(string name, BindingFlags invokeFlags, ob
return result;
}

if (invokeFlags.HasFlag(BindingFlags.GetField))
if (invokeFlags.HasFlag(BindingFlags.GetField) && (args.Length < 1))
{
return value;
}
Expand Down Expand Up @@ -609,7 +602,7 @@ private object InvokeListElement(int index, BindingFlags invokeFlags, object[] a
return result;
}

if (invokeFlags.HasFlag(BindingFlags.GetField))
if (invokeFlags.HasFlag(BindingFlags.GetField) && (args.Length < 1))
{
return targetList[index];
}
Expand Down Expand Up @@ -688,7 +681,7 @@ private object InvokeHostMember(string name, BindingFlags invokeFlags, object[]
return result;
}

if (invokeFlags.HasFlag(BindingFlags.GetField))
if (invokeFlags.HasFlag(BindingFlags.GetField) && (args.Length < 1))
{
return target;
}
Expand Down Expand Up @@ -803,13 +796,15 @@ private object GetHostProperty(string name, BindingFlags invokeFlags, object[] a
return new HostIndexer(this, name);
}

return property.GetValue(target.InvokeTarget, invokeFlags, Type.DefaultBinder, args, culture);
var result = property.GetValue(target.InvokeTarget, invokeFlags, Type.DefaultBinder, args, culture);
return property.IsRestrictedForScript() ? HostObject.WrapResult(result, property.PropertyType) : result;
}

var field = target.Type.GetScriptableField(name, invokeFlags);
if (field != null)
{
return field.GetValue(target.InvokeTarget);
var result = field.GetValue(target.InvokeTarget);
return field.IsRestrictedForScript() ? HostObject.WrapResult(result, field.FieldType) : result;
}

var eventInfo = target.Type.GetScriptableEvent(name, invokeFlags);
Expand Down
35 changes: 35 additions & 0 deletions ClearScript/HostObject.cs
Expand Up @@ -85,10 +85,45 @@ public static HostObject Wrap(object target, Type type)
return (target != null) ? new HostObject(target, type) : null;
}

public static object WrapResult<T>(T result)
{
return WrapResult(result, typeof(T));
}

public static object WrapResult(object result, Type type)
{
if (result == null)
{
return null;
}

if ((result is HostItem) || (result is HostTarget))
{
return result;
}

if ((type == typeof(void)) || (type == typeof(object)))
{
return result;
}

if ((type == result.GetType()) || (Type.GetTypeCode(type) != TypeCode.Object))
{
return result;
}

return Wrap(result, type);
}

#region Object overrides

public override string ToString()
{
if ((target is ScriptItem) && (typeof(ScriptItem).IsAssignableFrom(type)))
{
return "ScriptItem";
}

var objectName = target.GetFriendlyName(type);
return MiscHelpers.FormatInvariant("HostObject:{0}", objectName);
}
Expand Down
14 changes: 7 additions & 7 deletions ClearScript/HostVariable.cs
Expand Up @@ -87,12 +87,12 @@ internal class HostVariable<T> : HostVariableBase, IHostVariable

public HostVariable(T initValue)
{
if (typeof(HostTarget).IsAssignableFrom(typeof(T)))
if (typeof(HostItem).IsAssignableFrom(typeof(T)) || typeof(HostTarget).IsAssignableFrom(typeof(T)))
{
throw new NotSupportedException("Unsupported variable type");
}

if (initValue is HostTarget)
if ((initValue is HostItem) || (initValue is HostTarget))
{
throw new NotSupportedException("Unsupported value type");
}
Expand Down Expand Up @@ -183,9 +183,9 @@ public override bool TryInvokeAuxMember(string name, BindingFlags invokeFlags, o
return true;
}

if (invokeFlags.HasFlag(BindingFlags.GetField))
if (invokeFlags.HasFlag(BindingFlags.GetField) && (args.Length < 1))
{
result = value;
result = HostObject.WrapResult(value);
return true;
}

Expand All @@ -195,15 +195,15 @@ public override bool TryInvokeAuxMember(string name, BindingFlags invokeFlags, o

if ((invokeFlags & getPropertyFlags) != 0)
{
result = value;
result = HostObject.WrapResult(value);
return true;
}

if ((invokeFlags & setPropertyFlags) != 0)
{
if (args.Length == 1)
{
result = ((IHostVariable)this).Value = args[0];
result = HostObject.WrapResult(((IHostVariable)this).Value = args[0], typeof(T));
return true;
}
}
Expand Down Expand Up @@ -234,7 +234,7 @@ object IHostVariable.Value
throw new InvalidOperationException("Assignment invalid due to type mismatch");
}

if (tempValue is HostTarget)
if ((tempValue is HostItem) || (tempValue is HostTarget))
{
throw new NotSupportedException("Unsupported value type");
}
Expand Down

0 comments on commit 6a0f089

Please sign in to comment.