亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

第二人生的源碼分析(112)腳本的綜合分析(2)

系統(tǒng) 1920 0
?

前面介紹了分析腳本類的聲明,下面來仔細(xì)地分析它的實(shí)現(xiàn)代碼,理解它的實(shí)現(xiàn)過程,也就理解了腳本代碼的編譯過程,如下:

?

返回生成的代碼大小為 0.

#001 ? S32 LLScriptScript::getSize()

#002 ? {

#003 ? ?? return 0;

#004 ? }

#005 ?

?

腳本類的構(gòu)造函數(shù),主要進(jìn)行初始化的工作。

#006 ? LLScriptScript::LLScriptScript(LLScritpGlobalStorage *globals,

#007 ? ?????????????????????????? ??? LLScriptState *states) :

#008 ????? LLScriptFilePosition(0, 0),

#009 ? ?? mStates(states), mGlobalScope(NULL), mGlobals(NULL), mGlobalFunctions(NULL), mGodLike(FALSE)

#010 ? {

?

設(shè)置缺省生成字節(jié)碼的文件名稱。

#011 ? ?? const char DEFAULT_BYTECODE_FILENAME[] = "lscript.lso";

#012 ? ?? strncpy(mBytecodeDest, DEFAULT_BYTECODE_FILENAME, sizeof(mBytecodeDest) -1); /*Flawfinder: ignore*/

#013 ? ?? mBytecodeDest[MAX_STRING-1] = '/0';

?

下面開始分析全局變量和全局函數(shù)的保存位置。

#014 ? ?? LLScriptGlobalVariable ? *tvar;

#015 ? ?? LLScriptGlobalFunctions *tfunc;

#016 ? ?? LLScritpGlobalStorage *temp;

#017 ?

#018 ? ?? temp = globals;

#019 ? ?? while(temp)

#020 ? ?? {

#021 ? ?????? if (temp->mbGlobalFunction)

#022 ? ?????? {

#023 ? ?????????? if (!mGlobalFunctions)

#024 ? ?????????? {

#025 ? ?????????????? mGlobalFunctions = (LLScriptGlobalFunctions *)temp->mGlobal;

#026 ? ?????????? }

#027 ? ?????????? else

#028 ? ?????????? {

#029 ? ?????????????? tfunc = mGlobalFunctions;

#030 ? ?????????????? while(tfunc->mNextp)

#031 ? ?????????????? {

#032 ? ?????????????????? tfunc = tfunc->mNextp;

#033 ? ?????????????? }

#034 ? ?????????????? tfunc->mNextp = (LLScriptGlobalFunctions *)temp->mGlobal;

#035 ? ?????????? }

#036 ? ?????? }

#037 ? ?????? else

#038 ? ?????? {

#039 ? ?????????? if (!mGlobals)

#040 ? ?????????? {

#041 ? ?????????????? mGlobals = (LLScriptGlobalVariable *)temp->mGlobal;

#042 ? ?????????? }

#043 ? ?????????? else

#044 ? ?????????? {

#045 ? ?????????????? tvar = mGlobals;

#046 ? ?????????????? while(tvar->mNextp)

#047 ? ?????????????? {

#048 ? ?????????????????? tvar = tvar->mNextp;

#049 ? ?????????????? }

#050 ? ?????????????? tvar->mNextp = (LLScriptGlobalVariable *)temp->mGlobal;

#051 ? ?????????? }

#052 ? ?????? }

#053 ? ?????? temp = temp->mNextp;

#054 ? ?? }

#055 ? }

#056 ?

?

這個函數(shù)主要實(shí)現(xiàn)設(shè)置字節(jié)碼保存的文件名稱。

#057 ? void LLScriptScript::setBytecodeDest(const char* dst_filename)

#058 ? {

#059 ? ?? strncpy(mBytecodeDest, dst_filename, MAX_STRING); ? /*Flawfinder: ignore*/

#060 ? ?? mBytecodeDest[MAX_STRING-1] = '/0';

#061 ? }

#062 ?

?

#063 ? void print_cil_globals(FILE* fp, LLScriptGlobalVariable* global)

#064 ? {

