jbevain / cecil Goto Github PK
View Code? Open in Web Editor NEWCecil is a library to inspect, modify and create .NET programs and libraries.
License: MIT License
Cecil is a library to inspect, modify and create .NET programs and libraries.
License: MIT License
Hi Evain,
I decompiled a switch statement that follows:
switch (arg)
{
case 0:
{
return 2;
}
case 1:
{
return 4;
}
default:
{
return 0;
}
}
The result IL contains :
{IL_0004: switch IL_0013,IL_0018}
Followed by :
{IL_0011: br.s IL_001d}
{IL_0013: nop}
Now, instruction.Operand contains nop which is valid but not expected as it should contain the value from IL_0011 which is the switch branch needed to create proper control flow graph.
In this case, is it possible to send the desired OpCode through instruction.Operand ? So that implementer does not have to do an extra simulation on top it.
Regards,
Mehfuz
If a ModuleDefinition is created with the static CreateModule method, its AssemblyResolver is automatically assigned to GlobalAssemblyResolver.Instance, but this instance is very limited on Compact Framework.
Should it be possible to define the AssemblyResolver property, via for example a CreateParameters class?
In some cases Cecil don't modify target address of an jump corretly.
So if we have following IL code before modifing file with Cecil we have:
br.s L_008a
After addings to instructions (ldstr & call) some instructions behind this IL the target adress is changed to:
br.s L_ffffff94
Of course this adress is not anymore valid.
To reproduce:
You can also see the error, if you start APMVisualisation.exe -> Load Log -> test.apm -> scroll up and down. And after this do the same with Test.exe (Test.exe is crashing)
Cecil fails to read type specs in a custom attribute, be it an array, a pointer, or a generic instance.
It seems that the ImportMethod method of the class Import has a bug: if the method as variable arguments, it defines the CallingConvention with the "&" operator, rather than the "|", so the resulting method doesn't have the vararg flag:
if (method.IsVarArg()) reference.CallingConvention &= MethodCallingConvention.VarArg;
should be:
if (method.IsVarArg()) reference.CallingConvention |= MethodCallingConvention.VarArg;
Another bug : the Sentinel parameter is not created, because the type.IsTypeSpecification() returns false for this type !
A call to .Create (OpCode.Ldarg, 0) fails, because Cecil expects a InlineI opcodes, wheras it is authorized in Mono/Microsoft.
If a while or for loop is placed inside an if statement then the loop is incorrectly decompiled.
Decompiling the following C# code:
[MyFunction]
public void SimpleHello()
{
int x = DateTime.Now.Day;
if (x == 15)
{
for (int i = 0; i < 15; i++)
Console.WriteLine(i);
}
}
produces:
public void SimpleHello()
{
DateTime V_2 = DateTime.get_Now();
int V_0 = &V_2.get_Day();
if (V_0 == 15)
{
int V_1 = 0;
Console.WriteLine(V_1);
V_1++;
// two lines above should be inside a (for) loop below
// the decompilation works if there is not if statement around the loop
while (V_1 < 15)
{
}
}
}
Calling code:
Assembly ass = Assembly.GetExecutingAssembly();
AssemblyDefinition ad = AssemblyFactory.GetAssembly(ass.Location);
ModuleDefinitionCollection mdc = ad.Modules;
StringBuilder sb = new StringBuilder();
StringWriter streamWriter = new StringWriter(sb);
foreach (ModuleDefinition mod in mdc)
{
Console.WriteLine(mod.Name);
foreach (TypeDefinition type in mod.Types)
{
Console.WriteLine(type.FullName);
foreach (MethodDefinition md in type.Methods)
{
foreach (CustomAttribute ca in md.CustomAttributes)
{
if (ca.Constructor.DeclaringType.Name == "MyFunctionAttribute")
{
Console.WriteLine(md.Name);
ILanguage lan = Cecil.Decompiler.Languages.CSharp.GetLanguage(Cecil.Decompiler.Languages.CSharpVersion.V3);
ILanguageWriter lanWriter = lan.GetWriter(new PlainTextFormatter(streamWriter));
lanWriter.Write(md);
Console.WriteLine(sb.ToString());
}
}
}
}
}
Is there a way to find a type or a method by its name without going through the whole list?
I must have missed something in my explaination: I meant a memory-created ModuleDefinition, that have not been saved on disk. You don't provide a mean to set its AssemblyResolver property, which is used when the ModuleDefinition is saved on disk. But the default GlobalAssemblyResolver is not interesting on Compact Framework.
I compile an assembly using Visual Studio 2010, C#.
Target Framework is version 4 Client Profile.
Output type is class library.
Platform target is Any CPU.
Optimize code is on.
Allow Unsafe code is off.
There are no managed resources and no native resources.
The assembly is signed (strong name).
The PE Header says:
Section Alignment = 8192
File Alignment = 512
.text section is 254 KB
.rsrc section is 1 KB
.reloc section is 512 bytes
CLR Header says
MetaData is 147,59 KB
Total file size is 256 KB.
I then open the module using
ModuleDefinition md = ModuleDefinition.ReadModule(modulepath);
and save it using
WriterParameters wp = new WriterParameters
{
WriteSymbols = md.HasSymbols
};
md.Write(modulepath, wp);
The new file is now 258.5 KB.
The .text section has grown to 255.5 KB
A .sdata section has been added, 512 bytes
CLR Header says MetaData is now down to 147.5 KB.
The .text section should not grow.
A .sdata section should not be added.
The total file size should not increase (It would be ok if it went down without loosing information).
I have not tested this on other modules.
It is virtually impossible to modify a method body without invalidating instruction offsets. After updating instructions, offsets must be updated too or Mono.Cecil.Cil.CodeWriter::WriteMethodBody will write wrong offsets in branch instructions.
I believe that ComputeOffsets should be a public instance member on MethodBody (or on InstructionCollection as per my other suggestion). This should allow programs to call ComputeOffsets after applying modifications to the method body and before running further analysis logic.
I also feel the method should be renamed to UpdateOffsets.
I believe that Mono.Cecil.Cil.CodeWriter::WriteMethodBody should call ComputeOffsets before writing the method body. This ensures that wrong branch offsets are not written in case a program did not call UpdateOffsets/ComputeOffsets.
-- edit: Mono.Cecil.Cil.CodeWriter::WriteMethodBody does compute offsets.
Alternatively, the UpdateOffsets is private, but is called automatically after every update to MethodBody.Instructions. This would make the API significantly easier to use, at the expense of reduced performance.
When resolving a TypeReference failed, Cecil should try to check the exported types and if there's a match, resolve from the scope of the exported type.
Currently Cecil fails to read an assembly which has a non sorted GenericParameterTable.
When calling RemoveAt on Mono.Cecil.Cil.VariableDefinitionCollection, which is inherited from Collection, the variable indices are wrong.
The reason is that Collection::RemoveAt calls Collection::OnRemove before actually removing the item.
As a result, VariableDefinitionCollection::OnRemove calls ComputeIndexes() before the item is actually removed.
As a result, the call to VariableDefinitionCollection::ComputeIndexes() has no effect.
If I create a EmbeddedResource providing a Stream object, the method GetResourceData() doesn't exploit the stream field and fails.
I suggest the following:
public byte [] GetResourceData () { if (data != null) return data; // new code starts here if (stream != null) return ReadFully(stream); // new code ends here if (offset.HasValue) return reader.GetManagedResourceStream (offset.Value).ToArray (); throw new InvalidOperationException (); }
Here is an implementation of ReadFully (cf http://www.yoda.arachsys.com/csharp/readbinary.html) :
////// Reads data from a stream until the end is reached. The /// data is returned as a byte array. An IOException is /// thrown if any of the underlying IO calls fail. /// /// The stream to read data from public static byte[] ReadFully(Stream stream) { byte[] buffer = new byte[32768]; using (MemoryStream ms = new MemoryStream()) { while (true) { int read = stream.Read(buffer, 0, buffer.Length); if (read <= 0) return ms.ToArray(); ms.Write(buffer, 0, read); } } }
When renaming a MethodReference from another assembly, the change is not taken into account for methods with generic parameters.
For example, if a get a MethodReference from a call like module.GetMemberReferences.GetMemberReferences().OfType()
The behavior comes from AssemblyReader.GetMemberReference that doesn't cache generic methods.
It seems easy to fix but I don't know the side effects.
The maxstack computed for these generated instructions is 1, whereas it must be 5, so the code does not execute. Can you see why ?
.method public static bool TestFilter(bool) cil managed { .maxstack 1 .locals init ( [0] bool flag) L_0000: newobj instance void [mscorlib]System.Exception::.ctor() L_0005: throw L_0006: leave L_001b L_000b: pop L_000c: ldarg.0 L_000d: endfilter L_000f: ldc.i4.1 L_0010: stloc.0 L_0011: leave L_001d L_0016: leave L_001b L_001b: ldc.i4.0 L_001c: stloc.0 L_001d: ldloc.0 L_001e: ret .try L_0000 to L_000b filter L_000b handler L_000f to L_001b }
So we can determine wether a TypeReference is a primitive type or not.
Or expose e property that says wether a TypeReference is a primitive type ?
Primitive types are :
Boolean
Int8
UInt8
Int16
UInt16
Int32
UInt32
Int64
UInt64
IntPtr
UIntPtr
Char
Float32:
Float64
MethodBody.Instructions returns a Collection which can be modified. However, when inserting or removing items, invariants are not maintained.
The collection can also be modified through an ILProcessor, where the Append, InsertBefore, InsertAfter, and Remove methods maintain the Instruction.Next and Instruction.Previous properties (as do the Emit and Replace functions through them).
This is not good. I suggest that MethodBody.Instructions return an InstructionCollection, inheriting from Collection, that maintains the Instruction.Next and Instruction.Previous properties. This responsibility can than be removed from ILProcessor. More importantly, it then becomes safe to modify the MethodBody.Instructions collection directly.
We need to have multiple debug/release configurations for:
Using the following code to inject string interning whenever a string is stored inside a field on a rather large assembly resulted in 4 functions being rendered useless by wrong branch destinations.
Instruction instruction = methodBody.Instructions[index];
ILProcessor ilProcessor = methodBody.GetILProcessor();
if (instruction.OpCode == OpCodes.Stfld)
{
FieldDefinition fieldDef = instruction.Operand as FieldDefinition;
if (fieldDef != null && fieldDef.FieldType.FullName == "System.String")
{
if (instruction.Previous.OpCode != OpCodes.Ldstr && instruction.Previous.OpCode != OpCodes.Call && instruction.Previous.Operand != null && !instruction.Previous.Operand.Equals(methRef))
{
ilProcessor.InsertBefore(instruction,
ilProcessor.Create(OpCodes.Dup));
ilProcessor.InsertBefore(instruction,
ilProcessor.Create(OpCodes.Ldnull));
ilProcessor.InsertBefore(instruction,
ilProcessor.Create(OpCodes.Beq, instruction));
ilProcessor.InsertBefore(instruction,
ilProcessor.Create(OpCodes.Call, methRef));
index += 4;
retVal = true;
}
}
}
The branches in consideration are not part of the injected code and show up in PE Verifier as follows
[IL]: Error: jmp / exception into the middle of an instruction.
[IL]: Error: Branch into try block.
[IL]: Error: Branch out of the method.
Especially in the branch out of method, there might be an overflow hapenning as the Offsets are very large. I will try to provide more information as I see it, but cannot share the tested assemblies...
If you attempt to resolve an AssemblyNameReference with a null Version field, a null reference exception is thrown. This only happens when the assembly does not appear within the specified search directories.
eg.
GlobalAssemblyResolver.Instance.Resolve(AssemblyNameReference.Parse("System.Core"));
The exception is thrown in BaseAssemblyResolver.IsZero(). Its worth noting that AssemblyNameReference.Parse() returns a reference with a null version field if no version is specified in the fullname parameter. Is this by design?
It would be great to have Cecil import types only when the assembly is saved, as does Cci Metadata from Microsoft .
It would be easy to determine whether a TypeDefinition must be imported, from its Module property, and then from its Assembly property: if it's not the current Assembly, then the type must be a TypeReference, and the AssemblyReferences must be filled.
How long would it take to modify Cecil to work this way ?
Would there be some performance penalty?
First assembly :
Test.dll defines a generic type
public class G< T > { public static T F; }
Second assembly :
I want to define a ldsfld instruction - in a static Main method of a Test class - that uses the F field, but I don't know what context to pass to the ModuleDefinition.Import method in order to import the FieldDefinition :
In fact, I have the same importation errors when the G<> class is defined in the same ModuleDefinition, for exactly the same reasons.
Thanks a lot for your help.
Sometimes when I'm calling Resolve on a TypeReference, I get the following exception:
System.NotSupportedException was unhandled
Message="Version not supported: 2.0"
Source="Mono.Cecil"
StackTrace:
vid Mono.Cecil.BaseAssemblyResolver.GetCorlib(AssemblyNameReference reference)
vid Mono.Cecil.BaseAssemblyResolver.Resolve(AssemblyNameReference name)
vid Mono.Cecil.DefaultAssemblyResolver.Resolve(AssemblyNameReference name)
vid Mono.Cecil.MetadataResolver.Resolve(IAssemblyResolver resolver, TypeReference type)
vid Mono.Cecil.ModuleDefinition.Resolve(TypeReference type)
vid Mono.Cecil.TypeReference.Resolve()
It seems that the TypeReference is referencing mscorlib 2.0 instead of mscorlib 2.0.0.0.
.NET supports VTable entries and native (pe) exports that invoke static methods as if they were written in a non-managed language. Cecil doesn't expose this feature yet.
The getter methods are incorrectly using attributes whereas impl_attributes is expected.
For example:
public bool IsIL { get { return attributes.GetMaskedAttributes ((ushort) MethodImplAttributes.CodeTypeMask, (ushort) MethodImplAttributes.IL); } set { impl_attributes = impl_attributes.SetMaskedAttributes((ushort)MethodImplAttributes.CodeTypeMask, (ushort)MethodImplAttributes.IL, value); } }
We sould have:
public bool IsIL { get { return impl_attributes.GetMaskedAttributes ((ushort) MethodImplAttributes.CodeTypeMask, (ushort) MethodImplAttributes.IL); } set { impl_attributes = impl_attributes.SetMaskedAttributes((ushort)MethodImplAttributes.CodeTypeMask, (ushort)MethodImplAttributes.IL, value); } }
We need an API to parse and emit code without creating costly Instruction instances.
For the reading part, we would move the ILParse functionality from Cecil.Rocks to Cecil.
For the writing part, we would need a context to store the operands to be mapped to actual tokens.
MethodDefinition.Body throws a NullReferenceException when called on a method of an interface generated for COM interop.
(_System.Void Microsoft.Office.Interop.Excel._Application::VtblGap1_15())
namespace ciproject4
{
public class ComInterop
{
public static void main(String args)
{
var excel = new Microsoft.Office.Interop.Excel.Application();
excel.Cells[1, 1].Value2 = "Ma feuille Excel";
}
}
}
4 interfaces are generated by the compiler for this program :
_Application declaration looks like that :
[ComImport, TypeIdentifier, Guid("000208D5-0000-0000-C000-000000000046"), CompilerGenerated, DefaultMember("_Default")]
public interface _Application
{
void _VtblGap1_15();
Range Cells { [return: MarshalAs(UnmanagedType.Interface)] [DispId(238)] get; }
}
Stacktrace :
at Mono.Cecil.Cil.CodeReader.IsInSection(Int32 rva) in Mono.Cecil.Cil\CodeReader.cs:line 88
at Mono.Cecil.Cil.CodeReader.MoveTo(Int32 rva) in Mono.Cecil.Cil\CodeReader.cs:line 78
at Mono.Cecil.Cil.CodeReader.ReadMethodBody() in Mono.Cecil.Cil\CodeReader.cs:line 93
at Mono.Cecil.Cil.CodeReader.ReadMethodBody(MethodDefinition method) in Mono.Cecil.Cil\CodeReader.cs:line 71
at Mono.Cecil.MetadataReader.ReadMethodBody(MethodDefinition method) in Mono.Cecil\AssemblyReader.cs:line 1830
at Mono.Cecil.MethodDefinition.<get_Body>b__2(MethodDefinition method, MetadataReader reader) in Mono.Cecil\MethodDefinition.cs:line 152
at Mono.Cecil.ModuleDefinition.Read[TItem,TRet](TItem item, Func`3 read) in Mono.Cecil\ModuleDefinition.cs:line 704
at Mono.Cecil.MethodDefinition.get_Body() in Mono.Cecil\MethodDefinition.cs:line 152
Add the required nunit binaries to the git repository and change project reference appropriately.
Cecil depends on NUnit for its unit tests. The current version of NUnit is 2.5.8 however using that results in compile error in Addin.cs using type TestCaseResult. The best I can tell is NUnit 2.4.7 provides the required TestCaseResult type.
If the binaries for NUnit that Cecil requires is included in the git repository then there would not be issues for new people cloning and building the repository.
When an attribute uses an enum defined in other assembly and Cecil cannot resolve that assembly, the following exception occurs.
Cecil should not assume that referenced assemblies are always available and provide as much information as possible in such cases.
NullReferenceException
at Mono.Cecil.SignatureReader.ReadCustomAttributeEnum(TypeReference enum_type) in c:\work\cecil\Mono.Cecil\AssemblyReader.cs:line 2838
at Mono.Cecil.SignatureReader.ReadCustomAttributeElementValue(TypeReference type) in c:\work\cecil\Mono.Cecil\AssemblyReader.cs:line 2740
at Mono.Cecil.SignatureReader.ReadCustomAttributeElement(TypeReference type) in c:\work\cecil\Mono.Cecil\AssemblyReader.cs:line 2726
at Mono.Cecil.SignatureReader.ReadCustomAttributeFixedArgument(TypeReference type) in c:\work\cecil\Mono.Cecil\AssemblyReader.cs:line 2661
at Mono.Cecil.SignatureReader.ReadCustomAttributeConstructorArguments(CustomAttribute attribute, Collection1 parameters) in c:\work\cecil\Mono.Cecil\AssemblyReader.cs:line 2652 at Mono.Cecil.MetadataReader.ReadCustomAttributeSignature(CustomAttribute attribute) in c:\work\cecil\Mono.Cecil\AssemblyReader.cs:line 2194 at Mono.Cecil.CustomAttribute.<Resolve>b__2(CustomAttribute attribute, MetadataReader reader) in c:\work\cecil\Mono.Cecil\CustomAttribute.cs:line 194 at Mono.Cecil.ModuleDefinition.Read[TItem,TRet](TItem item, Func
3 read) in c:\work\cecil\Mono.Cecil\ModuleDefinition.cs:line 553
at Mono.Cecil.CustomAttribute.Resolve() in c:\work\cecil\Mono.Cecil\CustomAttribute.cs:line 193
at Mono.Cecil.CustomAttribute.get_ConstructorArguments() in c:\work\cecil\Mono.Cecil\CustomAttribute.cs:line 102
For now, ModuleDefination.Types returns TypeDefination.
It works well for normal types but not for generic types.
The same base class for GenericInstanceType and TypeDefination is TypeReference.
So I think ModuleDefination.Types should return TypeReference.
(There are other issues about generic types in cecil. Maybe the better way to solve it is to make GenericInstanceType inherits from TypeDefination.....)
Import for System.Reflection types probably doesn't work with nested generics types like:
class Foo { class Bar<T> {} }
class Baz<Y> { class Gazonk {} }
It does help a lot when debugging.
One implementation that does seem to work has been suggested already, see
http://permalink.gmane.org/gmane.comp.gnome.mono.cecil/1474
Note that this ToString() method requires instructions offsets to be correct.
Forgive me for repeating an earlier request here: please consider recalculating instruction offsets in the OnX methods of Mono.Cecil.Cil.InstructionCollection
This is an obscure one, and there are some workarounds, so it's not exactly a high priority, but:
At this point, csc should start complaining about multiple implementations of ExtensionAttribute in the global namespace, as a warning. This is annoying but harmless, until you:
at which point it breaks your build.
Workarounds:
The .net 4.0 GAC changed quite a bit:
http://stackoverflow.com/questions/2660355/net-4-0-has-a-new-gac-why
http://msdn.microsoft.com/en-us/magazine/dd727509.aspx
The BaseAssemblyResolver needs to be fixed for it.
It should be great to have access to the TypeSystem properties in order to use the basic types.
There is no way at the moment to use these basic types so that Cecil uses the ElementType value rather than creating a reference on mscorlib and a TypeReference, for System.Object, System.Void, etc...
When round tripping a pdb with Mono.Cecil and Mono.Cecil.Pdb, we're losing some custom data about iterators. VS is then unable to debug properly iterator variables.
It looks fixable.
With the CCI code, a PdbFunction has a iteratorClass field, mapping a method to its iterator class. Then the MoveNext method has an iteratorScopes field, which is a collection of scopes.
To encode that back in the PdbWriter, we have to use SetSymAttribute in between OpenMethod and CloseMethod. The PeWriter file of the CCI has the information.
Cecil currently does not support reading or writing custom attributes declared on a TypeRef or a MemberRef.
Import for Cecil types defined in another module of the same assembly doesn't work.
In the AssemblyWriter class, the AddMethod method checks that a MethodDefinition has some parameter, but not whether it has a return parameter. So the AddParameter is not called.
It should be possible to write the following method:
public static void StartWithNop(Mono.Collections.Generic.Collection<Instruction> instructions)
{
Instruction nop = // maybe Instruction.Create(OpCodes.Nop, null);
instructions.Insert(0, nop);
}
Currently, the only way to create an instruction is via Create methods on ILProcessor. Obviously, this requires creating an instance of ILProcessor and passing it around. As this instance is not actually used by the Create methods, it seems rather pointless to create it and pass it around. Put differently: the Create methods can and should be static, in which case they belong on the Instruction class.
In the example above, the method currently needs and additional parameter, either an ILProcessor or a MethodBody.
In the case of passing an ILProcessor, there's no way that the method can check that the instructions parameter corresponds to the instructions collection hidden inside the ILProcessor (and hidden it is).
In the case of passing the MethodBody, the instructions collection does not need to be passed separately, but an ILProcessor must be created to be able to create an instruction.
Furthermore, creating instructions is the only thing that an ILProcessor is required for. Every other operation offered by ILProcessor is easy to do directly on an instructions collection.
I therefor propose the following:
The Microsoft Reflection.Emit library allows to specify the filename of a dynamic module, that may be different from its name, but Cecil provide no way to do the same.
(note: the filename is built automatically by Cecil when an assembly with external modules is saved).
For the use case of disassembling with symbol info while using an assembly resolver, a new overload to IAssemblyResolver.Resolve
could be provided. The workaround is calling MethodDefinition.ReadSymbols()
.
Currently, in the BaseAssemblyResolver
class (line 95), the reader parameters are hardcoded.
return ModuleDefinition.ReadModule (file, new ReaderParameters { AssemblyResolver = this}).Assembly;
It is no longer possible to rename a generic type reference, due to the following commit :
In AssemblyReader.cs, GetMemberReference method, the added condition prevents renames to generic type references to be saved :
if (!member.ContainsGenericParameter)
metadata.AddMemberReference (member);
If I comment out that if, it fixes the problem, but I presume it might break what you were trying to fix with that change.
ElementType should be cleaned up to be made public, and TypeReference.etype should be exposed.
Possible property name, by order of preference: MetadataType, SignatureType, CoreType, TypeCode.
A per (now old) discussion on IRC. Application, like Gendarme, would benefit knowing/solving resolver failures. E.g. asking the user to manually locate mscorlib.dll instead of failing for an unknown (or newer) framework.
Cecil can round-trip an assembly containing win32 resources, and will preserve them, but doesn't offer a way to add / modify / remove win32 resources.
Environment :
Step to reproduce :
What I Expected :
I expected the project to compile without any issues as it occured the first time.
What I got :
Compilation issues :
Warning :
The predefined type 'System.Runtime.CompilerServices.ExtensionAttribute' is defined in
multiple assemblies in the global alias; using definition from 'c:\xxx\Mono.Cecil.dll'
Error CS0656
Missing compiler required member 'System.Runtime.CompilerServices.ExtensionAttribute..ctor'
Workaround :
Each time, you work again to the project, unreference Mono.Cecil, and reference it again
These properties use PInvokeAttributes.BestFitMask, but they must use ThrowOnUnmappableCharMask.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.