当前位置: 首页 > news >正文

百家号淄博圻谷网站建设网站首页标题设置

百家号淄博圻谷网站建设,网站首页标题设置,网络推广赚钱项目,培训机构哪家好Go语言是一门需要编译才能运行的编程语言#xff0c;也就说代码在运行之前需要通过编译器生成二进制机器码#xff0c;随后二进制文件才能在目标机器上运行#xff0c;如果我们想要了解Go语言的实现原理#xff0c;理解它的编译过程就是一个没有办法绕过的事情。预备知识想…Go语言是一门需要编译才能运行的编程语言也就说代码在运行之前需要通过编译器生成二进制机器码随后二进制文件才能在目标机器上运行如果我们想要了解Go语言的实现原理理解它的编译过程就是一个没有办法绕过的事情。预备知识想要深入了解Go语言的编译过程需要提前了解一下编译过程中涉及的一些术语和专业知识。这些知识其实在我们的日常工作和学习中比较难用到但是对于理解编译的过程和原理还是非常重要的。1) 抽象语法树抽象语法树(AST)是源代码语法的结构的一种抽象表示它用树状的方式表示编程语言的语法结构。抽象语法树中的每一个节点都表示源代码中的一个元素每一颗子树都表示一个语法元素例如一个 if else 语句我们可以从 2 * 3 7 这一表达式中解析出下图所示的抽象语法树。抽象语法树作为编译器常用的数据结构抽象语法树抹去了源代码中不重要的一些字符比如空格、分号或者括号等等。编译器在执行完语法分析之后会输出一个抽象语法树这棵树会辅助编译器进行语义分析我们可以用它来确定结构正确的程序是否存在一些类型不匹配或不一致的问题。2) 静态单赋值静态单赋值(SSA)是中间代码的一个特性如果一个中间代码具有静态单赋值的特性那么每个变量就只会被赋值一次在实践中我们通常会用添加下标的方式实现每个变量只能被赋值一次的特性这里以下面的代码举一个简单的例子x : 1x : 2y : x根据分析我们其实能够发现上述的代码其实并不需要第一个将 1 赋值给 x 的表达式也就是这一表达式在整个代码片段中是没有作用的x1 : 1x2 : 2y1 : x2从使用 SSA 的中间代码我们就可以非常清晰地看出变量 y1 的值和 x1 是完全没有任何关系的所以在机器码生成时其实就可以省略第一步这样就能减少需要执行的指令来优化这一段代码。根据 Wikipedia(维基百科)对 SSA 的介绍来看在中间代码中使用 SSA 的特性能够为整个程序实现以下的优化常数传播(constant propagation)值域传播(value range propagation)稀疏有条件的常数传播(sparse conditional constant propagation)消除无用的程式码(dead code elimination)全域数值编号(global value numbering)消除部分的冗余(partial redundancy elimination)强度折减(strength reduction)寄存器分配(register allocation)从 SSA 的作用我们就能看出因为它的主要作用就是代码的优化所以是编译器后端(主要负责目标代码的优化和生成)的一部分当然除了 SSA 之外代码编译领域还有非常多的中间代码优化方法优化编译器生成的代码是一个非常古老并且复杂的领域这里就不展开介绍了。3) 指令集架构最后要介绍的一个预备知识就是指令集的架构了很多开发者都会遇到在生产环境运行的结果和本地不同的问题导致这种情况的原因其实非常复杂不同机器使用不同的指令就是可能的原因之一。我们大多数开发者都会使用 x86_64 的 Macbook 作为工作上主要使用的硬件在命令行中输入 uname -m 就能够获得当前机器上硬件的信息$ uname -mx86_64x86_64 是目前比较常见的指令集架构之一除了 x86_64 之外还有其他类型的指令集架构例如 amd64、arm64 以及 mips 等等不同的处理器使用了大不相同的机器语言所以很多编程语言为了在不同的机器上运行需要将源代码根据架构翻译成不同的机器代码。复杂指令集计算机(CISC)和精简指令集计算机(RISC)是目前的两种 CPU 区别它们的在设计理念上会有一些不同从名字我们就能看出来这两种不同的设计有什么区别复杂指令集通过增加指令的数量减少需要执行的质量数而精简指令集能使用更少的指令完成目标的计算任务。早期的 CPU 为了减少机器语言指令的数量使用复杂指令集完成计算任务这两者之前的区别其实就是设计上的权衡。编译原理Go语言编译器的源代码在 cmd/compile 目录中目录下的文件共同构成了Go语言的编译器学过编译原理的人可能听说过编译器的前端和后端编译器的前端一般承担着词法分析、语法分析、类型检查和中间代码生成几部分工作而编译器后端主要负责目标代码的生成和优化也就是将中间代码翻译成目标机器能够运行的机器码。Go的编译器在逻辑上可以被分成四个阶段词法与语法分析、类型检查和 AST 转换、通用 SSA 生成和最后的机器代码生成下面我们来分别介绍一下这四个阶段做的工作。1) 词法与语法分析所有的编译过程其实都是从解析代码的源文件开始的词法分析的作用就是解析源代码文件它将文件中的字符串序列转换成 Token 序列方便后面的处理和解析我们一般会把执行词法分析的程序称为词法解析器(lexer)。而语法分析的输入就是词法分析器输出的 Token 序列这些序列会按照顺序被语法分析器进行解析语法的解析过程就是将词法分析生成的 Token 按照语言定义好的文法(Grammar)自下而上或者自上而下的进行规约每一个 Go 的源代码文件最终会被归纳成一个 SourceFile 结构SourceFile PackageClause ; { ImportDecl ; } { TopLevelDecl ; }标准的Go 语法解析器使用的就是 LALR(1) 的文法语法解析的结果其实就是上面介绍过的抽象语法树(AST)每一个 AST 都对应着一个单独的Go语言文件这个抽象语法树中包括当前文件属于的包名、定义的常量、结构体和函数等。如果在语法解析的过程中发生了任何语法错误都会被语法解析器发现并将消息打印到标准输出上整个编译过程也会随着错误的出现而被中止。2) 类型检查当拿到一组文件的抽象语法树 AST 之后Go语言的编译器会对语法树中定义和使用的类型进行检查类型检查分别会按照顺序对不同类型的节点进行验证按照以下的顺序进行处理常量、类型和函数名及类型变量的赋值和初始化函数和闭包的主体哈希键值对的类型导入函数体外部的声明通过对每一棵抽象节点树的遍历我们在每一个节点上都会对当前子树的类型进行验证保证当前节点上不会出现类型错误的问题所有的类型错误和不匹配都会在这一个阶段被发现和暴露出来。类型检查的阶段不止会对树状结构的节点进行验证同时也会对一些内建的函数进行展开和改写例如 make 关键字在这个阶段会根据子树的结构被替换成 makeslice 或者 makechan 等函数。我们其实能够看出类型检查不止做了验证类型的工作还对 AST 进行了改写和处理Go语言内置关键字的活所以这一过程在整个编译流程中还是非常重要的没有这个步骤很多关键字其实就没有办法工作。3) 中间代码生成当我们将源文件转换成了抽象语法树、对整棵树的语法进行解析并进行类型检查之后就可以认为当前文件中的代码基本上不存在无法编译或者语法错误的问题了Go语言的编译器就会将输入的 AST 转换成中间代码。Go语言编译器的中间代码使用了 SSA(Static Single Assignment Form) 的特性如果我们在中间代码生成的过程中使用这种特性就能够比较容易的分析出代码中的无用变量和片段并对代码进行优化。在类型检查之后就会通过一个名为 compileFunctions 的函数开始对整个Go语言项目中的全部函数进行编译这些函数会在一个编译队列中等待几个后端工作协程的消费这些 Goroutine 会将所有函数对应的 AST 转换成使用 SSA 特性的中间代码。4) 机器码生成Go语言源代码的 cmd/compile/internal 中包含了非常多机器码生成相关的包不同类型的 CPU 分别使用了不同的包进行生成 amd64、arm、arm64、mips、mips64、ppc64、s390x、x86 和 wasm也就是说Go语言能够在上述的 CPU 指令集类型上运行其中比较有趣的就是 WebAssembly 了。作为一种在栈虚拟机上使用的二进制指令格式它的设计的主要目标就是在 Web 浏览器上提供一种具有高可移植性的目标语言。Go语言的编译器既然能够生成 WASM 格式的指令那么就能够运行在常见的主流浏览器中。$ GOARCHwasm GOOSjs go build -o lib.wasm main.go我们可以使用上述的命令将 Go 的源代码编译成能够在浏览器上运行的汇编语言除了这种新兴的指令之外Go语言还支持了几乎全部常见的 CPU 指令集类型也就是说它编译出的机器码能够在使用上述指令集的机器上运行。编译器入口Go语言的编译器入口在 src/cmd/compile/internal/gc 包中的 main.go 文件这个 600 多行的 Main 函数就是Go语言编译器的主程序这个函数会先获取命令行传入的参数并更新编译的选项和配置随后就会开始运行 parseFiles 函数对输入的所有文件进行词法与语法分析得到文件对应的抽象语法树func Main(archInit func(*Arch)) { // ... lines : parseFiles(flag.Args())接下来就会分九个阶段对抽象语法树进行更新和编译就像我们在上面介绍的整个过程会经历类型检查、SSA 中间代码生成以及机器码生成三个部分检查常量、类型和函数的类型处理变量的赋值对函数的主体进行类型检查决定如何捕获变量检查内联函数的类型进行逃逸分析将闭包的主体转换成引用的捕获变量编译顶层函数检查外部依赖的声明了解了剩下的编译过程之后我们重新回到词法和语法分析后的具体流程在这里编译器会对生成语法树中的节点执行类型检查除了常量、类型和函数这些顶层声明之外它还会对变量的赋值语句、函数主体等结构进行检查for i : 0; i len(xtop); i { n : xtop[i] if op : n.Op; op ! ODCL op ! OAS op ! OAS2 (op ! ODCLTYPE || !n.Left.Name.Param.Alias) { xtop[i] typecheck(n, ctxStmt) }}for i : 0; i len(xtop); i { n : xtop[i] if op : n.Op; op ODCL || op OAS || op OAS2 || op ODCLTYPE n.Left.Name.Param.Alias { xtop[i] typecheck(n, ctxStmt) }}for i : 0; i len(xtop); i { n : xtop[i] if op : n.Op; op ODCLFUNC || op OCLOSURE { typecheckslice(Curfn.Nbody.Slice(), ctxStmt) }}checkMapKeys()for _, n : range xtop { if n.Op ODCLFUNC n.Func.Closure ! nil { capturevars(n) }}escapes(xtop)for _, n : range xtop { if n.Op ODCLFUNC n.Func.Closure ! nil { transformclosure(n) }}类型检查会对传入节点的子节点进行遍历这个过程会对 make 等关键字进行展开和重写类型检查结束之后并没有输出新的数据结构只是改变了语法树中的一些节点同时这个过程的结束也意味着源代码中已经不存在语法错误和类型错误中间代码和机器码也都可以正常的生成了。 initssaconfig() peekitabs() for i : 0; i len(xtop); i { n : xtop[i] if n.Op ODCLFUNC { funccompile(n) } } compileFunctions() for i, n : range externdcl { if n.Op ONAME { externdcl[i] typecheck(externdcl[i], ctxExpr) } } checkMapKeys()}在主程序运行的最后会将顶层的函数编译成中间代码并根据目标的 CPU 架构生成机器码不过这里其实也可能会再次对外部依赖进行类型检查以验证正确性。总结Go语言的编译过程其实是非常有趣并且值得学习的通过对Go语言四个编译阶段的分析和对编译器主函数的梳理我们能够对 Golang 的实现有一些基本的理解掌握编译的过程之后Go语言对于我们来讲也不再是一个黑盒所以学习其编译原理的过程还是非常让人着迷的。
http://www.huolong8.cn/news/186562/

