Skip to content

Commit 325a436

Browse files
Version 5.4.5: Added strongly-typed indexing support for IList<T>; added ScriptEngine.DisableListIndexTypeRestriction; reduced V8 stack overflow detection false positives; added tests for bug fixes and new APIs. Tested with V8 4.9.385.30.
1 parent bc70fda commit 325a436

37 files changed

Lines changed: 906 additions & 149 deletions

ClearScript/ClearScript.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@
9292
<Compile Include="Util\COMDispatchHelpers.cs" />
9393
<Compile Include="Util\CoTaskMemBlock.cs" />
9494
<Compile Include="Util\DisposedFlag.cs" />
95+
<Compile Include="HostList.cs" />
9596
<Compile Include="Util\IHostInvokeContext.cs" />
9697
<Compile Include="Util\NativeMethods.cs" />
9798
<Compile Include="Util\COMDispatch.cs" />

ClearScript/Exports/VersionSymbols.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,5 +63,5 @@
6363

6464
#pragma once
6565

66-
#define CLEARSCRIPT_VERSION_STRING "5.4.4.0"
67-
#define CLEARSCRIPT_VERSION_COMMA_SEPARATED 5,4,4,0
66+
#define CLEARSCRIPT_VERSION_STRING "5.4.5.0"
67+
#define CLEARSCRIPT_VERSION_COMMA_SEPARATED 5,4,5,0

