标签: intermediate-language

了解STG

GHC的设计基于一种名为STG的东西,它代表"无骨架,无标签G机".

现在G-machine显然是"图形缩减机"的缩写,它定义了如何实现懒惰.未评估的thunk被存储为表达式树,并且执行该程序涉及这些减少到正常形式.(是非循环图,但Haskell的普遍递归意味着Haskell表达式形成一般,因此图减少而不是树减少.)

不太清楚的是术语"无骨"和"无标记".

  1. 认为 "无脊椎"指的是功能应用程序没有功能应用程序节点的"脊椎"这一事实.相反,您有一个对象,该对象命名所调用的函数并指向其所有参数.那是对的吗?

  2. 我认为"无标签"指的是构造函数节点没有用构造函数ID"标记",而是使用跳转指令解析case-expression.但现在我不确定这是否正确.相反,它似乎指的是节点没有用其评估状态标记的事实.谁能澄清这些解释中哪些(如果有的话)是正确的?

haskell bytecode compilation ghc intermediate-language

41
推荐指数
2
解决办法
7901
查看次数

.NET IL .maxstack指令如何工作?

我想知道.maxstack是如何工作的.我知道它与您声明的类型的实际大小无关,而与它们的数量有关.我的问题是:

  1. 这仅适用于函数,还适用于我们要求的所有函数?
  2. 即使只是为了函数而声明了.maxstack,如果你有分支,你怎么知道maxstack是什么?你去看看所有的"路径"并尽可能返回最大值?
  3. 如果我将它设置为16并且实际上有17个变量会发生什么?
  4. 如果我把它设置为256,会有太大的惩罚吗?

.net c# vb.net reflection intermediate-language

24
推荐指数
2
解决办法
5671
查看次数

类型化中间语言的语用学

编译的一个趋势是使用类型化的中间语言.Haskell的ghc与它的core中间语言,系统F-ω变体,是本体系结构[1]的一个例子.另一个是LLVM,它的核心是一种类型化的中间语言[2].这种方法的好处是可以及早检测构成代码生成器部分的转换中的错误.此外,可以在优化和代码生成期间使用类型信息.

为了提高效率,对类型化的IR进行类型检查,而不是推断它们的类型.为了快速进行类型检查,每个变量和每个活页夹都带有类型以便于类型检查.

但是,编译器管道中的许多转换可能会引入新变量.例如,规范化转换K(.)可能会转换应用程序

M(N)
Run Code Online (Sandbox Code Playgroud)

变成一个表达式

let x = K(M) in
let y = K(N) in x(y)
Run Code Online (Sandbox Code Playgroud)

题.我想知道编译器如何处理给新引入的变量赋予类型的问题.难道他们重新类型检测,在上面的例子中K(M)K(N)?这不是很费时间吗?它需要通过环境吗?他们是否使用AST节点中的映射来键入信息以避免重新运行类型检查?


  1. S. Marlow,S.Peyton Jones,格拉斯哥Haskell编译器.

  2. LLVM语言参考手册.

compiler-construction ghc intermediate-language compiler-optimization llvm-ir

24
推荐指数
1
解决办法
385
查看次数

21
推荐指数
3
解决办法
4万
查看次数

为什么反编译.NET IL代码这么容易?

与反编译本机x86二进制文件相比,为什么将.NET IL-code反编译为源代码如此容易?(Reflector在大多数情况下都会生成相当好的源代码,而反编译C++编译器的输出几乎是不可能的.)

是因为IL包含大量元数据吗?或者是因为IL是比x86指令更高的抽象?我做了一些研究,发现了以下两篇有用的文章,但它们都没有回答我的问题.

.net cil decompiling bytecode intermediate-language

16
推荐指数
2
解决办法
4396
查看次数

接口作为类型约束和接口作为参数之间的区别?

如果我想创建一个以实例IList作为参数(或任何其他接口,但让我们IList用作示例)的方法,我可以创建一个带有类型约束的泛型方法,例如:

public static void Foo1<T>(T list) where T : IList
{

}
Run Code Online (Sandbox Code Playgroud)

或者,我可以创建一个IList直接获取参数的方法:

public static void Foo2(IList list)
{

}
Run Code Online (Sandbox Code Playgroud)

对于所有意图和目的,似乎这些方法的行为完全相同:

