`
RednaxelaFX
  • 浏览: 3052825 次
  • 性别: Icon_minigender_1
  • 来自: 海外
社区版块
存档分类
最新评论

目前DLR执行一棵DLR tree的过程(针对10月3日的ChangeSet 41087)

    博客分类:
  • DLR
阅读更多
先在Microsoft.Scripting.Actions.CallSite<T>的构造器设断点,然后开始调试。

在IronPythonConsole里,输入1+2回车,然后观察调用栈。可以看到在很多层调用之前是一个对Microsoft.Scripting.Generation.GlobalRewriter.RewriteLambda(lambda)的调用(注意到GlobalRewriter近期将会被refactor而去除掉,CodeContext也会消失掉)。在rewrite前,lambda(也就是console所执行的main,委托类型为DlrMainCallTarget)是:
//
// AST: Expression`1
//

.lambda (<module> Microsoft.Func`1[System.Object] #1)

//
// LAMBDA: <module>(1)
//
.lambda System.Object <module> ()(
) {
    .scope <module> (
        System.Int32 $lineNo
        System.Boolean $lineUpdated
    ) {
        {
            (PythonOps.ModuleStarted)(
                .extension (CodeContext) ;
                ,
                (BinderState)IronPython.Runtime.Binding.BinderState,
                (PythonLanguageFeatures)Default,
            )
            (.var $lineNo) = 0
            (.var $lineUpdated) = (Boolean)False
            .try {
                {
                    {
                    }
                    /*empty*/;
                    {
                        (.var $lineNo) = 1
                        {
                            (PythonOps.PrintExpressionValue)(
                                .extension (CodeContext) ;
                                ,
                                .site (Object) Operation Add( // Python Add
                                    1
                                    2
                                ),
                            )
                        }
                    }
                }
            } .fault {
                {
                    .if (!(.var $lineUpdated) ) {(ExceptionHelpers.UpdateStackTrace)(
                        .extension (CodeContext) ;
                        ,
                        (MethodBase.GetCurrentMethod)(),
                        "<module>",
                        "<stdin>",
                        (.var $lineNo),
                    )} .else {/*empty*/;
                    }
                    (.var $lineUpdated) = (Boolean)True
                }
            }
        }
    }
}

rewrite后则是:
//
// AST: Expression`1
//

.lambda (<module> Microsoft.Func`1[System.Object] #1)

//
// LAMBDA: <module>(1)
//
.lambda System.Object <module> ()(
) {
    .scope <module> (
        System.Int32 $lineNo
        System.Boolean $lineUpdated
    ) {
        {
            (PythonOps.ModuleStarted)(
                (.var $globalContext),
                (BinderState)IronPython.Runtime.Binding.BinderState,
                (PythonLanguageFeatures)Default,
            )
            (.var $lineNo) = 0
            (.var $lineUpdated) = (Boolean)False
            .try {
                {
                    {
                    }
                    /*empty*/;
                    {
                        (.var $lineNo) = 1
                        {
                            (PythonOps.PrintExpressionValue)(
                                (.var $globalContext),
                                .scope (
                                    Microsoft.Scripting.Actions.CallSite`1[Microsoft.Func`4[Microsoft.Scripting.Actions.CallSite,System.Int32,System.Int32,System.Object]] $site
                                ) {
                                    ((.var $site) = (CallSite`1)Microsoft.Scripting.Actions.CallSite`1[Microsoft.Func`4[Microsoft.Scripting.Actions.CallSite,System.Int32,System.Int32,System.Object]].Target).(Func`4.Invoke)(
                                        (.var $site),
                                        1,
                                        2,
                                    )}
                                ,
                            )
                        }
                    }
                }
            } .fault {
                {
                    .if (!(.var $lineUpdated) ) {(ExceptionHelpers.UpdateStackTrace)(
                        (.var $globalContext),
                        (MethodBase.GetCurrentMethod)(),
                        "<module>",
                        "<stdin>",
                        (.var $lineNo),
                    )} .else {/*empty*/;
                    }
                    (.var $lineUpdated) = (Boolean)True
                }
            }
        }
    }
}

Rewrite的意义在于把所有DynamicExpression重写为静态类型的节点,其中的动态行为则编译为CallSite的初始化(Expression.Constant())与调用(Expression.Call())。

编译出来的委托的类型为Func<Microsoft.Runtime.CompilerServices.Closure, Microsoft.Scripting.Runtime.Scope, Microsoft.Scripting.Runtime.LanguageContext, object>,内容是:
IL_0000:  ldarg.1
IL_0001:  ldarg.2
IL_0002:  call       Microsoft.Scripting.Runtime.CodeContext CreateTopLevelCodeContext(Microsoft.Scripting.Runtime.Scope, Microsoft.Scripting.Runtime.LanguageContext)/Microsoft.Scripting.Runtime.RuntimeHelpers
IL_0007:  stloc.2
IL_0008:  ldloc.2
IL_0009:  ldarg.0
IL_000a:  ldfld      !"指定的转换无效。"!
IL_000f:  ldc.i4.0
IL_0010:  ldelem.ref
IL_0011:  ldc.i4.0
IL_0012:  call       Void ModuleStarted(Microsoft.Scripting.Runtime.CodeContext, System.Object, IronPython.Compiler.PythonLanguageFeatures)/IronPython.Runtime.Operations.PythonOps
IL_0017:  ldc.i4.0
IL_0018:  stloc.0
IL_0019:  ldc.i4.0
IL_001a:  stloc.1
IL_001b:  ldc.i4.1
IL_001c:  stloc.0
IL_001d:  ldloc.2
IL_001e:  ldarg.0
IL_001f:  ldfld      !"指定的转换无效。"!
IL_0024:  ldc.i4.1
IL_0025:  ldelem.ref
IL_0026:  castclass  Microsoft.Scripting.Actions.CallSite`1[Microsoft.Func`4[Microsoft.Scripting.Actions.CallSite,System.Int32,System.Int32,System.Object]]
IL_002b:  dup
IL_002c:  stloc.3
IL_002d:  ldfld      !"指定的转换无效。"!
IL_0032:  ldloc.3
IL_0033:  ldc.i4.1
IL_0034:  ldc.i4.2
IL_0035:  callvirt   System.Object Invoke(Microsoft.Scripting.Actions.CallSite, Int32, Int32)/Microsoft.Func`4[Microsoft.Scripting.Actions.CallSite,System.Int32,System.Int32,System.Object]
IL_003a:  call       Void PrintExpressionValue(Microsoft.Scripting.Runtime.CodeContext, System.Object)/IronPython.Runtime.Operations.PythonOps
IL_003f:  leave      IL_006c
IL_0044:  ldloc.1
IL_0045:  ldc.i4.0
IL_0046:  ceq
IL_0048:  brfalse    IL_0063
IL_004d:  ldloc.2
IL_004e:  call       System.Reflection.MethodBase GetCurrentMethod()/System.Reflection.MethodBase
IL_0053:  ldstr      "<module>"
IL_0058:  ldstr      "<stdin>"
IL_005d:  ldloc.0
IL_005e:  call       Void UpdateStackTrace(Microsoft.Scripting.Runtime.CodeContext, System.Reflection.MethodBase, System.String, System.String, Int32)/Microsoft.Scripting.Runtime.ExceptionHelpers
IL_0063:  ldc.i4.1
IL_0064:  stloc.1
IL_0065:  rethrow
IL_0067:  leave      IL_006c
IL_006c:  ldnull
IL_006d:  ret

执行这个委托,在原本的加法调用点会进入到先前生成的UpdateDelegates.Update2<Func<CalSite,int,int,object>,int,int,object>中,进而调用CallSite<T>.UpdateAndExecute()。

此时,该调用点尚未有任何调用记录,所以会生成一个新的monomorphic rule(CallSite<T>.CreateNewRule())。在这里,通过CallSiteBinder<T>.Bind()(具体来说是IronPython.Runtime.Binding.OperationBinder,{Python Add};Bind()方法来自MetaAction类)得到一个Rule<Func<CalSite,int,int,object>>:
//
// AST: Rule
//

.scope <rule> (
) {
    .scope (
    ) {
        .return (Int32Ops.Add)(
            (.arg $arg0),
            (.arg $arg1),
        );
    }
}

接下来,这个Rule<T>会被加入Level 2 Cache,然后赋值给Level 0 Cache并执行,如果成功则加入Level 1 Cache并将执行结果返回;失败的话则会尝试再次创建Rule<T>,重复上述创建过程。

这样就完成了一次1+2的执行。上面省略了一些Python特定的步骤(如PythonBinder、PythonOps里许多初始化),专注于DLR一侧的运行步骤。
分享到:
评论
1 楼 cajon 2008-10-07  
难得有篇短一点的。收藏先,回头有机会看看这里的实现。

相关推荐

    .net4的DLR高级编程 Apress.Pro.DLR.in.NET.4.Nov.2010

    《.NET 4 的 DLR 高级编程》是一本深度探索 .NET 动态语言运行时(Dynamic Language Runtime,简称 DLR)的专著,由 Chaur Wu 撰写,出版于 2010 年 11 月。这本书针对 .NET 4 开发者,特别是那些对在 .NET 平台上...

    LINQ与DLR的Expression tree(4):创建静态类型的LINQ表达式树节点

    LINQ的核心之一是Expression Tree(表达式树),它将代码表达式转化为可遍历的数据结构。这篇博客文章“LINQ与DLR的Expression tree(4):创建静态类型的LINQ表达式树节点”深入探讨了如何构建这种数据结构,特别是...

    Pro DLR in .NET 4

    Dynamic Language Runtime (DLR) in .NET is a framework for designing and interacting with dynamic languages such as Python and Ruby. For the first time, the DLR places such languages on an equal ...

    dlr-618最新升级固件

    dlr-618最新升级固件

    针对Change Set 32648而更新的荒井省三的简单DLR语言例子

    3. 调用站点缓存:通过调用站点缓存,DLR能够记录先前的绑定信息,提高后续相同操作的执行速度。 4. 表达式树:DLR使用表达式树来表示动态操作,这有助于编译器理解和优化动态代码。 在MyCalc这个示例中,我们可以...

    AB设备级环网DLR应用

    AB PLC设备级环网交换机应用案例http://u.download.csdn.net/images/btn_submit.png

    3DsMax2009导出到Quest3d的.X文件插件_vrender2009.dlr

    3DsMax2009导出到Quest3d的.X文件插件_vrender2009.dlr

    Neo- AI -DLR 是 AWS SageMaker Neo、TVM 或 TreeLite 编译的机器学习模型的通用运行时

    C++__代码_下载 DLR 是由AWS SageMaker Neo、TVM或Treelite编译的深度...DLR 目前支持来自 Intel、NVIDIA 和 ARM 的平台,即将支持 Xilinx、Cadence 和 Qualcomm。 更多详情、使用方法,请下载后阅读README.md文件

    DLR DEM数据中国范围

    dlr dem是德国的免费dem数据,不是全覆盖的,但精度比一般的公开的30米dem要高;地图、遥感、Gis等相关行业使用,网盘链接

    Pro DLR in .NET 4 无水印pdf

    Pro DLR in .NET 4 英文无水印pdf pdf所有页面使用FoxitReader和PDF-XChangeViewer测试都可以打开 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载自网络,如有侵权,请联系上传者或csdn删除

    可莱特S125DLR 声光组合LED反射镜旋转警示灯产品目录.pdf

    可莱特S125DLR 声光组合LED反射镜旋转警示灯产品目录pdf,特点:LED反射镜旋转警示灯和信号扬声器为一体的声光组合产品;采用本司独特的信号扬声器的内装构造;以小的外形能发出最大105dB/m的高音量;采用大功率发光...

    Python库 | downward_dlr-19.6.0.tar.gz

    对于"downward_dlr-19.6.0",我们可以假设它可能提供了针对动态语言的一些优化策略,比如内存管理、垃圾回收或者执行效率的提升。此外,它可能还包含了对Python解释器的扩展,允许开发者更高效地编写和运行Python...

    一文带你了解 C# DLR 的世界(DLR 探秘)

    C# DLR(Dynamic Language Runtime)是.NET框架中一个重要的组成部分,主要负责处理动态类型和动态操作。DLR是在C# 4.0版本引入的,它的出现是为了增强C#对动态编程的支持,使得C#可以更好地与动态语言如Python和...

    DLR/HIT仿人机器人灵巧手的设计.doc

    DLR/HIT仿人机器人灵巧手的设计是一项前沿技术的结晶,它不仅仅是一次机械工程上的创新,更是机器人学与人类生理学相结合的典范。这一设计通过对人类手部的深入研究,结合抓握理论的最新成果,试图创造出一个能够...

    DLR 2015 Part3_SAR Image Formation and Image Properties.pdf

    3. SAR数据流: SAR系统工作时,包括发射机、接收天线、数据记录器等组成部分。SAR信号的采集过程涉及脉冲发射、接收回波信号、I/Q解调、基带信号处理以及最终的SAR图像数据生成。信号生成器、混频器、功率放大器、...

Global site tag (gtag.js) - Google Analytics