void fxWriteScriptHosts(txLinkerScript* script, FILE* file) { txByte* p = script->hostsBuffer; if (p) { txID c, i, id; mxDecode2(p, c); fprintf(file, "void xsHostModule%d(xsMachine* the)\n", script->scriptIndex); fprintf(file, "{\n"); fprintf(file, "\tstatic const xsHostBuilder builders[%d] = {\n", c); for (i = 0; i < c; i++) { txS1 length = *p++; mxDecode2(p, id); if (id != XS_NO_ID) id &= 0x7FFF; if (length < 0) fprintf(file, "\t\t{ (xsCallback)%s, -1, -1 },\n", p); else fprintf(file, "\t\t{ %s, %d, %d },\n", p, length, id); p += c_strlen((char*)p) + 1; } fprintf(file, "\t};\n"); fprintf(file, "\txsResult = xsBuildHosts(%d, (xsHostBuilder*)builders);\n", c); fprintf(file, "}\n\n"); } }
void xscBuildSymbolsID(txMachine* the, xsSymbolsData* theData, txByte* theCode) { txID anIndex; txSlot* aSymbol; txSize aModulo; txSlot* result; mxDecode2(theCode, anIndex); if ((aSymbol = fxGetSymbol(the, anIndex))) { aModulo = aSymbol->value.symbol.sum % theData->symbolModulo; result = theData->symbolTable[aModulo]; while (result != C_NULL) { if (result->value.symbol.sum == aSymbol->value.symbol.sum) if (result->value.symbol.string == aSymbol->value.symbol.string) break; result = result->next; } if (result == C_NULL) { anIndex = theData->symbolIndex; result = c_malloc(sizeof(txSlot)); xsElseError(result); result->next = theData->symbolTable[aModulo]; result->flag = XS_NO_FLAG; result->kind = XS_SYMBOL_KIND; result->ID = 0x8000 | anIndex; result->value.symbol.sum = aSymbol->value.symbol.sum; result->value.symbol.string = aSymbol->value.symbol.string; theData->symbolArray[anIndex] = result; theData->symbolTable[aModulo] = result; theData->symbolIndex++; } theCode -= 2; mxEncode2(theCode, result->ID); } }
void fxMapCode(txLinker* linker, txLinkerScript* script, txID* theIDs) { register const txS1* sizes = gxCodeSizes; register txByte* p = script->codeBuffer; register txByte* q = p + script->codeSize; register txS1 offset; txU1 code; txU2 index; txID id; while (p < q) { code = *((txU1*)p); if (XS_CODE_CODE_1 == code) *((txU1*)p) = code = XS_CODE_CODE_ARCHIVE_1; else if (XS_CODE_CODE_2 == code) *((txU1*)p) = code = XS_CODE_CODE_ARCHIVE_2; else if (XS_CODE_CODE_4 == code) *((txU1*)p) = code = XS_CODE_CODE_ARCHIVE_4; if (XS_CODE_STRING_1 == code) *((txU1*)p) = code = XS_CODE_STRING_ARCHIVE_1; else if (XS_CODE_STRING_2 == code) *((txU1*)p) = code = XS_CODE_STRING_ARCHIVE_2; offset = sizes[code]; if (0 < offset) p += offset; else if (0 == offset) { p++; mxDecode2(p, id); if (id != XS_NO_ID) { id &= 0x7FFF; id = theIDs[id]; p -= 2; mxEncode2(p, id); } } else if (-1 == offset) { p++; index = *((txU1*)p); p += 1 + index; } else if (-2 == offset) { p++; mxDecode2(p, index); p += index; } } }
void fxMapHosts(txLinker* linker, txLinkerScript* script, txID* theIDs) { txByte* p = script->hostsBuffer; if (p) { txID c, i, id; mxDecode2(p, c); for (i = 0; i < c; i++) { p++; mxDecode2(p, id); if (id != XS_NO_ID) { id = theIDs[id]; p -= 2; mxEncode2(p, id); } p += c_strlen((char*)p) + 1; } linker->hostsCount += c; } }
void fxWriteScriptExterns(txLinkerScript* script, FILE* file) { txByte* p = script->hostsBuffer; if (p) { txID c, i; mxDecode2(p, c); for (i = 0; i < c; i++) { txS1 length = *p++; p += 2; if (length < 0) fprintf(file, "extern void %s(void* data);\n", p); else fprintf(file, "extern void %s(xsMachine* the);\n", p); p += c_strlen((char*)p) + 1; } } }
static void fxDumpCode(txS1* path, txS1** symbols, txUsage* usages, txS1** hosts, txS1* codeBuffer, size_t codeSize) { txS1* p = codeBuffer; txS1* q = codeBuffer + codeSize; txS1 s1; txS2 s2; txS4 s4; txU1 u1; txU2 u2; double number; while (p < q) { u1 = *((txU1*)p); fprintf(stderr, "%8.8X: %d %s ", p - codeBuffer, u1, gxCodeNames[u1]); p++; switch (u1) { case XS_CODE_BRANCH_1: case XS_CODE_BRANCH_ELSE_1: case XS_CODE_BRANCH_IF_1: case XS_CODE_BRANCH_STATUS_1: case XS_CODE_CATCH_1: case XS_CODE_CODE_1: case XS_CODE_CODE_ARCHIVE_1: s1 = *p++; fprintf(stderr, "%8.8X", p + s1 - codeBuffer); break; case XS_CODE_BRANCH_2: case XS_CODE_BRANCH_ELSE_2: case XS_CODE_BRANCH_IF_2: case XS_CODE_BRANCH_STATUS_2: case XS_CODE_CATCH_2: case XS_CODE_CODE_2: case XS_CODE_CODE_ARCHIVE_2: mxDecode2(p, s2); fprintf(stderr, "%8.8X", p + s2 - codeBuffer); break; case XS_CODE_BRANCH_4: case XS_CODE_BRANCH_ELSE_4: case XS_CODE_BRANCH_IF_4: case XS_CODE_BRANCH_STATUS_4: case XS_CODE_CATCH_4: case XS_CODE_CODE_4: case XS_CODE_CODE_ARCHIVE_4: mxDecode4(p, s4); fprintf(stderr, "%8.8X", p + s4 - codeBuffer); break; case XS_CODE_ARROW: case XS_CODE_FILE: case XS_CODE_FUNCTION: case XS_CODE_GENERATOR: case XS_CODE_METHOD: case XS_CODE_NAME: mxDecode2(p, s2); if (s2 == XS_NO_ID) fprintf(stderr, "?"); else if (symbols) { s2 &= 0x7FFF; usages[s2].debug++; fprintf(stderr, "%s", symbols[s2]); } else fprintf(stderr, "%d", s2); break; case XS_CODE_CONST_GLOBAL: case XS_CODE_DELETE_EVAL: case XS_CODE_DELETE_GLOBAL: case XS_CODE_DELETE_PROPERTY: case XS_CODE_DELETE_SUPER: case XS_CODE_GET_EVAL: case XS_CODE_GET_GLOBAL: case XS_CODE_GET_PROPERTY: case XS_CODE_GET_SUPER: case XS_CODE_LET_GLOBAL: case XS_CODE_NEW_EVAL: case XS_CODE_NEW_GLOBAL: case XS_CODE_SET_EVAL: case XS_CODE_SET_GLOBAL: case XS_CODE_SET_PROPERTY: case XS_CODE_SET_SUPER: case XS_CODE_SYMBOL: mxDecode2(p, s2); if (s2 == XS_NO_ID) fprintf(stderr, "?"); else if (symbols) { s2 &= 0x7FFF; usages[s2].property++; fprintf(stderr, "%s", symbols[s2]); } else fprintf(stderr, "%d", s2); break; case XS_CODE_NEW_CLOSURE: case XS_CODE_NEW_LOCAL: mxDecode2(p, s2); if (s2 == XS_NO_ID) fprintf(stderr, "?"); else if (symbols) { s2 &= 0x7FFF; usages[s2].variable++; fprintf(stderr, "%s", symbols[s2]); } else fprintf(stderr, "%d", s2); break; case XS_CODE_NEW_PROPERTY: u1 = *((txU1*)p++); if (u1 & XS_DONT_DELETE_FLAG) fprintf(stderr, "C"); else fprintf(stderr, "c"); if (u1 & XS_DONT_ENUM_FLAG) fprintf(stderr, "E"); else fprintf(stderr, "e"); if (u1 & XS_DONT_SET_FLAG) fprintf(stderr, "W"); else fprintf(stderr, "w"); if (u1 & XS_METHOD_FLAG) fprintf(stderr, "method"); if (u1 & XS_GETTER_FLAG) fprintf(stderr, " getter"); if (u1 & XS_SETTER_FLAG) fprintf(stderr, " setter"); break; case XS_CODE_ARGUMENT: case XS_CODE_ARGUMENTS: case XS_CODE_ARGUMENTS_SLOPPY: case XS_CODE_ARGUMENTS_STRICT: case XS_CODE_BEGIN_SLOPPY: case XS_CODE_BEGIN_STRICT: case XS_CODE_BEGIN_STRICT_BASE: case XS_CODE_BEGIN_STRICT_DERIVED: u1 = *((txU1*)p++); fprintf(stderr, "%d", u1); break; case XS_CODE_LINE: mxDecode2(p, u2); fprintf(stderr, "%d", u2); break; case XS_CODE_RESERVE_1: case XS_CODE_RETRIEVE_1: case XS_CODE_UNWIND_1: u1 = *((txU1*)p++); fprintf(stderr, "#%d", u1); break; case XS_CODE_RESERVE_2: case XS_CODE_RETRIEVE_2: case XS_CODE_UNWIND_2: mxDecode2(p, u2); fprintf(stderr, "#%d", u2); break; case XS_CODE_CONST_CLOSURE_1: case XS_CODE_CONST_LOCAL_1: case XS_CODE_DELETE_CLOSURE_1: case XS_CODE_DELETE_LOCAL_1: case XS_CODE_GET_CLOSURE_1: case XS_CODE_GET_LOCAL_1: case XS_CODE_LET_CLOSURE_1: case XS_CODE_LET_LOCAL_1: case XS_CODE_PULL_CLOSURE_1: case XS_CODE_PULL_LOCAL_1: case XS_CODE_REFRESH_CLOSURE_1: case XS_CODE_REFRESH_LOCAL_1: case XS_CODE_RESET_CLOSURE_1: case XS_CODE_RESET_LOCAL_1: case XS_CODE_SET_CLOSURE_1: case XS_CODE_SET_LOCAL_1: case XS_CODE_STORE_1: u1 = *((txU1*)p++); fprintf(stderr, "[%d]", u1 - 2); break; case XS_CODE_CONST_CLOSURE_2: case XS_CODE_CONST_LOCAL_2: case XS_CODE_DELETE_CLOSURE_2: case XS_CODE_DELETE_LOCAL_2: case XS_CODE_GET_CLOSURE_2: case XS_CODE_GET_LOCAL_2: case XS_CODE_LET_CLOSURE_2: case XS_CODE_LET_LOCAL_2: case XS_CODE_PULL_CLOSURE_2: case XS_CODE_PULL_LOCAL_2: case XS_CODE_REFRESH_CLOSURE_2: case XS_CODE_REFRESH_LOCAL_2: case XS_CODE_RESET_CLOSURE_2: case XS_CODE_RESET_LOCAL_2: case XS_CODE_SET_CLOSURE_2: case XS_CODE_SET_LOCAL_2: case XS_CODE_STORE_2: mxDecode2(p, u2); fprintf(stderr, "[%d]", u2 - 2); break; case XS_CODE_INTEGER_1: s1 = *p++; fprintf(stderr, "%d", s1); break; case XS_CODE_INTEGER_2: mxDecode2(p, s2); fprintf(stderr, "%d", s2); break; case XS_CODE_INTEGER_4: mxDecode4(p, s4); fprintf(stderr, "%ld", s4); break; case XS_CODE_NUMBER: mxDecode8(p, number); fprintf(stderr, "%lf", number); break; case XS_CODE_STRING_1: case XS_CODE_STRING_ARCHIVE_1: u1 = *((txU1*)p++); fprintf(stderr, "\"%s\"", p); p += u1; break; case XS_CODE_STRING_2: case XS_CODE_STRING_ARCHIVE_2: mxDecode2(p, u2); fprintf(stderr, "\"%s\"", p); p += u2; break; case XS_CODE_HOST: mxDecode2(p, u2); if (hosts) fprintf(stderr, "%s", hosts[u2]); else fprintf(stderr, "[%d]", u2); break; } fprintf(stderr, "\n"); } }
void xscBuildSymbolsCode(txMachine* the, xsSymbolsData* theData, txByte* theCode) { txID aCount; for (;;) { // if (((XS_LABEL <= *((txU1*)theCode)) && (*((txU1*)theCode) < XS_COUNT))) // fprintf(stderr, "%s\n", gxCodeNames[*((txU1*)theCode)]); // else // fprintf(stderr, "%d\n", *((txU1*)theCode)); switch (*((txU1*)theCode++)) { case XS_LABEL: return; case XS_BEGIN: xscBuildSymbolsID(the, theData, theCode); theCode += 3; aCount = *theCode++; while (aCount) { xscBuildSymbolsID(the, theData, theCode); theCode += 2; aCount--; } aCount = *theCode++; while (aCount) { xscBuildSymbolsID(the, theData, theCode); theCode += 2; aCount--; } break; case PSEUDO_INCREMENT: case PSEUDO_DECREMENT: case XS_DELETE_AT: case XS_GET_AT: case PSEUDO_BRANCH_ELSE0: case PSEUDO_BRANCH_ELSE1: case PSEUDO_LESS: case PSEUDO_LESS_EQUAL: case PSEUDO_DOUBLE_GET_NEGATIVE: case PSEUDO_DOUBLE_GET_AT: case XS_GET_NEGATIVE_ID: case XS_INTEGER_8: case XS_SET_AT: case XS_SET_NEGATIVE_ID: theCode++; break; case XS_CATCH: case XS_DELETE: case XS_DELETE_MEMBER: case XS_FILE: case XS_GET: case XS_GET_FOR_NEW: case XS_GET_MEMBER: case XS_GET_MEMBER_FOR_CALL: case XS_SET: case XS_SET_MEMBER: xscBuildSymbolsID(the, theData, theCode); theCode += 2; break; case XS_PUT_MEMBER: case PSEUDO_PUT_MEMBER: xscBuildSymbolsID(the, theData, theCode); theCode += 4; break; case XS_PUT_MEMBER_AT: theCode += 3; break; case XS_BRANCH: case XS_BRANCH_ELSE: case XS_BRANCH_IF: case XS_BRANCH_ELSE_BOOL: case XS_BRANCH_IF_BOOL: case XS_FUNCTION: case XS_INTEGER_16: case XS_LINE: case XS_ROUTE: case XS_STATUS: theCode += 2; break; case XS_BRANCH2: case XS_BRANCH_ELSE2: case XS_BRANCH_IF2: case XS_BRANCH_ELSE_BOOL2: case XS_BRANCH_IF_BOOL2: case XS_FUNCTION2: case XS_INTEGER_32: case XS_ROUTE2: theCode += 4; break; case XS_NUMBER: theCode += 8; break; case XS_STRING_POINTER: case XS_STRING_CONCAT: case XS_STRING_CONCATBY: case XS_STRING: { txID len; #if mxStringLength mxDecode2(theCode,len); #else len = c_strlen((const char *)theCode) + 1; #endif theCode += len; }break; case XS_ADD: case XS_ALIAS: case XS_BIT_AND: case XS_BIT_NOT: case XS_BIT_OR: case XS_BIT_XOR: case XS_BREAK: case XS_CALL: case XS_DELETE_MEMBER_AT: case XS_DEBUGGER: case XS_DECREMENT: case XS_DIVIDE: case XS_DUB: case XS_END: case XS_ENUM: case XS_EQUAL: case XS_FALSE: case XS_FLAG_INSTANCE: case XS_GET_MEMBER_AT: case XS_GLOBAL: case XS_IN: case XS_INCREMENT: case XS_INSTANCEOF: case XS_INSTANCIATE: case XS_JUMP: case XS_LEFT_SHIFT: case XS_LESS: case XS_LESS_EQUAL: case XS_MINUS: case XS_MODULO: case XS_MORE: case XS_MORE_EQUAL: case XS_MULTIPLY: case XS_NEW: case XS_NOT: case XS_NOT_EQUAL: case XS_NULL: case XS_PARAMETERS: case XS_PLUS: case XS_POP: case PSEUDO_DUB: case XS_RESULT: case XS_RETURN: case XS_SCOPE: case XS_SET_MEMBER_AT: case XS_SIGNED_RIGHT_SHIFT: case XS_STRICT_EQUAL: case XS_STRICT_NOT_EQUAL: case XS_SUBTRACT: case XS_SWAP: case XS_THIS: case PSEUDO_SET_MEMBER: case PSEUDO_GET_MEMBER: case XS_THROW: case XS_TRUE: case XS_TYPEOF: case XS_UNCATCH: case XS_UNDEFINED: case XS_UNSCOPE: case XS_UNSIGNED_RIGHT_SHIFT: case XS_VOID: break; case XS_ATTRIBUTE_PATTERN: case XS_DATA_PATTERN: case XS_PI_PATTERN: case XS_EMBED_PATTERN: case XS_JUMP_PATTERN: case XS_REFER_PATTERN: case XS_REPEAT_PATTERN: aCount = *theCode++; while (aCount > 0) { xscBuildSymbolsID(the, theData, theCode); theCode += 2; xscBuildSymbolsID(the, theData, theCode); theCode += 2; aCount--; } break; default: xsDebugger(); break; } } }
void* fxMapArchive(txString base, txCallbackAt callbackAt) { FskErr err = kFskErrNone; txArchive* archive = NULL; txString p; Atom atom; int c, i; txString* symbol; txScript* script; bailIfError(FskMemPtrNewClear(sizeof(txArchive), &archive)); c_strcpy(archive->base, base); bailIfError(FskFileMap(base, (unsigned char**)&(archive->address), &(archive->size), 0, &(archive->map))); p = archive->address; p = fxMapAtom(p, &atom); bailAssert(atom.atomType == XS_ATOM_ARCHIVE); p = fxMapAtom(p, &atom); bailAssert(atom.atomType == XS_ATOM_VERSION); bailAssert(*p++ == XS_MAJOR_VERSION); bailAssert(*p++ == XS_MINOR_VERSION); bailAssert(*p++ == XS_PATCH_VERSION); if ((*p++) && !callbackAt) { char* dot; dot = c_strrchr(archive->base, '.'); if (dot) *dot = 0; #if mxWindows c_strcat(archive->base, ".dll"); #else c_strcat(archive->base, ".so"); #endif bailIfError(FskLibraryLoad(&(archive->library), archive->base)); bailIfError(FskLibraryGetSymbolAddress(archive->library, "xsHostModuleAt", &callbackAt)); archive->keys = callbackAt(0); } p = fxMapAtom(p, &atom); bailAssert(atom.atomType == XS_ATOM_SYMBOLS); mxDecode2(p, archive->symbolCount); c = archive->symbolCount; if (c) { bailIfError(FskMemPtrNew(c * sizeof(txString), &(archive->symbols))); symbol = archive->symbols; for (i = 0; i < c; i++) { *symbol = p; p += c_strlen(p) + 1; symbol++; } } p = fxMapAtom(p, &atom); bailAssert(atom.atomType == XS_ATOM_PATHS); mxDecode2(p, archive->scriptCount); c = archive->scriptCount; bailIfError(FskMemPtrNewClear(c * sizeof(txScript), &(archive->scripts))); script = archive->scripts; for (i = 1; i <= c; i++) { if (callbackAt) script->callback = callbackAt(i); script->path = p; bailIfNULL(script->path); p += c_strlen(p) + 1; script++; } script = archive->scripts; for (i = 0; i < c; i++) { p = fxMapAtom(p, &atom); bailAssert(atom.atomType == XS_ATOM_CODE); script->codeSize = atom.atomSize - sizeof(atom); script->codeBuffer = (txS1*)p; p += script->codeSize; script++; } p = c_strrchr(archive->base, '/'); if (p) { p++; *p = 0; archive->baseLength = p - archive->base; } bail: if (err) { fxUnmapArchive(archive); archive = NULL; } return archive; }