Skip to content

Commit f35b673

Browse files
authored
Update Readme.md
1 parent f3251f3 commit f35b673

File tree

1 file changed

+101
-103
lines changed

1 file changed

+101
-103
lines changed

Readme.md

Lines changed: 101 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,148 +1,135 @@
11
[![Actions Status](https://github.com/deniszykov/csharp-eval-unity3d/workflows/dotnet_build/badge.svg)](https://github.com/deniszykov/csharp-eval-unity3d/actions)
22

3-
# Licensing
3+
# Licensing
4+
This package is available for [purchase](https://assetstore.unity.com/packages/tools/visual-scripting/c-eval-56706) on the Unity Asset Store. A valid license is required for use in any project.
45

5-
This is a paid [package](https://assetstore.unity.com/packages/tools/visual-scripting/c-eval-56706), you can use it anywhere if you [purchased it](https://assetstore.unity.com/packages/tools/visual-scripting/c-eval-56706).
6+
# Overview
7+
This package delivers a C# parsing and expression execution API designed for [Unity](http://unity3d.com/) compatibility across multiple platforms. Implemented in C# 3.5 with no external dependencies, it maintains broad compatibility with Unity versions and .NET frameworks.
68

7-
# Introduction
9+
## Verified Platform Support
10+
• iOS
11+
• Android
12+
• WebGL
13+
• Windows/macOS/Linux
814

9-
This package provides the API for parsing and expression execution written in C#. It is specially designed to work with the [Unity](http://unity3d.com/) on various platforms. Since it is written in C# 3.5 and has no additional dependencies, it should work with any version of Unity (and .NET framework).
15+
The solution should function on additional Unity-supported platforms.
1016

11-
It is tested to work on:
12-
* IOS
13-
* Android
14-
* WebGL
15-
* PC/Mac
17+
> **Important Note for AOT Platforms (iOS, WebGL, IL2CPP):**
18+
> Projects targeting AOT compilation require inclusion of a [link.xml](https://github.com/deniszykov/csharp-eval-unity3d/blob/master/src/GameDevWare.Dynamic.Expressions.Unity.2021/Assets/Plugins/GameDevWare.Dynamic.Expressions/link.xml) file in the project root directory. Refer to Unity's documentation on [IL code stripping](https://docs.unity3d.com/Manual/IL2CPP-BytecodeStripping.html) for additional context.
1619
17-
It should work on any other platforms.
20+
## Core API
21+
**CSharpExpression**
22+
- Evaluate
23+
- Parse
24+
**AotCompilation**
25+
- RegisterFunc
26+
- RegisterForFastCall (performance optimization)
1827

19-
> :warning: For AOT execution platforms (**iOS, WebGL, IL2CPP**) a [link.xml](https://github.com/deniszykov/csharp-eval-unity3d/blob/master/src/GameDevWare.Dynamic.Expressions.Unity.2021/Assets/Plugins/GameDevWare.Dynamic.Expressions/link.xml) should be added to project's root directory. Read more about [IL code stripping](https://docs.unity3d.com/Manual/IL2CPP-BytecodeStripping.html) in official documentation.
28+
## Implementation Examples
2029

21-
**API**
22-
* CSharpExpression
23-
* Evaluate
24-
* Parse
25-
* AotCompilation
26-
* RegisterFunc
27-
* RegisterForFastCall (optional stuff)
28-
29-
## Example
30-
Parsing C# expression into **System.Linq.Expression.Expression[T]**:
30+
**Expression Parsing:**
3131
```csharp
3232
var mathExpr = "Math.Max(x, y)";
33-
var exprTree = CSharpExpression.Parse<double, double, double>(mathExpr, arg1Name: "x", arg2Name: "y")
34-
// exprTree -> Expression<Func<double, double, double>>
33+
var exprTree = CSharpExpression.Parse<double, double, double>(mathExpr, arg1Name: "x", arg2Name: "y");
34+
// Returns Expression<Func<double, double, double>>
35+
var expr = exprTree.CompileAot();
36+
// Returns Func<double, double, double>
3537
```
36-
Evaluating C# expression:
38+
39+
**Expression Evaluation:**
3740
```csharp
3841
var arifExpr = "2 * (2 + 3) << 1 + 1 & 7 | 25 ^ 10";
3942
var result = CSharpExpression.Evaluate<int>(arifExpr);
40-
// result -> 19
43+
// Returns 19
4144
```
4245

43-
## Parser
44-
The parser recognizes the C# 4 grammar only. It includes:
45-
46-
* Arithmetic operations
47-
* Bitwise operations
48-
* Logical operations
49-
* [Conditional operator](https://msdn.microsoft.com/en-us/library/ty67wk28.aspx)
50-
* [Null-coalescing operator](https://msdn.microsoft.com/en-us/library/ms173224.aspx)
51-
* Method/Delegate/Constructor call
52-
* [Property/Field access](https://msdn.microsoft.com/en-us/library/6zhxzbds.aspx)
53-
* [Indexers](https://msdn.microsoft.com/en-gb/library/6x16t2tx.aspx)
54-
* [Casting and Conversion](https://msdn.microsoft.com/en-us/library/ms173105.aspx)
55-
* [Is Operator](https://msdn.microsoft.com/en-us/library/scekt9xw.aspx)
56-
* [As Operator](https://msdn.microsoft.com/en-us/library/cscsdfbt.aspx)
57-
* [TypeOf Operator](https://msdn.microsoft.com/en-us/library/58918ffs.aspx)
58-
* [Default Operator](https://msdn.microsoft.com/en-us/library/xwth0h0d.aspx)
59-
* [Expression grouping with parentheses](https://msdn.microsoft.com/en-us/library/0z4503sa.aspx)
60-
* [Checked/Unchecked scopes](https://msdn.microsoft.com/en-us/library/khy08726.aspx)
61-
* [Aliases for Built-In Types](https://msdn.microsoft.com/en-us/library/ya5y69ds.aspx)
62-
* [Null-conditional Operators](https://msdn.microsoft.com/en-us/library/dn986595.aspx)
63-
* Power operator ``**``
64-
* [Lambda expressions](https://msdn.microsoft.com/en-us/library/bb397687.aspx)
65-
* "true", "false", "null"
66-
67-
Nullable types are supported.
68-
Generics are supported.
69-
Enumerations are supported.
70-
[Type inference](https://docs.microsoft.com/en-us/dotnet/articles/fsharp/language-reference/type-inference) is not available and your should always specify generic parameters on types and methods.
71-
72-
**Known Types**
73-
74-
For security reasons the parser does not provide access to any types except:
75-
* types used in arguments
76-
* primitive types
77-
* `Math`, `Array`, `Func<>` types
78-
79-
To access other types your should pass **typeResolver** parameter in **Parse** and **Evaluate** method:
46+
## Parser Specifications
47+
The parser implements C# 4 grammar with support for:
48+
49+
• Arithmetic, bitwise, and logical operations
50+
[Conditional](https://msdn.microsoft.com/en-us/library/ty67wk28.aspx) and [null-coalescing operators](https://msdn.microsoft.com/en-us/library/ms173224.aspx)
51+
• Method/delegate/constructor invocation
52+
[Property/field access](https://msdn.microsoft.com/en-us/library/6zhxzbds.aspx) and [indexers](https://msdn.microsoft.com/en-gb/library/6x16t2tx.aspx)
53+
• Type operations ([casting, conversion](https://msdn.microsoft.com/en-us/library/ms173105.aspx), [is](https://msdn.microsoft.com/en-us/library/scekt9xw.aspx)/[as](https://msdn.microsoft.com/en-us/library/cscsdfbt.aspx)/[typeof](https://msdn.microsoft.com/en-us/library/58918ffs.aspx)/[default](https://msdn.microsoft.com/en-us/library/xwth0h0d.aspx))
54+
[Expression grouping](https://msdn.microsoft.com/en-us/library/0z4503sa.aspx) and [checked/unchecked contexts](https://msdn.microsoft.com/en-us/library/khy08726.aspx)
55+
[Type aliases](https://msdn.microsoft.com/en-us/library/ya5y69ds.aspx) and [null-conditional operators](https://msdn.microsoft.com/en-us/library/dn986595.aspx)
56+
• Power operator (**)
57+
[Lambda expressions](https://msdn.microsoft.com/en-us/library/bb397687.aspx)
58+
• Literal values (true, false, null)
59+
60+
**Type Support:**
61+
• Nullable types
62+
• Generics
63+
• Enumerations
64+
65+
> **Note:** [Type inference](https://docs.microsoft.com/en-us/dotnet/articles/fsharp/language-reference/type-inference) is not implemented - explicit generic parameter specification is required.
66+
67+
## Type Resolution
68+
For security, the parser restricts type access to:
69+
• Argument types
70+
• Primitive types
71+
• Math, Array, and Func<> types
72+
73+
Additional types require specification through the typeResolver parameter:
8074
```csharp
8175
var typeResolver = new KnownTypeResolver(typeof(Mathf), typeof(Time));
82-
CSharpExpression.Evaluate<int>("Mathf.Clamp(Time.time, 1.0f, 3.0f)", typeResolver);
76+
CSharpExpression.Evaluate<int>("Mathf.Clamp(Time.time, 1.0f, 3.0f)", typeResolver);
8377
```
84-
If you want to access all types in **UnityEngine** you can pass custom **AssemblyTypeResolver** as typeResolver parameter.
78+
79+
Full namespace access can be enabled via AssemblyTypeResolver:
8580
```csharp
8681
var typeResolver = new AssemblyTypeResolver(typeof(UnityEngine.Application).Assembly);
8782
```
8883

89-
> ℹ️ For security reasons any method/property calls on **System.Type** will throw exceptions until **System.Type** is added as known type.
84+
> **Security Note:** System.Type operations will throw exceptions unless **System.Type** explicitly added as a known type.
85+
86+
## AOT Compilation Support
87+
The package enables compilation and execution of System.Linq.Expression expressions in AOT environments:
9088

91-
## AOT Execution
92-
You can compile and evaluate expression created by **System.Linq.Expression** and execute it in AOT environment where it is usually impossible.
9389
```csharp
9490
var expr = (Expression<Func<Vector3>>)(() => new Vector3(1.0f, 1.0f, 1.0f));
9591
var fn = expr.CompileAot();
96-
97-
fn; // -> Func<Vector3>
98-
fn(); // -> Vector3(1.0f, 1.0f, 1.0f)
92+
// Returns Func<Vector3>
9993
```
10094

101-
iOS, WebGL and most console platforms use AOT compilation which imposes following restrictions on the dynamic code execution:
102-
103-
* only **Expression&lt;Func&lt;...&gt;&gt;** delegate type could be used with **CompileAot()**.
104-
* only static methods using primitives (int, float, string, object ...) are optimized for fast calls, others are called with reflection.
105-
* all used classes/methods/properties should be visible to [Unity's static code analyser](https://docs.unity3d.com/Manual/ScriptingRestrictions.html)
106-
* ⚠️ An additional preparation should be made for AOT execution platforms. This [link.xml](https://github.com/deniszykov/csharp-eval-unity3d/blob/master/src/GameDevWare.Dynamic.Expressions.Unity.2021/Assets/Plugins/GameDevWare.Dynamic.Expressions/link.xml) should be added in project's root folder. Read more about [IL code stripping](https://docs.unity3d.com/Manual/IL2CPP-BytecodeStripping.html) in official documentation.
95+
**AOT Environment Requirements (iOS, WebGL and most console platforms):**
96+
1. Only Expression<Func<...>> delegate types supported
97+
2. Only static methods using primitives arguments receive optimization
98+
3. All referenced members must be visible to [Unity's static analyzer](https://docs.unity3d.com/Manual/ScriptingRestrictions.html) to prevent eager [IL code stripping](https://docs.unity3d.com/Manual/IL2CPP-BytecodeStripping.html)
99+
4. ⚠️ Required [link.xml](https://github.com/deniszykov/csharp-eval-unity3d/blob/master/src/GameDevWare.Dynamic.Expressions.Unity.2021/Assets/Plugins/GameDevWare.Dynamic.Expressions/link.xml) configuration (see above)
107100

108101
**See Also**
109102
* [AOT Exception Patterns and Hacks](https://github.com/neuecc/UniRx/wiki/AOT-Exception-Patterns-and-Hacks)
110103
* [Ahead of Time Compilation (AOT)](http://www.mono-project.com/docs/advanced/runtime/docs/aot/)
111104

112-
### WebGL and iOS
113105

114-
* Only [Func<>](https://msdn.microsoft.com/en-us/library/bb534960(v=vs.110).aspx) (up to 4 arguments) lambdas are supported with `CompileAot()`.
115-
* Instance methods calls performs slowly due reflection
116-
* Moderate boxing for value types (see roadmap)
106+
### Platform-Specific Considerations
117107

118-
You can prepare [Func<>](https://msdn.microsoft.com/en-us/library/bb534960(v=vs.110).aspx) lambda for AOT compilation/execution by registering it with **AotCompilation.RegisterFunc**.
108+
**WebGL and iOS:**
109+
• Func<> lambdas limited to 4 arguments
110+
• Instance methods incur reflection overhead
111+
• Value types experience moderate boxing
119112

113+
**Preparation for AOT Execution:**
120114
```csharp
121-
AotCompilation.RegisterFunc<int, bool>(); // will enable Func<int, bool> lambdas anywhere in expressions
115+
AotCompilation.RegisterFunc<int, bool>(); // Enables Func<int, bool> in expressions
122116
```
123117

124-
### Unity 2020.3.2 Issues
125-
This version of Unity has runtime bug related to lambda compilation. Please use following workaround for IL2CPP/AOT runtime:
126-
```cs
127-
#if ((UNITY_WEBGL || UNITY_IOS || ENABLE_IL2CPP) && !UNITY_EDITOR)
118+
**Unity 2020.3.2 Workaround:**
119+
```csharp
120+
#if ((UNITY_WEBGL || UNITY_IOS || ENABLE_IL2CPP) && !UNITY_EDITOR
128121
GameDevWare.Dynamic.Expressions.AotCompilation.IsAotRuntime = true;
129122
#endif
130123
```
131124

125+
## Performance Optimization
126+
Method invocation performance can be enhanced through signature registration:
132127

133-
**Improving Performance**
134-
135-
You can improve the performance of methods invocation by registering their signatures in **AotCompilation.RegisterForFastCall()**.
136-
137-
```
138-
// Supports up to 3 arguments.
139-
// First generic argument is your class type.
140-
// Last generic argument is return type.
141-
142-
AotCompilation.RegisterForFastCall<InstanceT, ResultT>()
143-
AotCompilation.RegisterForFastCall<InstanceT, Arg1T, ResultT>()
144-
AotCompilation.RegisterForFastCall<InstanceT, Arg1T, Arg2T, ResultT>()
145-
AotCompilation.RegisterForFastCall<InstanceT, Arg1T, Arg2T, Arg3T, ResultT>()
128+
```csharp
129+
// Supports up to 3 arguments
130+
AotCompilation.RegisterForFastCall<MyClass, ReturnType>();
131+
AotCompilation.RegisterForFastCall<MyClass, Arg1Type, ReturnType>();
132+
// Additional signatures...
146133
```
147134

148135
Example:
@@ -160,18 +147,29 @@ AotCompilation.RegisterForFastCall<MyVectorMath, Vector4, Vector4, Vector4>();
160147
AotCompilation.RegisterForFastCall<MyVectorMath, Vector4, float, Vector4>();
161148
```
162149

150+
## Development Roadmap
151+
Expression serialization (completed)
152+
Void expression support (completed)
153+
Future enhancements:
154+
- Delegate construction from method references
155+
- Generic type inference
156+
- C#6 syntax support
157+
- Extension method support
158+
- Type/list initializers
159+
160+
Feature suggestions may be submitted to support@gamedevware.com.
161+
163162
## Roadmap
164163

165164
You can send suggestions at support@gamedevware.com
166165

167-
* Expression serialization (in-progress)
168-
* Void expressions (`System.Action` delegates) (done)
166+
* ~Expression serialization~
167+
* ~Void expressions (`System.Action` delegates)~
169168
* Parser: Delegate construction from method reference
170169
* Parser: Type inference for generics
171-
* Parser: Full C#6 syntax
170+
* Parser: Full C#6 expression syntax
172171
* Parser: Extension methods
173172
* Parser: Type initializers, List initializers
174-
* Custom editor with auto-completion for Unity
175173

176174
## Changes
177175
# 2.3.0

0 commit comments

Comments
 (0)