当前位置:网站首页>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
......
}
typechecktypechecktypecheck1func 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
typecheckascase 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
}
typecheckasfunc 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
TMAPcase 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语言底层原理剖析》
- 面向信仰编程-类型检查
边栏推荐
- Bias lock/light lock/heavy lock lock is healthier. How is locking and unlocking accomplished?
- 第四章:redis 数组结构的set和一些通用命令「建议收藏」
- Data Middle Office Construction (10): Data Security Management
- 皕杰报表的下拉框联动
- IO stream articles -- based on io stream to realize folder copy (copy subfolders and files in subfolders) full of dry goods
- 自定义过滤器和拦截器实现ThreadLocal线程封闭
- mysql索引
- 阿里顶级架构师多年总结的JVM宝典,哪里不会查哪里!
- 2022华数杯数学建模思路分析交流
- [Strong Net Cup 2022] WP-UM
猜你喜欢

偏向锁/轻量锁/重级锁锁锁更健康,上锁解锁到底是怎么完成实现的

告白数字化转型时代:麦聪软件以最简单的方式让企业把数据用起来

微服务 技术栈

Which big guy has the 11G GI and ojvm patches in April or January 2020, please help?

七夕浪漫约会不加班,RPA机器人帮你搞定工作

Huawei's lightweight neural network architecture GhostNet has been upgraded again, and G-GhostNet (IJCV22) has shown its talents on the GPU

哪位大佬有20年4月或者1月的11G GI和ojvm补丁呀,帮忙发下?

STM32+ULN2003 drives 28BYJ4 stepper motor (forward and reverse according to the number of turns)

What is SPL?

Bias lock/light lock/heavy lock lock is healthier. How is locking and unlocking accomplished?
随机推荐
创建一个 Dapp,为什么要选择波卡?
The difference between find, matches, lookingAt matching strings in matcher
[强网杯2022]WP-UM
微服务 技术栈
深入理解 Istio 流量管理的超时时间设置
企业的数字化转型到底是否可以买来?
牛刀小试基本语法,Go lang1.18入门精炼教程,由白丁入鸿儒,go lang基本语法和变量的使用EP02
three.js debugging tool dat.gui use
Getting started with Polkadot parachain development, this article is enough
偏向锁/轻量锁/重级锁锁锁更健康,上锁解锁到底是怎么完成实现的
机器学习-基础知识 - Precision, Recall, Sensitivity, Specificity, Accuracy, FNR, FPR, TPR, TNR, F1 Score, Bal
JS introduction to reverse the recycling business network of learning, simple encryption mobile phone number
C语言的高级用法
【综合类型第 35 篇】程序员的七夕浪漫时刻
Wei Dongshan Digital Photo Frame Project Learning (6) Transplantation of tslib
Four years of weight loss record
leetcode: 529. Minesweeper Game
【AGC】增长服务1-远程配置示例
QSS 选择器
开发常用手册链接分享