#065 ? ?? fprintf(fp, ".field private ");

#066 ? ?? print_cil_type(fp, global->mType->mType);

#067 ? ?? fprintf(fp, " ");

#068 ? ?? fprintf(fp, global->mIdentifier->mName); ??????? /*Flawfinder: ignore*/

#069 ? ?? fprintf(fp, "/n");

#070 ? ?? if(NULL != global->mNextp)

#071 ? ?? {

#072 ? ?????? print_cil_globals(fp, global->mNextp);

#073 ? ?? }

#074 ? }

#075

?

開始遞歸處理所有腳本樹。

#076 ? void LLScriptScript::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type,

#077 ? LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)

#078 ? {

?

如果分析有出錯,就不再處理。

#079 ? ?? if (gErrorToText.getErrors())

#080 ? ?? {

#081 ? ?????? return;

#082 ? ?? }

?

根據(jù)不同的編譯遍來作不同的樹遍歷處理。

#083 ? ?? switch(pass)

#084 ? ?? {

?

輸出合適的說明文字。

#085 ? ?? case LSCP_PRETTY_PRINT:

#086 ? ?????? if (mGlobals)

#087 ? ?????? {

#088 ? ?????????? fdotabs(fp, tabs, tabsize);

#089 ? ?????????? mGlobals->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount,

#090 ? NULL);

#091 ? ?????? }

#092 ?

#093 ? ?????? if (mGlobalFunctions)

#094 ? ?????? {

#095 ? ?????????? fdotabs(fp, tabs, tabsize);

#096 ? ?????????? mGlobalFunctions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry,

#097 ? entrycount, NULL);

#098 ? ?????? }

#099 ?

#100 ? ?????? fdotabs(fp, tabs, tabsize);

#101 ? ?????? mStates->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);

#102 ? ?????? break;

?

進(jìn)行代碼優(yōu)化,主要刪除不需要的代碼。

#103 ? ?? case LSCP_PRUNE:

#104 ? ?????? if (mGlobalFunctions)

#105 ? ?????? {

#106 ? ?????????? mGlobalFunctions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry,

#107 ? entrycount, NULL);

#108 ? ?????? }

#109 ? ?????? mStates->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);

#110 ? ?????? break;

?

全局的作用域檢查。

#111 ? ?? case LSCP_SCOPE_PASS1:

#112 ? ?????? {

#113 ? ?????????? mGlobalScope = new LLScriptScope(gScopeStringTable);

#114 ? ?????????? // zeroth, add library functions to global scope

#115 ? ?????????? S32 i;

#116 ? ?????????? char *arg;

#117 ? ?????????? LLScriptScopeEntry *sentry;

#118 ? ?????????? for (i = 0; i < gScriptLibrary.mNextNumber; i++)

#119 ? ?????????? {

#120 ? ?????????????? // First, check to make sure this isn't a god only function, or that the viewer's agent is a god.

#121 ? ?????????????? if (!gScriptLibrary.mFunctions[i]->mGodOnly || mGodLike)

#122 ? ?????????????? {

#123 ? ?????????????????? if (gScriptLibrary.mFunctions[i]->mReturnType)

#124 ? ?????????????????????? sentry = mGlobalScope->addEntry(gScriptLibrary.mFunctions[i]->mName,

#125 ? LIT_LIBRARY_FUNCTION, char2type(*gScriptLibrary.mFunctions[i]->mReturnType));

#126 ? ?????????????????? else

#127 ? ?????????????????????? sentry = mGlobalScope->addEntry(gScriptLibrary.mFunctions[i]->mName,

#128 ? LIT_LIBRARY_FUNCTION, LST_NULL);

#129 ? ?????????????????? sentry->mLibraryNumber = i;

#130 ? ?????????????????? arg = gScriptLibrary.mFunctions[i]->mArgs;

#131 ? ?????????????????? if (arg)

#132 ? ?????????????????? {

#133 ? ?????????????????????? while (*arg)

#134 ? ?????????????????????? {

#135 ? ?????????????????????????? sentry->mFunctionArgs.addType(char2type(*arg));

