<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US">
  <title>而今迈步从头越 - Home</title>
  <id>tag:leeseon.com,2009:mephisto/</id>
  <generator uri="http://mephistoblog.com" version="0.8.0">Mephisto Drax</generator>
  
  <link href="http://leeseon.com/" rel="alternate" type="text/html" />
  <updated>2009-06-03T02:27:42Z</updated>
  <link rel="self" href="http://feeds.feedburner.com/leeseon" type="application/atom+xml" /><entry xml:base="http://leeseon.com/">
    <author>
      <name>leeseon</name>
    </author>
    <id>tag:leeseon.com,2009-06-03:55</id>
    <published>2009-06-03T01:41:00Z</published>
    <updated>2009-06-03T02:27:42Z</updated>
    <category term="Ruby" />
    <category term="ruby" />
    <category term="scheme" />
    <link href="http://leeseon.com/2009/6/3/scheme_interpreter_in_15-minutes" rel="alternate" type="text/html" />
    <title>Scheme interpreter in 15 minutes</title>
<content type="html">
            &amp;lt;object height="290" width="400"&gt;
&amp;lt;param /&gt;
&amp;lt;param /&gt;
&amp;lt;param /&gt;
&amp;lt;/object&gt;
          </content>  </entry>
  <entry xml:base="http://leeseon.com/">
    <author>
      <name>leeseon</name>
    </author>
    <id>tag:leeseon.com,2009-05-22:54</id>
    <published>2009-05-22T22:00:00Z</published>
    <updated>2009-05-25T06:02:47Z</updated>
    <category term="37signals" />
    <category term="business" />
    <category term="dhh" />
    <category term="vedio" />
    <link href="http://leeseon.com/2009/5/22/david_heinemeier_hansson_at_startup_school_08" rel="alternate" type="text/html" />
    <title>David Heinemeier Hansson at Startup School 08 </title>
<content type="html">
            &amp;lt;object&gt;&amp;lt;param /&gt;&amp;lt;param /&gt;&amp;lt;param /&gt;&amp;lt;param /&gt;&amp;lt;param /&gt;&amp;lt;/object&gt;
          </content>  </entry>
  <entry xml:base="http://leeseon.com/">
    <author>
      <name>leeseon</name>
    </author>
    <id>tag:leeseon.com,2009-04-24:52</id>
    <published>2009-04-24T10:01:00Z</published>
    <updated>2009-05-25T05:17:30Z</updated>
    <category term="from" />
    <category term="mail" />
    <category term="proxy" />
    <category term="rising" />
    <category term="send" />
    <link href="http://leeseon.com/2009/4/24/email_send_successed_but_never_get_it" rel="alternate" type="text/html" />
    <title>邮件发送提示成功，但是无法接收</title>
<content type="html">
            &lt;p&gt;自己写了一段发送邮件的客户端程序，一直运行良好。可是某天开始，程序发送能提示成功，但是一直接收不到，深感诧异。将笔记本带回家中，程序又运行良好。第二天上班，发现问题依旧。&lt;/p&gt;


	&lt;p&gt;随决定使用最原始的telnet命令查看问题原因，命令如下&lt;/p&gt;


&lt;pre class="blackboard"&gt;
16:52:22 [rx] 220 XXX.com ESMTP(EQManager V6.0) ESMTP
16:52:22 [tx] EHLO computer1
16:52:22 [rx] 250-XXX.com ESMTP(EQManager V6.0)
16:52:22 [rx] 250-STARTTLS
16:52:22 [rx] 250-AUTH LOGIN PLAIN
16:52:22 [rx] 250-AUTH=LOGIN PLAIN
16:52:22 [rx] 250-PIPELINING
16:52:22 [rx] 250-SIZE 25530692
16:52:22 [rx] 250 8BITMIME
16:52:22 [tx] AUTH LOGIN
16:52:22 [rx] 334 VXNlcm5hbWU6
16:52:22 [tx] e===========
16:52:22 [rx] 334 UGFzc3dvcmQ6
16:52:22 [tx] N===========
16:52:22 [rx] 235 ok, go ahead (#2.0.0)
16:52:22 [tx] MAIL FROM: &amp;lt;account@XXX.com&amp;gt;
16:52:22 [rx] 250 ok
16:52:22 [tx] RCPT TO: &amp;lt;account@sina.com&amp;gt;
16:52:22 [rx] 250 ok
16:52:22 [tx] DATA
16:52:22 [rx] 354 Send from Rising mail proxy
16:52:22 [tx] 
.
&lt;/pre&gt;

	&lt;p&gt;执行完DATA命令，发送结束符，然后等待从服务器的信息，等待足够长的时间后，系统提示超时。
邮件一直发送不成功。看到DATA命令紧跟着 Send from Rising mail proxy，猜测可能与瑞星
防毒软件有关，之后关闭了瑞星，再次发送，ok，一切正常，所有命令没有任何问题。DATA命令
也能返回响应，但是登录sina还是接受不到。考虑到网络延时，又等待了20分钟，还是接受不到。
至此黔驴技穷，无计可施了。遂放弃，回家休息了。&lt;/p&gt;


	&lt;p&gt;第二日上班后，登录sina，一下接收了n多封信，至此我的问题解决。&lt;/p&gt;


	&lt;p&gt;究其原因
1.确实是瑞星杀毒软件导致邮件接收不到。因为安装的是网络版，所以回家就关闭了瑞星，到公司
才打开，解释了为什么在家可以发送成功，而在公司不成功。
2.sina信箱使用的是免费信箱，上网查找，发现不止我一人，很多使用sina免费信箱的用户都抱怨
邮件接收延时大，夸张的需要隔一天才可以接收到，可能和他的服务器繁忙有关，当然也可能是不重视
免费的用户。&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://leeseon.com/">
    <author>
      <name>leeseon</name>
    </author>
    <id>tag:leeseon.com,2009-03-28:48</id>
    <published>2009-03-28T18:33:00Z</published>
    <updated>2009-04-02T17:03:57Z</updated>
    <category term="dhh" />
    <category term="dream" />
    <category term="education" />
    <category term="time" />
    <category term="翻译" />
    <link href="http://leeseon.com/2009/3/28/there_is_always_time_to_launch_your_dream" rel="alternate" type="text/html" />
    <title>总会有时间来实现你的梦想</title>
<content type="html">
            &lt;blockquote&gt;
		&lt;p&gt;“I’d love to start a company / become a great programmer / write an awesome blog, but there’s just not enough time in the day!” Bullshit. There’s always enough time, you’re just not spending it right.&lt;/p&gt;
	&lt;/blockquote&gt;


看到了&lt;a href="http://www.loudthinking.com/"&gt;&lt;span class="caps"&gt;DHH&lt;/span&gt;&lt;/a&gt; 的这篇&lt;a href="http://www.37signals.com/svn/posts/1619-theres-always-time-to-launch-your-dream"&gt;post&lt;/a&gt; 当时感触就很深，本想译出来偏不得闲，恰今天遇一事忆起且又有闲，试译一下，原文就很简单本不需译，纯当练手好玩尔;)
&lt;blockquote&gt;&lt;p&gt;“I’d love to start a company / become a great programmer / write an awesome blog, but there’s just not enough time in the day!” Bullshit. There’s always enough time, you’re just not spending it right.&lt;/p&gt;

	&lt;p&gt;Now that’s some tough love, but I’m sick and tired of hearing “no time” as an excuse for why you can’t be great. It really doesn’t take that much time to get started, but it does take wanting it really bad. Most people just doesn’t want it bad enough and protect their ego with the excuse of time.&lt;/p&gt;


	&lt;p&gt;This excuse is particularly depressing when it comes from students. Oh, I have so many classes. Oh, I have so much home work. There’s simply no time to learn outside of school. Then you’re doing it wrong!&lt;/p&gt;


	&lt;p&gt;Never let your schooling interfere with your education, someone clever once said. Being willing to sacrifice at the edges is one of the most important skills you’ll ever learn.&lt;/p&gt;


	&lt;p&gt;I’ve received plenty of Bs and even Cs for classes that I was incredibly proud of because they came from hardly no time spent at all. Time that I could then spend on reading my own curriculum, starting my own projects, and running my own businesses.&lt;/p&gt;


	&lt;p&gt;And I did. During my undergrad, I created Instiki, Rails, Basecamp, and got on the path to being a partner at 37signals. Do you think I could fit all that and still get straight As and have lots of time left over for playing World of Warcraft? No.&lt;/p&gt;


	&lt;p&gt;If you want it bad enough, you’ll make the time, regardless of your other obligations. Don’t let yourself off the hook with excuses. It’s too easy and, to be honest, nobody cares on the other side.&lt;/p&gt;


