Skip to content

Commit 9a668f9

Browse files
Version 5.4.10: Improved indexing support for dynamic host objects; added V8ScriptEngine.SuppressInstanceMethodEnumeration.
1 parent 0c9f2c3 commit 9a668f9

60 files changed

Lines changed: 611 additions & 211 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

ClearScript/Exports/VersionSymbols.h

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

66
#pragma once
77

8-
#define CLEARSCRIPT_VERSION_STRING "5.4.9.0"
9-
#define CLEARSCRIPT_VERSION_COMMA_SEPARATED 5,4,9,0
8+
#define CLEARSCRIPT_VERSION_STRING "5.4.10.0"
9+
#define CLEARSCRIPT_VERSION_COMMA_SEPARATED 5,4,10,0

ClearScript/HostItem.cs

Lines changed: 136 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ private string[] OwnMethodNames
333333

334334
private string[] EnumeratedMethodNames
335335
{
336-
get { return engine.EnumerateExtensionMethods ? AllMethodNames : OwnMethodNames; }
336+
get { return engine.EnumerateInstanceMethods ? (engine.EnumerateExtensionMethods ? AllMethodNames : OwnMethodNames) : MiscHelpers.GetEmptyArray<string>(); }
337337
}
338338

339339
private string[] AllPropertyNames
@@ -366,6 +366,12 @@ private PropertyInfo[] AllProperties
366366
set { targetMemberData.AllProperties = value; }
367367
}
368368

369+
private object EnumerationSettingsToken
370+
{
371+
get { return targetMemberData.EnumerationSettingsToken; }
372+
set { targetMemberData.EnumerationSettingsToken = value; }
373+
}
374+
369375
private ExtensionMethodSummary ExtensionMethodSummary
370376
{
371377
get { return targetMemberData.ExtensionMethodSummary; }
@@ -760,6 +766,20 @@ private void UpdatePropertyNames(out bool updated)
760766
}
761767
}
762768

769+
private void UpdateEnumerationSettingsToken(out bool updated)
770+
{
771+
var enumerationSettingsToken = engine.EnumerationSettingsToken;
772+
if (EnumerationSettingsToken != enumerationSettingsToken)
773+
{
774+
EnumerationSettingsToken = enumerationSettingsToken;
775+
updated = true;
776+
}
777+
else
778+
{
779+
updated = false;
780+
}
781+
}
782+
763783
private void AddExpandoMemberName(string name)
764784
{
765785
if (ExpandoMemberNames == null)
@@ -1185,6 +1205,8 @@ private object InvokeHostMember(string name, BindingFlags invokeFlags, object[]
11851205
{
11861206
return target;
11871207
}
1208+
1209+
return result;
11881210
}
11891211

11901212
throw new NotSupportedException("Object does not support the requested invocation operation");
@@ -1292,35 +1314,75 @@ private object GetHostProperty(string name, BindingFlags invokeFlags, object[] a
12921314
return GetHostProperty(defaultProperty, invokeFlags, args, culture);
12931315
}
12941316

1317+
if (TargetDynamicMetaObject != null)
1318+
{
1319+
object result;
1320+
if (TargetDynamicMetaObject.TryGetIndex(args, out result))
1321+
{
1322+
return result;
1323+
}
1324+
}
1325+
12951326
return Nonexistent.Value;
12961327
}
12971328

