pyston的generator实现

1. python的generator是啥?

参见

https://wiki.python.org/moin/Generators

http://linuxgazette.net/100/pramode.html

就是一个能够当做iterator使用的function。例如如下常用的玩意

for i in range(10):
   print i

2. 这东西难不难实现?

如果不允许用户自定义generator函数,就range这种内置的东西而言,不难实现。把range定义成一个类的对象,通过内部状态维护当前的值,在定义诸如next的方法就ok了。但是如果允许用户定义这种函数就有点要命了。例如如下的代码:

def forfun():
 yield "hello"
 yield "world"
def forfun1(n):
  i = 0
  while i < 10 :
     if i < n:
       yield i
     else :
       yield i * 10
     i = i + 1

这下就比较要命了,forfun和forfun1被编译成函数,可是函数是没状态的(static这种就不提了),每次执行不可能接着上次返回之后继续来。在pyston中,其实generator的实现类似与co-route.

3. ucontex这么个东西

参见:http://linux.die.net/man/3/swapcontext

通过getcontex这个函数,我们可以获得一个ucontex_t类型的实例,在通过makecontext函数修改这个实例,makecontext需要提供被调用的函数,参数列表。例如那个页面里面的一段代码:

uctx_func1.uc_stack.ss_sp = func1_stack;
uctx_func1.uc_stack.ss_size = sizeof(func1_stack);
uctx_func1.uc_link = &uctx_main;
makecontext(&uctx_func1, func1, 0);

uctx_func1就是通过getconext获取的,首先我们需要设置它执行函数时使用的栈,栈的大小,uc_link应该就是调用它所服务的那个函数的context。

现在是如何在每个函数之间跳来跳去,还能保证回到原函数时,继续执行之前跳出的代码之后的代码。关键是swapcontext函数,它会把当前的context保存在第一个指针指向的ucontext_t,然后执行第二个指针所保存的文境。

4.generator怎么实现的呢

实现generator表达式或者函数都是BoxedGenerator类型的一个对象,这个类记录了用户定义的generator函数执行的stack,并且包含两个ucontext_t类型的变量context和returncontext。客户端在不断的调用它的next函数时,其实执行的流程如下:

next->generatorNext
-> generatorSend(注意,里面调用了swapcontext(&self->returnContext,&self->context);)->跳至用户定义的函数->用户定义代码中执行yield,调用实现函数yield

->yield(它干啥里,就是调用swapcontext(&self->context,&self->returnContext);)

->这时执行流程又回到了generatorSend,开始执行swapcontext下一条指令。

这里还漏了一点,也就是第一次调用next的时候,context的值从何而来,这个关键在BoxGenerator的够着函数中了,代码如下:

getcontext(&context);
    context.uc_link = 0;
    context.uc_stack.ss_sp = stack;
    context.uc_stack.ss_size = STACK_SIZE;
    makecontext(&context, (void (*)(void))generatorEntry, 1, this);

而在generatorEntry中就会调用用户定义的代码。然后这个环就链上了,用户定义的代码里面有yield,yield又会回到generatorSend,哈,拿到了需要的结果。

实现文件:https://github.com/dropbox/pyston/blob/28c651ab0918b318ce99852f0ea8edd84527c74a/src/runtime/generator.cpp

pyston的generator实现

时间: 2024-11-06 03:55:32

pyston的generator实现的相关文章

使用MyBatis Generator自动生成实体、mapper和dao层

通过MyBatis Generator可以自动生成实体.mapper和dao层,记录一下怎么用的. 主要步骤: 关于mybatis从数据库反向生成实体.DAO.mapper: 参考文章:http://www.cnblogs.com/wangkeai/p/6934683.html第一种方式:main方法运行(推荐) 1.在pom.xml中加入插件依赖: 2.写mbgConfiguration.xml文件,jdbc.properties文件 3.写/SSM/src/main/java/main/Ge

babel转码时generator的regeneratorRuntime

今天写generator函数时发现出错:regeneratorRuntime. 在stackoverflow网友说需是本地babel软件包没有安装完全. package.json: "devDependencies": { "babel-core": "^6.0.20", "babel-polyfill": "^6.0.16", "babel-preset-es2015": "

async(await)函数和 Generator 函数 区别

async 函数是 Generator 函数的语法糖. async 函数对 Generator 函数的改进体现在: 1. async 内置执行器. Generator 函数的执行必须靠执行器,需要调用 next() 方法,或者用co 模块:而 async 函数自带执行器.也就是说,async 函数的执行与普通函数一模一样,只要一行. 2. 更好的语义. async 和 await 比起星号和 yield,语义更清楚. 3.更广的适用性. co 模块约定,yield 命令后面只能是 Thunk 函

MyEclipse下安装MyBatis Generator代码反向生成工具

一.离线方式: 在http://mybatis.googlecode.com/svn/sub-projects/generator/trunk/eclipse/UpdateSite/下载 features/ plugins/ 里面所有的jar包,新建一个mybatis-generator文件夹,把features跟plugins都丢到mybatis-generator文件夹中,把mybatis-generator文件夹移到D:\MyEclipse10_7\MyEclipse 10\dropins

Entity Framework工具POCO Code First Generator的使用

在使用Entity Framework过程中,有时需要借助工具生成Code First的代码,而Entity Framework Reverse POCO Code First Generator是一款不错的工具 在Visual Studio中,通过"工具"→"扩展和更新..."来安装Entity Framework Reverse POCO Code First Generator 这里添加一个控制台项目,并在项目中添加POCO Code First Genera

Mybatis入门实例(三)——使用MyBatis Generator生成DAO(转载http://qiuqiu0034.iteye.com/blog/1163026)

接上回 http://qiuqiu0034.iteye.com/blog/1162952 虽然MyBatis很方便,但是想要手写全部的mapper还是很累人的,好在MyBatis官方推出了自动化工具,可以根据数据库和定义好的配置直接生成DAO层及以下的全部代码,非常方便. 需要注意的是,虽然自动化工具需要一个配置文件,但是MyBatis的配置文件仍然不能少,自动化工具的配置文件用于对生成的代码的选项进行配置,MyBatis的配置文件才是运行时的主要配置文件. 这个工具叫做MyBatis_Gene

ES6生成器函数generator

generator是ES6新增的一个特殊函数,通过 function* 声明,函数体内通过 yield 来指明函数的暂停点,该函数返回一个迭代器,并且函数执行到 yield语句前面暂停,之后通过调用返回的迭代器next()方法来执行yield语句.如下代码演示: function* generator() { yield 1; yield 2; yield 3; } var gen = generator(); 如上代码:generator函数的调用方法与普通函数一样,也是在函数名后面加上一对圆

Python 基础 - Day 4 Learning Note - Generator 生成器

列表生成器/列表解析 list comprehension 简单灵活地创建列表,通常和lambda(), map(), filter() 一起使用 通过列表生成式, 直接创建列表.但是,收到内容限制,列表容量肯定是有限的.而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问几个元素,那其他的就白占空间.列表生成器能够一边循环一边计算,大大节省大量的空间.是生成器的一种. 只有调用,才能生成. 不支持切片操作,只能通过__next()___一个个取数字. 基本语法

mybatis generator工具的使用

mybatis反转数据库的配置文件: generatorConfig.xml: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybati