Skip to content

Commit 3d8246f

Browse files
committed
Added the EmbedHostType method (embeds a host type to script code)
1 parent 6c288c3 commit 3d8246f

24 files changed

+1356
-689
lines changed

src/MsieJavaScriptEngine/ActiveScript/ActiveScriptJsEngineBase.cs

+397-59
Large diffs are not rendered by default.

src/MsieJavaScriptEngine/ActiveScript/ActiveScriptSiteWrapper.cs

-494
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace MsieJavaScriptEngine.Constants
2+
{
3+
/// <summary>
4+
/// Special member names
5+
/// </summary>
6+
internal static class SpecialMemberName
7+
{
8+
public const string Default = "[DISPID=0]";
9+
}
10+
}
+184
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
namespace MsieJavaScriptEngine
2+
{
3+
using System;
4+
using System.Globalization;
5+
using System.Linq;
6+
using System.Reflection;
7+
8+
/// <summary>
9+
/// Base class of item, that implements <see cref="IReflect"/> interface
10+
/// </summary>
11+
internal abstract class HostItemBase : IReflect
12+
{
13+
/// <summary>
14+
/// Target type
15+
/// </summary>
16+
protected readonly Type _type;
17+
18+
/// <summary>
19+
/// Target object
20+
/// </summary>
21+
protected readonly object _target;
22+
23+
/// <summary>
24+
/// JavaScript engine mode
25+
/// </summary>
26+
protected readonly JsEngineMode _engineMode;
27+
28+
/// <summary>
29+
/// List of fields
30+
/// </summary>
31+
private readonly FieldInfo[] _fields;
32+
33+
/// <summary>
34+
/// List of properties
35+
/// </summary>
36+
private readonly PropertyInfo[] _properties;
37+
38+
/// <summary>
39+
/// List of methods
40+
/// </summary>
41+
private readonly MethodInfo[] _methods;
42+
43+
/// <summary>
44+
/// Gets a target object
45+
/// </summary>
46+
public object Target
47+
{
48+
get { return _target; }
49+
}
50+
51+
52+
/// <summary>
53+
/// Constructs an instance of the wrapper for item, that implements <see cref="IReflect"/> interface
54+
/// </summary>
55+
/// <param name="type">Target type</param>
56+
/// <param name="target">Target object</param>
57+
/// <param name="engineMode">JavaScript engine mode</param>
58+
/// <param name="instance">Flag for whether to allow access to members of the instance</param>
59+
protected HostItemBase(Type type, object target, JsEngineMode engineMode, bool instance)
60+
{
61+
_type = type;
62+
_target = target;
63+
_engineMode = engineMode;
64+
65+
BindingFlags bindingFlags = BindingFlags.Public;
66+
if (instance)
67+
{
68+
bindingFlags |= BindingFlags.Instance;
69+
}
70+
else
71+
{
72+
bindingFlags |= BindingFlags.Static;
73+
}
74+
75+
_fields = _type.GetFields(bindingFlags);
76+
_properties = _type.GetProperties(bindingFlags);
77+
_methods = _type.GetMethods(bindingFlags);
78+
}
79+
80+
81+
protected abstract object InnerInvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target,
82+
object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters);
83+
84+
protected object InvokeStandardMember(string name, BindingFlags invokeAttr, Binder binder, object target,
85+
object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters)
86+
{
87+
BindingFlags processedInvokeAttr = invokeAttr;
88+
if ((processedInvokeAttr.HasFlag(BindingFlags.GetProperty)
89+
|| processedInvokeAttr.HasFlag(BindingFlags.PutDispProperty))
90+
&& !_properties.Any(p => p.Name == name)
91+
&& _fields.Any(p => p.Name == name))
92+
{
93+
if (processedInvokeAttr.HasFlag(BindingFlags.GetProperty))
94+
{
95+
processedInvokeAttr &= ~BindingFlags.GetProperty;
96+
processedInvokeAttr |= BindingFlags.GetField;
97+
}
98+
else if (processedInvokeAttr.HasFlag(BindingFlags.PutDispProperty))
99+
{
100+
processedInvokeAttr &= ~BindingFlags.PutDispProperty;
101+
processedInvokeAttr |= BindingFlags.SetField;
102+
}
103+
}
104+
105+
object result = _type.InvokeMember(name, processedInvokeAttr, binder, target,
106+
args, modifiers, culture, namedParameters);
107+
108+
return result;
109+
}
110+
111+
#region IReflect implementation
112+
113+
Type IReflect.UnderlyingSystemType
114+
{
115+
get { throw new NotImplementedException(); }
116+
}
117+
118+
119+
FieldInfo IReflect.GetField(string name, BindingFlags bindingAttr)
120+
{
121+
FieldInfo field = _fields.SingleOrDefault(f => f.Name == name);
122+
123+
return field;
124+
}
125+
126+
FieldInfo[] IReflect.GetFields(BindingFlags bindingAttr)
127+
{
128+
return _fields;
129+
}
130+
131+
MemberInfo[] IReflect.GetMember(string name, BindingFlags bindingAttr)
132+
{
133+
throw new NotImplementedException();
134+
}
135+
136+
MemberInfo[] IReflect.GetMembers(BindingFlags bindingAttr)
137+
{
138+
throw new NotImplementedException();
139+
}
140+
141+
MethodInfo IReflect.GetMethod(string name, BindingFlags bindingAttr)
142+
{
143+
MethodInfo method = _methods.SingleOrDefault(m => m.Name == name);
144+
145+
return method;
146+
}
147+
148+
MethodInfo IReflect.GetMethod(string name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers)
149+
{
150+
throw new NotImplementedException();
151+
}
152+
153+
MethodInfo[] IReflect.GetMethods(BindingFlags bindingAttr)
154+
{
155+
return _methods;
156+
}
157+
158+
PropertyInfo[] IReflect.GetProperties(BindingFlags bindingAttr)
159+
{
160+
return _properties;
161+
}
162+
163+
PropertyInfo IReflect.GetProperty(string name, BindingFlags bindingAttr)
164+
{
165+
PropertyInfo property = _properties.SingleOrDefault(p => p.Name == name);
166+
167+
return property;
168+
}
169+
170+
PropertyInfo IReflect.GetProperty(string name, BindingFlags bindingAttr, Binder binder,
171+
Type returnType, Type[] types, ParameterModifier[] modifiers)
172+
{
173+
throw new NotImplementedException();
174+
}
175+
176+
object IReflect.InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target,
177+
object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters)
178+
{
179+
return InnerInvokeMember(name, invokeAttr, binder,target, args, modifiers, culture, namedParameters);
180+
}
181+
182+
#endregion
183+
}
184+
}