1298-
if ((TargetDynamicMetaObject != null) && (TargetDynamicMetaObject.GetDynamicMemberNames().Contains(name)))
1329+
if ((TargetDynamicMetaObject != null) && (args.Length < 1))
12991330
{
1331+
int index;
13001332
object result;
1301-
if (TargetDynamicMetaObject.TryGetMember(name, out result))
1302-
{
1303-
return result;
1304-
}
13051333

1306-
if (includeBoundMembers)
1334+
if (TargetDynamicMetaObject.GetDynamicMemberNames().Contains(name))
13071335
{
1308-
if (HostMethodMap == null)
1336+
if (TargetDynamicMetaObject.TryGetMember(name, out result))
13091337
{
1310-
HostMethodMap = new Dictionary<string, HostMethod>();
1338+
return result;
13111339
}
13121340

1313-
HostMethod hostMethod;
1314-
if (!HostMethodMap.TryGetValue(name, out hostMethod))
1341+
if (int.TryParse(name, NumberStyles.Integer, CultureInfo.InvariantCulture, out index))
13151342
{
1316-
hostMethod = new HostMethod(this, name);
1317-
HostMethodMap.Add(name, hostMethod);
1343+
if (TargetDynamicMetaObject.TryGetIndex(new object[] { index }, out result))
1344+
{
1345+
return result;
1346+
}
13181347
}
13191348

1320-
return hostMethod;
1349+
if (TargetDynamicMetaObject.TryGetIndex(new object[] { name }, out result))
1350+
{
1351+
return result;
1352+
}
1353+
1354+
if (includeBoundMembers)
1355+
{
1356+
if (HostMethodMap == null)
1357+
{
1358+
HostMethodMap = new Dictionary<string, HostMethod>();
1359+
}
1360+
1361+
HostMethod hostMethod;
1362+
if (!HostMethodMap.TryGetValue(name, out hostMethod))
1363+
{
1364+
hostMethod = new HostMethod(this, name);
1365+
HostMethodMap.Add(name, hostMethod);
1366+
}
1367+
1368+
return hostMethod;
1369+
}
1370+
1371+
return Nonexistent.Value;
13211372
}
13221373

1323-
return Nonexistent.Value;
1374+
if (int.TryParse(name, NumberStyles.Integer, CultureInfo.InvariantCulture, out index))
1375+
{
1376+
if (TargetDynamicMetaObject.TryGetIndex(new object[] { index }, out result))
1377+
{
1378+
return result;
1379+
}
1380+
}
1381+
1382+
if (TargetDynamicMetaObject.TryGetIndex(new object[] { name }, out result))
1383+
{
1384+
return result;
1385+
}
13241386
}
13251387

13261388
var property = target.Type.GetScriptableProperty(name, invokeFlags, bindArgs, defaultAccess);
@@ -1412,15 +1474,29 @@ private object SetHostProperty(string name, BindingFlags invokeFlags, object[] a
14121474
{
14131475
if (name == SpecialMemberNames.Default)
14141476
{
1477+
if (args.Length < 2)
1478+
{
1479+
throw new InvalidOperationException("Invalid argument count");
1480+
}
1481+
1482+
object result;
1483+
14151484
var defaultProperty = target.Type.GetScriptableDefaultProperty(invokeFlags, bindArgs.Take(bindArgs.Length - 1).ToArray(), defaultAccess);
14161485
if (defaultProperty != null)
14171486
{
14181487
return SetHostProperty(defaultProperty, invokeFlags, args, culture);
14191488
}
14201489

1490+
if (TargetDynamicMetaObject != null)
1491+
{
1492+
if (TargetDynamicMetaObject.TrySetIndex(args.Take(args.Length - 1).ToArray(), args[args.Length - 1], out result))
1493+
{
1494+
return result;
1495+
}
1496+
}
1497+
14211498
// special case to enable JScript/VBScript "x(a) = b" syntax when x is a host indexed property
14221499

1423-
object result;
14241500
if (InvokeHelpers.TryInvokeObject(this, target, invokeFlags, args, bindArgs, false, out result))
14251501
{
14261502
return result;
@@ -1432,10 +1508,25 @@ private object SetHostProperty(string name, BindingFlags invokeFlags, object[] a
14321508
if ((TargetDynamicMetaObject != null) && (args.Length == 1))
14331509
{
14341510
object result;
1511+
14351512
if (TargetDynamicMetaObject.TrySetMember(name, args[0], out result))
14361513
{
14371514
return result;
14381515
}
1516+
1517+
int index;
1518+
if (int.TryParse(name, NumberStyles.Integer, CultureInfo.InvariantCulture, out index))
1519+
{
1520+
if (TargetDynamicMetaObject.TrySetIndex(new object[] { index }, args[0], out result))
1521+
{
1522+
return result;
1523+
}
1524+
}
1525+
1526+
if (TargetDynamicMetaObject.TrySetIndex(new object[] { name }, args[0], out result))
1527+
{
1528+
return result;
1529+
}
14391530
}
14401531

14411532
if (args.Length < 1)
@@ -1790,7 +1881,12 @@ bool IDynamic.DeleteProperty(string name)
17901881
if (TargetDynamicMetaObject != null)
17911882
{
17921883
bool result;
1793-
if (TargetDynamicMetaObject.TryDeleteMember(name, out result))
1884+
if (TargetDynamicMetaObject.TryDeleteMember(name, out result) && result)
1885+
{
1886+
return true;
1887+
}
1888+
1889+
if (TargetDynamicMetaObject.TryDeleteIndex(new object[] { name }, out result))
17941890
{
17951891
return result;
17961892
}
@@ -1815,7 +1911,10 @@ string[] IDynamic.GetPropertyNames()
18151911
bool updatedPropertyNames;
18161912
UpdatePropertyNames(out updatedPropertyNames);
18171913

1818-
if (updatedFieldNames || updatedMethodNames || updatedPropertyNames || (AllMemberNames == null))
1914+
bool updatedEnumerationSettingsToken;
1915+
UpdateEnumerationSettingsToken(out updatedEnumerationSettingsToken);
1916+
1917+
if (updatedFieldNames || updatedMethodNames || updatedPropertyNames || updatedEnumerationSettingsToken || (AllMemberNames == null))
18191918
{
18201919
AllMemberNames = AllFieldNames.Concat(EnumeratedMethodNames).Concat(AllPropertyNames).ExcludeIndices().Distinct().ToArray();
18211920
}
@@ -1851,7 +1950,13 @@ bool IDynamic.DeleteProperty(int index)
18511950
if (TargetDynamicMetaObject != null)
18521951
{
18531952
bool result;
1854-
if (TargetDynamicMetaObject.TryDeleteMember(index.ToString(CultureInfo.InvariantCulture), out result))
1953+
1954+
if (TargetDynamicMetaObject.TryDeleteMember(index.ToString(CultureInfo.InvariantCulture), out result) && result)
1955+
{
1956+
return true;
1957+
}
1958+
1959+
if (TargetDynamicMetaObject.TryDeleteIndex(new object[] { index }, out result))
18551960
{
18561961
return result;
18571962
}
@@ -2087,6 +2192,18 @@ void IExpando.RemoveMember(MemberInfo member)
20872192
{
20882193
RemoveExpandoMemberName(member.Name);
20892194
}
2195+
else
2196+
{
2197+
int index;
2198+
if (int.TryParse(member.Name, NumberStyles.Integer, CultureInfo.InvariantCulture, out index) && TargetDynamicMetaObject.TryDeleteIndex(new object[] { index }, out result))
2199+
{
2200+
RemoveExpandoMemberName(index.ToString(CultureInfo.InvariantCulture));
2201+
}
2202+
else if (TargetDynamicMetaObject.TryDeleteIndex(new object[] { member.Name }, out result))
2203+
{
2204+
RemoveExpandoMemberName(member.Name);
2205+
}
2206+
}
20902207
}
20912208
else
20922209
{

ClearScript/HostTargetMemberData.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ internal class HostTargetMemberData
2222
public FieldInfo[] AllFields;
2323
public MethodInfo[] AllMethods;
2424
public PropertyInfo[] AllProperties;
25+
26+
public object EnumerationSettingsToken;
2527
public ExtensionMethodSummary ExtensionMethodSummary;
2628
}
2729

ClearScript/Properties/AssemblyInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,5 @@
1717
[assembly: InternalsVisibleTo("ClearScriptTest")]
1818

1919
[assembly: ComVisible(false)]
20-
[assembly: AssemblyVersion("5.4.9.0")]
21-
[assembly: AssemblyFileVersion("5.4.9.0")]
20+
[assembly: AssemblyVersion("5.4.10.0")]
21+
[assembly: AssemblyFileVersion("5.4.10.0")]

ClearScript/ScriptEngine.cs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1140,11 +1140,16 @@ public object Invoke(string funcName, params object[] args)
11401140

11411141
#region internal members
11421142

1143-
internal virtual bool EnumerateExtensionMethods
1143+
internal virtual bool EnumerateInstanceMethods
11441144
{
11451145
get { return true; }
11461146
}
11471147

1148+
internal virtual bool EnumerateExtensionMethods
1149+
{
1150+
get { return EnumerateInstanceMethods; }
1151+
}
1152+
11481153
internal abstract void AddHostItem(string itemName, HostItemFlags flags, object item);
11491154

11501155
internal object PrepareResult<T>(T result, ScriptMemberFlags flags, bool isListIndexResult)
@@ -1368,6 +1373,22 @@ internal virtual T SyncInvoke<T>(Func<T> func)
13681373

13691374
#endregion
13701375

1376+
#region enumeration settings
1377+
1378+
private object enumerationSettingsToken = new object();
1379+
1380+
internal object EnumerationSettingsToken
1381+
{
1382+
get { return enumerationSettingsToken; }
1383+
}
1384+
1385+
internal void OnEnumerationSettingsChanged()
1386+
{
1387+
enumerationSettingsToken = new object();
1388+
}
1389+
1390+
#endregion
1391+
13711392
#region extension method table
13721393

13731394
private readonly ExtensionMethodTable extensionMethodTable = new ExtensionMethodTable();

ClearScript/V8/V8ScriptEngine.cs

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public sealed class V8ScriptEngine : ScriptEngine
3636
private readonly HostItemCollateral hostItemCollateral;
3737
private readonly IUniqueNameManager documentNameManager = new UniqueFileNameManager();
3838
private List<string> documentNames;
39+
private bool suppressInstanceMethodEnumeration;
3940
private bool suppressExtensionMethodEnumeration;
4041

4142
#endregion
@@ -374,15 +375,41 @@ public UIntPtr MaxRuntimeStackUsage
374375
}
375376
}
376377

378+
/// <summary>
379+
/// Enables or disables instance method enumeration.
380+
/// </summary>
381+
/// <remarks>
382+
/// By default, a host object's instance methods are exposed as enumerable properties.
383+
/// Setting this property to <c>true</c> causes instance methods to be excluded from
384+
/// property enumeration. This affects all host objects exposed in the current script
385+
/// engine. Note that instance methods remain both retrievable and invocable regardless of
386+
/// this property's value.
387+
/// </remarks>
388+
public bool SuppressInstanceMethodEnumeration
389+
{
390+
get { return suppressInstanceMethodEnumeration; }
391+
set
392+
{
393+
suppressInstanceMethodEnumeration = value;
394+
OnEnumerationSettingsChanged();
395+
}
396+
}
397+
377398
/// <summary>
378399
/// Enables or disables extension method enumeration.
379400
/// </summary>
380401
/// <remarks>
402+
/// <para>
381403
/// By default, all exposed extension methods appear as enumerable properties of all host
382-
/// objects, regardless of type. Setting this property to <c>true</c> excludes all
383-
/// extension methods from the list of enumerable properties of all host objects. Note that
384-
/// doing so affects only property enumeration; extension methods remain both retrievable
385-
/// and invocable regardless of this property's value.
404+
/// objects, regardless of type. Setting this property to <c>true</c> causes extension
405+
/// methods to be excluded from property enumeration. This affects all host objects exposed
406+
/// in the current script engine. Note that extension methods remain both retrievable and
407+
/// invocable regardless of this property's value.
408+
/// </para>
409+
/// <para>
410+
/// This property has no effect if <see cref="SuppressInstanceMethodEnumeration"/> is set
411+
/// to <c>true</c>.
412+
/// </para>
386413
/// </remarks>
387414
public bool SuppressExtensionMethodEnumeration
388415
{
@@ -738,6 +765,11 @@ public override void CollectGarbage(bool exhaustive)
738765

739766
#region ScriptEngine overrides (internal members)
740767

768+
internal override bool EnumerateInstanceMethods
769+
{
770+
get { return base.EnumerateInstanceMethods && !SuppressInstanceMethodEnumeration; }
771+
}
772+
741773
internal override bool EnumerateExtensionMethods
742774
{
743775
get { return base.EnumerateExtensionMethods && !SuppressExtensionMethodEnumeration; }

ClearScript/doc/Reference.chm

2.78 KB
Binary file not shown.

ClearScriptBenchmarks/Properties/AssemblyInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@
1111
[assembly: AssemblyCopyright("(c) Microsoft Corporation")]
1212

1313
[assembly: ComVisible(false)]
14-
[assembly: AssemblyVersion("5.4.9.0")]
15-
[assembly: AssemblyFileVersion("5.4.9.0")]
14+
[assembly: AssemblyVersion("5.4.10.0")]
15+
[assembly: AssemblyFileVersion("5.4.10.0")]

0 commit comments

Comments
 (0)