But now, when installing Cobra svn3087, I had some trouble,
because I have .NET 4.0 installed, and not .NET 4.5 (which cannot be installed on Windows XP).
Issue
Under this condition
- Windows XP SP3
- .NET Framework v4.0.30319
- current dir: "\Source" in SVN working copy of Revision 3087
- "gacutil.exe" in PATH
calling "bin\install-from-workspace.bat" gives this output:
- Code: Select all
Compiling installation program...
Unhandled Exception: System.MissingMethodException: Method not found: 'Int32 System.Environment.get_CurrentManagedThreadId()'.
at Cobra.Core_ert_b2a27b97480f2efb38f55a0042ba2a48.Extend_IEnumerable__T__ExtendIEnumerable.<Numbered>d__12`1..ctor(Int32 <>1__state)
at Compiler._compile1(CompileParams params) in c:\Users\Administrator\Dropbox\Projects\Cobra\workspace-misc\Source\Compiler.cobra:line 394
at Compiler.Compile(CompileParams params) in c:\Users\Administrator\Dropbox\Projects\Cobra\workspace-misc\Source\Compiler.cobra:line 387
at CommandLine.DoCompile(List`1 paths, Boolean willPrintSuccessMsg, Boolean writeTestInvocation, Predicate`1 stopCompilation) in c:\Users\Administrator\Dropbox\Projects\Cobra\workspace-misc\Source\CommandLine.cobra:line 747
at CommandLine.DoRun(List`1 paths) in c:\Users\Administrator\Dropbox\Projects\Cobra\workspace-misc\Source\CommandLine.cobra:line 888
at CommandLine.Run(List`1 args) in c:\Users\Administrator\Dropbox\Projects\Cobra\workspace-misc\Source\CommandLine.cobra:line 712
at CommandLine.Run() in c:\Users\Administrator\Dropbox\Projects\Cobra\workspace-misc\Source\CommandLine.cobra:line 648
at CobraMain.Main() in c:\Users\Administrator\Dropbox\Projects\Cobra\workspace-misc\Source\cobra.cobra:line 26
Workaround
Copy
- "Snapshot\cobra.exe" of svn3079
onto
- "Snapshot\cobra.exe" of svn3087
Now calling
- "bin\install-from-workspace.bat"
gives this output:
- Code: Select all
Compiling installation program...
...
Success!
But why? Not important, but the following text is about the reason.
------------------------------------------------------------------------------
Analysis
Presumably the "Snapshot\cobra.exe" of svn3079 was built with
- (M4) "mscorlib.dll" of "Mono\...\lib\mono\4.0", or
- (N4) "mscorlib.dll" of .NET Framework 4.0
and the "Snapshot\cobra.exe" of svn3087 (and svn3080, ...) was built with
- (M45) "mscorlib.dll" of "Mono\...\lib\mono\4.5", or
- (N45) "mscorlib.dll" of .NET Framework 4.5
If this code (in file "Source\Cobra.Core\ExtendIEnumerable.cobra")
extend IEnumerable<of T>
def numbered as KeyValuePair<of int, T>*
i = 0
for item in this
yield KeyValuePair<of int, T>(i, item)
i += 1
is compiled under M45/N45 then the output assembly contains a call to the property
- System.Environment.get_CurrentManagedThreadId()
which is not defined in M4/N4.
Hence, running the "Snapshot\cobra.exe" of svn3087 under M4/N4,
throws this Exception:
"System.MissingMethodException: Method not found:
'Int32 System.Environment.get_CurrentManagedThreadId()'."
Disassembling
How this Cobra code is translated via the C# compiler can be seen by disassembling "Snapshot\cobra.exe" of svn3087 (e.g. with ".NET Reflector"). This gives the following C#-like code -- the arrows (<===(n)===) are added. (Hard to read, because the C# compiler uses identifiers like "<Foo>" or "<>__foo", when it generates code for Iterators.)
- Code: Select all
public class Extend_IEnumerable__T__ExtendIEnumerable {
// ...
[NotNull]
public static IEnumerable<KeyValuePair<int, T>>
Numbered<T>([NotNull] IEnumerable<T> _lh_this) {
<Numbered>d__12<T> d__ = new <Numbered>d__12<T>(-2); // <===(1)===
d__.<>3___lh_this = _lh_this;
return d__;
}
// ===(1)===>
public <Numbered>d__12(int <>1__state) {
this.<>1__state = <>1__state;
this.<>l__initialThreadId = Environment.CurrentManagedThreadId; // <===(2)===
}
// ...
}
Disassembling the "Snapshot\cobra.exe" of svn3079 shows that it does not contain a call to this property:
- Code: Select all
public class Extend_IEnumerable__T__ExtendIEnumerable {
//...
[DebuggerHidden, NotNull]
public static IEnumerable<KeyValuePair<int, T>>
Numbered<T>([NotNull] IEnumerable<T> _lh_this) {
<Numbered>c__Iterator5<T> iterator = new <Numbered>c__Iterator5<T>(); //<===(1)===
iterator._lh_this = _lh_this;
iterator.$PC = -2;
return iterator;
//...
//===(1)===>
public <Numbered>c__Iterator5() {
// <===(2)===
}
//...
}