#136 ? ?????????????????????????? sentry->mSize += LSCRIPTDataSize[char2type(*arg)];

#137 ? ?????????????????????????? sentry->mOffset += LSCRIPTDataSize[char2type(*arg)];

#138 ? ?????????????????????????? arg++;

#139 ? ?????????????????????? }

#140 ? ?????????????????? }

#141 ? ?????????????? }

#142 ? ?????????? }

#143 ? ?????????? // first go and collect all the global variables

#144 ? ?????????? if (mGlobals)

#145 ? ?????????????? mGlobals->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mGlobalScope, type, basetype, count, chunk, heap,

#146 ? stacksize, entry, entrycount, NULL);

#147 ? ?????????? // second, do the global functions

#148 ? ?????????? if (mGlobalFunctions)

#149 ? ?????????????? mGlobalFunctions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mGlobalScope, type, basetype, count, chunk, heap,

#150 ? stacksize, entry, entrycount, NULL);

#151 ? ?????????? // now do states

#152 ? ?????????? mStates->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mGlobalScope, type, basetype, count, chunk, heap, stacksize, entry,

#153 ? entrycount, NULL);

#154 ? ?????????? break;

#155 ? ?????? }

?

第二次作用域檢查,主要檢查跳轉(zhuǎn)、函數(shù)調(diào)用和狀態(tài)轉(zhuǎn)換。

#156 ? ?? case LSCP_SCOPE_PASS2:

#157 ? ?????? // now we're checking jumps, function calls, and state transitions

#158 ? ?????? if (mGlobalFunctions)

#159 ? ?????????? mGlobalFunctions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mGlobalScope, type, basetype, count, chunk, heap, stacksize, entry,

#160 ? entrycount, NULL);

#161 ? ?????? mStates->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mGlobalScope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);

#162 ? ?????? break;

?

對腳本的類型進(jìn)行檢查。

#163 ? ?? case LSCP_TYPE:

#164 ? ?????? // first we need to check global variables

#165 ? ?????? if (mGlobals)

#166 ? ?????????? mGlobals->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount,

#167 ? NULL);

#168 ? ?????? // now do global functions and states

#169 ? ?????? if (mGlobalFunctions)

#170 ? ?????????? mGlobalFunctions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry,

#171 ? entrycount, NULL);

#172 ? ?????? mStates->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);

#173 ? ?????? break;

?

確定所有腳本需的資源大小。

#174 ? ?? case LSCP_RESOURCE:

#175 ? ?????? // first determine resource counts for globals

#176 ? ?????? count = 0;

#177 ? ?????? if (mGlobals)

#178 ? ?????????? mGlobals->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount,

#179 ? NULL);

#180 ? ?????? // now do locals

#181 ? ?????? if (mGlobalFunctions)

#182 ? ?????????? mGlobalFunctions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry,

#183 ? entrycount, NULL);

#184 ? ?????? mStates->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);

#185 ? ?????? break;

?

輸出匯編代碼。

#186 ? ?? case LSCP_EMIT_ASSEMBLY:

#187 ?

#188 ? ?????? if (mGlobals)

#189 ? ?????? {

#190 ? ?????????? fprintf(fp, "GLOBALS/n");

#191 ? ?????????? fdotabs(fp, tabs, tabsize);

#192 ? ?????????? mGlobals->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount,

#193 ? NULL);

#194 ? ?????????? fprintf(fp, "/n");

#195 ? ?????? }

#196 ?

#197 ? ?????? if (mGlobalFunctions)

#198 ? ?????? {

#199 ? ?????????? fprintf(fp, "GLOBAL FUNCTIONS/n");

#200 ? ?????????? fdotabs(fp, tabs, tabsize);

#201 ? ?????????? mGlobalFunctions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry,

#202 ? entrycount, NULL);

#203 ? ?????????? fprintf(fp, "/n");

#204 ? ?????? }

#205 ?

#206 ? ?????? fprintf(fp, "STATES/n");

#207 ? ?????? fdotabs(fp, tabs, tabsize);

#208 ? ?????? mStates->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);

#209 ? ?????? fprintf(fp, "/n");

#210 ? ?????? break;

?