ClearScript/HostFunctions.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,11 @@ public PropertyBag newObj()
130130
/// <param name="args">Optional constructor arguments.</param>
131131
/// <returns>A new host object of the specified type.</returns>
132132
/// <remarks>
133+
/// <para>
133134
/// This function is provided for script languages that do not support external
134135
/// instantiation. It is overloaded with <see cref="newObj(object, object[])"/> and
135136
/// selected at runtime if <typeparamref name="T"/> can be used as a type argument.
137+
/// </para>
136138
/// <para>
137139
/// For information about the mapping between host members and script-callable properties
138140
/// and methods, see
@@ -167,10 +169,12 @@ public T newObj<T>(params object[] args)
167169
/// <param name="args">Optional constructor arguments.</param>
168170
/// <returns>A new host object of the specified type.</returns>
169171
/// <remarks>
172+
/// <para>
170173
/// This function is provided for script languages that do not support external
171174
/// instantiation. It is overloaded with <see cref="newObj{T}"/> and selected at runtime if
172175
/// <paramref name="type"/> cannot be used as a type argument. Note that this applies
173176
/// to some host types that support instantiation, such as certain COM/ActiveX types.
177+
/// </para>
174178
/// <para>
175179
/// For information about the mapping between host members and script-callable properties
176180
/// and methods, see
@@ -256,10 +260,12 @@ public object newArr(params int[] lengths)
256260
/// <param name="initValue">An optional initial value for the variable.</param>
257261
/// <returns>A new host variable of the specified type.</returns>
258262
/// <remarks>
263+
/// <para>
259264
/// A host variable is a strongly typed object that holds a value of the specified type.
260265
/// Host variables are useful for passing method arguments by reference. In addition to
261266
/// being generally interchangeable with their stored values, host variables support the
262267
/// following properties:
268+
/// </para>
263269
/// <para>
264270
/// <list type="table">
265271
/// <listheader>
@@ -432,11 +438,13 @@ public object func<T>(int argCount, object scriptFunc)
432438
/// <param name="scriptFunc">The script function for which to create a delegate.</param>
433439
/// <returns>A new delegate that invokes the specified script function and returns its result value.</returns>
434440
/// <remarks>
441+
/// <para>
435442
/// This function creates a delegate that accepts <paramref name="argCount"/> arguments and
436443
/// returns the result of invoking <paramref name="scriptFunc"/>. The type of all
437444
/// parameters and the return value is <see cref="System.Object"/>. Such a delegate is
438445
/// often useful in strongly typed contexts because of
439446
/// <see href="http://msdn.microsoft.com/en-us/library/ms173174(VS.80).aspx">contravariance</see>.
447+
/// </para>
440448
/// <para>
441449
/// For information about the types of result values that script code can return, see
442450
/// <see cref="ScriptEngine.Evaluate(string, bool, string)"/>.
@@ -455,10 +463,12 @@ public object func(int argCount, object scriptFunc)
455463
/// <typeparam name="T">The host type for which to get the <see cref="System.Type"/>.</typeparam>
456464
/// <returns>The <see cref="System.Type"/> for the specified host type.</returns>
457465
/// <remarks>
466+
/// <para>
458467
/// This function is similar to the C#
459468
/// <c><see href="http://msdn.microsoft.com/en-us/library/58918ffs(VS.71).aspx">typeof</see></c>
460469
/// operator. It is overloaded with <see cref="typeOf(object)"/> and selected at runtime if
461470
/// <typeparamref name="T"/> can be used as a type argument.
471+
/// </para>
462472
/// <para>
463473
/// This function throws an exception if the script engine's
464474
/// <see cref="ScriptEngine.AllowReflection"/> property is set to <c>false</c>.
@@ -488,11 +498,13 @@ public Type typeOf<T>()
488498
/// <param name="value">The host type for which to get the <see cref="System.Type"/>.</param>
489499
/// <returns>The <see cref="System.Type"/> for the specified host type.</returns>
490500
/// <remarks>
501+
/// <para>
491502
/// This function is similar to the C#
492503
/// <c><see href="http://msdn.microsoft.com/en-us/library/58918ffs(VS.71).aspx">typeof</see></c>
493504
/// operator. It is overloaded with <see cref="typeOf{T}"/> and selected at runtime if
494505
/// <paramref name="value"/> cannot be used as a type argument. Note that this applies to
495506
/// some host types; examples are static types and overloaded generic type groups.
507+
/// </para>
496508
/// <para>
497509
/// This function throws an exception if the script engine's
498510
/// <see cref="ScriptEngine.AllowReflection"/> property is set to <c>false</c>.
@@ -1454,10 +1466,12 @@ public ExtendedHostFunctions()
14541466
/// <param name="hostTypeArgs">Optional generic type arguments.</param>
14551467
/// <returns>The imported host type.</returns>
14561468
/// <remarks>
1469+
/// <para>
14571470
/// Host types are imported in the form of objects whose properties and methods are bound
14581471
/// to the host type's static members and nested types. If <paramref name="name"/> refers
14591472
/// to a generic type, the corresponding object will be invocable with type arguments to
14601473
/// yield a specific type.
1474+
/// </para>
14611475
/// <para>
14621476
/// For more information about the mapping between host members and script-callable
14631477
/// properties and methods, see
@@ -1496,10 +1510,12 @@ public object type(string name, params object[] hostTypeArgs)
14961510
/// <param name="hostTypeArgs">Optional generic type arguments.</param>
14971511
/// <returns>The imported host type.</returns>
14981512
/// <remarks>
1513+
/// <para>
14991514
/// Host types are imported in the form of objects whose properties and methods are bound
15001515
/// to the host type's static members and nested types. If <paramref name="name"/> refers
15011516
/// to a generic type, the corresponding object will be invocable with type arguments to
15021517
/// yield a specific type.
1518+
/// </para>
15031519
/// <para>
15041520
/// For more information about the mapping between host members and script-callable
15051521
/// properties and methods, see
@@ -1533,10 +1549,12 @@ public object type(string name, string assemblyName, params object[] hostTypeArg
15331549
/// <param name="type">The <see cref="System.Type"/> that specifies the host type to import.</param>
15341550
/// <returns>The imported host type.</returns>
15351551
/// <remarks>
1552+
/// <para>
15361553
/// Host types are imported in the form of objects whose properties and methods are bound
15371554
/// to the host type's static members and nested types. If <paramref name="type"/> refers
15381555
/// to a generic type, the corresponding object will be invocable with type arguments to
15391556
/// yield a specific type.
1557+
/// </para>
15401558
/// <para>
15411559
/// For more information about the mapping between host members and script-callable
15421560
/// properties and methods, see

ClearScript/HostItem.cs

Lines changed: 38 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ private IPropertyBag TargetPropertyBag
286286
set { Collateral.TargetPropertyBag.Set(this, value); }
287287
}
288288