&lt;p&gt;It’s entirely your responsibility to make your dreams come through.
&lt;/p&gt;&lt;/blockquote&gt;

	&lt;p&gt;“我非常希望开一家公司/成为一个伟大的程序员/写一篇令人惊叹博客，但是没有足够的时间！”屁话。总有足够的时间，你只是没有正确使用！&lt;/p&gt;


	&lt;p&gt;爱之深责之切吧，现我已经十分厌倦听到以“没有时间”作为自己为何不足够强大的借口。不需要太多时间就可以开始，但这取决于是否真的非常想要。大多数人并不是真的足够想要，仅仅是拿时间作为自我开脱的借口而已。&lt;/p&gt;


	&lt;p&gt;尤其是听到学生说出这个借口时，会特别令人沮丧。“噢，我有这么多课。噢，我有那么多的家庭工作。有根本没有时间学习的学校以外的东西。”你错了！&lt;/p&gt;


	&lt;p&gt;绝不让学业干扰了您的教育，曾有智者如是说。为了取得优势情愿付出是你需要学习的最重要技能之一。&lt;/p&gt;


	&lt;p&gt;我的成绩曾得过大量的B，甚至还有C，但我仍然为此非常自豪，因为我几乎没有时间管它们。当时我的时间都花在阅读自己的课程，开始自己的项目，并运行自己的业务上了。&lt;/p&gt;


	&lt;p&gt;我做到了。在我大学阶段，我创建Instiki ，Rails，BaseCamp，并走上了37signals合伙人之路。那么你会认为我能搞定上面所说的这一切，并有很多时间来魔兽世界？No&lt;/p&gt;


	&lt;p&gt;如果你真的非常想要，无论怎样你都会抽出时间。不要拿借口来开脱。这是太容易了，并坦率地说，别人鬼在乎你这些。&lt;/p&gt;


	&lt;p&gt;让你梦想成真完全你自己的责任。&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://leeseon.com/">
    <author>
      <name>leeseon</name>
    </author>
    <id>tag:leeseon.com,2009-03-10:47</id>
    <published>2009-03-10T16:34:00Z</published>
    <updated>2009-03-10T16:43:20Z</updated>
    <category term="dhh" />
    <category term="dream" />
    <category term="good blog" />
    <category term="梦想" />
    <link href="http://leeseon.com/2009/3/10/there_is_always_time_to_launch_your_dream_if_it_is_your_real_dream" rel="alternate" type="text/html" />
    <title>总会有时间来实现自己的梦想，如果那真的是你的梦想的话</title>
<content type="html">
            &lt;p&gt;看来DHH是在厌倦了别人向他抱怨，或者是什么刺激之后吧，说出了一个真理，虽然是大白话，但是听上去还是让人不得不深思一番，这不，俺虽然也困得不行，也只好上来先发个post占个位先，等醒了之后再好好品读一下。志之&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://leeseon.com/">
    <author>
      <name>leeseon</name>
    </author>
    <id>tag:leeseon.com,2009-02-17:38</id>
    <published>2009-02-17T18:52:00Z</published>
    <updated>2009-05-10T17:17:17Z</updated>
    <category term="data migrate" />
    <category term="dreamhost" />
    <category term="export" />
    <category term="mysql" />
    <category term="rails" />
    <category term="sqlite3" />
    <link href="http://leeseon.com/2009/2/17/export_mysql_data_to_sqlite3_for_rails" rel="alternate" type="text/html" />
    <title>将mysql数据导入到sqlite中</title>
<content type="html">
            &lt;p&gt;自&lt;a href="http://www.rubyonrails.org"&gt;rails&lt;/a&gt; 2.0将默认配置的数据库改成&lt;a href="http://www.sqlite.org"&gt;sqlite&lt;/a&gt; 之后，我才真的开始使用这个”self-contained, serverless, zero-configuration, transactional”小巧，轻便的嵌入式的数据库、、、以下省去 溢美之词n多字&lt;/p&gt;


	&lt;p&gt;不对sqlite对我来说最大的好处就是不用安装与启动服务，完全就是一个绿色版，只要拷贝过来，放在路径之下就能直接使用了，而且数据库也就是一个文件也是可以随身携带的&lt;/p&gt;


	&lt;p&gt;如果不喜欢二进制文件也可以将数据转成文本，命令如下：&lt;/p&gt;


&lt;pre class="blackboard"&gt;
sqlite3 dbfile.sqlite3 &amp;quot;.dump&amp;quot; &amp;gt; sqlite3db.sql
&lt;/pre&gt;

	&lt;p&gt;不过我倒是没有试过在生产环境中使用它，平时在开发与测试时才使用，因此需要将一些mysql中的数据导入到我本地的sqlite3中&lt;/p&gt;


自然是先google之，看到一个比较直白的&lt;a href="http://www.dangarland.co.uk/2008/09/27/exporting-mysql-data-into-sqlite3/"&gt;解决方案&lt;/a&gt; 它使用mysqldump导出sql语句并从中仅grep(提取)出insert语句，然后在使用
&lt;pre class="blackboard"&gt;
rake db:create
rake db:migrate
&lt;/pre&gt;
之后用
&lt;pre class="blackboard"&gt;
sqlite3 dbfile.sqlite3 &amp;lt; backup.sql
&lt;/pre&gt;
将数据导入到sqlite3中

	&lt;p&gt;不过其中有一点小问题：正如文中所说，mysql与sqlite3的转义符并不一致，&lt;code&gt;除了需要将\'转成''(两个单引号)之外，还需要将"\r"(0x5c0x72)与"\n"(0x5c0x6e)转成\r(0x0d)\n(0x0a)，此外\"也是需要转成"(双引号)的&lt;/code&gt;&lt;/p&gt;


	&lt;p&gt;并且文中的替换方法是使用编辑器手工替换的，这点与我懒惰的习惯实在是不符，还是用sed来自动化一下吧！最终拼成一个脚本如下：&lt;/p&gt;


&lt;pre class="blackboard"&gt;
#!/bin/sh
mysqldump  --opt --no-create-db --no-create-info --default-character-set=utf8 --extended-insert=0 -u user -ppassword database \
| grep 'INSERT' \
| sed -e &amp;quot;s/\\\'/''/g&amp;quot; -e &amp;quot;s/\\\r/\r/g&amp;quot; -e &amp;quot;s/\\\n/\n/g&amp;quot; -e 's/\\\&amp;quot;/&amp;quot;/g' &amp;gt; backup.sql
&lt;/pre&gt;

	&lt;p&gt;如果你需要每天将服务器上的数据备份并应用在日常的开发中的话，可以参考上次所写的&lt;a href="/2009/1/24/daily_backup_dreamhost_mysql_database_to_gmail"&gt;DreamHost每日mysql数据库备份方案&lt;/a&gt; 将上面这段合并到&lt;a href="http://www.dreamhost.com/r.cgi?282910"&gt;Dreamhost&lt;/a&gt; 的cron任务中&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://leeseon.com/">
    <author>
      <name>leeseon</name>
    </author>
    <id>tag:leeseon.com,2009-02-14:37</id>
    <published>2009-02-14T21:09:00Z</published>
    <updated>2009-02-14T21:17:20Z</updated>
    <category term="Interesting" />
    <category term="interesting" />
    <category term="Ruby" />
    <category term="ruby" />
    <category term="time zone" />
    <category term="unix time" />
    <category term="valentine's day" />
    <category term="情人节" />
    <link href="http://leeseon.com/2009/2/14/an_interesting_unix_time_just_at_valentines_day" rel="alternate" type="text/html" />
    <title>有趣的情人节时间密码</title>
<content type="html">
            &lt;pre class="blackboard"&gt;
&lt;span class="Keyword"&gt;require&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;rubygems&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="Keyword"&gt;require&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;active_support&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;

&lt;span class="Support"&gt;Time&lt;/span&gt;.&lt;span class="Entity"&gt;at&lt;/span&gt; &lt;span class="Constant"&gt;1234567890&lt;/span&gt; &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt; =&amp;gt; Sat Feb 14 07:31:30 +0800 2009&lt;/span&gt;

&lt;span class="Support"&gt;Time&lt;/span&gt;.&lt;span class="Entity"&gt;zone&lt;/span&gt; &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;Beijing&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt; =&amp;gt; &amp;quot;Beijing&amp;quot;&lt;/span&gt;

