tinypy源码笔记(二)——目录及构建分析
来源:互联网 发布:海岛奇兵 数据 编辑:程序博客网 时间:2024/06/07 03:03
简介
这篇文章是对tinypy的实现结构一个综述,虚拟机技术是一个非常迷人的技术,由于成熟的虚拟机一般非常庞大,动辄几十上百万代码,初学者难以入手(后来我发现lua也是非常好的学习项目,而且更加成熟),后来我无意中发现tinypy
这个项目,完成了对虚拟机技术的一次初窥,愈发对其感兴趣了,(我自己后来也实现了一个类似的项目minipy,有兴趣的同好可以移步https://github.com/xupingmao/minipy,有什么建议批评也欢迎指出),由于关于tinypy
的文档较少,所以我开始整理了这本源码笔记(开始只写了个头,进行简单介绍,后来实现的时候加深了理解,也觉得做事还是得有始有终,所以又继续写了,后面我还会写一系列文章介绍,直到整个笔记在结构上是完整的为止),希望对有兴趣研究的同学有所帮助。
tinypy官方网站是 http://tinypy.org,源代码在github上也维护了一套 https://github.com/philhassey/tinypy
如果只是想大概了解下tinypy的功能,可以参考前一篇文章 tinypy源码笔记——简单介绍
目录分析
cpython/ # CPython的扩展doc/ # 文档examples/ # 示例modules/ # 扩展模块tinypy/ # 语言的实现 ./boot.py # 构建的启动文件 ./tokenize.py # 词法分析器 ./parse.py # 语法解析器 ./encode.py # 代码生成器 ./py2bc.py # 把tinypy字节码转换成C语言数组工具 ./tests.py # 测试用例 ./tp.h # 头文件,所有的结构定义都在这个文件中 ./tp.c # C语言调用tinypy编译器接口 ./tpmain.c # tinypy编译器入口,可以忽略 ./vmmain.c # tinypy解释器入口,及从这里编译得到tinypy解释器 ./vm.c # tinypy解释器(虚拟机)实现 ./gc.c # 垃圾回收器 ./string.c # str的实现 ./list.c # list的实现 ./dict.c # dict的实现 ./ops.c # 操作符运算的实现 ./misc.c # 未分类的函数,或者说工具函数CHANGES.txt # 修改记录LICENSE.txt # 协议说明,tinypy基于MIT协议,由于参考了Python的设计,所以也附带了PSF协议README.txt # 说明文件setup.txt # 构建工具,非常重要
构建过程
这一节具体查看setup.py
的内容
- 首先看
main
方法
tinypy 一共提供了5个选项
tinypy # 构建tinypy的解释器64k # 构建64k的编译器源码blob # 构建独立的tinypy.c和tinypy.h文件,方便嵌入C/C++使用build # 构建CPython模块,完成后可以在Python解释器中使用tinypy的模块install # 安装CPython模块
其他一些是构建清除以及优化的选项,可以不用考虑。
main
方法中首先处理了编译选项,生成了编译命令行,并且根据操作系统选择了不同的构建方法,为了简便起见,之间查看linux
平台下的构建方法build_gcc
(这个方法在安装好mingw的环境下也可以使用)
同样为了分析方便,删除所有其他选项的代码(DEBUG,TEST,BOOT什么的),这样原来一堆代码现在只有下面几行,看起来非常清爽了。
核心的方法只有三个build_gcc
, build_bc
, py2bc
核心流程也比较清晰了,
- 进入源码目录
- 把关键python文件编译成
.tpc
字节码 - 把字节码合并到
bc.c
文件中,转换成C语言无符号数组定义 - 编译入口文件
mymain.c
,得到tinpy的可执行文件 - 回到原来目录,打印
OK
CORE = ['tokenize','parse','encode','py2bc']def build_bc(opt=False): out = [] for mod in CORE: out.append("""unsigned char tp_%s[] = {"""%mod) fname = mod+".tpc" data = open(fname,'rb').read() cols = 16 for n in xrange(0,len(data),cols): out.append(",".join([str(ord(v)) for v in data[n:n+cols]])+',') out.append("""};""") out.append("") f = open('bc.c','wb') f.write('\n'.join(out)) f.close()def py2bc(cmd,mod): src = '%s.py'%mod dest = '%s.tpc'%mod if CLEAN or not os.path.exists(dest) or os.stat(src).st_mtime > os.stat(dest).st_mtime: cmd = cmd.replace('$SRC',src) cmd = cmd.replace('$DEST',dest) do_cmd(cmd) else: print '#',dest,'is up to date'def build_gcc(): mods = CORE[:] do_chdir(os.path.join(TOPDIR,'tinypy')) nopos = ' -nopos ' for mod in mods: py2bc('python py2bc.py $SRC $DEST'+nopos,mod) build_bc(True) do_cmd("gcc $WFLAGS -O3 mymain.c $FLAGS -lm -o ../build/tinypy") do_chdir('..') print("# OK")
后续文章
后续的文章我将主要着重于虚拟机部分,编译器部分大家有兴趣可以看看相关编译原理的书籍,建议初学者实现使用递归下降即可,tinypy
的语法分析算法是采用的称之为Top Down Operator Precedence
(自顶向下算符优先)的算法,这也是一个比较有意思的算法,有兴趣的可以参考JavaScript专家Douglas Crockford写的介绍文章http://javascript.crockford.com/tdop/tdop.html
- tinypy源码笔记(二)——目录及构建分析
- tinypy源码笔记(三)——虚拟机启动过程以及字节码分析
- tinypy源码笔记(一)——简单介绍
- tinypy源码笔记(五)——异常处理
- tinypy源码分析(四)——函数调用的实现分析
- 嵌入式linux开发uboot移植(二)——uboot工程源码目录分析
- 蓝牙(Bluetooth)---源码目录及设置应用源码分析
- 蓝牙(Bluetooth)---源码目录及设置应用源码分析
- 目录树构建及查询案例(二)
- Tinker接入及源码分析(二)
- Weevely使用及源码分析(二)
- Tinker接入及源码分析(二)
- OpenCV学习笔记(28)KAZE 算法原理与源码分析(二)非线性尺度空间构建
- tomcat源码分析学习笔记(二)
- Ceph 学习——CRUSH算法及源码分析(二)
- glance-0.1.7 分析(二)—— 构建文档
- Tor源码分析二 -- 目录结构
- UE4源码分析—文件目录说明
- UVA - 1584 Circular Sequence
- 第十五周项目 程序填空(2)自定义普通函数实现add
- 大型web系统架构详谈
- 整理的JavaScript的数据类型
- C++日期类的运算符重载和简单边界条件
- tinypy源码笔记(二)——目录及构建分析
- 3dmax做的某学校科探室设计
- Error:Execution failed for task ':app:dexDebug'. > com.android.ide.common.process.ProcessException:
- 编程规范 --- 排版
- Android图像处理(五)镜像、倒影、drawBitmapMesh实现旗帜飘扬效果
- 206, 92, 65. Reverse Linked List 系列
- CocoaPods 安装及使用
- 第一部分 简介(第一章 简介 + 第二章 Posix IPC + 第三章 System V IPC)
- 一颗糖的爱情