289-
private IList TargetList
289+
private IHostList TargetList
290290
{
291291
get { return Collateral.TargetList.Get(this); }
292292
set { Collateral.TargetList.Set(this, value); }
@@ -491,17 +491,49 @@ private bool BindSpecialTarget<T>(CollateralObject<HostItem, T> property) where
491491

492492
private bool BindSpecialTarget<T>(out T specialTarget) where T : class
493493
{
494-
// provide fully dynamic behavior for exposed IDispatchEx implementations
494+
if (target.InvokeTarget == null)
495+
{
496+
specialTarget = null;
497+
return false;
498+
}
495499

496500
if (typeof(T) == typeof(IDynamic))
497501
{
502+
// provide fully dynamic behavior for exposed IDispatchEx implementations
503+
498504
var dispatchEx = target.InvokeTarget as IDispatchEx;
499505
if ((dispatchEx != null) && dispatchEx.GetType().IsCOMObject)
500506
{
501507
specialTarget = (T)(object)(new DynamicDispatchExWrapper(dispatchEx));
502508
return true;
503509
}
504510
}
511+
else if (typeof(T) == typeof(IHostList))
512+
{
513+
// generic list support
514+
515+
Type[] typeArgs;
516+
if (target.Type.IsAssignableToGenericType(typeof(IList<>), out typeArgs))
517+
{
518+
if (typeof(IList).IsAssignableFrom(target.Type))
519+
{
520+
specialTarget = new HostList(engine, (IList)target.InvokeTarget, typeArgs[0]) as T;
521+
return specialTarget != null;
522+
}
523+
524+
specialTarget = typeof(HostList<>).MakeGenericType(typeArgs).CreateInstance(engine, target.InvokeTarget) as T;
525+
return specialTarget != null;
526+
}
527+
528+
if (typeof(IList).IsAssignableFrom(target.Type))
529+
{
530+
specialTarget = new HostList(engine, (IList)target.InvokeTarget, typeof(object)) as T;
531+
return specialTarget != null;
532+
}
533+
534+
specialTarget = null;
535+
return false;
536+
}
505537

506538
// The check here is required because the item may be bound to a specific target base
507539
// class or interface - one that must not trigger special treatment.
@@ -1218,10 +1250,10 @@ private object InvokeHostMember(string name, BindingFlags invokeFlags, object[]
12181250
IEnumerable enumerable;
12191251
if (BindSpecialTarget(out enumerable))
12201252
{
1221-
var enumerationHelpersHostItem = Wrap(engine, EnumerationHelpers.HostType, HostItemFlags.PrivateAccess);
1253+
var enumerableHelpersHostItem = Wrap(engine, EnumerableHelpers.HostType, HostItemFlags.PrivateAccess);
12221254
try
12231255
{
1224-
return ((IDynamic)enumerationHelpersHostItem).InvokeMethod("GetEnumerator", new object[] { this });
1256+
return ((IDynamic)enumerableHelpersHostItem).InvokeMethod("GetEnumerator", new object[] { this });
12251257
}
12261258
catch (MissingMemberException)
12271259
{
@@ -1360,7 +1392,7 @@ private object GetHostProperty(string name, BindingFlags invokeFlags, object[] a
13601392
{
13611393
var result = field.GetValue(target.InvokeTarget);
13621394
isCacheable = (TargetDynamicMetaObject == null) && (field.IsLiteral || field.IsInitOnly);
1363-
return engine.PrepareResult(result, field.FieldType, field.GetScriptMemberFlags());
1395+
return engine.PrepareResult(result, field.FieldType, field.GetScriptMemberFlags(), false);
13641396
}
13651397

13661398
var eventInfo = target.Type.GetScriptableEvent(name, invokeFlags, defaultAccess);
@@ -1421,7 +1453,7 @@ private object GetHostProperty(PropertyInfo property, BindingFlags invokeFlags,
14211453
}
14221454

14231455
var result = property.GetValue(target.InvokeTarget, invokeFlags, Type.DefaultBinder, args, culture);
1424-
return engine.PrepareResult(result, property.PropertyType, property.GetScriptMemberFlags());
1456+
return engine.PrepareResult(result, property.PropertyType, property.GetScriptMemberFlags(), false);
14251457
}
14261458

14271459
private object SetHostProperty(string name, BindingFlags invokeFlags, object[] args, object[] bindArgs, CultureInfo culture)
@@ -2115,28 +2147,5 @@ void IExpando.RemoveMember(MemberInfo member)
21152147
}
21162148

21172149
#endregion
2118-
2119-
#region Nested type: EnumerationHelpers
2120-
2121-
private static class EnumerationHelpers
2122-
{
2123-
// ReSharper disable UnusedMember.Local
2124-
2125-
public static readonly HostType HostType = HostType.Wrap(typeof(EnumerationHelpers));
2126-
2127-
public static IEnumerator<T> GetEnumerator<T>(IEnumerable<T> source)
2128-
{
2129-
return source.GetEnumerator();
2130-
}
2131-
2132-
public static IEnumerator GetEnumerator(IEnumerable source)
2133-
{
2134-
return source.GetEnumerator();
2135-
}
2136-
2137-
// ReSharper restore UnusedMember.Local
2138-
}
2139-
2140-
#endregion
21412150
}
21422151
}

ClearScript/HostItemCollateral.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ internal class HostItemCollateral
7272

7373
public readonly CollateralObject<IDynamic> TargetDynamic = new CollateralObject<IDynamic>();
7474
public readonly CollateralObject<IPropertyBag> TargetPropertyBag = new CollateralObject<IPropertyBag>();
75-
public readonly CollateralObject<IList> TargetList = new CollateralObject<IList>();
75+
public readonly CollateralObject<IHostList> TargetList = new CollateralObject<IHostList>();
7676
public readonly CollateralObject<DynamicMetaObject> TargetDynamicMetaObject = new CollateralObject<DynamicMetaObject>();
7777
public readonly CollateralObject<IEnumerator> TargetEnumerator = new CollateralObject<IEnumerator>();
7878

0 commit comments

Comments
 (0)