当前位置:网站首页>Go compilation principle series 6 (type checking)
Go compilation principle series 6 (type checking)
2022-08-05 10:17:00 【InfoQ】
6. Go编译过程-类型检查
前言
- 常量、Type and function names and type validation
- 变量的赋值和初始化
- Computes compile-time constants、Bind declarations to identifiers
- Some built-in functions will be rewritten(It will be mentioned when the source code is introduced below)
- 哈希键值对的类型
- Do special syntactic or semantic checks(引用的结构体字段是否是大写可导出的?数组字面量的访问是否超过了其长度?数组的索引是不是正整数?)
Overall overview of type checking
var test int
test := 1
GoCompile entry file:src/cmd/compile/main.go -> gc.Main(archInit)
func Main(archInit func(*Arch)) {
......
lines := parseFiles(flag.Args())//词法分析、语法分析、The abstract syntax tree construction is all here
......
//Start traversing the abstract syntax tree,Type checking for each node
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)
}
}
......
checkMapKeys()//Check the type of the keys in the hash
......
}
typecheck
typecheck
typecheck1
func typecheck1(n *Node, top int) (res *Node) {
......
switch n.Op {
// until typecheck is complete, do nothing.
default:
Dump("typecheck", n)
Fatalf("typecheck %v", n.Op)
// names
case OLITERAL:
ok |= ctxExpr
if n.Type == nil && n.Val().Ctype() == CTSTR {
n.Type = types.UntypedString
}
case ONONAME:
ok |= ctxExpr
case ONAME:
......
case OTARRAY:
......
case OTMAP:
......
}
......
}
Learn more about type checking
OAS:赋值语句
// Left = Right or (if Colas=true) Left := Right
// If Colas, then Ninit includes a DCL node for Left.
OAS
typecheckas
case OAS:
ok |= ctxStmt
typecheckas(n)
// Code that creates temps does not bother to set defn, so do it here.
if n.Left.Op == ONAME && n.Left.IsAutoTmp() {
n.Left.Name.Defn = n
}
typecheckas
func typecheckas(n *Node) {
......
if n.Left.Name != nil && n.Left.Name.Defn == n && n.Left.Name.Param.Ntype == nil {
n.Right = defaultlit(n.Right, nil)
n.Left.Type = n.Right.Type
}
......
}
OTARRAY:切片
OTARRAY // []int, [8]int, [N]int or [...]int
case OTARRAY:
ok |= ctxType
r := typecheck(n.Right, ctxType)
if r.Type == nil {
n.Type = nil
return n
}
- []int:直接调用
t = types.NewSlice(r.Type)
,返回了一个 TSLICE
类型的结构体,The element's type information is also stored in the structure
- [...]int:交由
typecheckcomplit
方法处理,
func typecheckcomplit(n *Node) (res *Node) {
......
// Need to handle [...]T arrays specially.
if n.Right.Op == OTARRAY && n.Right.Left != nil && n.Right.Left.Op == ODDD {
n.Right.Right = typecheck(n.Right.Right, ctxType)
if n.Right.Right.Type == nil {
n.Type = nil
return n
}
elemType := n.Right.Right.Type
length := typecheckarraylit(elemType, -1, n.List.Slice(), "array literal")
n.Op = OARRAYLIT
n.Type = types.NewArray(elemType, length)
n.Right = nil
return n
}
......
}
[types.NewArray](https://draveness.me/golang/tree/cmd/compile/internal/types.NewArray)
- [6]int:If when declaring slice,with the size of the array,则直接调用
[types.NewArray](https://draveness.me/golang/tree/cmd/compile/internal/types.NewArray)
Initializes a structure that stores the type of elements in the array and the size of the array
setTypeNode(n, t)
n.Left = nil
n.Right = nil
checkwidth(t)
OTMAP:map(哈希)
OTMAP // map[string]int
TMAP
case OTMAP:
ok |= ctxType
n.Left = typecheck(n.Left, ctxType)
n.Right = typecheck(n.Right, ctxType)
l := n.Left
r := n.Right
if l.Type == nil || r.Type == nil {
n.Type = nil
return n
}
if l.Type.NotInHeap() {
yyerror("incomplete (or unallocatable) map key not allowed")
}
if r.Type.NotInHeap() {
yyerror("incomplete (or unallocatable) map value not allowed")
}
setTypeNode(n, types.NewMap(l.Type, r.Type))
mapqueue = append(mapqueue, n) // check map keys when all types are settled
n.Left = nil
n.Right = nil
......
func NewMap(k, v *Type) *Type {
t := New(TMAP)
mt := t.MapType()
mt.Key = k
mt.Elem = v
return t
}
func checkMapKeys() {
for _, n := range mapqueue {
k := n.Type.MapType().Key
if !k.Broke() && !IsComparable(k) {
yyerrorl(n.Pos, "invalid map key type %v", k)
}
}
mapqueue = nil
}
OMAKE:make
OMAKE // make(List) (before type checking converts to one of the following)
OMAKECHAN // make(Type, Left) (type is chan)
OMAKEMAP // make(Type, Left) (type is map)
OMAKESLICE // make(Type, Left, Right) (type is slice)
make slice:OMAKESLICE
make map:OMAKEMAP
make chan:OMAKECHAN
case OMAKE:
ok |= ctxExpr
args := n.List.Slice()
......
l := args[0]
l = typecheck(l, ctxType)
t := l.Type
......
i := 1
switch t.Etype {
default:
yyerror("cannot make type %v", t)
n.Type = nil
return n
case TSLICE:
......
n.Left = l
n.Right = r
n.Op = OMAKESLICE
case TMAP:
......
n.Op = OMAKEMAP
case TCHAN:
......
n.Op = OMAKECHAN
}
n.Type = t
- 如果第一个参数是切片类型:获取切片的长度(len)和容量(cap),然后对len和cap进行合法性校验.And rewrite the node type
- 如果第一个参数是map类型:获取make的第二个参数,如果没有,则默认设置为0(map的大小).And rewrite the node type
- 如果第一个参数是chan类型:获取make的第二个参数,如果没有,则默认设置为0(chan的缓冲区大小).And rewrite the node type
总结
参考
- go-ast-book
- 《Go语言底层原理剖析》
- 面向信仰编程-类型检查
边栏推荐
- 【MindSpore易点通机器人-01】你也许见过很多知识问答机器人,但这个有点不一样
- 如何选币与确定对应策略研究
- 蚁剑webshell动态加密连接分析与实践
- 基于MindSpore高效完成图像分割,实现Dice!
- Microservice Technology Stack
- Can MySQL use aggregate functions without GROUP BY?
- C语言的高级用法
- Complete image segmentation efficiently based on MindSpore and realize Dice!
- IO stream articles -- based on io stream to realize folder copy (copy subfolders and files in subfolders) full of dry goods
- 5. Deploy the web project to the cloud server
猜你喜欢
SQL外连接之交集、并集、差集查询
Bias lock/light lock/heavy lock lock is healthier. How is locking and unlocking accomplished?
Analysis and practice of antjian webshell dynamic encrypted connection
产品太多了,如何实现一次登录多产品互通?
JS introduction to reverse the recycling business network of learning, simple encryption mobile phone number
微服务 技术栈
The JVM collection that Alibaba's top architects have summarized for many years, where can't I check it!
IDEA performs the Test operation, resulting in duplicate data when data is inserted
基于MindSpore高效完成图像分割,实现Dice!
技术干货 | 基于 MindSpore 实现图像分割之豪斯多夫距离
随机推荐
Oracle temporary table space role
我们的Web3创业项目,黄了
多线程(进阶) - 2.5w字总结
Is digital transformation a business buy-in?
[Unity] [UGUI] [Display text on the screen]
第四章:activiti RuntimeService设置获和取流程变量,及与taskService的区别,开始和完成任务时设置流程变量[通俗易懂]
阿里全新推出:微服务突击手册,把所有操作都写出来了PDF
ffmpeg drawtext 添加文本水印
SD NAND Flash简介!
什么是CRM决策分析管理?
First Decentralized Heist?Loss of nearly 200 million US dollars: analysis of the attack on the cross-chain bridge Nomad
微服务 技术栈
【MindSpore易点通机器人-01】你也许见过很多知识问答机器人,但这个有点不一样
阿里顶级架构师多年总结的JVM宝典,哪里不会查哪里!
Where is your most secretive personality?
【Unity】【UGUI】【在屏幕上显示文本】
three objects are arranged in a spherical shape around the circumference
牛刀小试基本语法,Go lang1.18入门精炼教程,由白丁入鸿儒,go lang基本语法和变量的使用EP02
入门 Polkadot 平行链开发,看这一篇就够了
linux下oracle常见操作以及日常积累知识点(函数、定时任务)