List<string> myList = new List<string>();
Foo1(myList);
Foo2(myList);
Run Code Online (Sandbox Code Playgroud)

所以这是我的问题 - 这两种方法之间的区别是什么?似乎第二种方法更具可读性; 我应该注意哪些其他差异(生成不同的IL等)?提前致谢.

c# generics intermediate-language type-constraints type-parameter

13
推荐指数
1
解决办法
654
查看次数

c#编译器比VB.NET编译器更智能吗?

如果我查看Linqpad中为以下两个代码片段创建的IL,我想知道这里发生了什么.

在c#中

int i = 42;
Run Code Online (Sandbox Code Playgroud)

得到以下IL代码

IL_0000:  ret
Run Code Online (Sandbox Code Playgroud)

而在VB中

Dim i As Integer = 42
Run Code Online (Sandbox Code Playgroud)

它是

IL_0000:  ldc.i4.s    2A 
IL_0002:  stloc.0  
Run Code Online (Sandbox Code Playgroud)

显然,c#编译器理解该值从未使用过,因此根本不返回任何内容.在VB.NET中,实际代码被翻译.

这是由于编译器优化的差异还是还有其他工作原因?

更新:只是为了澄清这一点 - 我只是将这一行输入LinqPad并查看它创建的IL(最明确的是运行相应的编译器).有没有计划.

c# vb.net compiler-construction intermediate-language linqpad

11
推荐指数
1
解决办法
507
查看次数

对于实现功能语言的虚拟机,有哪些明显的优化?

我正在研究一种中间语言和一个虚拟机来运行具有一些"有问题"属性的函数式语言:

  • 词法命名空间(闭包)
  • 动态增长的调用堆栈
  • 慢整数类型(bignums)

中间语言是基于堆栈的,具有当前命名空间的简单哈希表.只是让你了解它的外观,这是McCarthy91的功能:

# McCarthy 91: M(n) = n - 10 if n > 100 else M(M(n + 11))
.sub M
    args
    sto n

    rcl n
    float 100
    gt
    .if
        .sub
            rcl n
            float 10
            sub
        .end
        .sub
            rcl n
            float 11
            add
            list 1
            rcl M
            call-fast
            list 1
            rcl M
            tail
        .end
    call-fast
.end
Run Code Online (Sandbox Code Playgroud)

"大循环"很简单:

  • 获取指令
  • 递增指令指针(或程序计数器)
  • 评估指令

随着sto,rcl和一大堆更多,有三种指令函数调用:

  • call 复制命名空间(深层复制)并将指令指针推送到调用堆栈
  • call-fast 是相同的,但只创建一个浅的副本
  • tail 基本上是'转到''

实施非常简单.为了给你一个更好的主意,这里只是一个来自"大循环"中间的随机片段(更新,见下文)

    } else …
Run Code Online (Sandbox Code Playgroud)

interpreter functional-programming go intermediate-language vm-implementation

11
推荐指数
2
解决办法
721
查看次数

如何在方案中将字符串列表转换为一个字符串?

比如我有(list "a" "1" "b" "2" "c" "3").

现在我想把这个列表变成一个"a1b2c3".

我怎么做?

谢谢.

string scheme list intermediate-language racket

11
推荐指数
3
解决办法
8464
查看次数

不运行.NET接口上的静态构造函数

您可以在IL中的.NET中的接口上定义静态构造函数.但是,如果这样做,则在接口上运行方法时不会运行静态构造函数:

.method public static void Main() {
    .entrypoint    
    .locals init ( class IInterface cls1 )

    // InterfaceClass static constructor is run
    newobj instance void InterfaceClass::.ctor()
    stloc.0
    ldloc.0
    // IInterface static constructor is not run!!!!!
    callvirt instance int32 IInterface::Method()
    call void [mscorlib]System.Console::WriteLine(int32)
    ret
}

.class public interface IInterface {
    .method private static specialname rtspecialname void .cctor() {
        ldstr "Interface static cctor"
        call void [mscorlib]System.Console::WriteLine(string)
        ret
    }

    .method public abstract virtual instance int32 Method() {}
}

.class public InterfaceClass implements IInterface { …
Run Code Online (Sandbox Code Playgroud)

.net interface static-constructor intermediate-language

10
推荐指数
1
解决办法
752
查看次数