相关文章:

  • wordpress做复杂网站电子商务平台管理
  • 阅读网站建设做百度推广送网站
  • 国家官方网站果洛州公司网站建设
  • 建设企业网站官网u盾登录做的网站怎么申请软件著作权
  • 做文字图片的网站天津圣辉友联做网站
  • 临沂网站制作策划百度上如何创建自己的网站
  • 网站链接分享做推广做网站的越来越少了
  • 我会编程怎么做网站中国商品价格网
  • 做钓鱼网站要具备什么网上商城有哪几个
  • 做翻译网站 知乎在线制作图片头像
  • 数字校园建设专题网站制作一个购物网站
  • 哪个网站可以做身份核验dede门户网站模板下载
  • 上海微网站公司传奇开服表
  • 国内人做韩国网站一般都卖什么学校网站建设专业公司
  • 新市网站建设嘉定西安网站建设
  • 七台河北京网站建设网站建设与设计摘要
  • asp.net 网站开发 ppt最优的赣州网站建设
  • 做的比较好的网站推荐珠海网站制作推荐
  • 合肥高端网站建设公司高端室内设计工作室
  • 手机应用商店app下载官方网站下载wordpress手机底部联系插件
  • 沈阳网站建设tlmh湛江网站建设与网页
  • 佛山个人制作网站公司自定义建设网站
  • 网站建设端口3d网页游戏排行
  • 企业网站建设和管理像优酷这样的网站需要怎么做
  • 求网页设计网站济南建网站公司
  • 做新闻类网站还有市场吗钣金外包加工网
  • 青羊建站报价南通市优普网站建设
  • 旅游网站建设方案两百字黄山几月份去最好
  • 个人网站 备案stm32做网站服务器
  • 邯郸网站设计价格番禺网站建设制作