&lt;span class="Support"&gt;Time&lt;/span&gt;.&lt;span class="Entity"&gt;zone&lt;/span&gt;.&lt;span class="Entity"&gt;at&lt;/span&gt; &lt;span class="Constant"&gt;1234567890&lt;/span&gt; &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt; =&amp;gt; Sat, 14 Feb 2009 07:31:30 CST +08:00&lt;/span&gt;
&lt;/pre&gt;

	&lt;p&gt;可惜今天一天都在加班，早上6:30才回，倒头就睡了，在不知不觉中就已经错过了这个有趣时间:(&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://leeseon.com/">
    <author>
      <name>leeseon</name>
    </author>
    <id>tag:leeseon.com,2009-01-24:36</id>
    <published>2009-01-24T07:49:00Z</published>
    <updated>2009-04-02T17:18:09Z</updated>
    <category term="backup" />
    <category term="dreamhost" />
    <category term="gmail" />
    <category term="mysql" />
    <link href="http://leeseon.com/2009/1/24/daily_backup_dreamhost_mysql_database_to_gmail" rel="alternate" type="text/html" />
    <title>DreamHost每日mysql数据库备份方案</title>
<content type="html">
            &lt;p&gt;因为&lt;a href="http://www.dreamhost.com/r.cgi?282910"&gt;DreamHost&lt;/a&gt; 本身就提供了数据库的备份功能，尤其是象我这样更新不多blog数据也不多:( 一般出了问题restore一下就行了。&lt;/p&gt;


不过前几天我犯了一个相当低级的错误，执行了一次
&lt;pre&gt;&lt;code&gt;rake db:reset&lt;/code&gt;&lt;/pre&gt;

谁知&lt;a href="http://www.dreamhost.com/r.cgi?282910"&gt;DreamHost&lt;/a&gt; 居然只能在命令行中执行
&lt;pre&gt;&lt;code&gt;drop database&lt;/code&gt;&lt;/pre&gt;
却不能执行
&lt;pre&gt;&lt;code&gt;create database&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;再去找panel里的数据库还在，但是restore居然提示没有任何内容，也不知出了什么事，只好发邮件问support.,但是网页总不能总是空的啊，好在幸好前几天为&lt;a href="http://leeseon.com/2009/1/2/port_inove_wordpress_theme_to_mephisto"&gt;移植一个WordPress下的theme&lt;/a&gt; 导了一份数据出来，换了个数据改了database.yml就搞定了&lt;/p&gt;


	&lt;p&gt;只好亡羊补牢google了一下，自然是有现成的方案的，只是因为我想使用gmail来作为接受邮箱，但是gmail会拒收tar.gz, zip之类的文件，我修改了一下使用rar来打包，脚本如下：&lt;/p&gt;


&lt;pre class="blackboard"&gt;
#!/bin/bash
cd /home/yourname/backups/ 
mkdir mysql 
suffix=$(date +%y%m%d)
mysqldump --opt --default-character-set=utf8 -uyourname -ppassword -h yourhost.com database | sed &amp;quot;s/\\\'/''/g&amp;quot; &amp;gt; mysql/database.$suffix.sql
rar a archives/mysql_backup.$suffix.rar -r mysql/*
rm -r mysql/
mutt youname@gmail.com -a /home/yourname/backups/archives/mysql_backup.$suffix.rar -s &amp;quot;MySQL Backup&amp;quot;
&lt;/pre&gt;

	&lt;p&gt;其中，mysqldump之后需要加上—default-character-set=utf8 而且再一个sed “s/\\\’/’’/g” 通道比较好，这样导出的文件会将\’替成”看起来比较方便&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://leeseon.com/">
    <author>
      <name>leeseon</name>
    </author>
    <id>tag:leeseon.com,2009-01-02:35</id>
    <published>2009-01-02T18:36:00Z</published>
    <updated>2009-01-10T01:03:49Z</updated>
    <category term="just for fun" />
    <category term="port" />
    <category term="wordpress theme" />
    <link href="http://leeseon.com/2009/1/2/port_inove_wordpress_theme_to_mephisto" rel="alternate" type="text/html" />
    <title>自己移植了一个比较喜欢的wordpress主题用用</title>
<content type="html">
            &lt;p&gt;一直垂涎于Wordpress有很多好看的theme可以用，mephisto这两年的更新与发展也太慢了，看来rails的blog系统，相对于PHP来说还真的有一些小众的感觉。&lt;/p&gt;


	&lt;p&gt;等着别人port我看基本是没戏，自己动手吧，虽然不难，但是有一点啰嗦，加上我的CSS知识也很一般，好在做port这种事其实与CSS基本无关，对于mephisto来说，其实要了解的主要是liquid与mephisto自己的一点变量而已。&lt;/p&gt;


	&lt;p&gt;截了以前的样子，留个记录吧&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://www.slide.com/s/Zm5xneBv1z8bWbV7FtDfAKCYPCJl5_u0?referrer=hlnk"&gt;&lt;img title="免费无限存放图片在slide.com!" src="http://widget.slide.com/rdr/1/1/1/W/250000000c9da7f3/1/231/z_ZiBIoh6T-vmw_b8qKm1ZZWrx3ijB2n.jpg" alt="免费无限存放图片在slide.com!" /&gt;&lt;/a&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://leeseon.com/">
    <author>
      <name>leeseon</name>
    </author>
    <id>tag:leeseon.com,2009-01-01:34</id>
    <published>2009-01-01T13:27:00Z</published>
    <updated>2009-01-01T13:47:41Z</updated>
    <category term="new year" />
    <category term="wish" />
    <category term="展望" />
    <category term="感想" />
    <category term="愿景" />
    <link href="http://leeseon.com/2009/1/1/wishes_in_the_new_year" rel="alternate" type="text/html" />
    <title>新年新气象</title>
<content type="html">
            &lt;p&gt;2008年混杂着奥运的狂喜与自然灾害及金融危机呼啸而过，时间真的是过的越来越快，果然是：”我觉察他去的匆匆了，伸出手遮挽时，他又从遮挽着的手边过去“。&lt;/p&gt;


	&lt;p&gt;此去经年是我最爱在元旦时留下的标题，而今又是“流光容易把人抛，红了樱桃，绿了芭蕉“了、、、然掩而叹息亦不能改变我又老去了一岁，在过去的一年中我又一事无成的事实。&lt;/p&gt;


	&lt;p&gt;看来历史总是重复的基本上也是对的吧，不过人总会不满足于现状，在回首看看逝去的一年，心中不由的生出的恐惧与懊恼，追悔不及自然是有的，但是后悔是不能解决问题的，真的问题是需要解决问题，让自己成长，能在自己曾经的时光废墟中立起来，也算是新年新气象吧。&lt;/p&gt;


	&lt;p&gt;特此立酸文志之，只需要在明年的元旦再看时不再心中有悔，此愿足矣！&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://leeseon.com/">
    <author>
      <name>leeseon</name>
    </author>
    <id>tag:leeseon.com,2008-11-19:31</id>
    <published>2008-11-19T16:08:00Z</published>
    <updated>2008-11-24T13:08:43Z</updated>
    <category term="apple advertisement" />
    <category term="mac" />
    <link href="http://leeseon.com/2008/11/19/so_cool_apple_advertisement" rel="alternate" type="text/html" />
    <title>太酷的广告了</title>
<content type="html">
            &amp;lt;object&gt;
&amp;lt;param /&gt;
&amp;lt;/object&gt;
          </content>  </entry>
  <entry xml:base="http://leeseon.com/">
    <author>
      <name>leeseon</name>
    </author>
    <id>tag:leeseon.com,2008-11-10:30</id>
    <published>2008-11-10T15:48:00Z</published>
    <updated>2008-11-12T13:59:42Z</updated>
    <category term="emacs" />
    <category term="no pirated" />
    <category term="textmate" />
    <category term="viusal c++ express" />
    <category term="windows" />
    <link href="http://leeseon.com/2008/11/10/from_textmate_to_emacs" rel="alternate" type="text/html" />
    <title>从Textmate到Emacs</title>
<content type="html">
            &lt;p&gt;虽然Textmate一直是俺的最爱，但是出了ruby及os x之外，使用Textmate有时成了一种奢望，就说rubinius吧，这个*nix only的项目，现在也没有办法在cgywin上编译通过，在我打过多处补丁之后，发现这几乎对我来说是一项不可能完成的任务。不太懂*nix下的线程与信号的说，这个以后俺再补补，争取出个windows上原生线程的port。&lt;/p&gt;


	&lt;p&gt;为了在*nix（ubuntu与mac os x)下读读它，并跟踪一下它的运行，我只好祭出emacs了，好在它可以整合emacs code browser及cscope，而且还能同时使用图形化的gdb界面。看来Ｃ++还是用emacs好了。&lt;/p&gt;


	&lt;p&gt;其实我也一直很叶公好龙滴，虽然早就耳闻emacs的好，但是在ubuntu下俺就用gedit来偷懒，dreamhost上用不太熟的vi来混混，windows上还是主要依赖于VS、notepad++，有时也拿intype来找一下textmate的感觉。&lt;/p&gt;


	&lt;p&gt;最近又因为公司里不许安装Ｄ版，而且VS公司又不肯买，在这点的Jole测试上公司应该是零分的:( 还说是因为印度那边用VC++ Express一直都很好，而且因为金融危机的问题，公司不肯再在软件上投入更多的预算，真是服了公司的目光短浅及印度人的忍耐力、、、、&lt;/p&gt;


	&lt;p&gt;不过我是被Visual Assist X给宠坏了，不让我使用alt+o, alt+shift+s, alt+shift+o我是没有办法习惯了,而且我曾经花美金买到绝版的ref++及现在refactor!等等的插件都再也办法用了:( 不能装插件的vc express是一个让我无法适应的IDE。&lt;/p&gt;


	&lt;p&gt;好在emacs还有一个windows的版本，在配完cedet之后，与VAX相同的功能也都回来了，只是emacs下的重构功能我还没有试过，而且那个是要收费滴&lt;/p&gt;


	&lt;p&gt;经过了几天与emacs的搏斗之后，才发现emacs的难学只是听起来吓人的，慢慢的，还不等你记住，你的手指也开始记住了它的习惯了。而且使用它与*nix下的工具合作起来真的是很爽的，而且这样你在三个平台之下都有了一个统一的IDE感觉真的很爽，不过不知为什么，我居然没有想过用eclipse与netbean呢？我也不知道，可能我天生爱受虐，或者喜欢虐键盘，总对用quicksilver与launchy调出一个emacs疯狂打上一些古怪组合键感觉良好。不知你是否有同好？呵呵&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://leeseon.com/">
    <author>
      <name>leeseon</name>
    </author>
    <id>tag:leeseon.com,2008-10-05:29</id>
    <published>2008-10-05T07:25:00Z</published>
    <updated>2008-10-07T14:08:04Z</updated>
    <category term="bytecode" />
    <category term="jit" />
    <category term="llvm" />
    <category term="rubinius" />
    <link href="http://leeseon.com/2008/10/5/rubinius-and-llvm-jit" rel="alternate" type="text/html" />
    <title>Rubinius与LLVM</title>
<content type="html">
            &lt;p&gt;一直对&lt;a href="http://rubini.us/"&gt;Rubinius&lt;/a&gt;所宣称的“Ruby In Ruby”很以为然，而且龙书中之也提到一个语言成熟的标志之一就是能“自举”--即使用自已来实现自己。以此为标准，Fortran、Basic、Javascript、Perl、PHP之类应该都算是不举，而LISP、C/C++、Smalltalk早就是很举的，Python、Java与Ruby现在是半举，并在让自己摆脱ED的印象之中，而&lt;a href="http://rubini.us/"&gt;Rubinius&lt;/a&gt;自然是Rubyist的春药罗&lt;/p&gt;
&lt;p&gt;这两天读到&lt;a href="http://blog.fallingsnow.net/2008/05/23/simple-vm-jit-with-llvm/"&gt;Simple VM JIT with LLVM&lt;/a&gt; 觉得很是有趣，不过奇怪的是居然这个网站也被盾了，如果你从来没有tor过，或者gladder过，建议你赶紧找一个翻过墙去看看。不过顺便也谈谈我的读后感吧，算是学习笔记了。&lt;/p&gt;
&lt;p&gt;Rubinius与YARV一样是一个虚拟机(VM)，它如同Python一样，先将源代码编译成Bytecode文件，在执行时优先执行Bytecode。这样能提高ruby的执行效率。说到VM自然不能不说它的bc了，一个VM无非就是拿一些bc来执行了事而已，其实PC也是这样的，只是一个实一个虚而已。&lt;/p&gt;
&lt;p&gt;Evan为了举例说明，首先杜撰了一个足够tiny的VM：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;只操作整数&lt;/li&gt; 
&lt;li&gt;被编号的寄存器&lt;/li&gt;  
&lt;li&gt;只有三条指令&lt;/li&gt;  
&lt;li&gt;
&lt;ol&gt;
&lt;li&gt;&lt;b&gt;0 - set(reg, val)&lt;/b&gt;　将第reg号寄存器设为整数值val &lt;/li&gt; 
&lt;li&gt;&lt;strong&gt;1 - add(result, reg, val)&lt;/strong&gt;&amp;nbsp; 将第reg寄存器与val相加，并将结果放入result寄存器 &lt;/li&gt; 
&lt;li&gt;&lt;b&gt;2 - show(reg)&lt;/b&gt; 将寄存器reg中的内容打印出来&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;因此下面这字节&lt;/p&gt;&lt;pre&gt;  [ 0, 0, 3,
    1, 0, 0, 4,
    2, 0 ]&lt;/pre&gt;
&lt;p&gt;就表明将3与4相加并打印出来这样一个简单的功能，结果嘛如果不出意思自然是7&lt;/p&gt;
&lt;p&gt;用C实现这个VM最平铺直叙的方法就是直接写就好了，如下&lt;/p&gt;&lt;pre class="blackboard"&gt;&lt;span class="Storage"&gt;void&lt;/span&gt; add(&lt;span class="Storage"&gt;int&lt;/span&gt;* ops, &lt;span class="Storage"&gt;int&lt;/span&gt;* registers) {
  registers[ops[&lt;span class="Constant"&gt;1&lt;/span&gt;]] = registers[ops[&lt;span class="Constant"&gt;2&lt;/span&gt;]] + ops[&lt;span class="Constant"&gt;3&lt;/span&gt;];
}

&lt;span class="Storage"&gt;void&lt;/span&gt; set(&lt;span class="Storage"&gt;int&lt;/span&gt;* ops, &lt;span class="Storage"&gt;int&lt;/span&gt;* registers) {
  registers[ops[&lt;span class="Constant"&gt;1&lt;/span&gt;]] = ops[&lt;span class="Constant"&gt;2&lt;/span&gt;];
}

&lt;span class="Storage"&gt;void&lt;/span&gt; &lt;span class="Entity"&gt;sh&lt;span class="Entity"&gt;ow&lt;/span&gt;&lt;/span&gt;(&lt;span class="Storage"&gt;int&lt;/span&gt;* ops, &lt;span class="Storage"&gt;int&lt;/span&gt;* registers) {
  &lt;span class="Support"&gt;printf&lt;/span&gt;(&lt;span class="String"&gt;&lt;span class="String"&gt;"&lt;/span&gt;=&amp;gt; &lt;span class="StringInterpolation"&gt;%d&lt;/span&gt;&lt;span class="Constant"&gt;\n&lt;/span&gt;&lt;span class="String"&gt;"&lt;/span&gt;&lt;/span&gt;, registers[ops[&lt;span class="Constant"&gt;1&lt;/span&gt;]]);
}

&lt;span class="Storage"&gt;void&lt;/span&gt; run(&lt;span class="Storage"&gt;int&lt;/span&gt;* ops, &lt;span class="Storage"&gt;int&lt;/span&gt;* registers) {
  &lt;span class="Keyword"&gt;switch&lt;/span&gt;(*ops) {
  &lt;span class="Keyword"&gt;case&lt;/span&gt; &lt;span class="Constant"&gt;0&lt;/span&gt;:
	set(ops, registers);
	ops += &lt;span class="Constant"&gt;3&lt;/span&gt;;
    &lt;span class="Keyword"&gt;break&lt;/span&gt;;
  &lt;span class="Keyword"&gt;case&lt;/span&gt; &lt;span class="Constant"&gt;1&lt;/span&gt;:
	add(ops, registers);
	ops += &lt;span class="Constant"&gt;4&lt;/span&gt;;
    &lt;span class="Keyword"&gt;break&lt;/span&gt;;
  &lt;span class="Keyword"&gt;case&lt;/span&gt; &lt;span class="Constant"&gt;2&lt;/span&gt;:
	show(ops, registers);
    &lt;span class="Keyword"&gt;return&lt;/span&gt;;
  }
}
&lt;/pre&gt;
&lt;p&gt;随后Evan还另给出一个去除switch的直接的不能再直接的版本：&lt;/p&gt;
&lt;pre class="blackboard"&gt;&lt;span class="Storage"&gt;void&lt;/span&gt; &lt;span class="Entity"&gt;my_progr&lt;span class="Entity"&gt;am&lt;/span&gt;&lt;/span&gt;() {
  &lt;span class="Storage"&gt;int&lt;/span&gt; registers[&lt;span class="Constant"&gt;2&lt;/span&gt;] = {&lt;span class="Constant"&gt;0&lt;/span&gt;, &lt;span class="Constant"&gt;0&lt;/span&gt;};
  &lt;span class="Storage"&gt;int&lt;/span&gt; program[&lt;span class="Constant"&gt;10&lt;/span&gt;] = [ &lt;span class="Constant"&gt;0&lt;/span&gt;, &lt;span class="Constant"&gt;0&lt;/span&gt;, &lt;span class="Constant"&gt;3&lt;/span&gt;,
                      &lt;span class="Constant"&gt;1&lt;/span&gt;, &lt;span class="Constant"&gt;0&lt;/span&gt;, &lt;span class="Constant"&gt;0&lt;/span&gt;, &lt;span class="Constant"&gt;4&lt;/span&gt;,
                      &lt;span class="Constant"&gt;2&lt;/span&gt;, &lt;span class="Constant"&gt;0&lt;/span&gt; ]

  &lt;span class="Storage"&gt;int&lt;/span&gt;* ops = (&lt;span class="Storage"&gt;int&lt;/span&gt;*)program;

  set(ops, registers);
  ops += &lt;span class="Constant"&gt;3&lt;/span&gt;;
  add(ops, registers);
  ops += &lt;span class="Constant"&gt;4&lt;/span&gt;;
  show(ops, registers);
  ops += &lt;span class="Constant"&gt;2&lt;/span&gt;;
}
&lt;/pre&gt;
&lt;p&gt;其实两者的功能是一样的，唯一的区别是前者更通用一点，可以在运行时执行，而后者比较象使用Bytecode直接翻译过来的样子。&lt;/p&gt;
&lt;p&gt;而且的确是这样，处理这样将Bytecode执行的一种最最静态的方法，就是写一个bc的C代码生成器(C code emitter)，将bc一次解析并产生一个类似第二段代码后几句的c代码文件，然后编译执行即可。&lt;/p&gt;
&lt;p&gt;不过这种方法最大的缺点就是太静态了，所以的东西已经在编译时就定了，这当然不是Rubinius可以使用的方式，至于如第一段代码那样，一个更动态一点的方法，就是写一个解释器，在运行时解析代码并动态执行。其实这就有点类似YARV的方式。&lt;br /&gt;除此之外有没有别的什么方法还执行bc呢？自然是有的，而且早就有很多人使用过了，那就是JIT(Just-in-time compilation)嘛:　JIT是一个不那么纯编译也不那么纯解释的方法，bc在被执行前，先被转成目标机器上的原生指令，然后再执行，因为这一过程是即时的生成的，因此可以在其中增加一个优化的环节。而且因为代码是即时生成的，因此它可以对生成的代码做一些caching，所以它要比一句一句“忠实”执行的解释器快，而且因为JIT能获得更多的运行时信息，如CPU的架构及代码执行统计信息，因此能够生成一些CPU“特化”的代码及运行时的优化工作，所以JIT也是很有可能比静态编译要快的。&lt;/p&gt;
&lt;p&gt;其实说了这么多也不过是为了引入今天所要谈的主角-----&lt;a href="http://llvm.org/"&gt;LLVM&lt;/a&gt;: LLVM并不是一个编译器，而仅仅只是一个编译器的基础设施(infrastructure)，这个比较绕，其实它最有趣是提供了一套语言无关的中间层的优化与分析工具集。晕，其实这样说依然很绕:( 不过如果看一看Evan的例子之后可能会明白一些&lt;/p&gt;
&lt;p&gt;首先就算是JIT也是需要将Bytecode的语义，即set/add/show指令提供给LLVM滴，先将这三个函数放入一个ops.c文件中，再用到llvm-gcc工具了，它利用gcc的前端，将C代码转换成LLVM的bc文件&lt;/p&gt;
&lt;p&gt;命令如下&lt;/p&gt;
&lt;p&gt;&lt;code&gt;llvm-gcc -emit-llvm -O3 -c ops.c&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;这会生成一个ops.o的bc文件&lt;/p&gt;
&lt;p&gt;使用&lt;code&gt;llvm-dis &amp;lt; ops.o&lt;/code&gt;　命令查看，会看到与bc文件相对应的LLVM汇编指令&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;pre class="blackboard"&gt;@.&lt;span class="Entity"&gt;str&lt;/span&gt; &lt;span class="Keyword"&gt;=&lt;/span&gt; internal constant [&lt;span class="Constant"&gt;7&lt;/span&gt; x i8] c&lt;span class="String"&gt;&lt;span class="String"&gt;"&lt;/span&gt;=&amp;gt; %dA0&lt;span class="String"&gt;"&lt;/span&gt;&lt;/span&gt;		;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=1]&lt;/span&gt;

define void &lt;span class="Variable"&gt;&lt;span class="Variable"&gt;@&lt;/span&gt;add&lt;/span&gt;(i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;ops, i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;registers) nounwind  {
entry:
	&lt;span class="Keyword"&gt;%&lt;/span&gt;tmp1 &lt;span class="Keyword"&gt;=&lt;/span&gt; getelementptr i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;ops, i32 &lt;span class="Constant"&gt;1&lt;/span&gt;		;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=1]&lt;/span&gt;
	&lt;span class="Keyword"&gt;%&lt;/span&gt;tmp2 &lt;span class="Keyword"&gt;=&lt;/span&gt; load i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;tmp1, align &lt;span class="Constant"&gt;4&lt;/span&gt;		;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=1]&lt;/span&gt;
	&lt;span class="Keyword"&gt;%&lt;/span&gt;tmp4 &lt;span class="Keyword"&gt;=&lt;/span&gt; getelementptr i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;ops, i32 &lt;span class="Constant"&gt;2&lt;/span&gt;		;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=1]&lt;/span&gt;
	&lt;span class="Keyword"&gt;%&lt;/span&gt;tmp5 &lt;span class="Keyword"&gt;=&lt;/span&gt; load i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;tmp4, align &lt;span class="Constant"&gt;4&lt;/span&gt;		;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=1]&lt;/span&gt;
	&lt;span class="Keyword"&gt;%&lt;/span&gt;tmp7 &lt;span class="Keyword"&gt;=&lt;/span&gt; getelementptr i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;registers, i32 &lt;span class="Keyword"&gt;%&lt;/span&gt;tmp5		;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=1]&lt;/span&gt;
	&lt;span class="Keyword"&gt;%&lt;/span&gt;tmp8 &lt;span class="Keyword"&gt;=&lt;/span&gt; load i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;tmp7, align &lt;span class="Constant"&gt;4&lt;/span&gt;		;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=1]&lt;/span&gt;
	&lt;span class="Keyword"&gt;%&lt;/span&gt;tmp10 &lt;span class="Keyword"&gt;=&lt;/span&gt; getelementptr i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;ops, i32 &lt;span class="Constant"&gt;3&lt;/span&gt;		;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=1]&lt;/span&gt;
	&lt;span class="Keyword"&gt;%&lt;/span&gt;tmp11 &lt;span class="Keyword"&gt;=&lt;/span&gt; load i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;tmp10, align &lt;span class="Constant"&gt;4&lt;/span&gt;		;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=1]&lt;/span&gt;
	&lt;span class="Keyword"&gt;%&lt;/span&gt;tmp12 &lt;span class="Keyword"&gt;=&lt;/span&gt; add i32 &lt;span class="Keyword"&gt;%&lt;/span&gt;tmp11, &lt;span class="Keyword"&gt;%&lt;/span&gt;tmp8		;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=1]&lt;/span&gt;
	&lt;span class="Keyword"&gt;%&lt;/span&gt;tmp14 &lt;span class="Keyword"&gt;=&lt;/span&gt; getelementptr i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;registers, i32 &lt;span class="Keyword"&gt;%&lt;/span&gt;tmp2		;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=1]&lt;/span&gt;
	store i32 &lt;span class="Keyword"&gt;%&lt;/span&gt;tmp12, i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;tmp14, align &lt;span class="Constant"&gt;4&lt;/span&gt;
	ret void
}

define void &lt;span class="Variable"&gt;&lt;span class="Variable"&gt;@&lt;/span&gt;set&lt;/span&gt;(i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;ops, i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;registers) nounwind  {
entry:
	&lt;span class="Keyword"&gt;%&lt;/span&gt;tmp1 &lt;span class="Keyword"&gt;=&lt;/span&gt; getelementptr i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;ops, i32 &lt;span class="Constant"&gt;1&lt;/span&gt;		;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=1]&lt;/span&gt;
	&lt;span class="Keyword"&gt;%&lt;/span&gt;tmp2 &lt;span class="Keyword"&gt;=&lt;/span&gt; load i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;tmp1, align &lt;span class="Constant"&gt;4&lt;/span&gt;		;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=1]&lt;/span&gt;
	&lt;span class="Keyword"&gt;%&lt;/span&gt;tmp4 &lt;span class="Keyword"&gt;=&lt;/span&gt; getelementptr i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;ops, i32 &lt;span class="Constant"&gt;2&lt;/span&gt;		;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=1]&lt;/span&gt;
	&lt;span class="Keyword"&gt;%&lt;/span&gt;tmp5 &lt;span class="Keyword"&gt;=&lt;/span&gt; load i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;tmp4, align &lt;span class="Constant"&gt;4&lt;/span&gt;		;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=1]&lt;/span&gt;
	&lt;span class="Keyword"&gt;%&lt;/span&gt;tmp7 &lt;span class="Keyword"&gt;=&lt;/span&gt; getelementptr i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;registers, i32 &lt;span class="Keyword"&gt;%&lt;/span&gt;tmp2		;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=1]&lt;/span&gt;
	store i32 &lt;span class="Keyword"&gt;%&lt;/span&gt;tmp5, i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;tmp7, align &lt;span class="Constant"&gt;4&lt;/span&gt;
	ret void
}

declare i32 &lt;span class="Variable"&gt;&lt;span class="Variable"&gt;@&lt;/span&gt;printf&lt;/span&gt;(i8&lt;span class="Keyword"&gt;*&lt;/span&gt;, ...) nounwind 

define void &lt;span class="Variable"&gt;&lt;span class="Variable"&gt;@&lt;/span&gt;show&lt;/span&gt;(i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;ops, i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;registers) nounwind  {
entry:
	&lt;span class="Keyword"&gt;%&lt;/span&gt;tmp1 &lt;span class="Keyword"&gt;=&lt;/span&gt; getelementptr i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;ops, i32 &lt;span class="Constant"&gt;1&lt;/span&gt;		;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=1]&lt;/span&gt;
	&lt;span class="Keyword"&gt;%&lt;/span&gt;tmp2 &lt;span class="Keyword"&gt;=&lt;/span&gt; load i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;tmp1, align &lt;span class="Constant"&gt;4&lt;/span&gt;		;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=1]&lt;/span&gt;
	&lt;span class="Keyword"&gt;%&lt;/span&gt;tmp4 &lt;span class="Keyword"&gt;=&lt;/span&gt; getelementptr i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;registers, i32 &lt;span class="Keyword"&gt;%&lt;/span&gt;tmp2		;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=1]&lt;/span&gt;
	&lt;span class="Keyword"&gt;%&lt;/span&gt;tmp5 &lt;span class="Keyword"&gt;=&lt;/span&gt; load i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;tmp4, align &lt;span class="Constant"&gt;4&lt;/span&gt;		;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=1]&lt;/span&gt;
	&lt;span class="Keyword"&gt;%&lt;/span&gt;tmp7 &lt;span class="Keyword"&gt;=&lt;/span&gt; tail call i32 (i8&lt;span class="Keyword"&gt;*&lt;/span&gt;, ...)&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Variable"&gt;&lt;span class="Variable"&gt;@&lt;/span&gt;printf&lt;/span&gt;( i8&lt;span class="Keyword"&gt;*&lt;/span&gt; getelementptr ([&lt;span class="Constant"&gt;7&lt;/span&gt; x i8]&lt;span class="Keyword"&gt;*&lt;/span&gt; @.&lt;span class="Entity"&gt;str&lt;/span&gt;, i32 &lt;span class="Constant"&gt;0&lt;/span&gt;, i32 &lt;span class="Constant"&gt;0&lt;/span&gt;), i32 &lt;span class="Keyword"&gt;%&lt;/span&gt;tmp5 ) nounwind 		;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=0]&lt;/span&gt;
	ret void
}
&lt;/pre&gt;
&lt;p&gt;无它，这个ops.o主要是拿来给LLVM使用的，在运行时生成相应的语义调用&lt;/p&gt;
&lt;p&gt;然后使用LLVM的C++ API来生成一段与第二段代码相应的LLVM代码&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;pre class="blackboard"&gt;Function* &lt;span class="Entity"&gt;crea&lt;span class="Entity"&gt;te&lt;/span&gt;&lt;/span&gt;(Module** out) {
  std::string error;
  Module* jit;

  &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;//&lt;/span&gt; Load in the bitcode file containing the functions for each&lt;/span&gt;
  &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;//&lt;/span&gt; bytecode operation.&lt;/span&gt;
  &lt;span class="Keyword"&gt;if&lt;/span&gt;(MemoryBuffer* buffer = MemoryBuffer::getFile(&lt;span class="String"&gt;&lt;span class="String"&gt;"&lt;/span&gt;ops.o&lt;span class="String"&gt;"&lt;/span&gt;&lt;/span&gt;, &amp;amp;error)) {
    jit = ParseBitcodeFile(buffer, &amp;amp;error);
    &lt;span class="Keyword"&gt;delete&lt;/span&gt; buffer;
  }

  &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;//&lt;/span&gt; Pull out references to them.&lt;/span&gt;
  Function* set =  jit-&amp;gt;getFunction(std::string(&lt;span class="String"&gt;&lt;span class="String"&gt;"&lt;/span&gt;set&lt;span class="String"&gt;"&lt;/span&gt;&lt;/span&gt;));
  Function* add =  jit-&amp;gt;getFunction(std::string(&lt;span class="String"&gt;&lt;span class="String"&gt;"&lt;/span&gt;add&lt;span class="String"&gt;"&lt;/span&gt;&lt;/span&gt;));
  Function* show = jit-&amp;gt;getFunction(std::string(&lt;span class="String"&gt;&lt;span class="String"&gt;"&lt;/span&gt;show&lt;span class="String"&gt;"&lt;/span&gt;&lt;/span&gt;));

  &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;//&lt;/span&gt; Now, begin building our new function, which calls the&lt;/span&gt;
  &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;//&lt;/span&gt; above functions.&lt;/span&gt;
  Function* body = cast&amp;lt;Function&amp;gt;(jit-&amp;gt;getOrInsertFunction(&lt;span class="String"&gt;&lt;span class="String"&gt;"&lt;/span&gt;body&lt;span class="String"&gt;"&lt;/span&gt;&lt;/span&gt;,
        Type::VoidTy,
        PointerType::getUnqual(Type::Int32Ty),
        PointerType::getUnqual(Type::Int32Ty), (Type*)&lt;span class="Constant"&gt;0&lt;/span&gt;));

  &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;//&lt;/span&gt; Our function will be passed the ops pointer and the&lt;/span&gt;
  &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;//&lt;/span&gt; registers pointer, just like before.&lt;/span&gt;
  Function::arg_iterator args = body-&amp;gt;arg_begin();
  Value* ops = args++;
  ops-&amp;gt;setName(&lt;span class="String"&gt;&lt;span class="String"&gt;"&lt;/span&gt;ops&lt;span class="String"&gt;"&lt;/span&gt;&lt;/span&gt;);
  Value* registers = args++;
  registers-&amp;gt;setName(&lt;span class="String"&gt;&lt;span class="String"&gt;"&lt;/span&gt;registers&lt;span class="String"&gt;"&lt;/span&gt;&lt;/span&gt;);

  BasicBlock *bb = BasicBlock::Create(&lt;span class="String"&gt;&lt;span class="String"&gt;"&lt;/span&gt;entry&lt;span class="String"&gt;"&lt;/span&gt;&lt;/span&gt;, body);

  &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;//&lt;/span&gt; Set up our arguments to be passed to set.&lt;/span&gt;
  std::vector&amp;lt;Value*&amp;gt; params;
  params.push_back(ops);
  params.push_back(registers);

  &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;//&lt;/span&gt; Call out to set, passing ops and registers down&lt;/span&gt;
  CallInst* call = CallInst::Create(set, params.begin(), params.end(), &lt;span class="String"&gt;&lt;span class="String"&gt;"&lt;/span&gt;&lt;span class="String"&gt;"&lt;/span&gt;&lt;/span&gt;, bb);
  ConstantInt* const_3 = ConstantInt::get(APInt(&lt;span class="Constant"&gt;32&lt;/span&gt;,  &lt;span class="String"&gt;&lt;span class="String"&gt;"&lt;/span&gt;3&lt;span class="String"&gt;"&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;10&lt;/span&gt;));
  ConstantInt* const_4 = ConstantInt::get(APInt(&lt;span class="Constant"&gt;32&lt;/span&gt;,  &lt;span class="String"&gt;&lt;span class="String"&gt;"&lt;/span&gt;4&lt;span class="String"&gt;"&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;10&lt;/span&gt;));

  &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;//&lt;/span&gt; add 3 to the ops pointer.&lt;/span&gt;
  GetElementPtrInst* ptr1 = GetElementPtrInst::Create(ops, const_3, &lt;span class="String"&gt;&lt;span class="String"&gt;"&lt;/span&gt;tmp3&lt;span class="String"&gt;"&lt;/span&gt;&lt;/span&gt;, bb);

  &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;//&lt;/span&gt; Setup and call add, notice we pass down the updated ops pointer&lt;/span&gt;
  &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;//&lt;/span&gt; rather than the original, so that we've moved down.&lt;/span&gt;
  std::vector&amp;lt;Value*&amp;gt; params2;
  params2.push_back(ptr1);
  params2.push_back(registers);
  CallInst* call2 = CallInst::Create(add, params2.begin(), params2.end(), &lt;span class="String"&gt;&lt;span class="String"&gt;"&lt;/span&gt;&lt;span class="String"&gt;"&lt;/span&gt;&lt;/span&gt;, bb);

  &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;//&lt;/span&gt; Push the ops pointer down another 4.&lt;/span&gt;
  GetElementPtrInst* ptr2 = GetElementPtrInst::Create(ops, const_4, &lt;span class="String"&gt;&lt;span class="String"&gt;"&lt;/span&gt;tmp3&lt;span class="String"&gt;"&lt;/span&gt;&lt;/span&gt;, bb);

  &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;//&lt;/span&gt; Setup and call show.&lt;/span&gt;
  std::vector&amp;lt;Value*&amp;gt; params3;
  params3.push_back(ptr2);
  params3.push_back(registers);
  CallInst* call3 = CallInst::Create(show, params3.begin(), params3.end(), &lt;span class="String"&gt;&lt;span class="String"&gt;"&lt;/span&gt;&lt;span class="String"&gt;"&lt;/span&gt;&lt;/span&gt;, bb);

  &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;//&lt;/span&gt; And we're done!&lt;/span&gt;
  ReturnInst::Create(bb);

  *out = jit;
  &lt;span class="Keyword"&gt;return&lt;/span&gt; body;
}

&lt;/pre&gt;
&lt;p&gt;然后调用之&lt;/p&gt;&lt;pre class="blackboard"&gt;&lt;span class="Storage"&gt;int&lt;/span&gt; &lt;span class="Entity"&gt;ma&lt;span class="Entity"&gt;in&lt;/span&gt;&lt;/span&gt;() {
  &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;//&lt;/span&gt; The registers.&lt;/span&gt;
  &lt;span class="Storage"&gt;int&lt;/span&gt; registers[&lt;span class="Constant"&gt;2&lt;/span&gt;] = {&lt;span class="Constant"&gt;0&lt;/span&gt;, &lt;span class="Constant"&gt;0&lt;/span&gt;};

  &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;//&lt;/span&gt; Our program.&lt;/span&gt;
  &lt;span class="Storage"&gt;int&lt;/span&gt; program[&lt;span class="Constant"&gt;20&lt;/span&gt;] = {&lt;span class="Constant"&gt;0&lt;/span&gt;, &lt;span class="Constant"&gt;0&lt;/span&gt;, &lt;span class="Constant"&gt;3&lt;/span&gt;,
                     &lt;span class="Constant"&gt;1&lt;/span&gt;, &lt;span class="Constant"&gt;0&lt;/span&gt;, &lt;span class="Constant"&gt;0&lt;/span&gt;, &lt;span class="Constant"&gt;4&lt;/span&gt;,
                     &lt;span class="Constant"&gt;2&lt;/span&gt;, &lt;span class="Constant"&gt;0&lt;/span&gt;};

  &lt;span class="Storage"&gt;int&lt;/span&gt;* ops = (&lt;span class="Storage"&gt;int&lt;/span&gt;*)program;

  &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;//&lt;/span&gt; Create our function and give us the Module and Function back.&lt;/span&gt;
  Module* jit;
  Function* func = create(&amp;amp;jit);

  &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;//&lt;/span&gt; Add in optimizations. These were taken from a list that 'opt', LLVMs optimization tool, uses.&lt;/span&gt;
  PassManager p;

  &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;/*&lt;/span&gt; Comment out optimize&lt;/span&gt;
&lt;span class="Comment"&gt;  p.add(new TargetData(jit));&lt;/span&gt;
&lt;span class="Comment"&gt;  p.add(createVerifierPass());&lt;/span&gt;
&lt;span class="Comment"&gt;  p.add(createLowerSetJmpPass());&lt;/span&gt;
&lt;span class="Comment"&gt;  p.add(createRaiseAllocationsPass());&lt;/span&gt;
&lt;span class="Comment"&gt;  p.add(createCFGSimplificationPass());&lt;/span&gt;
&lt;span class="Comment"&gt;  p.add(createPromoteMemoryToRegisterPass());&lt;/span&gt;
&lt;span class="Comment"&gt;  p.add(createGlobalOptimizerPass());&lt;/span&gt;
&lt;span class="Comment"&gt;  p.add(createGlobalDCEPass());&lt;/span&gt;
&lt;span class="Comment"&gt;  p.add(createFunctionInliningPass());&lt;/span&gt;
&lt;span class="Comment"&gt;  &lt;span class="Comment"&gt;*/&lt;/span&gt;&lt;/span&gt;

  &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;//&lt;/span&gt; Run these optimizations on our Module&lt;/span&gt;
  p.run(*jit);

  &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;//&lt;/span&gt; Setup for JIT&lt;/span&gt;
  ExistingModuleProvider* mp = &lt;span class="Keyword"&gt;new&lt;/span&gt; ExistingModuleProvider(jit);
  ExecutionEngine* engine = ExecutionEngine::create(mp);

  &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;//&lt;/span&gt; Show us what we've created!&lt;/span&gt;
  std::cout &amp;lt;&amp;lt; &lt;span class="String"&gt;&lt;span class="String"&gt;"&lt;/span&gt;Created&lt;/span&gt;
&lt;span class="String"&gt;&lt;span class="String"&gt;"&lt;/span&gt;&lt;/span&gt; &amp;lt;&amp;lt; *jit;

  &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;//&lt;/span&gt; Have our function JIT'd into machine code and return. We cast it to a particular C function pointer signature so we can call in nicely.&lt;/span&gt;
  &lt;span class="Storage"&gt;void&lt;/span&gt; (*fp)(&lt;span class="Storage"&gt;int&lt;/span&gt;*, &lt;span class="Storage"&gt;int&lt;/span&gt;*) = (&lt;span class="Storage"&gt;void&lt;/span&gt; (*)(&lt;span class="Storage"&gt;int&lt;/span&gt;*, &lt;span class="Storage"&gt;int&lt;/span&gt;*))engine-&amp;gt;getPointerToFunction(func);

  &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;//&lt;/span&gt; Call what we've created!&lt;/span&gt;
  fp(ops, registers);
}
&lt;/pre&gt;
&lt;p&gt;最后的结果会是这样&lt;/p&gt;
&lt;pre class="blackboard"&gt;&lt;span class="Keyword"&gt;&amp;lt;&lt;/span&gt;snip same &lt;span class="Variable"&gt;LLVM&lt;/span&gt; as before&lt;span class="Keyword"&gt;&amp;gt;&lt;/span&gt;

define void &lt;span class="Variable"&gt;&lt;span class="Variable"&gt;@&lt;/span&gt;body&lt;/span&gt;(i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;ops, i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;registers) {
entry:
call void &lt;span class="Variable"&gt;&lt;span class="Variable"&gt;@&lt;/span&gt;set&lt;/span&gt;( i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;ops, i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;registers )
&lt;span class="Keyword"&gt;%&lt;/span&gt;tmp3 &lt;span class="Keyword"&gt;=&lt;/span&gt; getelementptr i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;ops, i32 &lt;span class="Constant"&gt;3&lt;/span&gt; ;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=1]&lt;/span&gt;
call void &lt;span class="Variable"&gt;&lt;span class="Variable"&gt;@&lt;/span&gt;add&lt;/span&gt;( i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;tmp3, i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;registers )
&lt;span class="Keyword"&gt;%&lt;/span&gt;tmp31 &lt;span class="Keyword"&gt;=&lt;/span&gt; getelementptr i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;ops, i32 &lt;span class="Constant"&gt;4&lt;/span&gt; ;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=1]&lt;/span&gt;
call void &lt;span class="Variable"&gt;&lt;span class="Variable"&gt;@&lt;/span&gt;show&lt;/span&gt;( i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;tmp31, i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;registers )
ret void
}
=&amp;gt; &lt;span class="Constant"&gt;7&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;bc被执行了，不是吗？而且上面的那个boby就如同是&lt;span class="Entity"&gt;my_progr&lt;span class="Entity"&gt;am最后几行代码最直白的翻译，不同这处只是它是用API来产生的而已。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class="Entity"&gt;&lt;span class="Entity"&gt;不过等等，最有趣的在后面，如果将LLVM的优化功能全部打开了之后，我们能得到什么？&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class="Entity"&gt;&lt;span class="Entity"&gt;&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;pre class="blackboard"&gt;define void &lt;span class="Variable"&gt;&lt;span class="Variable"&gt;@&lt;/span&gt;body&lt;/span&gt;(i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;ops, i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;registers) {
entry:
	&lt;span class="Keyword"&gt;%&lt;/span&gt;tmp1.&lt;span class="Entity"&gt;i&lt;/span&gt; &lt;span class="Keyword"&gt;=&lt;/span&gt; getelementptr i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;ops, i32 &lt;span class="Constant"&gt;1&lt;/span&gt;		;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=1]&lt;/span&gt;
	&lt;span class="Keyword"&gt;%&lt;/span&gt;tmp2.&lt;span class="Entity"&gt;i&lt;/span&gt; &lt;span class="Keyword"&gt;=&lt;/span&gt; load i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;tmp1.&lt;span class="Entity"&gt;i&lt;/span&gt;, align &lt;span class="Constant"&gt;4&lt;/span&gt;		;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=1]&lt;/span&gt;
	&lt;span class="Keyword"&gt;%&lt;/span&gt;tmp4.&lt;span class="Entity"&gt;i&lt;/span&gt; &lt;span class="Keyword"&gt;=&lt;/span&gt; getelementptr i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;ops, i32 &lt;span class="Constant"&gt;2&lt;/span&gt;		;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=1]&lt;/span&gt;
	&lt;span class="Keyword"&gt;%&lt;/span&gt;tmp5.&lt;span class="Entity"&gt;i&lt;/span&gt; &lt;span class="Keyword"&gt;=&lt;/span&gt; load i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;tmp4.&lt;span class="Entity"&gt;i&lt;/span&gt;, align &lt;span class="Constant"&gt;4&lt;/span&gt;		;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=1]&lt;/span&gt;
	&lt;span class="Keyword"&gt;%&lt;/span&gt;tmp7.&lt;span class="Entity"&gt;i&lt;/span&gt; &lt;span class="Keyword"&gt;=&lt;/span&gt; getelementptr i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;registers, i32 &lt;span class="Keyword"&gt;%&lt;/span&gt;tmp2.&lt;span class="Entity"&gt;i&lt;/span&gt;		;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=1]&lt;/span&gt;
	store i32 &lt;span class="Keyword"&gt;%&lt;/span&gt;tmp5.&lt;span class="Entity"&gt;i&lt;/span&gt;, i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;tmp7.&lt;span class="Entity"&gt;i&lt;/span&gt;, align &lt;span class="Constant"&gt;4&lt;/span&gt;
	&lt;span class="Keyword"&gt;%&lt;/span&gt;tmp3 &lt;span class="Keyword"&gt;=&lt;/span&gt; getelementptr i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;ops, i32 &lt;span class="Constant"&gt;3&lt;/span&gt;		;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=3]&lt;/span&gt;
	&lt;span class="Keyword"&gt;%&lt;/span&gt;tmp1.&lt;span class="Entity"&gt;i7&lt;/span&gt; &lt;span class="Keyword"&gt;=&lt;/span&gt; getelementptr i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;tmp3, i32 &lt;span class="Constant"&gt;1&lt;/span&gt;		;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=1]&lt;/span&gt;
	&lt;span class="Keyword"&gt;%&lt;/span&gt;tmp2.&lt;span class="Entity"&gt;i8&lt;/span&gt; &lt;span class="Keyword"&gt;=&lt;/span&gt; load i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;tmp1.&lt;span class="Entity"&gt;i7&lt;/span&gt;, align &lt;span class="Constant"&gt;4&lt;/span&gt;		;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=1]&lt;/span&gt;
	&lt;span class="Keyword"&gt;%&lt;/span&gt;tmp4.&lt;span class="Entity"&gt;i9&lt;/span&gt; &lt;span class="Keyword"&gt;=&lt;/span&gt; getelementptr i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;tmp3, i32 &lt;span class="Constant"&gt;2&lt;/span&gt;		;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=1]&lt;/span&gt;
	&lt;span class="Keyword"&gt;%&lt;/span&gt;tmp5.&lt;span class="Entity"&gt;i10&lt;/span&gt; &lt;span class="Keyword"&gt;=&lt;/span&gt; load i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;tmp4.&lt;span class="Entity"&gt;i9&lt;/span&gt;, align &lt;span class="Constant"&gt;4&lt;/span&gt;		;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=1]&lt;/span&gt;
	&lt;span class="Keyword"&gt;%&lt;/span&gt;tmp7.&lt;span class="Entity"&gt;i11&lt;/span&gt; &lt;span class="Keyword"&gt;=&lt;/span&gt; getelementptr i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;registers, i32 &lt;span class="Keyword"&gt;%&lt;/span&gt;tmp5.&lt;span class="Entity"&gt;i10&lt;/span&gt;		;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=1]&lt;/span&gt;
	&lt;span class="Keyword"&gt;%&lt;/span&gt;tmp8.&lt;span class="Entity"&gt;i&lt;/span&gt; &lt;span class="Keyword"&gt;=&lt;/span&gt; load i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;tmp7.&lt;span class="Entity"&gt;i11&lt;/span&gt;, align &lt;span class="Constant"&gt;4&lt;/span&gt;		;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=1]&lt;/span&gt;
	&lt;span class="Keyword"&gt;%&lt;/span&gt;tmp10.&lt;span class="Entity"&gt;i&lt;/span&gt; &lt;span class="Keyword"&gt;=&lt;/span&gt; getelementptr i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;tmp3, i32 &lt;span class="Constant"&gt;3&lt;/span&gt;		;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=1]&lt;/span&gt;
	&lt;span class="Keyword"&gt;%&lt;/span&gt;tmp11.&lt;span class="Entity"&gt;i&lt;/span&gt; &lt;span class="Keyword"&gt;=&lt;/span&gt; load i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;tmp10.&lt;span class="Entity"&gt;i&lt;/span&gt;, align &lt;span class="Constant"&gt;4&lt;/span&gt;		;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=1]&lt;/span&gt;
	&lt;span class="Keyword"&gt;%&lt;/span&gt;tmp12.&lt;span class="Entity"&gt;i&lt;/span&gt; &lt;span class="Keyword"&gt;=&lt;/span&gt; add i32 &lt;span class="Keyword"&gt;%&lt;/span&gt;tmp11.&lt;span class="Entity"&gt;i&lt;/span&gt;, &lt;span class="Keyword"&gt;%&lt;/span&gt;tmp8.&lt;span class="Entity"&gt;i&lt;/span&gt;		;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=1]&lt;/span&gt;
	&lt;span class="Keyword"&gt;%&lt;/span&gt;tmp14.&lt;span class="Entity"&gt;i&lt;/span&gt; &lt;span class="Keyword"&gt;=&lt;/span&gt; getelementptr i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;registers, i32 &lt;span class="Keyword"&gt;%&lt;/span&gt;tmp2.&lt;span class="Entity"&gt;i8&lt;/span&gt;		;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=1]&lt;/span&gt;
	store i32 &lt;span class="Keyword"&gt;%&lt;/span&gt;tmp12.&lt;span class="Entity"&gt;i&lt;/span&gt;, i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;tmp14.&lt;span class="Entity"&gt;i&lt;/span&gt;, align &lt;span class="Constant"&gt;4&lt;/span&gt;
	&lt;span class="Keyword"&gt;%&lt;/span&gt;tmp31 &lt;span class="Keyword"&gt;=&lt;/span&gt; getelementptr i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;ops, i32 &lt;span class="Constant"&gt;4&lt;/span&gt;		;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=1]&lt;/span&gt;
	&lt;span class="Keyword"&gt;%&lt;/span&gt;tmp1.&lt;span class="Entity"&gt;i2&lt;/span&gt; &lt;span class="Keyword"&gt;=&lt;/span&gt; getelementptr i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;tmp31, i32 &lt;span class="Constant"&gt;1&lt;/span&gt;		;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=1]&lt;/span&gt;
	&lt;span class="Keyword"&gt;%&lt;/span&gt;tmp2.&lt;span class="Entity"&gt;i3&lt;/span&gt; &lt;span class="Keyword"&gt;=&lt;/span&gt; load i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;tmp1.&lt;span class="Entity"&gt;i2&lt;/span&gt;, align &lt;span class="Constant"&gt;4&lt;/span&gt;		;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=1]&lt;/span&gt;
	&lt;span class="Keyword"&gt;%&lt;/span&gt;tmp4.&lt;span class="Entity"&gt;i4&lt;/span&gt; &lt;span class="Keyword"&gt;=&lt;/span&gt; getelementptr i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;registers, i32 &lt;span class="Keyword"&gt;%&lt;/span&gt;tmp2.&lt;span class="Entity"&gt;i3&lt;/span&gt;		;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=1]&lt;/span&gt;
	&lt;span class="Keyword"&gt;%&lt;/span&gt;tmp5.&lt;span class="Entity"&gt;i5&lt;/span&gt; &lt;span class="Keyword"&gt;=&lt;/span&gt; load i32&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt;tmp4.&lt;span class="Entity"&gt;i4&lt;/span&gt;, align &lt;span class="Constant"&gt;4&lt;/span&gt;		;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=1]&lt;/span&gt;
	&lt;span class="Keyword"&gt;%&lt;/span&gt;tmp7.&lt;span class="Entity"&gt;i6&lt;/span&gt; &lt;span class="Keyword"&gt;=&lt;/span&gt; call i32 (i8&lt;span class="Keyword"&gt;*&lt;/span&gt;, ...)&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Variable"&gt;&lt;span class="Variable"&gt;@&lt;/span&gt;printf&lt;/span&gt;( i8&lt;span class="Keyword"&gt;*&lt;/span&gt; getelementptr ([&lt;span class="Constant"&gt;7&lt;/span&gt; x i8]&lt;span class="Keyword"&gt;*&lt;/span&gt; @.&lt;span class="Entity"&gt;str&lt;/span&gt;, i32 &lt;span class="Constant"&gt;0&lt;/span&gt;, i32 &lt;span class="Constant"&gt;0&lt;/span&gt;), i32 &lt;span class="Keyword"&gt;%&lt;/span&gt;tmp5.&lt;span class="Entity"&gt;i5&lt;/span&gt; ) nounwind 		;  [&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;uses=0]&lt;/span&gt;
	ret void
}
=&amp;gt; &lt;span class="Constant"&gt;7&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;对，函数被LLVM给Inline化了，强吧！Evan称之为使用核能做饭，呵呵。&lt;/p&gt;
&lt;p&gt;嗯，的确是很趣，那么我们从中又能学到什么呢？使用LLVM强大的中间层基础设施，可以为rubinius的bc执行带来强大的JIT功能。至于rubinius真的是怎样做到，让我读读rubinius的代码之后再接着谈吧:)&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://leeseon.com/">
    <author>
      <name>leeseon</name>
    </author>
    <id>tag:leeseon.com,2008-09-06:28</id>
    <published>2008-09-06T18:50:00Z</published>
    <updated>2008-10-07T14:08:51Z</updated>
    <category term="dreamhost" />
    <category term="leeseon" />
    <category term="promo code" />
    <link href="http://leeseon.com/2008/9/6/dreamhost_promo_code_leeseon" rel="alternate" type="text/html" />
    <title>做下广告吧Promo Code: LEESEON</title>