輸出虛擬機(jī)可以運(yùn)行的字節(jié)碼。

#211 ? ?? case LSCP_EMIT_BYTE_CODE:

#212 ? ?????? {

#213 ? ?????????? // first, create data structure to hold the whole shebang

#214 ? ?????????? LLScriptScriptCodeChunk *code = new LLScriptScriptCodeChunk(TOP_OF_MEMORY);

#215 ?

#216 ? ?????????? // ok, let's add the registers, all zeroes for now

#217 ? ?????????? S32 i;

#218 ? ?????????? S32 nooffset = 0;

#219 ?

#220 ? ?????????? for (i = LREG_IP; i < LREG_EOF; i++)

#221 ? ?????????? {

#222 ? ?????????????? if (i < LREG_NCE)

#223 ? ?????????????????? code->mRegisters->addBytes(4);

#224 ? ?????????????? else if (LSL2_CURRENT_MAJOR_VERSION == LSL2_MAJOR_VERSION_TWO)

#225 ? ?????????????????? code->mRegisters->addBytes(8);

#226 ? ?????????? }

#227 ? ?????????? // global variables

#228 ? ?????????? if (mGlobals)

#229 ? ?????????????? mGlobals->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, code->mGlobalVariables,

#230 ? code->mHeap, stacksize, entry, entrycount, NULL);

#231 ?

#232 ? ?????????? // put the ending heap block onto the heap

#233 ? ?????????? U8 *temp;

#234 ? ?????????? S32 size = lsa_create_data_block(&temp, NULL, 0);

#235 ? ?????????? code->mHeap->addBytes(temp, size);

#236 ? ?????????? delete [] temp;

#237 ?

#238 ? ?????????? // global functions

#239 ? ?????????? // make space for global function jump table

#240 ? ?????????? if (mGlobalFunctions)

#241 ? ?????????? {

#242 ? ?????????? code->mGlobalFunctions->addBytes(LSCRIPTDataSize[LST_INTEGER]*mGlobalScope->mFunctionCount +

#243 ? LSCRIPTDataSize[LST_INTEGER]);

#244 ? ?????????????? integer2bytestream(code->mGlobalFunctions->mCodeChunk, nooffset, mGlobalScope->mFunctionCount);

#245 ? ?????????????? mGlobalFunctions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, code-

#246 ? >mGlobalFunctions, NULL, stacksize, entry, entrycount, NULL);

#247 ? ?????????? }

#248 ?

#249 ?

#250 ? ?????????? nooffset = 0;

#251 ? ?????????? // states

#252 ? ?????????? // make space for state jump/info table

#253 ? ?????????? if (LSL2_CURRENT_MAJOR_VERSION == LSL2_MAJOR_VERSION_TWO)

#254 ? ?????????? {

#255 ? ?????????? code->mStates->addBytes(LSCRIPTDataSize[LST_INTEGER]*3*mGlobalScope->mStateCount + LSCRIPTDataSize

#256 ? [LST_INTEGER]);

#257 ? ?????????? }

#258 ? ?????????? else

#259 ? ?????????? {

#260 ? ?????????? code->mStates->addBytes(LSCRIPTDataSize[LST_INTEGER]*2*mGlobalScope->mStateCount + LSCRIPTDataSize

#261 ? [LST_INTEGER]);

#262 ? ?????????? }

#263 ? ?????????? integer2bytestream(code->mStates->mCodeChunk, nooffset, mGlobalScope->mStateCount);

#264 ? ?????????? mStates->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, code->mStates, NULL, stacksize, entry,

#265 ? entrycount, NULL);

#266 ?

#267 ? ?????????? // now, put it all together and spit it out

#268 ? ?????????? // we need

#269 ? ?????????? FILE* bcfp = LLFile::fopen(mBytecodeDest, "wb"); ??????? /*Flawfinder: ignore*/

#270 ? ??????????

#271 ? ?????????? code->build(fp, bcfp);

#272 ? ?????????? fclose(bcfp);

#273 ? ?????????????????????????????????? ???

#274 ? ?????????? delete code;

#275 ? ?????? }

#276 ? ?????? break;

?

