当前位置:网站首页>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语言底层原理剖析》
- 面向信仰编程-类型检查
边栏推荐
- 为什么sys_class 里显示的很多表的 RELTABLESPACE 值为 0 ?
- What is SPL?
- 2022杭电多校 第6场 1008.Shinobu Loves Segment Tree 规律题
- NowCoderTOP35-40 - continuous update ing
- Tanabata romantic date without overtime, RPA robot helps you get the job done
- 公众号如何运维?公众号运维专业团队
- IDEA performs the Test operation, resulting in duplicate data when data is inserted
- Bias lock/light lock/heavy lock lock is healthier. How is locking and unlocking accomplished?
- 【温度预警程序de开发】事件驱动模型实例运用
- 深入理解 Istio 流量管理的超时时间设置
猜你喜欢

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

The century-old Nordic luxury home appliance brand ASKO smart wine cabinet in the three-temperature area presents the Chinese Valentine’s Day, and tastes the love of the delicacy

气象数据数据处理实例——matlab字符串切割匹配与R语言日期匹配(数据拼接)

Pytorch Deep Learning Quick Start Tutorial -- Mound Tutorial Notes (3)

Egg framework usage (2)

dotnet OpenXML 解析 PPT 图表 面积图入门

Our Web3 Entrepreneurship Project, Yellow

Jenkins使用手册(2) —— 软件配置

The founder of the DFINITY Foundation talks about the ups and downs of the bear market, and where should DeFi projects go?

Pycharm 常用外部工具
随机推荐
three.js调试工具dat.gui使用
STM32+ULN2003驱动28BYJ4步进电机(根据圈数正转、反转)
MySQL事务
Can MySQL use aggregate functions without GROUP BY?
How can project cost control help project success?
开发常用手册链接分享
Confessing in the era of digital transformation: Mai Cong Software allows enterprises to use data in the easiest way
three.js debugging tool dat.gui use
The difference between find, matches, lookingAt matching strings in matcher
Where is your most secretive personality?
Oracle temporary table space role
我们的Web3创业项目,黄了
What is the function of the regular expression replaceAll() method?
一文道清什么是SPL
[Strong Net Cup 2022] WP-UM
【MindSpore易点通机器人-01】你也许见过很多知识问答机器人,但这个有点不一样
上位机开发C#语言:模拟STC串口助手接收单片机发送数据
微服务 技术栈
力扣(LeetCode)216. 组合总和 III(2022.08.04)
入门 Polkadot 平行链开发,看这一篇就够了