第一章先開個頭
看不明白的話也不要緊,下一章將從怎麼編譯介紹起。
源**閱讀貴在堅持,當然有乙個好工具也是必要的。
推薦大家使用source insight ,這是乙個非常好用的東西。
不管是閱讀還是寫c/c++/c#的**,使用它都會感覺非常爽!
今天開始閱讀,因為是開頭,所以選擇乙個簡單的檔案--etc/min.c
作為開始,但是並不限於這個檔案,我們還會發散到其他檔案中。
//這段**實現了乙個非常簡單的lua的直譯器
int main(void)
這些很簡單吧,需要住意的就是lual_dofile()函式,當引數2為null時,自動開啟stdin。
if (filename == null)
#define lua_pushliteral(l, s) /
lua_pushlstring(l, "" s, (sizeof(s)/sizeof(char))-1)//這裡的引數3的值是6。
這個函式需要特別注意:
lua的string的概念和c的定義不同,c的字串不能中間含有0x0,但是lua的字串可以。
這裡的sizeof(s)是特別需要注意的,這裡是c語言的sizeof對乙個字元陣列求值,所以字元陣列被看作是
按照0x0結尾的字串來數數並且加上1!恐怖吧!
這也是為什麼把字串的長度暴露給呼叫者的原因,當需要傳入中間含有0x0的字串的時候,使用者可以手動
寫乙個求長度的函式,而不是使用sizeof操作符。
#define lual_dofile(l, fn) /
(lual_loadfile(l, fn) || lua_pcall(l, 0, lua_multret, 0))
好!接下來,讓我們看看lual_loadfile()函式。
lualib_api int lual_loadfile (lua_state *l, const char *filename) loadf;
loadf lf;
int status, readstatus;
int c;
int fnameindex = lua_gettop(l) + 1; /* index of filename on the stack */
lf.extraline = 0;
if (filename == null)
else
c = getc(lf.f);//獲取檔案中乙個字元,並返回乙個字元。
if (c == '#')
//預編譯檔案標識
///* mark for precompiled code (`lua') */
//#define lua_signature "/033lua"
if (c == lua_signature[0] && lf.f != stdin)
ungetc(c, lf.f);//回顯字元
status = lua_load(l, getf, &lf, lua_tostring(l, -1));//讀入檔案
readstatus = ferror(lf.f);
if (lf.f != stdin) fclose(lf.f); /* close file (even in case of errors) */
if (readstatus)
lua_remove(l, fnameindex);
return status;
}lua_api int lua_load (lua_state *l, lua_reader reader, void *data,
const char *chunkname) ;
int status;
lua_lock(l);//加鎖#define lua_lock(l) ((void) 0)
//因為lua內部實際上沒有多執行緒,所以不需要加鎖解鎖
if (!chunkname) chunkname = "?";
luaz_init(l, &z, reader, data);//初始化zio結構體,輔助描述lua_reader物件
status = luad_protectedparser(l, &z, chunkname);//執行
lua_unlock(l);//解鎖#define lua_unlock(l) ((void) 0)
return status;
}int luad_protectedparser (lua_state *l, zio *z, const char *name)
int luad_pcall (lua_state *l, pfunc func, void *u,
ptrdiff_t old_top, ptrdiff_t ef)
l->errfunc = old_errfunc;
return status;
}注意:
int luad_rawrunprotected (lua_state *l, pfunc f, void *ud)
下面是讓人佩服的地方,雖然
lua是用
pure c
書寫,但是還是不忘為
c++的異常作了特別的優化。
/*
@@ luai_throw/luai_try define how lua does exception handling.
** change them if you prefer to use longjmp/setjmp even with c++
** or if want/don't to use _longjmp/_setjmp instead of regular
** longjmp/setjmp. by default, lua handles errors with exceptions when
** compiling as c++ code, with _longjmp/_setjmp when asked to use them,
** and with longjmp/setjmp otherwise.
*/#if defined(__cplusplus)//使用此定義的時候,c++異常必須開啟
/* c++ exceptions */
#define luai_throw(l,c) throw(c)
#define luai_try(l,c,a) try catch(...) /
#define luai_jmpbuf int /* dummy variable */
#elif defined(lua_use_ulongjmp)
/* in unix, try _longjmp/_setjmp (more efficient) */
#define luai_throw(l,c) _longjmp((c)->b, 1)
#define luai_try(l,c,a) if (_setjmp((c)->b) == 0)
#define luai_jmpbuf jmp_buf
#else
/* default handling with long jumps */
#define luai_throw(l,c) longjmp((c)->b, 1)
#define luai_try(l,c,a) if (setjmp((c)->b) == 0)
#define luai_jmpbuf jmp_buf
#endif
順便說一下,luajit裡面保留了同樣的定義。
/* chain list of long jump buffers */
struct lua_longjmp ;
在來看乙個函式:
static void restore_stack_limit (lua_state *l)
}
/*
** `per thread' state
*/struct lua_state ;
好吧,好像都很模糊,沒有關係,剛開始就是這樣。
JUnit5 整合指南
junit之前的版本是乙個整體,而junit5與其不同,它是由幾個不同的模組組成,而這些模組分別來自三個不同的子專案中。在官方文件中,給出了這麼乙個junit5的等式 junit 5 junit platform junit jupiter junit vintage junit jupiter 是...
struts1整合ajax技術
1.寫乙個繼承actionservlet的類a。在該類a中重寫httpservlet的service方法,然後呼叫actionservlet中的process方法,然後從requst中得到要返回給前台的值value,如果不為空,則用response.getwriter print value 2.修...
HBASE高階(6) 整合 1 與Hive的整合
1 hive 1 資料倉儲 hive的本質其實就相當於將hdfs中已經儲存的檔案在mysql中做了乙個雙射關係,以方便使用hql去管理查詢。2 用於資料分析 清洗 hive適用於離線的資料分析和清洗,延遲較高。3 基於hdfs mapreduce hive儲存的資料依舊在datanode上,編寫的h...