輸出 CIL 的匯編代碼。

#277 ? ?? case LSCP_EMIT_CIL_ASSEMBLY:

#278 ?

#279 ? ?????? // Output dependencies.

#280 ? ?????? fprintf(fp, ".assembly extern mscorlib {.ver 1:0:5000:0}/n");

#281 ? ?????? fprintf(fp, ".assembly extern LScriptLibrary {.ver 0:0:0:0}/n");

#282 ?

#283 ? ?????? // Output assembly name.

#284 ? ?????? fprintf(fp, ".assembly 'lsl' {.ver 0:0:0:0}/n");

#285 ?

#286 ? ?????? // Output class header.

#287 ? ?????? fprintf(fp, ".class public auto ansi beforefieldinit LSL extends [mscorlib]System.Object/n");

#288 ? ?????? fprintf(fp, "{/n");

#289 ?

#290 ? ?????? // Output globals as members.

#291 ? ?????? if(NULL != mGlobals)

#292 ? ?????? {

#293 ? ?????????? print_cil_globals(fp, mGlobals);

#294 ? ?????? }

#295 ?

#296 ? ?????? // Output "runtime". Only needed to allow stand alone execution. Not needed when compiling to DLL and using embedded runtime.

#297 ? ?????? fprintf(fp, ".method public static ? hidebysig default void Main () ? cil managed/n");

#298 ? ?????? fprintf(fp, "{/n");

#299 ? ?????? fprintf(fp, ".entrypoint/n");

#300 ? ?????? fprintf(fp, ".maxstack 2/n");

#301 ? ?????? fprintf(fp, ".locals init (class LSL V_0)/n");

#302 ? ?????? fprintf(fp, "newobj instance void class LSL::.ctor()/n");

#303 ? ?????? fprintf(fp, "stloc.0/n");

#304 ? ?????? fprintf(fp, "ldloc.0/n");

#305 ? ?????? fprintf(fp, "callvirt instance void class LSL::defaultstate_entry()/n");

#306 ? ?????? fprintf(fp, "ret/n");

#307 ? ?????? fprintf(fp, "}/n");

#308 ?

#309 ? ?????? // Output ctor header.

#310 ? ?????? fprintf(fp, ".method public hidebysig ? specialname ? rtspecialname instance default void .ctor () ? cil managed/n");

#311 ? ?????? fprintf(fp, "{/n");

#312 ? ?????? fprintf(fp, ".maxstack 500/n");

#313 ?

#314 ? ?????? // Initialise globals as members in ctor.

#315 ? ?????? if (mGlobals)

#316 ? ?????? {

#317 ? ?????????? fdotabs(fp, tabs, tabsize);

#318 ? ?????????? mGlobals->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount,

#319 ? NULL);

#320 ? ?????????? fprintf(fp, "/n");

#321 ? ?????? }

#322 ?

#323 ? ?????? // Output ctor footer.

#324 ? ?????? fprintf(fp, "ldarg.0/n");

#325 ? ?????? fprintf(fp, "call instance void valuetype [mscorlib]System.Object::.ctor()/n");

#326 ? ?????? fprintf(fp, "ret/n");

#327 ? ?????? fprintf(fp, "}/n");

#328 ?

#329 ? ?????? // Output functions as methods.

#330 ? ?????? if (mGlobalFunctions)

#331 ? ?????? {

#332 ? ?????????? fdotabs(fp, tabs, tabsize);

#333 ? ?????????? mGlobalFunctions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry,

#334 ? entrycount, NULL);

#335 ? ?????????? fprintf(fp, "/n");

#336 ? ?????? }

#337 ?

#338 ? ?????? // Output states as name mangled methods.

#339 ? ?????? fdotabs(fp, tabs, tabsize);

#340 ? ?????? mStates->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);

#341 ? ?????? fprintf(fp, "/n");

#342 ?

#343 ? ?????? // Output class footer.

#344 ? ?????? fprintf(fp, "}/n");

#345 ?

#346 ? ?????? break;

?

下面進(jìn)行缺省的處理。

#347 ? ?? default:

#348 ? ?????? if (mGlobals)