src/MsieJavaScriptEngine/HostObject.cs

+22-134
Original file line numberDiff line numberDiff line change
@@ -5,172 +5,60 @@
55
using System.Linq;
66
using System.Reflection;
77

8+
using Constants;
89
using Helpers;
910

1011
/// <summary>
1112
/// Wrapper for object, that implements <see cref="IReflect"/> interface
1213
/// </summary>
13-
internal class HostObject : IReflect
14+
internal sealed class HostObject : HostItemBase
1415
{
15-
/// <summary>
16-
/// Target object
17-
/// </summary>
18-
private readonly object _target;
19-
20-
/// <summary>
21-
/// Target type
22-
/// </summary>
23-
private readonly Type _type;
24-
25-
/// <summary>
26-
/// JavaScript engine mode
27-
/// </summary>
28-
private readonly JsEngineMode _engineMode;
29-
30-
/// <summary>
31-
/// List of fields
32-
/// </summary>
33-
private readonly FieldInfo[] _fields;
34-
35-
/// <summary>
36-
/// List of properties
37-
/// </summary>
38-
private readonly PropertyInfo[] _properties;
39-
40-
/// <summary>
41-
/// List of methods
42-
/// </summary>
43-
private readonly MethodInfo[] _methods;
44-
45-
/// <summary>
46-
/// Gets a target object
47-
/// </summary>
48-
public object Target
49-
{
50-
get { return _target; }
51-
}
52-
53-
5416
/// <summary>
5517
/// Constructs an instance of the wrapper for object, that implements <see cref="IReflect"/> interface
5618
/// </summary>
5719
/// <param name="target">Target object</param>
5820
/// <param name="engineMode">JavaScript engine mode</param>
5921
public HostObject(object target, JsEngineMode engineMode)
60-
{
61-
_target = target;
62-
_type = target.GetType();
63-
_engineMode = engineMode;
64-
65-
var defaultBindingFlags = BindingFlags.Instance | BindingFlags.Public;
66-
_fields = _type.GetFields(defaultBindingFlags);
67-
_properties = _type.GetProperties(defaultBindingFlags);
68-
_methods = _type.GetMethods(defaultBindingFlags);
69-
}
70-
71-
#region IReflect implementation
72-
73-
Type IReflect.UnderlyingSystemType
74-
{
75-
get { throw new NotImplementedException(); }
76-
}
22+
: base(target.GetType(), target, engineMode, true)
23+
{ }
7724

7825

79-
FieldInfo IReflect.GetField(string name, BindingFlags bindingAttr)
26+
private object InvokeDelegate(Delegate del, object[] args)
8027
{
81-
FieldInfo field = _fields.SingleOrDefault(f => f.Name == name);
82-
83-
return field;
84-
}
85-
86-
FieldInfo[] IReflect.GetFields(BindingFlags bindingAttr)
87-
{
88-
return _fields;
89-
}
90-
91-
MemberInfo[] IReflect.GetMember(string name, BindingFlags bindingAttr)
92-
{
93-
throw new NotImplementedException();
94-
}
95-
96-
MemberInfo[] IReflect.GetMembers(BindingFlags bindingAttr)
97-
{
98-
throw new NotImplementedException();
99-
}
100-
101-
MethodInfo IReflect.GetMethod(string name, BindingFlags bindingAttr)
102-
{
103-
MethodInfo method = _methods.SingleOrDefault(m => m.Name == name);
104-
105-
return method;
106-
}
107-
108-
MethodInfo IReflect.GetMethod(string name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers)
109-
{
110-
throw new NotImplementedException();
111-
}
28+
if (del == null)
29+
{
30+
throw new ArgumentNullException("del");
31+
}
11232

113-
MethodInfo[] IReflect.GetMethods(BindingFlags bindingAttr)
114-
{
115-
return _methods;
116-
}
33+
object[] processedArgs = args;
11734

118-
PropertyInfo[] IReflect.GetProperties(BindingFlags bindingAttr)
119-
{
120-
return _properties;
121-
}
35+
if (_engineMode == JsEngineMode.Classic && processedArgs.Length > 0)
36+
{
37+
processedArgs = processedArgs.Skip(1).ToArray();
38+
}
12239

123-
PropertyInfo IReflect.GetProperty(string name, BindingFlags bindingAttr)
124-
{
125-
PropertyInfo property = _properties.SingleOrDefault(p => p.Name == name);
40+
object result = del.DynamicInvoke(processedArgs);
12641

127-
return property;
42+
return result;
12843
}
12944

130-
PropertyInfo IReflect.GetProperty(string name, BindingFlags bindingAttr, Binder binder,
131-
Type returnType, Type[] types, ParameterModifier[] modifiers)
132-
{
133-
throw new NotImplementedException();
134-
}
45+
#region HostItemBase implementation
13546

136-
object IReflect.InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target,
47+
protected override object InnerInvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target,
13748
object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters)
13849
{
13950
object result;
14051
object processedTarget = TypeMappingHelpers.MapToHostType(target);
14152
object[] processedArgs = TypeMappingHelpers.MapToHostType(args);
14253

143-
var del = processedTarget as Delegate;
144-
if (del != null)
54+
if (name == SpecialMemberName.Default && processedTarget is Delegate)
14555
{
146-
if (_engineMode == JsEngineMode.Classic && processedArgs.Length > 0)
147-
{
148-
processedArgs = processedArgs.Skip(1).ToArray();
149-
}
150-
151-
result = del.DynamicInvoke(processedArgs);
56+
var del = (Delegate)processedTarget;
57+
result = InvokeDelegate(del, processedArgs);
15258
}
15359
else
15460
{
155-
BindingFlags processedInvokeAttr = invokeAttr;
156-
if ((processedInvokeAttr.HasFlag(BindingFlags.GetProperty)
157-
|| processedInvokeAttr.HasFlag(BindingFlags.PutDispProperty))
158-
&& !_properties.Any(p => p.Name == name)
159-
&& _fields.Any(p => p.Name == name))
160-
{
161-
if (processedInvokeAttr.HasFlag(BindingFlags.GetProperty))
162-
{
163-
processedInvokeAttr &= ~BindingFlags.GetProperty;
164-
processedInvokeAttr |= BindingFlags.GetField;
165-
}
166-
else if (processedInvokeAttr.HasFlag(BindingFlags.PutDispProperty))
167-
{
168-
processedInvokeAttr &= ~BindingFlags.PutDispProperty;
169-
processedInvokeAttr |= BindingFlags.SetField;
170-
}
171-
}
172-
173-
result = _type.InvokeMember(name, processedInvokeAttr, binder, processedTarget,
61+
result = InvokeStandardMember(name, invokeAttr, binder, processedTarget,
17462
processedArgs, modifiers, culture, namedParameters);
17563
}
17664

0 commit comments

Comments
 (0)