锘??xml version="1.0" encoding="utf-8" standalone="yes"?>
鎭版伆鐩稿弽錛屾湁浜涘弽灝勭殑鐗規ф槸緇忓父浼氳浣跨敤鍒扮殑銆?/p>
鍙嶅皠鎬諱綋涓婂垎鎴愪袱澶х壒鎬э紝涓鏄嚜鐪侊紝浜屾槸鍙戝皠錛?/p>
鑷渷鐨勮兘鍔涙瀬涓洪噸瑕侊紝鑰屼笖鍑犱箮浼氬ぉ澶╃敤鍒幫紝寰堝皯瑙佸埌榪囧摢涓?net搴旂敤涓笉浣跨敤attribute鐨勶紝鑰宎ttribute鐗規у氨鏄痬etadata閫氳繃鍦ㄨ嚜鐪佽兘鍔涙敮鎾戜笅瀹炵幇鐨勶紱褰撶劧鑷渷涓嶅崟鍗曟槸attribute鐗規х殑榪愮敤錛屽彧瑕佹槸鍦ㄨ繍琛屾椂鍔ㄦ佹瑙嗙▼搴忚嚜韜殑鐗規ч兘瑕佺敱鍙嶅皠鐨勮嚜鐪佽兘鍔涙潵鏀寔錛屾瘮濡俈isual Studio鐨処DE錛堣繖涓泦鎴愬紑鍙戠幆澧冩湰韜氨鏄?net搴旂敤鐨勫ソ妗堜緥錛夊浜?net緇勪歡鐨勮嚜鍔ㄦ帰嫻嬪姛鑳斤紱鍚屾椂錛岃嚜鐪佺殑鑳藉姏涔熸槸鍩轟簬铏氭嫙鏈哄鉤鍙扮殑璇█錛屾瘮濡俢#鍜宩ava錛屽尯鍒簬浼犵粺璇█姣斿c鍜宑++鐨勯噸瑕佺壒鎬т箣涓錛岃繖鎻愪緵浜嗙▼搴忚璁″紑鍙戞洿涓轟究鍒╁拰瀹夊叏鐨勮繍琛屾椂鐜錛涚浉瀵硅岃█錛屽湪c++錛堝綋鐒舵槸native鑰屼笉鏄痬anaged錛夌殑鐜涓嬶紝闄や簡RTTI鏋佷負鍗曡杽鐨勮繍琛屾椂鑷渷錛屼篃灝辨槸QT榪欎釜搴撻氳繃meta-object system閮ㄥ垎妯℃嫙浜嗚嚜鐪佺殑鐗規э紱
鍙嶅皠鐨勫彟澶栦竴涓噸瑕佺壒鎬у氨鏄彂灝勶紝瀹冭“紼嬪簭鍙互鍐欑▼搴?#8221;浜嗭紝綆瑕佺殑璇村氨鏄湪榪愯鏃跺姩鎬佺敓鎴怣SIL騫跺姞杞借繍琛屼互鍙婃寔涔呭寲鍔ㄦ佺敓鎴愮殑MSIL鐨勮兘鍔涳紱鐢辮繖涓壒鎬х殑鏀寔錛岃鍘熷厛涓浜涚▼搴忚璁″拰寮鍙戦鍩熺浉瀵瑰洶闅懼拰綣佺悙鐨勫伐浣滐紝姣斿鍏冪紪紼媘eta programming錛屾瘮濡傚姩鎬佷唬鐞哾ynamic proxy錛屾瘮濡侫OP涓殑鍩虹璁炬柦weaver鐨勫疄鐜幫紝鍙樺緱鍙兘鎴栫浉瀵規槗浜庡疄鐜幫紱鍙嶅皠鐨勭壒鎬э紝涔熸槸鍩轟簬铏氭嫙鏈哄鉤鍙癈LR鐨勬敮鎸侊紝浠etadata涓哄熀紜鏉ュ疄鐜扮殑錛屾墍浠ヨ繖涔熸槸铏氭嫙鏈哄鉤鍙拌璦鐨勭壒鏈変紭鍔匡紝鑰屽湪浼犵粺璇█騫沖彴涓婏紝榪欐槸闅句互瀹炵幇鐨勶紱姣斿鍏充簬meta programming錛宑++灝辨槸閫氳繃妯℃澘鐗規у疄鐜扮殑緙栬瘧鏈焟eta programming錛岃繖涓庤櫄鎷熸満騫沖彴涓婂疄鐜扮殑榪愯鏃秏eta programming榪樻槸鏈夋瘮杈冨ぇ鐨勫樊璺濓紙姣斿鍓嶈呭浣曚繚璇佺敓鎴愮殑浠g爜鐨則ype-safe錛夛紱
浠ヤ笂榪欎袱涓壒鎬э紝鑷渷鍜屽彂灝勶紝閮芥湁涓叡鍚岀偣錛屼粬浠兘鏄洿緇曠潃metadata鏈哄埗錛屽茍鍦ㄨ櫄鎷熸満騫沖彴榪愯鏃剁幆澧僀LR鏀寔涓嬪疄鐜扮殑錛屽墠鑰呮槸榪愯鏃舵瑙嗙浉鍏崇殑metadata錛屽悗鑰呮槸榪愯鏃跺姩鎬佺敓鎴愮浉鍏崇殑metadata鍜孧SIL錛涗粠榪欑偣涔熷氨鍙互鐪嬪嚭錛岃鎯蟲繁鍏ョ悊瑙h繖浜涚壒鎬э紝灝遍渶瑕佺爺絀秏etadata鍜孧SIL鐨勫疄鐜幫紝浠ュ強铏氭嫙鏈鴻繍琛屾椂鐜鐨勫疄鐜幫紙鍦╦ava騫沖彴涓婏紝灝辨槸bytecode鍜孞VM錛夛紱
鎵浠ワ紝鍙嶅皠錛屽彲鑳芥槸铏氭嫙鏈哄鉤鍙版墍鎻愪緵鐨勭浉瀵規渶涓哄己鍔詫紝鏈涓哄鏉傦紝鍜屽鉤鍙拌繍琛屾椂鏈韓鍏崇郴鏈瀵嗗垏錛屼篃鏄尯鍒簬浼犵粺璇█鍜岃繍琛屾椂鏈椴滄槑鐨勭壒鎬с?/p>
In the fusion, or any other components or modules, how to retrieve the execution engine instance and how to generate such engine?
UtilExecutionEngine, implemented as COM object, support Queryinterface/AddRef/Release, and exposed via interface IExecutionEngine.
With SELF_NO_HOST defined,
BYTE g_ExecutionEngineInstance[sizeof(UtilExecutionEngine)];
g_ExecutionEngineInstance would be the singleton instance of current execution engine,
otherwise, without SELF_NO_HOST, the 'sscoree' dll would be loaded and try to get the exported function, which is named 'IEE' from such dll. Here, it is the well-known shim, in .net CLR, such module is named 'mscoree'. Further, if 'IEE' could not be found in such dll, system would try to locate another exported function, named 'LoadLibraryShim', and use such function to load the 'mscorwks' module, and try to locate the 'IEE' exportd functionin it.
It's very obvious that Rotor has implemented its own execution engine, but it also gives or make space for implementation of execution engine from 3rd party. Here, .net CLR is a good candidate definitely, Rotor might load the mscorwks.dll module for its usage.
PAL, PALAPI, for example, HeapAlloc, one famous WIN32 API, has been implemented as one PALAPI (defined in Heap.c), to make it possible that the CLI/Rotor be ported smoothly to other OS, such freebsd/mac os.
CRT routines are also reimplemented, such as memcpy, it has been implemented as GCSafeMemCpy
There're many macros in fuctions, such as SCAN_IGNORE_FAULT/STATIC_CONTRACT_NOTHROW/STATIC_CONTRACT_NOTRIGGER, they are for static analysis tool to scan, analyse and figour out the potential issues in code.
From view point of the execution model by CLI, the act of compiling (including JIT) high-level type descriptions would be separated from the act of turning these type descriptions into processor-specific code and memory structures.
And such executino model, in other word, the well-known 'managed execution', would defer the loading, verification and compilation of components until runtime really needs; At the same time, the type-loading is the key trigger that causes CLI's tool chain to be engaged at runtime. Deferred compilation(lead to JIT)/linking/loading would get better portability to different target platform and be ready for version change; The whole deferred process would driven by well-defined metadata and policy, and it would be very robust for building a virtual execution environment;
At the top of such CLI tool chain, fusion is reponsible for not only finding and binding related assemblies, which are via assembly reference defined in assembly, fusion also takes another important role, loader, and its part of functionality is implemented in PEAssembly, ClassLoader classes. For example, ClassLoader::LoadTypeHandleForTypeKey.
For types in virtual execution environment of CLI, rotor defines four kinds of elements for internal conducting,
ELEMENT_TYPE_CLASS for ordinary classes and generic instantiations(including value types);
ELEMENT_TYPE_ARRAY AND ELEMENT_TYPE_SZARRAY for array types
ELEMENT_TYPE_PRT and ELEMENT_TYPE_BYREF for pointer types
ELEMENT_TYPE_FNPTR for function pointer types
every type would be assigned unique ulong-typed token, and such token would be used to look up in m_TypeDefToMethodTableMap (Linear mapping from TypeDef token to MethodTable *)which is maintained by current module; If there it is, the pointer to method table of such type would be retrieved, or it would look up in the loader module, where the method table should exist in while it's JIT loaded, not launched from NGEN image;
And all the unresolved typed would be maintained in a hash table, PendingTypeLoadTable; Types and only those types that are needed, such as dependencies, including parent types, are loaded in runtime, such type is fully loaded and ready for further execution, and other unresolved types would be kept in the previous hash table.