diff --git a/build-js.cmd b/build-js.cmd
new file mode 100644
index 0000000..1e607da
--- /dev/null
+++ b/build-js.cmd
@@ -0,0 +1,34 @@
+@echo off
+setlocal
+
+cd ./src/MsieJavaScriptEngine/
+
+::--------------------------------------------------------------------------------
+:: Build
+::--------------------------------------------------------------------------------
+
+echo Installing Node.js packages ...
+echo.
+call npm install
+if errorlevel 1 goto error
+echo.
+
+echo Minifying JS files ...
+echo.
+call npm run -s minify-js
+if errorlevel 1 goto error
+echo.
+
+::--------------------------------------------------------------------------------
+:: Exit
+::--------------------------------------------------------------------------------
+
+echo Succeeded!
+goto exit
+
+:error
+echo *** Error: The previous step failed!
+
+:exit
+cd ../../
+endlocal
\ No newline at end of file
diff --git a/global.json b/global.json
index 9b92080..4347eeb 100644
--- a/global.json
+++ b/global.json
@@ -1,5 +1,5 @@
{
"sdk": {
- "version": "7.0.102"
+ "version": "7.0.200"
}
}
diff --git a/src/MsieJavaScriptEngine/.uglifyjsrc b/src/MsieJavaScriptEngine/.uglifyjsrc
new file mode 100644
index 0000000..8a91584
--- /dev/null
+++ b/src/MsieJavaScriptEngine/.uglifyjsrc
@@ -0,0 +1,11 @@
+{
+ "compress": {
+ "hoist_funs": true,
+ "hoist_vars": true,
+ "passes": 2
+ },
+ "mangle": {},
+ "output": {
+ "comments": "/^!/"
+ }
+}
diff --git a/src/MsieJavaScriptEngine/ActiveScript/ActiveScriptJsEngineBase.cs b/src/MsieJavaScriptEngine/ActiveScript/ActiveScriptJsEngineBase.cs
index 1b71fa8..eeabc4e 100644
--- a/src/MsieJavaScriptEngine/ActiveScript/ActiveScriptJsEngineBase.cs
+++ b/src/MsieJavaScriptEngine/ActiveScript/ActiveScriptJsEngineBase.cs
@@ -571,7 +571,7 @@ private void InnerCollectGarbage(ScriptGCType type)
/// The mapped value
private object MapToScriptType(object value)
{
- return TypeMappingHelpers.MapToScriptType(value, _settings.EngineMode);
+ return TypeMappingHelpers.MapToScriptType(value, _settings.EngineMode, _settings.AllowReflection);
}
///
@@ -581,7 +581,7 @@ private object MapToScriptType(object value)
/// The mapped array
private object[] MapToScriptType(object[] args)
{
- return TypeMappingHelpers.MapToScriptType(args, _settings.EngineMode);
+ return TypeMappingHelpers.MapToScriptType(args, _settings.EngineMode, _settings.AllowReflection);
}
///
@@ -900,7 +900,7 @@ public override void EmbedHostObject(string itemName, object value)
public override void EmbedHostType(string itemName, Type type)
{
- var typeValue = new HostType(type, _settings.EngineMode);
+ var typeValue = new HostType(type, _settings.EngineMode, _settings.AllowReflection);
_dispatcher.Invoke(() =>
{
diff --git a/src/MsieJavaScriptEngine/ActiveScript/HostItemBase.cs b/src/MsieJavaScriptEngine/ActiveScript/HostItemBase.cs
index 5e9cbf7..7d0b945 100644
--- a/src/MsieJavaScriptEngine/ActiveScript/HostItemBase.cs
+++ b/src/MsieJavaScriptEngine/ActiveScript/HostItemBase.cs
@@ -27,6 +27,11 @@ internal abstract class HostItemBase : IReflect
///
protected readonly JsEngineMode _engineMode;
+ ///
+ /// Flag for whether to allow the usage of reflection API in the script code
+ ///
+ protected readonly bool _allowReflection;
+
///
/// List of fields
///
@@ -57,20 +62,26 @@ public object Target
/// Target type
/// Target object
/// JS engine mode
+ /// Flag for whether to allow the usage of reflection API in the script code
/// Flag for whether to allow access to members of the instance
- protected HostItemBase(Type type, object target, JsEngineMode engineMode, bool instance)
+ protected HostItemBase(Type type, object target, JsEngineMode engineMode, bool allowReflection, bool instance)
{
_type = type;
_target = target;
+ _allowReflection = allowReflection;
_engineMode = engineMode;
BindingFlags defaultBindingFlags = ReflectionHelpers.GetDefaultBindingFlags(instance);
FieldInfo[] fields = _type.GetFields(defaultBindingFlags);
PropertyInfo[] properties = _type.GetProperties(defaultBindingFlags);
+ if (properties.Length > 0 && !allowReflection)
+ {
+ properties = GetAvailableProperties(properties);
+ }
MethodInfo[] methods = _type.GetMethods(defaultBindingFlags);
- if (methods.Length > 0 && properties.Length > 0)
+ if (methods.Length > 0 && (properties.Length > 0 || !allowReflection))
{
- methods = ReflectionHelpers.GetFullyFledgedMethods(methods);
+ methods = GetAvailableMethods(methods, allowReflection);
}
_fields = fields;
@@ -79,6 +90,49 @@ protected HostItemBase(Type type, object target, JsEngineMode engineMode, bool i
}
+ private static PropertyInfo[] GetAvailableProperties(PropertyInfo[] properties)
+ {
+ int propertyCount = properties.Length;
+ var availableProperties = new PropertyInfo[propertyCount];
+ int availablePropertyIndex = 0;
+
+ for (int propertyIndex = 0; propertyIndex < propertyCount; propertyIndex++)
+ {
+ PropertyInfo property = properties[propertyIndex];
+ if (ReflectionHelpers.IsAllowedProperty(property))
+ {
+ availableProperties[availablePropertyIndex] = property;
+ availablePropertyIndex++;
+ }
+ }
+
+ Array.Resize(ref availableProperties, availablePropertyIndex);
+
+ return availableProperties;
+ }
+
+ private static MethodInfo[] GetAvailableMethods(MethodInfo[] methods, bool allowReflection)
+ {
+ int methodCount = methods.Length;
+ var availableMethods = new MethodInfo[methodCount];
+ int availableMethodIndex = 0;
+
+ for (int methodIndex = 0; methodIndex < methodCount; methodIndex++)
+ {
+ MethodInfo method = methods[methodIndex];
+ if (ReflectionHelpers.IsFullyFledgedMethod(method)
+ && (allowReflection || ReflectionHelpers.IsAllowedMethod(method)))
+ {
+ availableMethods[availableMethodIndex] = method;
+ availableMethodIndex++;
+ }
+ }
+
+ Array.Resize(ref availableMethods, availableMethodIndex);
+
+ return availableMethods;
+ }
+
private bool IsField(string name)
{
bool isField = false;
diff --git a/src/MsieJavaScriptEngine/ActiveScript/HostObject.cs b/src/MsieJavaScriptEngine/ActiveScript/HostObject.cs
index fd91ba0..cb00656 100644
--- a/src/MsieJavaScriptEngine/ActiveScript/HostObject.cs
+++ b/src/MsieJavaScriptEngine/ActiveScript/HostObject.cs
@@ -25,8 +25,9 @@ internal sealed class HostObject : HostItemBase
///
/// Target object
/// JS engine mode
- public HostObject(object target, JsEngineMode engineMode)
- : base(target.GetType(), target, engineMode, true)
+ /// Flag for whether to allow the usage of reflection API in the script code
+ public HostObject(object target, JsEngineMode engineMode, bool allowReflection)
+ : base(target.GetType(), target, engineMode, allowReflection, true)
{
var del = _target as Delegate;
if (del != null)
@@ -88,7 +89,7 @@ protected override object InnerInvokeMember(string name, BindingFlags invokeAttr
processedArgs, modifiers, culture, namedParameters);
}
- return TypeMappingHelpers.MapToScriptType(result, _engineMode);
+ return TypeMappingHelpers.MapToScriptType(result, _engineMode, _allowReflection);
}
#endregion
diff --git a/src/MsieJavaScriptEngine/ActiveScript/HostType.cs b/src/MsieJavaScriptEngine/ActiveScript/HostType.cs
index 0071c0b..855d02d 100644
--- a/src/MsieJavaScriptEngine/ActiveScript/HostType.cs
+++ b/src/MsieJavaScriptEngine/ActiveScript/HostType.cs
@@ -19,8 +19,9 @@ internal sealed class HostType : HostItemBase
///
/// Target type
/// JS engine mode
- public HostType(Type type, JsEngineMode engineMode)
- : base(type, null, engineMode, false)
+ /// Flag for whether to allow the usage of reflection API in the script code
+ public HostType(Type type, JsEngineMode engineMode, bool allowReflection)
+ : base(type, null, engineMode, allowReflection, false)
{ }
@@ -51,7 +52,7 @@ protected override object InnerInvokeMember(string name, BindingFlags invokeAttr
processedArgs, modifiers, culture, namedParameters);
}
- return TypeMappingHelpers.MapToScriptType(result, _engineMode);
+ return TypeMappingHelpers.MapToScriptType(result, _engineMode, _allowReflection);
}
#endregion
diff --git a/src/MsieJavaScriptEngine/Helpers/ReflectionHelpers.cs b/src/MsieJavaScriptEngine/Helpers/ReflectionHelpers.cs
index 0f37cf5..304edc0 100644
--- a/src/MsieJavaScriptEngine/Helpers/ReflectionHelpers.cs
+++ b/src/MsieJavaScriptEngine/Helpers/ReflectionHelpers.cs
@@ -12,6 +12,19 @@ namespace MsieJavaScriptEngine.Helpers
///
internal static class ReflectionHelpers
{
+ private static readonly PropertyInfo[] _disallowedProperties =
+ {
+ typeof(Delegate).GetProperty("Method"),
+ typeof(Exception).GetProperty("TargetSite")
+ };
+
+ private static readonly MethodInfo[] _disallowedMethods =
+ {
+ typeof(object).GetMethod("GetType"),
+ typeof(Exception).GetMethod("GetType")
+ };
+
+
public static BindingFlags GetDefaultBindingFlags(bool instance)
{
BindingFlags bindingFlags = BindingFlags.Public;
@@ -27,6 +40,20 @@ public static BindingFlags GetDefaultBindingFlags(bool instance)
return bindingFlags;
}
+ public static bool IsAllowedProperty(PropertyInfo property)
+ {
+ bool isAllowed = !_disallowedProperties.Contains(property, MemberComparer.Instance);
+
+ return isAllowed;
+ }
+
+ public static bool IsAllowedMethod(MethodInfo method)
+ {
+ bool isAllowed = !_disallowedMethods.Contains(method, MemberComparer.Instance);
+
+ return isAllowed;
+ }
+
public static bool IsFullyFledgedMethod(MethodInfo method)
{
if (!method.Attributes.HasFlag(MethodAttributes.SpecialName))
@@ -40,29 +67,6 @@ public static bool IsFullyFledgedMethod(MethodInfo method)
return isFullyFledged;
}
-#if NETFRAMEWORK
-
- public static MethodInfo[] GetFullyFledgedMethods(MethodInfo[] methods)
- {
- int methodCount = methods.Length;
- var fullyFledgedMethods = new MethodInfo[methodCount];
- int fullyFledgedMethodIndex = 0;
-
- for (int methodIndex = 0; methodIndex < methodCount; methodIndex++)
- {
- MethodInfo method = methods[methodIndex];
- if (IsFullyFledgedMethod(method))
- {
- fullyFledgedMethods[fullyFledgedMethodIndex] = method;
- fullyFledgedMethodIndex++;
- }
- }
-
- Array.Resize(ref fullyFledgedMethods, fullyFledgedMethodIndex);
-
- return fullyFledgedMethods;
- }
-#endif
public static void FixFieldValueType(ref object value, FieldInfo field)
{
@@ -244,6 +248,38 @@ private static bool CompareParameterTypes(object[] argValues, Type[] argTypes, T
}
+ private sealed class MemberComparer : EqualityComparer
+ where T : MemberInfo
+ {
+ public static MemberComparer Instance { get; } = new MemberComparer();
+
+
+ private MemberComparer()
+ { }
+
+
+ #region MemberComparer overrides
+
+ public override bool Equals(T x, T y)
+ {
+ return x.Module == y.Module
+#if !NETSTANDARD1_3
+ && x.MetadataToken == y.MetadataToken
+#else
+ && x.DeclaringType == y.DeclaringType
+ && x.Name == y.Name
+#endif
+ ;
+ }
+
+ public override int GetHashCode(T obj)
+ {
+ return obj != null ? obj.GetHashCode() : 0;
+ }
+
+ #endregion
+ }
+
private sealed class MethodWithMetadata
{
public MethodBase Method
diff --git a/src/MsieJavaScriptEngine/Helpers/TypeMappingHelpers.cs b/src/MsieJavaScriptEngine/Helpers/TypeMappingHelpers.cs
index 424f45a..843ef9c 100644
--- a/src/MsieJavaScriptEngine/Helpers/TypeMappingHelpers.cs
+++ b/src/MsieJavaScriptEngine/Helpers/TypeMappingHelpers.cs
@@ -17,8 +17,9 @@ internal static class TypeMappingHelpers
///
/// The source value
/// JavaScript engine mode
+ /// Flag for whether to allow the usage of reflection API in the script code
/// The mapped value
- public static object MapToScriptType(object value, JsEngineMode engineMode)
+ public static object MapToScriptType(object value, JsEngineMode engineMode, bool allowReflection)
{
if (value == null)
{
@@ -36,7 +37,7 @@ public static object MapToScriptType(object value, JsEngineMode engineMode)
return value;
}
- var result = new HostObject(value, engineMode);
+ var result = new HostObject(value, engineMode, allowReflection);
return result;
}
@@ -46,10 +47,11 @@ public static object MapToScriptType(object value, JsEngineMode engineMode)
///
/// The source array
/// JavaScript engine mode
+ /// Flag for whether to allow the usage of reflection API in the script code
/// The mapped array
- public static object[] MapToScriptType(object[] args, JsEngineMode engineMode)
+ public static object[] MapToScriptType(object[] args, JsEngineMode engineMode, bool allowReflection)
{
- return args.Select(arg => MapToScriptType(arg, engineMode)).ToArray();
+ return args.Select(arg => MapToScriptType(arg, engineMode, allowReflection)).ToArray();
}
///
diff --git a/src/MsieJavaScriptEngine/JsEngineSettings.cs b/src/MsieJavaScriptEngine/JsEngineSettings.cs
index 85c0e6f..ff92ee5 100644
--- a/src/MsieJavaScriptEngine/JsEngineSettings.cs
+++ b/src/MsieJavaScriptEngine/JsEngineSettings.cs
@@ -27,6 +27,19 @@ public sealed class JsEngineSettings
private int _maxStackSize;
#endif
+ ///
+ /// Gets or sets a flag for whether to allow the usage of reflection API in the script code
+ ///
+ ///
+ /// This affects , Exception.GetType,
+ /// Exception.TargetSite and Delegate.Method.
+ ///
+ public bool AllowReflection
+ {
+ get;
+ set;
+ }
+
///
/// Gets or sets a flag for whether to enable script debugging features
///
@@ -95,6 +108,7 @@ public bool UseJson2Library
///
public JsEngineSettings()
{
+ AllowReflection = false;
EnableDebugging = false;
EngineMode = JsEngineMode.Auto;
#if !NETSTANDARD1_3
diff --git a/src/MsieJavaScriptEngine/JsRt/Edge/ChakraEdgeJsRtJsEngine.cs b/src/MsieJavaScriptEngine/JsRt/Edge/ChakraEdgeJsRtJsEngine.cs
index d7271ac..7ed6c07 100644
--- a/src/MsieJavaScriptEngine/JsRt/Edge/ChakraEdgeJsRtJsEngine.cs
+++ b/src/MsieJavaScriptEngine/JsRt/Edge/ChakraEdgeJsRtJsEngine.cs
@@ -61,7 +61,7 @@ internal sealed class ChakraEdgeJsRtJsEngine : ChakraJsRtJsEngineBase
public ChakraEdgeJsRtJsEngine(JsEngineSettings settings)
: base(settings)
{
- _typeMapper = new EdgeTypeMapper();
+ _typeMapper = new EdgeTypeMapper(settings.AllowReflection);
try
{
diff --git a/src/MsieJavaScriptEngine/JsRt/Edge/EdgeTypeMapper.cs b/src/MsieJavaScriptEngine/JsRt/Edge/EdgeTypeMapper.cs
index 37ca65b..eabfe7a 100644
--- a/src/MsieJavaScriptEngine/JsRt/Edge/EdgeTypeMapper.cs
+++ b/src/MsieJavaScriptEngine/JsRt/Edge/EdgeTypeMapper.cs
@@ -26,7 +26,9 @@ internal sealed class EdgeTypeMapper : TypeMapper
/// Constructs an instance of the “Edge” type mapper
///
- public EdgeTypeMapper()
+ /// Flag for whether to allow the usage of reflection API in the script code
+ public EdgeTypeMapper(bool allowReflection)
+ : base(allowReflection)
{ }
@@ -437,6 +439,11 @@ private void ProjectProperties(EdgeEmbeddedItem externalItem)
foreach (PropertyInfo property in properties)
{
+ if (!IsAvailableProperty(property))
+ {
+ continue;
+ }
+
string propertyName = property.Name;
EdgeJsValue descriptorValue = EdgeJsValue.CreateObject();
@@ -565,11 +572,10 @@ private void ProjectMethods(EdgeEmbeddedItem externalItem)
string typeName = type.FullName;
BindingFlags defaultBindingFlags = ReflectionHelpers.GetDefaultBindingFlags(instance);
- IEnumerable methods = type.GetMethods(defaultBindingFlags)
- .Where(ReflectionHelpers.IsFullyFledgedMethod);
- IEnumerable> methodGroups = methods.GroupBy(m => m.Name);
+ MethodInfo[] methods = type.GetMethods(defaultBindingFlags);
+ IEnumerable> availableMethodGroups = GetAvailableMethodGroups(methods);
- foreach (IGrouping methodGroup in methodGroups)
+ foreach (IGrouping methodGroup in availableMethodGroups)
{
string methodName = methodGroup.Key;
MethodInfo[] methodCandidates = methodGroup.ToArray();
diff --git a/src/MsieJavaScriptEngine/JsRt/Ie/ChakraIeJsRtJsEngine.cs b/src/MsieJavaScriptEngine/JsRt/Ie/ChakraIeJsRtJsEngine.cs
index 11fddd7..c405866 100644
--- a/src/MsieJavaScriptEngine/JsRt/Ie/ChakraIeJsRtJsEngine.cs
+++ b/src/MsieJavaScriptEngine/JsRt/Ie/ChakraIeJsRtJsEngine.cs
@@ -69,7 +69,7 @@ internal sealed class ChakraIeJsRtJsEngine : ChakraJsRtJsEngineBase
public ChakraIeJsRtJsEngine(JsEngineSettings settings)
: base(settings)
{
- _typeMapper = new IeTypeMapper();
+ _typeMapper = new IeTypeMapper(settings.AllowReflection);
try
{
diff --git a/src/MsieJavaScriptEngine/JsRt/Ie/IeTypeMapper.cs b/src/MsieJavaScriptEngine/JsRt/Ie/IeTypeMapper.cs
index 5d50d7c..a3e4944 100644
--- a/src/MsieJavaScriptEngine/JsRt/Ie/IeTypeMapper.cs
+++ b/src/MsieJavaScriptEngine/JsRt/Ie/IeTypeMapper.cs
@@ -26,7 +26,9 @@ internal sealed class IeTypeMapper : TypeMapper
///
/// Constructs an instance of the “IE” type mapper
///
- public IeTypeMapper()
+ /// Flag for whether to allow the usage of reflection API in the script code
+ public IeTypeMapper(bool allowReflection)
+ : base(allowReflection)
{ }
@@ -437,6 +439,11 @@ private void ProjectProperties(IeEmbeddedItem externalItem)
foreach (PropertyInfo property in properties)
{
+ if (!IsAvailableProperty(property))
+ {
+ continue;
+ }
+
string propertyName = property.Name;
IeJsValue descriptorValue = IeJsValue.CreateObject();
@@ -565,11 +572,10 @@ private void ProjectMethods(IeEmbeddedItem externalItem)
string typeName = type.FullName;
BindingFlags defaultBindingFlags = ReflectionHelpers.GetDefaultBindingFlags(instance);
- IEnumerable methods = type.GetMethods(defaultBindingFlags)
- .Where(ReflectionHelpers.IsFullyFledgedMethod);
- IEnumerable> methodGroups = methods.GroupBy(m => m.Name);
+ MethodInfo[] methods = type.GetMethods(defaultBindingFlags);
+ IEnumerable> availableMethodGroups = GetAvailableMethodGroups(methods);
- foreach (IGrouping methodGroup in methodGroups)
+ foreach (IGrouping methodGroup in availableMethodGroups)
{
string methodName = methodGroup.Key;
MethodInfo[] methodCandidates = methodGroup.ToArray();
diff --git a/src/MsieJavaScriptEngine/JsRt/TypeMapper.cs b/src/MsieJavaScriptEngine/JsRt/TypeMapper.cs
index a4a50f6..8615e09 100644
--- a/src/MsieJavaScriptEngine/JsRt/TypeMapper.cs
+++ b/src/MsieJavaScriptEngine/JsRt/TypeMapper.cs
@@ -1,9 +1,11 @@
using System;
using System.Collections.Concurrent;
+using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
+using MsieJavaScriptEngine.Helpers;
using MsieJavaScriptEngine.JsRt.Embedding;
using MsieJavaScriptEngine.Utilities;
@@ -23,6 +25,11 @@ internal abstract class TypeMapper : IDisposable
///
protected const string ExternalObjectPropertyName = "_MsieJavaScriptEngine_externalObject";
+ ///
+ /// Flag for whether to allow the usage of reflection API in the script code
+ ///
+ protected readonly bool _allowReflection;
+
///
/// Storage for lazy-initialized embedded objects
///
@@ -69,6 +76,16 @@ internal abstract class TypeMapper : IDisposable
private InterlockedStatedFlag _disposedFlag = new InterlockedStatedFlag();
+ ///
+ /// Constructs an instance of the type mapper
+ ///
+ /// Flag for whether to allow the usage of reflection API in the script code
+ protected TypeMapper(bool allowReflection)
+ {
+ _allowReflection = allowReflection;
+ }
+
+
///
/// Creates a JavaScript value from an host object if the it does not already exist
///
@@ -200,6 +217,30 @@ private void EmbeddedTypeFinalizeCallback(IntPtr ptr)
embeddedTypeHandle.Free();
}
+ protected bool IsAvailableProperty(PropertyInfo property)
+ {
+ if (_allowReflection)
+ {
+ return true;
+ }
+
+ bool isAvailable = ReflectionHelpers.IsAllowedProperty(property);
+
+ return isAvailable;
+ }
+
+ protected IEnumerable> GetAvailableMethodGroups(MethodInfo[] methods)
+ {
+ IEnumerable availableMethods = methods.Where(ReflectionHelpers.IsFullyFledgedMethod);
+ if (!_allowReflection)
+ {
+ availableMethods = availableMethods.Where(ReflectionHelpers.IsAllowedMethod);
+ }
+ IEnumerable> availableMethodGroups = availableMethods.GroupBy(m => m.Name);
+
+ return availableMethodGroups;
+ }
+
protected object[] GetHostItemMemberArguments(TValue[] args, int maxArgCount = -1)
{
if (args == null)
diff --git a/src/MsieJavaScriptEngine/MsieJavaScriptEngine.csproj b/src/MsieJavaScriptEngine/MsieJavaScriptEngine.csproj
index 41e1e91..72acc70 100644
--- a/src/MsieJavaScriptEngine/MsieJavaScriptEngine.csproj
+++ b/src/MsieJavaScriptEngine/MsieJavaScriptEngine.csproj
@@ -25,8 +25,7 @@
true
snupkg
JavaScript;ECMAScript;MSIE;IE;Edge;Chakra
- 1. In JsRT modes, `JsVariantToValue` and `JsValueToVariant` native methods are no longer used for embedding objects and types;
-2. JSON2 library was updated to version of October 30, 2022.
+ In JavaScript engine settings was added one new property - `AllowReflection` (default `false`).
en-US
../../nuget
true
@@ -40,7 +39,6 @@
-
@@ -87,4 +85,10 @@
+
+
+
+
\ No newline at end of file
diff --git a/src/MsieJavaScriptEngine/bundleconfig.json b/src/MsieJavaScriptEngine/bundleconfig.json
deleted file mode 100644
index 9153a95..0000000
--- a/src/MsieJavaScriptEngine/bundleconfig.json
+++ /dev/null
@@ -1,14 +0,0 @@
-[
- {
- "outputFileName": "Resources/ES5.min.js",
- "inputFiles": [
- "Resources/ES5.js"
- ]
- },
- {
- "outputFileName": "Resources/json2.min.js",
- "inputFiles": [
- "Resources/json2.js"
- ]
- }
-]
diff --git a/src/MsieJavaScriptEngine/package.json b/src/MsieJavaScriptEngine/package.json
new file mode 100644
index 0000000..381dbb5
--- /dev/null
+++ b/src/MsieJavaScriptEngine/package.json
@@ -0,0 +1,12 @@
+{
+ "name": "MsieJavaScriptEngine",
+ "version": "3.1.0",
+ "devDependencies": {
+ "uglify-js": "3.16.1"
+ },
+ "scripts": {
+ "minify-es5-js": "uglifyjs ./Resources/ES5.js --output ./Resources/ES5.min.js --config-file ./.uglifyjsrc",
+ "minify-json2-js": "uglifyjs ./Resources/json2.js --output ./Resources/json2.min.js --config-file ./.uglifyjsrc",
+ "minify-js": "npm run -s minify-es5-js && npm run -s minify-json2-js"
+ }
+}
diff --git a/src/MsieJavaScriptEngine/readme.txt b/src/MsieJavaScriptEngine/readme.txt
index 6827039..319849c 100644
--- a/src/MsieJavaScriptEngine/readme.txt
+++ b/src/MsieJavaScriptEngine/readme.txt
@@ -21,9 +21,8 @@
=============
RELEASE NOTES
=============
- 1. In JsRT modes, `JsVariantToValue` and `JsValueToVariant` native methods are
- no longer used for embedding objects and types;
- 2. JSON2 library was updated to version of October 30, 2022.
+ In JavaScript engine settings was added one new property - `AllowReflection`
+ (default `false`).
============
PROJECT SITE
diff --git a/test/MsieJavaScriptEngine.Benchmarks/MsieJavaScriptEngine.Benchmarks.csproj b/test/MsieJavaScriptEngine.Benchmarks/MsieJavaScriptEngine.Benchmarks.csproj
index c122933..674cebb 100644
--- a/test/MsieJavaScriptEngine.Benchmarks/MsieJavaScriptEngine.Benchmarks.csproj
+++ b/test/MsieJavaScriptEngine.Benchmarks/MsieJavaScriptEngine.Benchmarks.csproj
@@ -21,7 +21,7 @@
-
+
diff --git a/test/MsieJavaScriptEngine.Test.Auto/InteropTests.cs b/test/MsieJavaScriptEngine.Test.Auto/InteropTests.cs
index c6e4def..3034802 100644
--- a/test/MsieJavaScriptEngine.Test.Auto/InteropTests.cs
+++ b/test/MsieJavaScriptEngine.Test.Auto/InteropTests.cs
@@ -8,5 +8,45 @@ namespace MsieJavaScriptEngine.Test.Auto
public class InteropTests : InteropTestsBase
{
protected override JsEngineMode EngineMode => JsEngineMode.Auto;
+
+
+ #region Embedding of objects
+
+ #region Objects with methods
+
+ public override void EmbeddingOfInstanceOfCustomValueTypeAndCallingOfItsGetTypeMethod()
+ { }
+
+ public override void EmbeddingOfInstanceOfCustomReferenceTypeAndCallingOfItsGetTypeMethod()
+ { }
+
+ #endregion
+
+ #region Delegates
+
+ public override void EmbeddingOfInstanceOfDelegateAndCheckingItsPrototype()
+ { }
+
+ public override void EmbeddingOfInstanceOfDelegateAndGettingItsMethodProperty()
+ { }
+
+ #endregion
+
+ #endregion
+
+
+ #region Embedding of types
+
+ #region Creating of instances
+
+ public override void CreatingAnInstanceOfEmbeddedBuiltinExceptionAndGettingItsTargetSiteProperty()
+ { }
+
+ public override void CreatingAnInstanceOfEmbeddedCustomExceptionAndCallingOfItsGetTypeMethod()
+ { }
+
+ #endregion
+
+ #endregion
}
}
\ No newline at end of file
diff --git a/test/MsieJavaScriptEngine.Test.Auto/MsieJavaScriptEngine.Test.Auto.csproj b/test/MsieJavaScriptEngine.Test.Auto/MsieJavaScriptEngine.Test.Auto.csproj
index ef7fdd3..7748d17 100644
--- a/test/MsieJavaScriptEngine.Test.Auto/MsieJavaScriptEngine.Test.Auto.csproj
+++ b/test/MsieJavaScriptEngine.Test.Auto/MsieJavaScriptEngine.Test.Auto.csproj
@@ -5,6 +5,7 @@
3.1.0
net40;net45;netcoreapp2.1;netcoreapp3.1;net5.0;net6.0;net7.0
Library
+ latest
true
true
false
@@ -14,9 +15,15 @@
+
+
+
+
+
-
+
+
\ No newline at end of file
diff --git a/test/MsieJavaScriptEngine.Test.ChakraActiveScript/CommonTests.cs b/test/MsieJavaScriptEngine.Test.ChakraActiveScript/CommonTests.cs
index a3d4893..b33e52e 100644
--- a/test/MsieJavaScriptEngine.Test.ChakraActiveScript/CommonTests.cs
+++ b/test/MsieJavaScriptEngine.Test.ChakraActiveScript/CommonTests.cs
@@ -65,7 +65,7 @@ public void MappingCompilationErrorDuringEvaluationOfExpressionInDebugMode()
JsCompilationException exception = null;
// Act
- using (var jsEngine = CreateJsEngine(true))
+ using (var jsEngine = CreateJsEngine(enableDebugging: true))
{
try
{
@@ -186,7 +186,7 @@ public void MappingCompilationErrorDuringExecutionOfCodeInDebugMode()
JsCompilationException exception = null;
// Act
- using (var jsEngine = CreateJsEngine(true))
+ using (var jsEngine = CreateJsEngine(enableDebugging: true))
{
try
{
@@ -300,7 +300,7 @@ public void GenerationOfCompilationErrorMessageInDebugMode()
JsCompilationException exception = null;
// Act
- using (var jsEngine = CreateJsEngine(true))
+ using (var jsEngine = CreateJsEngine(enableDebugging: true))
{
try
{
diff --git a/test/MsieJavaScriptEngine.Test.ChakraActiveScript/InteropTests.cs b/test/MsieJavaScriptEngine.Test.ChakraActiveScript/InteropTests.cs
index d6c6443..432f127 100644
--- a/test/MsieJavaScriptEngine.Test.ChakraActiveScript/InteropTests.cs
+++ b/test/MsieJavaScriptEngine.Test.ChakraActiveScript/InteropTests.cs
@@ -4,6 +4,7 @@
using NUnit.Framework;
using MsieJavaScriptEngine.Test.Common;
+using MsieJavaScriptEngine.Test.Common.Interop.Animals;
namespace MsieJavaScriptEngine.Test.ChakraActiveScript
{
@@ -15,6 +16,35 @@ public class InteropTests : InteropTestsBase
#region Embedding of objects
+ #region Delegates
+
+ [Test]
+ public override void EmbeddingOfInstanceOfDelegateAndCheckingItsPrototype()
+ { }
+
+ [Test]
+ public override void EmbeddingOfInstanceOfDelegateAndGettingItsMethodProperty()
+ {
+ // Arrange
+ string TestAllowReflectionSetting(bool allowReflection)
+ {
+ var cat = new Cat();
+ var cryFunc = new Func(cat.Cry);
+
+ using (var jsEngine = CreateJsEngine(allowReflection: allowReflection))
+ {
+ jsEngine.EmbedHostObject("cry", cryFunc);
+ return jsEngine.Evaluate("cry.Method;");
+ }
+ }
+
+ // Act and Assert
+ Assert.AreEqual("System.String Cry()", TestAllowReflectionSetting(true));
+ Assert.AreEqual("undefined", TestAllowReflectionSetting(false));
+ }
+
+ #endregion
+
#region Recursive calls
#region Mapping of errors
diff --git a/test/MsieJavaScriptEngine.Test.ChakraActiveScript/MsieJavaScriptEngine.Test.ChakraActiveScript.csproj b/test/MsieJavaScriptEngine.Test.ChakraActiveScript/MsieJavaScriptEngine.Test.ChakraActiveScript.csproj
index 8bd96f8..3ba8b43 100644
--- a/test/MsieJavaScriptEngine.Test.ChakraActiveScript/MsieJavaScriptEngine.Test.ChakraActiveScript.csproj
+++ b/test/MsieJavaScriptEngine.Test.ChakraActiveScript/MsieJavaScriptEngine.Test.ChakraActiveScript.csproj
@@ -5,6 +5,7 @@
3.1.0
net40;net45
Library
+ latest
true
true
false
diff --git a/test/MsieJavaScriptEngine.Test.ChakraEdgeJsRt/CommonTests.cs b/test/MsieJavaScriptEngine.Test.ChakraEdgeJsRt/CommonTests.cs
index 8549729..09acc27 100644
--- a/test/MsieJavaScriptEngine.Test.ChakraEdgeJsRt/CommonTests.cs
+++ b/test/MsieJavaScriptEngine.Test.ChakraEdgeJsRt/CommonTests.cs
@@ -66,7 +66,7 @@ public void MappingCompilationErrorDuringEvaluationOfExpressionInDebugMode()
JsCompilationException exception = null;
// Act
- using (var jsEngine = CreateJsEngine(true))
+ using (var jsEngine = CreateJsEngine(enableDebugging: true))
{
try
{
@@ -187,7 +187,7 @@ public virtual void MappingCompilationErrorDuringExecutionOfCodeInDebugMode()
JsCompilationException exception = null;
// Act
- using (var jsEngine = CreateJsEngine(true))
+ using (var jsEngine = CreateJsEngine(enableDebugging: true))
{
try
{
@@ -305,7 +305,7 @@ public void GenerationOfCompilationErrorMessageInDebugMode()
JsCompilationException exception = null;
// Act
- using (var jsEngine = CreateJsEngine(true))
+ using (var jsEngine = CreateJsEngine(enableDebugging: true))
{
try
{
diff --git a/test/MsieJavaScriptEngine.Test.ChakraEdgeJsRt/InteropTests.cs b/test/MsieJavaScriptEngine.Test.ChakraEdgeJsRt/InteropTests.cs
index 65bca83..14eefa0 100644
--- a/test/MsieJavaScriptEngine.Test.ChakraEdgeJsRt/InteropTests.cs
+++ b/test/MsieJavaScriptEngine.Test.ChakraEdgeJsRt/InteropTests.cs
@@ -15,31 +15,6 @@ public class InteropTests : InteropTestsBase
#region Embedding of objects
- #region Delegates
-
- [Test]
- public void EmbeddedInstanceOfDelegateHasFunctionPrototype()
- {
- // Arrange
- var someFunc = new Func(() => 42);
-
- const string input = "Object.getPrototypeOf(embeddedFunc) === Function.prototype";
-
- // Act
- bool output;
-
- using (var jsEngine = CreateJsEngine())
- {
- jsEngine.EmbedHostObject("embeddedFunc", someFunc);
- output = jsEngine.Evaluate(input);
- }
-
- // Assert
- Assert.True(output);
- }
-
- #endregion
-
#region Recursive calls
#region Mapping of errors
diff --git a/test/MsieJavaScriptEngine.Test.ChakraEdgeJsRt/MsieJavaScriptEngine.Test.ChakraEdgeJsRt.csproj b/test/MsieJavaScriptEngine.Test.ChakraEdgeJsRt/MsieJavaScriptEngine.Test.ChakraEdgeJsRt.csproj
index b087cc1..07c196f 100644
--- a/test/MsieJavaScriptEngine.Test.ChakraEdgeJsRt/MsieJavaScriptEngine.Test.ChakraEdgeJsRt.csproj
+++ b/test/MsieJavaScriptEngine.Test.ChakraEdgeJsRt/MsieJavaScriptEngine.Test.ChakraEdgeJsRt.csproj
@@ -5,6 +5,7 @@
3.1.0
net40;net45;netcoreapp2.1;netcoreapp3.1;net5.0;net6.0;net7.0
Library
+ latest
true
true
false
@@ -14,9 +15,15 @@
+
+
+
+
+
-
+
+
\ No newline at end of file
diff --git a/test/MsieJavaScriptEngine.Test.ChakraIeJsRt/CommonTests.cs b/test/MsieJavaScriptEngine.Test.ChakraIeJsRt/CommonTests.cs
index 2c34764..9983e4a 100644
--- a/test/MsieJavaScriptEngine.Test.ChakraIeJsRt/CommonTests.cs
+++ b/test/MsieJavaScriptEngine.Test.ChakraIeJsRt/CommonTests.cs
@@ -65,7 +65,7 @@ public void MappingCompilationErrorDuringEvaluationOfExpressionInDebugMode()
JsCompilationException exception = null;
// Act
- using (var jsEngine = CreateJsEngine(true))
+ using (var jsEngine = CreateJsEngine(enableDebugging: true))
{
try
{
@@ -186,7 +186,7 @@ public virtual void MappingCompilationErrorDuringExecutionOfCodeInDebugMode()
JsCompilationException exception = null;
// Act
- using (var jsEngine = CreateJsEngine(true))
+ using (var jsEngine = CreateJsEngine(enableDebugging: true))
{
try
{
@@ -304,7 +304,7 @@ public void GenerationOfCompilationErrorMessageInDebugMode()
JsCompilationException exception = null;
// Act
- using (var jsEngine = CreateJsEngine(true))
+ using (var jsEngine = CreateJsEngine(enableDebugging: true))
{
try
{
diff --git a/test/MsieJavaScriptEngine.Test.ChakraIeJsRt/InteropTests.cs b/test/MsieJavaScriptEngine.Test.ChakraIeJsRt/InteropTests.cs
index 3d06904..15ee2c5 100644
--- a/test/MsieJavaScriptEngine.Test.ChakraIeJsRt/InteropTests.cs
+++ b/test/MsieJavaScriptEngine.Test.ChakraIeJsRt/InteropTests.cs
@@ -15,31 +15,6 @@ public class InteropTests : InteropTestsBase
#region Embedding of objects
- #region Delegates
-
- [Test]
- public void EmbeddedInstanceOfDelegateHasFunctionPrototype()
- {
- // Arrange
- var someFunc = new Func(() => 42);
-
- const string input = "Object.getPrototypeOf(embeddedFunc) === Function.prototype";
-
- // Act
- bool output;
-
- using (var jsEngine = CreateJsEngine())
- {
- jsEngine.EmbedHostObject("embeddedFunc", someFunc);
- output = jsEngine.Evaluate(input);
- }
-
- // Assert
- Assert.True(output);
- }
-
- #endregion
-
#region Recursive calls
#region Mapping of errors
diff --git a/test/MsieJavaScriptEngine.Test.ChakraIeJsRt/MsieJavaScriptEngine.Test.ChakraIeJsRt.csproj b/test/MsieJavaScriptEngine.Test.ChakraIeJsRt/MsieJavaScriptEngine.Test.ChakraIeJsRt.csproj
index a6090e4..d849933 100644
--- a/test/MsieJavaScriptEngine.Test.ChakraIeJsRt/MsieJavaScriptEngine.Test.ChakraIeJsRt.csproj
+++ b/test/MsieJavaScriptEngine.Test.ChakraIeJsRt/MsieJavaScriptEngine.Test.ChakraIeJsRt.csproj
@@ -5,6 +5,7 @@
3.1.0
net40;net45;netcoreapp2.1;netcoreapp3.1;net5.0;net6.0;net7.0
Library
+ latest
true
true
false
@@ -14,9 +15,15 @@
+
+
+
+
+
-
+
+
\ No newline at end of file
diff --git a/test/MsieJavaScriptEngine.Test.Classic/CommonTests.cs b/test/MsieJavaScriptEngine.Test.Classic/CommonTests.cs
index 43b314c..45a5ac3 100644
--- a/test/MsieJavaScriptEngine.Test.Classic/CommonTests.cs
+++ b/test/MsieJavaScriptEngine.Test.Classic/CommonTests.cs
@@ -65,7 +65,7 @@ public void MappingCompilationErrorDuringEvaluationOfExpressionInDebugMode()
JsCompilationException exception = null;
// Act
- using (var jsEngine = CreateJsEngine(true))
+ using (var jsEngine = CreateJsEngine(enableDebugging: true))
{
try
{
@@ -186,7 +186,7 @@ public void MappingCompilationErrorDuringExecutionOfCodeInDebugMode()
JsCompilationException exception = null;
// Act
- using (var jsEngine = CreateJsEngine(true))
+ using (var jsEngine = CreateJsEngine(enableDebugging: true))
{
try
{
@@ -300,7 +300,7 @@ public void GenerationOfCompilationErrorMessageInDebugMode()
JsCompilationException exception = null;
// Act
- using (var jsEngine = CreateJsEngine(true))
+ using (var jsEngine = CreateJsEngine(enableDebugging: true))
{
try
{
diff --git a/test/MsieJavaScriptEngine.Test.Classic/InteropTests.cs b/test/MsieJavaScriptEngine.Test.Classic/InteropTests.cs
index 41d91a0..48763b5 100644
--- a/test/MsieJavaScriptEngine.Test.Classic/InteropTests.cs
+++ b/test/MsieJavaScriptEngine.Test.Classic/InteropTests.cs
@@ -4,6 +4,8 @@
using NUnit.Framework;
using MsieJavaScriptEngine.Test.Common;
+using MsieJavaScriptEngine.Test.Common.Interop;
+using MsieJavaScriptEngine.Test.Common.Interop.Animals;
namespace MsieJavaScriptEngine.Test.Classic
{
@@ -15,6 +17,85 @@ public class InteropTests : InteropTestsBase
#region Embedding of objects
+ #region Objects with methods
+
+ [Test]
+ public override void EmbeddingOfInstanceOfCustomValueTypeAndCallingOfItsGetTypeMethod()
+ {
+ // Arrange
+ string TestAllowReflectionSetting(bool allowReflection)
+ {
+ var date = new Date();
+
+ using (var jsEngine = CreateJsEngine(allowReflection: allowReflection))
+ {
+ jsEngine.EmbedHostObject("date", date);
+ return jsEngine.Evaluate("date.GetType();");
+ }
+ }
+
+ // Act and Assert
+ Assert.AreEqual(typeof(Date).FullName, TestAllowReflectionSetting(true));
+
+ var exception = Assert.Throws(() => TestAllowReflectionSetting(false));
+ Assert.AreEqual("Runtime error", exception.Category);
+ Assert.AreEqual("Object doesn't support this property or method", exception.Description);
+ }
+
+ [Test]
+ public override void EmbeddingOfInstanceOfCustomReferenceTypeAndCallingOfItsGetTypeMethod()
+ {
+ // Arrange
+ string TestAllowReflectionSetting(bool allowReflection)
+ {
+ var cat = new Cat();
+
+ using (var jsEngine = CreateJsEngine(allowReflection: allowReflection))
+ {
+ jsEngine.EmbedHostObject("cat", cat);
+ return jsEngine.Evaluate("cat.GetType();");
+ }
+ }
+
+ // Act and Assert
+ Assert.AreEqual(typeof(Cat).FullName, TestAllowReflectionSetting(true));
+
+ var exception = Assert.Throws(() => TestAllowReflectionSetting(false));
+ Assert.AreEqual("Runtime error", exception.Category);
+ Assert.AreEqual("Object doesn't support this property or method", exception.Description);
+ }
+
+ #endregion
+
+ #region Delegates
+
+ [Test]
+ public override void EmbeddingOfInstanceOfDelegateAndCheckingItsPrototype()
+ { }
+
+ [Test]
+ public override void EmbeddingOfInstanceOfDelegateAndGettingItsMethodProperty()
+ {
+ // Arrange
+ string TestAllowReflectionSetting(bool allowReflection)
+ {
+ var cat = new Cat();
+ var cryFunc = new Func(cat.Cry);
+
+ using (var jsEngine = CreateJsEngine(allowReflection: allowReflection))
+ {
+ jsEngine.EmbedHostObject("cry", cryFunc);
+ return jsEngine.Evaluate("cry.Method;");
+ }
+ }
+
+ // Act and Assert
+ Assert.AreEqual("System.String Cry()", TestAllowReflectionSetting(true));
+ Assert.AreEqual("undefined", TestAllowReflectionSetting(false));
+ }
+
+ #endregion
+
#region Recursive calls
#region Mapping of errors
@@ -67,5 +148,37 @@ public void MappingRuntimeErrorDuringRecursiveEvaluationOfFiles()
#endregion
#endregion
+
+
+ #region Embedding of types
+
+ #region Creating of instances
+
+ [Test]
+ public override void CreatingAnInstanceOfEmbeddedCustomExceptionAndCallingOfItsGetTypeMethod()
+ {
+ // Arrange
+ string TestAllowReflectionSetting(bool allowReflection)
+ {
+ Type loginFailedExceptionType = typeof(LoginFailedException);
+
+ using (var jsEngine = CreateJsEngine(allowReflection: allowReflection))
+ {
+ jsEngine.EmbedHostType("LoginFailedError", loginFailedExceptionType);
+ return jsEngine.Evaluate("new LoginFailedError(\"Wrong password entered!\").GetType();");
+ }
+ }
+
+ // Act and Assert
+ Assert.AreEqual(typeof(LoginFailedException).FullName, TestAllowReflectionSetting(true));
+
+ var exception = Assert.Throws(() => TestAllowReflectionSetting(false));
+ Assert.AreEqual("Runtime error", exception.Category);
+ Assert.AreEqual("Object doesn't support this property or method", exception.Description);
+ }
+
+ #endregion
+
+ #endregion
}
}
\ No newline at end of file
diff --git a/test/MsieJavaScriptEngine.Test.Classic/MsieJavaScriptEngine.Test.Classic.csproj b/test/MsieJavaScriptEngine.Test.Classic/MsieJavaScriptEngine.Test.Classic.csproj
index beaee3e..d8d21a3 100644
--- a/test/MsieJavaScriptEngine.Test.Classic/MsieJavaScriptEngine.Test.Classic.csproj
+++ b/test/MsieJavaScriptEngine.Test.Classic/MsieJavaScriptEngine.Test.Classic.csproj
@@ -5,6 +5,7 @@
3.1.0
net40;net45
Library
+ latest
true
true
false
diff --git a/test/MsieJavaScriptEngine.Test.Common/Interop/LoginFailedException.cs b/test/MsieJavaScriptEngine.Test.Common/Interop/LoginFailedException.cs
new file mode 100644
index 0000000..72e6b20
--- /dev/null
+++ b/test/MsieJavaScriptEngine.Test.Common/Interop/LoginFailedException.cs
@@ -0,0 +1,50 @@
+using System;
+using System.Runtime.Serialization;
+
+namespace MsieJavaScriptEngine.Test.Common.Interop
+{
+ [Serializable]
+ public class LoginFailedException : Exception
+ {
+ private string _userName;
+
+ public string UserName
+ {
+ get { return _userName; }
+ set { _userName = value; }
+ }
+
+
+ public LoginFailedException()
+ { }
+
+ public LoginFailedException(string message)
+ : base(message)
+ { }
+
+ public LoginFailedException(string message, Exception innerException)
+ : base(message, innerException)
+ { }
+
+ protected LoginFailedException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ if (info != null)
+ {
+ _userName = info.GetString("UserName");
+ }
+ }
+
+
+ public override void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ if (info == null)
+ {
+ throw new ArgumentNullException(nameof(info));
+ }
+
+ base.GetObjectData(info, context);
+ info.AddValue("UserName", this._userName);
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/MsieJavaScriptEngine.Test.Common/InteropTestsBase.cs b/test/MsieJavaScriptEngine.Test.Common/InteropTestsBase.cs
index 9bd2684..53274a2 100644
--- a/test/MsieJavaScriptEngine.Test.Common/InteropTestsBase.cs
+++ b/test/MsieJavaScriptEngine.Test.Common/InteropTestsBase.cs
@@ -432,7 +432,7 @@ public virtual void EmbeddingOfInstanceOfCustomReferenceTypeWithMethod()
}
[Test]
- public virtual void CallingOfMethodOfCustomReferenceTypeWithInterfaceParameter()
+ public virtual void EmbeddingOfInstancesOfCustomReferenceTypesAndCallingOfMethodOfWithInterfaceParameter()
{
// Arrange
var animalTrainer = new AnimalTrainer();
@@ -463,6 +463,52 @@ public virtual void CallingOfMethodOfCustomReferenceTypeWithInterfaceParameter()
Assert.AreEqual(targetOutput2, output2);
}
+ [Test]
+ public virtual void EmbeddingOfInstanceOfCustomValueTypeAndCallingOfItsGetTypeMethod()
+ {
+ // Arrange
+ string TestAllowReflectionSetting(bool allowReflection)
+ {
+ var date = new Date();
+
+ using (var jsEngine = CreateJsEngine(allowReflection: allowReflection))
+ {
+ jsEngine.EmbedHostObject("date", date);
+ return jsEngine.Evaluate("date.GetType();");
+ }
+ }
+
+ // Act and Assert
+ Assert.AreEqual(typeof(Date).FullName, TestAllowReflectionSetting(true));
+
+ var exception = Assert.Throws(() => TestAllowReflectionSetting(false));
+ Assert.AreEqual("Runtime error", exception.Category);
+ Assert.AreEqual("Object doesn't support property or method 'GetType'", exception.Description);
+ }
+
+ [Test]
+ public virtual void EmbeddingOfInstanceOfCustomReferenceTypeAndCallingOfItsGetTypeMethod()
+ {
+ // Arrange
+ string TestAllowReflectionSetting(bool allowReflection)
+ {
+ var cat = new Cat();
+
+ using (var jsEngine = CreateJsEngine(allowReflection: allowReflection))
+ {
+ jsEngine.EmbedHostObject("cat", cat);
+ return jsEngine.Evaluate("cat.GetType();");
+ }
+ }
+
+ // Act and Assert
+ Assert.AreEqual(typeof(Cat).FullName, TestAllowReflectionSetting(true));
+
+ var exception = Assert.Throws(() => TestAllowReflectionSetting(false));
+ Assert.AreEqual("Runtime error", exception.Category);
+ Assert.AreEqual("Object doesn't support property or method 'GetType'", exception.Description);
+ }
+
#endregion
#region Delegates
@@ -597,7 +643,28 @@ public virtual void EmbeddingOfInstanceOfDelegateWithoutResult()
}
[Test]
- public virtual void CallingOfEmbeddedDelegateWithMissingParameter()
+ public virtual void EmbeddingOfInstanceOfDelegateAndCheckingItsPrototype()
+ {
+ // Arrange
+ var someFunc = new Func(() => 42);
+
+ const string input = "Object.getPrototypeOf(embeddedFunc) === Function.prototype";
+
+ // Act
+ bool output;
+
+ using (var jsEngine = CreateJsEngine())
+ {
+ jsEngine.EmbedHostObject("embeddedFunc", someFunc);
+ output = jsEngine.Evaluate(input);
+ }
+
+ // Assert
+ Assert.True(output);
+ }
+
+ [Test]
+ public virtual void EmbeddingOfInstanceOfDelegateAndCallingItWithMissingParameter()
{
// Arrange
var sumFunc = new Func((a, b) => a + b);
@@ -625,7 +692,7 @@ public virtual void CallingOfEmbeddedDelegateWithMissingParameter()
}
[Test]
- public virtual void CallingOfEmbeddedDelegateWithExtraParameter()
+ public virtual void EmbeddingOfInstanceOfDelegateAndCallingItWithExtraParameter()
{
// Arrange
var sumFunc = new Func((a, b) => a + b);
@@ -646,6 +713,27 @@ public virtual void CallingOfEmbeddedDelegateWithExtraParameter()
Assert.AreEqual(targetOutput, output);
}
+ [Test]
+ public virtual void EmbeddingOfInstanceOfDelegateAndGettingItsMethodProperty()
+ {
+ // Arrange
+ string TestAllowReflectionSetting(bool allowReflection)
+ {
+ var cat = new Cat();
+ var cryFunc = new Func(cat.Cry);
+
+ using (var jsEngine = CreateJsEngine(allowReflection: allowReflection))
+ {
+ jsEngine.EmbedHostObject("cry", cryFunc);
+ return jsEngine.Evaluate("cry.Method;");
+ }
+ }
+
+ // Act and Assert
+ Assert.AreEqual("undefined", TestAllowReflectionSetting(true));
+ Assert.AreEqual("undefined", TestAllowReflectionSetting(false));
+ }
+
#endregion
#region Integration
@@ -888,6 +976,49 @@ public virtual void CreatingAnInstanceOfEmbeddedCustomReferenceType()
Assert.AreEqual(targetOutput, output);
}
+ [Test]
+ public virtual void CreatingAnInstanceOfEmbeddedBuiltinExceptionAndGettingItsTargetSiteProperty()
+ {
+ // Arrange
+ string TestAllowReflectionSetting(bool allowReflection)
+ {
+ Type invalidOperationExceptionType = typeof(InvalidOperationException);
+
+ using (var jsEngine = CreateJsEngine(allowReflection: allowReflection))
+ {
+ jsEngine.EmbedHostType("InvalidOperationError", invalidOperationExceptionType);
+ return jsEngine.Evaluate("new InvalidOperationError(\"A terrible thing happened!\").TargetSite;");
+ }
+ }
+
+ // Act and Assert
+ Assert.AreEqual(null, TestAllowReflectionSetting(true));
+ Assert.AreEqual("undefined", TestAllowReflectionSetting(false));
+ }
+
+ [Test]
+ public virtual void CreatingAnInstanceOfEmbeddedCustomExceptionAndCallingOfItsGetTypeMethod()
+ {
+ // Arrange
+ string TestAllowReflectionSetting(bool allowReflection)
+ {
+ Type loginFailedExceptionType = typeof(LoginFailedException);
+
+ using (var jsEngine = CreateJsEngine(allowReflection: allowReflection))
+ {
+ jsEngine.EmbedHostType("LoginFailedError", loginFailedExceptionType);
+ return jsEngine.Evaluate("new LoginFailedError(\"Wrong password entered!\").GetType();");
+ }
+ }
+
+ // Act and Assert
+ Assert.AreEqual(typeof(LoginFailedException).FullName, TestAllowReflectionSetting(true));
+
+ var exception = Assert.Throws(() => TestAllowReflectionSetting(false));
+ Assert.AreEqual("Runtime error", exception.Category);
+ Assert.AreEqual("Object doesn't support property or method 'GetType'", exception.Description);
+ }
+
#endregion
#region Types with constants
diff --git a/test/MsieJavaScriptEngine.Test.Common/MsieJavaScriptEngine.Test.Common.csproj b/test/MsieJavaScriptEngine.Test.Common/MsieJavaScriptEngine.Test.Common.csproj
index 1398b23..c32328a 100644
--- a/test/MsieJavaScriptEngine.Test.Common/MsieJavaScriptEngine.Test.Common.csproj
+++ b/test/MsieJavaScriptEngine.Test.Common/MsieJavaScriptEngine.Test.Common.csproj
@@ -5,6 +5,7 @@
3.1.0
net40;net45;netcoreapp2.1;netcoreapp3.1;net5.0;net6.0;net7.0
Library
+ latest
true
true
false
@@ -15,12 +16,19 @@
-
+
+
+
+
+
+
+
+
diff --git a/test/MsieJavaScriptEngine.Test.Common/TestsBase.cs b/test/MsieJavaScriptEngine.Test.Common/TestsBase.cs
index 81c99f7..6854dfb 100644
--- a/test/MsieJavaScriptEngine.Test.Common/TestsBase.cs
+++ b/test/MsieJavaScriptEngine.Test.Common/TestsBase.cs
@@ -18,15 +18,11 @@ public abstract class TestsBase
protected virtual bool UseJson2Library => false;
- protected MsieJsEngine CreateJsEngine()
- {
- return CreateJsEngine(false);
- }
-
- protected MsieJsEngine CreateJsEngine(bool enableDebugging)
+ protected MsieJsEngine CreateJsEngine(bool allowReflection = false, bool enableDebugging = false)
{
var jsEngine = new MsieJsEngine(new JsEngineSettings
{
+ AllowReflection = allowReflection,
EnableDebugging = enableDebugging,
EngineMode = EngineMode,
UseEcmaScript5Polyfill = UseEcmaScript5Polyfill,