#349 ? ?????????? mGlobals->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount,

#350 ? NULL);

#351 ? ?????? if (mGlobalFunctions)

#352 ? ?????????? mGlobalFunctions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry,

#353 ? entrycount, NULL);

#354 ? ?????? mStates->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);

#355 ? ?????? break;

#356 ? ?? }

#357 ? }

#358 ?

?

通過上面的代碼,看到對腳本代碼完整的分析過程,其實(shí)它是依照下面的狀態(tài)來進(jìn)行不同的階段處理的,如下:

#001 ? typedef enum e_lscript_compile_pass

#002 ? {

?

非法編譯狀態(tài)。

#003 ? ?? LSCP_INVALID,

?

輸出合適的說明文字

#004 ? ?? LSCP_PRETTY_PRINT,

?

進(jìn)行代碼化減和優(yōu)化。

#005 ? ?? LSCP_PRUNE,

?

對腳本代碼進(jìn)行全局的作用域檢查。

#006 ? ?? LSCP_SCOPE_PASS1,

?

對腳本代碼進(jìn)行跳轉(zhuǎn)等作用域檢查。

#007 ? ?? LSCP_SCOPE_PASS2,

?

對腳本代碼進(jìn)行類型檢查。

#008 ? ?? LSCP_TYPE,

?

對腳本代碼進(jìn)行需要的資源分配。

#009 ? ?? LSCP_RESOURCE,

?

對腳本代碼進(jìn)行匯編輸出處理。

#010 ? ?? LSCP_EMIT_ASSEMBLY,

?

對腳本代碼進(jìn)行字節(jié)碼編譯輸出。

#011 ? ?? LSCP_EMIT_BYTE_CODE,

?

對腳本代碼進(jìn)行事件處理計(jì)數(shù)。

#012 ? ?? LSCP_DETERMINE_HANDLERS,

?

輸出 LIB 數(shù)據(jù)。

#013 ? ?? LSCP_LIST_BUILD_SIMPLE,

?

對于棧進(jìn)行處理。

#014 ? ?? LSCP_TO_STACK,

?

函數(shù)聲明參數(shù)處理。

#015 ? ?? LSCP_BUILD_FUNCTION_ARGS,

?

對腳本代碼進(jìn)行 CIL 匯編輸出。

#016 ? ?? LSCP_EMIT_CIL_ASSEMBLY,

?

腳本處理結(jié)束狀態(tài)。

#017 ? ?? LSCP_EOF

#018 ? } LSCRIPTCompilePass;

?

因此一個腳本代碼需要經(jīng)過上面 13 種的組合分析,才會真正地處理完腳本的編譯,這是一個非常復(fù)雜漫長的過程。

?

第二人生的源碼分析(112)腳本的綜合分析(2)


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 国产精品免费aⅴ片在线观看 | 久久爱www人成 | 四虎免费看黄 | 天天舔天天射天天干 | 国产在线小视频 | 成人私人影院www片免费高清 | www国产视频 | 国产精品日韩欧美久久综合 | 亚洲综合精品香蕉久久网 | 午夜国产福利在线 | 91色爱| 久久日韩 | 毛片一级免费 | 欧美成人在线观看 | 黄色日比视频 | 国产日韩欧美成人 | 性欧美日韩 | 国产高清国产精品国产k | 国产高清在线精品一区二区三区 | 欧美性猛交xxxxx按摩欧美 | 99久久精品免费看国产高清 | 日本色综合| 13一14周岁毛片免费 | 一级片短视频 | 婷婷国产偷v国产偷v亚洲 | 成年激情网 | 国产精品一区二区三区久久 | 亚洲国产系列久久精品99人人 | 欧洲国产伦久久久久久久 | 亚洲欧美日韩国产精品影院 | 国产福利免费 | 欧美日韩国产一区二区三区播放 | 久久精品国产无限资源 | 毛片网站在线 | 波多野结衣 久久 | 日本一级淫片a免费播放 | 亚洲不卡一区二区三区在线 | 四虎影院免费在线播放 | 波多野吉衣一区二区三区在线观看 | 九九九九九热 | 狠狠狠地在啪线香蕉 |