<content type="html">
            &lt;p&gt;无意间发现&lt;a href="http://www.dreamhost.com/r.cgi?282910"&gt;DreamHost&lt;/a&gt; 最近在搞优惠活动，凡是在9月10号之前注册的用户，都能享受无限的(之前是500G)磁盘空间与无限的带宽(之前是5T)。呵呵，其实这当然是有一点噱头的成份在里面，毕竟500G与5T(每周都会涨的)我是根本没有用完过，不过如果你认为你一定能用完，或者你梦想远大，或者只为了YY，那你可以赶紧注册一个噢!&lt;/p&gt;


	&lt;p&gt;当然当然最重要的就是，呵呵，使用我的PROMO &lt;span class="caps"&gt;CODE&lt;/span&gt;：&lt;strong&gt;&lt;span class="caps"&gt;LEESEON&lt;/span&gt;&lt;/strong&gt; 噢，这个是能打折滴，以前是$97，现在也就只有$50了，看来老外滑头起来也是不差的&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://www.slide.com/s/7XR8siYX7j9pX-H9gIIpX48muIiuRz1-?referrer=hlnk"&gt;&lt;img title="免费无限存放图片在slide.com!" src="http://widget.slide.com/rdr/1/1/1/W/2500000003fc4baa/1/118/dGJLfAwY3D9FeEigRy1f-cnKep93ZREK.jpg" alt="免费无限存放图片在slide.com!" /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;自然自然无利不起早嘛，听说使用我的Promo Code我是能赚钱滴—俺从来没有拿到过:(,不过还是要佩服一下这种有点象传销一般的病毒式商业运作方式&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://leeseon.com/">
    <author>
      <name>leeseon</name>
    </author>
    <id>tag:leeseon.com,2008-09-06:27</id>
    <published>2008-09-06T15:28:00Z</published>
    <updated>2008-09-06T17:45:56Z</updated>
    <category term="edge rails" />
    <category term="mephisto" />
    <category term="mephisto 0.8" />
    <link href="http://leeseon.com/2008/9/6/mephisto0-8_error_maybe_from_edge_rails" rel="alternate" type="text/html" />
    <title>mephisto0.8出错了:(</title>
<content type="html">
            &lt;p&gt;好久没有写blog了，最近才发现游戏公司忙起来还真的不是一般的忙，现在对那著名的“对EA的血泪控诉”也开始是感同身受了啊，唉!&lt;/p&gt;


&lt;p&gt;好在最近闲下来了一点，而且发现自己的gmail里面堆满了从dreamhost发过来的Cron Daemon的错误提示，提示我mephisto的/admin出错了。&lt;/p&gt;


&lt;p&gt;本来没有当回事，估计是因为dreamhost的rails升级到2.1.0引起的，当时我使用mephisto0.8，因为正好系统中有rails 2.0.2一时偷懒没有将rails freeze起来，心想应该freeze一下就没有问题了。二话不说，开工，运行&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;
rake rails:freeze:gems VERSION=2.0.2
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;本以为重启一下服务就能好了，谁知出了一堆错，提示我 “undefined method ‘install_gem_spec_stubs’”&lt;/p&gt;

&lt;p&gt;查了一下文档，不对啊，install_gem_spec_stubs可是rails2.1.0中的函数啊，怎么会出现在mephisto 0.8之中，怪啊，不过即然如此，拿2.0.2试试便知，运行&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;
rails _2.0.2_ testrails
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;打开config/boot.rb看了看，根本不用比较工具就能发现mephisto0.8的文件中的确是多出一行，注掉即可&lt;/p&gt;

&lt;pre class="blackboard"&gt;  &lt;span class="Keyword"&gt;class&lt;/span&gt; &lt;span class="Entity"&gt;VendorBoot&lt;span class="Superclass"&gt; &lt;span class="Superclass"&gt;&amp;lt;&lt;/span&gt; Boot&lt;/span&gt;&lt;/span&gt;
    &lt;span class="Keyword"&gt;def&lt;/span&gt; &lt;span class="Entity"&gt;load_initializer&lt;/span&gt;
      &lt;span class="Keyword"&gt;require&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;&lt;span class="String"&gt;#{&lt;/span&gt;&lt;span class="Variable"&gt;RAILS_ROOT&lt;/span&gt;&lt;span class="String"&gt;}&lt;/span&gt;&lt;/span&gt;/vendor/rails/railties/lib/initializer&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class="Comment"&gt;      &lt;span class="Comment"&gt;#&lt;/span&gt;Rails::Initializer.run(:install_gem_spec_stubs)&lt;/span&gt;
    &lt;span class="Keyword"&gt;end&lt;/span&gt;
  &lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;想想，可能是因为使用edge rails来生成的mephisto 0.8的原始文件的吧&lt;/p&gt;
          </content>  </entry>
</feed>
