txBoolean fxExecute(txMachine* the, void* theStream, txGetter theGetter, txString thePath, txInteger theLine) { #ifdef mxDebug txUnsigned flags = mxProgramFlag | mxDebugFlag; #else txUnsigned flags = mxProgramFlag; #endif txParser _parser; txParser* parser = &_parser; txParserJump jump; txScript* script = NULL; fxInitializeParser(parser, the, 32*1024, 1993); parser->firstJump = &jump; if (c_setjmp(jump.jmp_buf) == 0) { if (thePath) parser->path = fxNewParserSymbol(parser, thePath); fxParserTree(parser, theStream, theGetter, flags, NULL); fxParserHoist(parser); fxParserBind(parser); script = fxParserCode(parser); } fxTerminateParser(parser); if (script) { fxRunScript(the, script, &mxGlobal, C_NULL, C_NULL, C_NULL); return 1; } return 0; }
void fxLoadModuleJS(txMachine* the, txString path, txID moduleID) { FskErr err = kFskErrNone; FskFileMapping map = NULL; txFileMapStream stream; txParser _parser; txParser* parser = &_parser; txParserJump jump; txScript* script = NULL; bailIfError(FskFileMap(path, (unsigned char**)&(stream.buffer), &(stream.size), 0, &map)); stream.offset = 0; fxInitializeParser(parser, the, 32*1024, 1993); parser->firstJump = &jump; parser->path = fxNewParserSymbol(parser, path); if (c_setjmp(jump.jmp_buf) == 0) { fxParserTree(parser, &stream, fxFileMapGetter, 2, NULL); fxParserHoist(parser); fxParserBind(parser); script = fxParserCode(parser); } fxTerminateParser(parser); bail: FskFileDisposeMap(map); if (err && script) { fxDeleteScript(script); script = NULL; } fxResolveModule(the, moduleID, script, NULL, NULL); }
void fxIncludeTree(txParser* parser, void* stream, txGetter getter, txUnsigned flags, txString path) { txParserJump jump; txSymbol* symbol = parser->path; jump.nextJump = parser->firstJump; parser->firstJump = &jump; if (c_setjmp(jump.jmp_buf) == 0) { parser->path = fxNewParserSymbol(parser, path); fxParserTree(parser, stream, getter, flags, C_NULL); } parser->firstJump = jump.nextJump; parser->path = symbol; }
txScript* fxParseScript(txMachine* the, void* stream, txGetter getter, txUnsigned flags) { txParser _parser; txParser* parser = &_parser; txParserJump jump; txScript* script = NULL; fxInitializeParser(parser, the, 32*1024, 1993); parser->firstJump = &jump; if (c_setjmp(jump.jmp_buf) == 0) { fxParserTree(parser, stream, getter, flags, NULL); fxParserHoist(parser); fxParserBind(parser); script = fxParserCode(parser); } fxTerminateParser(parser); return script; }
txScript* fxLoadText(txMachine* the, txString path, txUnsigned flags) { txParser _parser; txParser* parser = &_parser; txParserJump jump; FILE* file = NULL; txString name = NULL; char buffer[PATH_MAX]; char map[PATH_MAX]; txScript* script = NULL; fxInitializeParser(parser, the); parser->firstJump = &jump; if (c_setjmp(jump.jmp_buf) == 0) { parser->path = fxNewParserSymbol(parser, path); file = fopen(path, "r"); mxParserThrowElse(file); fxParserTree(parser, file, (txGetter)fgetc, flags, &name); fclose(file); file = NULL; if (name) { fxMergePath(path, name, buffer); mxParserThrowElse(realpath(buffer, map)); parser->path = fxNewParserSymbol(parser, map); file = fopen(map, "r"); mxParserThrowElse(file); fxParserSourceMap(parser, file, (txGetter)fgetc, flags, &name); fclose(file); file = NULL; fxMergePath(map, name, buffer); mxParserThrowElse(realpath(buffer, map)); parser->path = fxNewParserSymbol(parser, map); } fxParserHoist(parser); fxParserBind(parser); script = fxParserCode(parser); } if (file) fclose(file); fxTerminateParser(parser); return script; }
void fxNewFunction(txMachine* the, txString arguments, txInteger argumentsSize, txString body, txInteger bodySize, txFlag theFlag, txString thePath, txInteger theLine) { txNewFunctionStream stream; #ifdef mxDebug txUnsigned flags = mxProgramFlag | mxDebugFlag; #else txUnsigned flags = mxProgramFlag; #endif txParser _parser; txParser* parser = &_parser; txParserJump jump; txScript* script = NULL; stream.strings[0] = "(function"; stream.strings[1] = arguments; stream.strings[2] = "{"; stream.strings[3] = body; stream.strings[4] = "})"; stream.sizes[0] = 9; stream.sizes[1] = argumentsSize; stream.sizes[2] = 1; stream.sizes[3] = bodySize; stream.sizes[4] = 2; stream.offset = 0; stream.index = 0; fxInitializeParser(parser, the, 32*1024, 1993); parser->firstJump = &jump; if (c_setjmp(jump.jmp_buf) == 0) { if (thePath) parser->path = fxNewParserSymbol(parser, thePath); fxParserTree(parser, &stream, fxNewFunctionStreamGetter, flags, NULL); fxParserHoist(parser); fxParserBind(parser); script = fxParserCode(parser); } fxTerminateParser(parser); fxRunScript(the, script, C_NULL, C_NULL, C_NULL, C_NULL); }
int main(int argc, char* argv[]) { int argi; txString base = NULL; txString output = NULL; txString input = NULL; char name[PATH_MAX]; char path[PATH_MAX]; txLinker _linker; txLinker* linker = &_linker; txInteger modulo = 0; txLinkerScript** link; txLinkerScript* script; FILE* file = C_NULL; txSize size; txByte byte; fxInitializeLinker(linker); if (c_setjmp(linker->jmp_buf) == 0) { c_strcpy(name, "a"); link = &(linker->firstScript); for (argi = 1; argi < argc; argi++) { if (!c_strcmp(argv[argi], "-a")) { argi++; c_strncpy(name, argv[argi], sizeof(name)); } else if (!c_strcmp(argv[argi], "-b")) { argi++; if (argi >= argc) fxReportError(linker, "-b: no directory"); base = fxRealDirectoryPath(linker, argv[argi]); if (!base) fxReportError(linker, "-b '%s': directory not found", argv[argi]); } else if (!c_strcmp(argv[argi], "-o")) { argi++; if (argi >= argc) fxReportError(linker, "-o: no directory"); output = fxRealDirectoryPath(linker, argv[argi]); if (!output) fxReportError(linker, "-o '%s': directory not found", argv[argi]); } else if (!c_strcmp(argv[argi], "-r")) { argi++; if (argi >= argc) fxReportError(linker, "-r: no modulo"); modulo = (txInteger)fxStringToNumber(linker->dtoa, argv[argi], 1); if (modulo <= 0) fxReportError(linker, "-r: invalid modulo"); linker->symbolModulo = modulo; } else { input = fxRealFilePath(linker, argv[argi]); if (!input) fxReportError(linker, "'%s': file not found", argv[argi]); fxLoadScript(linker, input, link, &file); link = &((*link)->nextScript); } } if (!output) output = fxRealDirectoryPath(linker, "."); if (!base) base = output; linker->symbolTable = fxNewLinkerChunkClear(linker, linker->symbolModulo * sizeof(txSymbol*)); c_strcpy(path, output); c_strcat(path, name); c_strcat(path, ".xsa"); if (!modulo && fxRealFilePath(linker, path)) fxLoadArchive(linker, path, &file); size = c_strlen(base); script = linker->firstScript; while (script) { fxBaseScript(linker, script, base, size); script = script->nextScript; } fxBufferPaths(linker); fxDefaultSymbols(linker); script = linker->firstScript; while (script) { fxMapScript(linker, script); script = script->nextScript; } fxBufferSymbols(linker, modulo); file = fopen(path, "wb"); mxThrowElse(file); size = 8 + 8 + 4 + 8 + linker->symbolsSize + 8 + linker->pathsSize + (8 * linker->scriptCount) + linker->codeSize; size = htonl(size); mxThrowElse(fwrite(&size, 4, 1, file) == 1); mxThrowElse(fwrite("XS6A", 4, 1, file) == 1); size = 8 + 4; size = htonl(size); mxThrowElse(fwrite(&size, 4, 1, file) == 1); mxThrowElse(fwrite("VERS", 4, 1, file) == 1); byte = XS_MAJOR_VERSION; mxThrowElse(fwrite(&byte, 1, 1, file) == 1); byte = XS_MINOR_VERSION; mxThrowElse(fwrite(&byte, 1, 1, file) == 1); byte = XS_PATCH_VERSION; mxThrowElse(fwrite(&byte, 1, 1, file) == 1); byte = (linker->hostsCount) ? 1 : 0; mxThrowElse(fwrite(&byte, 1, 1, file) == 1); size = 8 + linker->symbolsSize; size = htonl(size); mxThrowElse(fwrite(&size, 4, 1, file) == 1); mxThrowElse(fwrite("SYMB", 4, 1, file) == 1); mxThrowElse(fwrite(linker->symbolsBuffer, linker->symbolsSize, 1, file) == 1); size = 8 + linker->pathsSize; size = htonl(size); mxThrowElse(fwrite(&size, 4, 1, file) == 1); mxThrowElse(fwrite("PATH", 4, 1, file) == 1); mxThrowElse(fwrite(linker->pathsBuffer, linker->pathsSize, 1, file) == 1); script = linker->firstScript; while (script) { size = 8 + script->codeSize; size = htonl(size); mxThrowElse(fwrite(&size, 4, 1, file) == 1); mxThrowElse(fwrite("CODE", 4, 1, file) == 1); mxThrowElse(fwrite(script->codeBuffer, script->codeSize, 1, file) == 1); script = script->nextScript; } fclose(file); file = NULL; if (linker->hostsCount || modulo) { c_strcpy(path, base); c_strcat(path, name); c_strcat(path, ".xs.h"); file = fopen(path, "w"); mxThrowElse(file); fprintf(file, "/* XS GENERATED FILE; DO NOT EDIT! */\n\n"); fprintf(file, "#include <xs.h>\n\n"); fxWriteExterns(linker, file); fxWriteIDs(linker, file); fclose(file); file = NULL; c_strcpy(path, base); c_strcat(path, name); c_strcat(path, ".xs.c"); file = fopen(path, "w"); mxThrowElse(file); fprintf(file, "/* XS GENERATED FILE; DO NOT EDIT! */\n\n"); if (modulo) fprintf(file, "#include <xs6All.h>\n\n"); fprintf(file, "#include \"%s.xs.h\"\n\n", name); if (modulo) { txS2 c, i; txSymbol** address; c = (txS2)(linker->symbolIndex); address = &(linker->symbolArray[0]); for (i = 0; i < c; i++) { txSymbol* symbol = *address; fprintf(file, "static const txSlot xs_key_%d = {\n", symbol->ID & 0x7FFF); if (symbol->next) fprintf(file, "\t(txSlot *)&xs_key_%d,\n", symbol->next->ID & 0x7FFF); else fprintf(file, "\tNULL,\n"); if (i < XS_SYMBOL_ID_COUNT) { fprintf(file, "\tXS_NO_ID, XS_DONT_ENUM_FLAG | XS_MARK_FLAG, XS_STRING_X_KIND,\n"); fprintf(file, "\t{ .string = \""); fxWriteSymbolString(linker, file, symbol->string); fprintf(file, "\" }\n"); } else { fprintf(file, "\t%d, XS_DONT_ENUM_FLAG | XS_MARK_FLAG, XS_KEY_X_KIND,\n", (int)symbol->ID); fprintf(file, "\t{ .key = {\""); fxWriteSymbolString(linker, file, symbol->string); fprintf(file, "\", 0x%X} }\n", (int)symbol->sum); } fprintf(file, "};\n"); address++; } fprintf(file, "static const txSlot *xs_keys[%d] = {\n", c); address = &(linker->symbolArray[0]); for (i = 0; i < c; i++) { txSymbol* symbol = *address; fprintf(file, "\t&xs_key_%d,\n", symbol->ID & 0x7FFF); address++; } fprintf(file, "};\n\n"); fprintf(file, "static void xsHostKeys(txMachine* the)\n"); fprintf(file, "{\n"); fprintf(file, "\ttxSlot* code = &mxIDs;\n"); fprintf(file, "\ttxInteger i;\n"); fprintf(file, "\tmxCheck(the, the->nameModulo == %ld);\n", modulo); fprintf(file, "\tcode->value.code = (txByte *)fxNewChunk(the, %d * sizeof(txID));\n", c); fprintf(file, "\tcode->kind = XS_CODE_KIND;\n"); fprintf(file, "\tfor (i = 0; i < XS_SYMBOL_ID_COUNT; i++) {\n"); fprintf(file, "\t\ttxSlot *description = (txSlot *)xs_keys[i];\n"); fprintf(file, "\t\tthe->keyArray[i] = description;\n"); fprintf(file, "\t\tmxID(i) = 0x8000 | i;\n"); fprintf(file, "\t}\n"); fprintf(file, "\tfor (; i < %d; i++) {\n", c); fprintf(file, "\t\ttxSlot *key = (txSlot *)xs_keys[i];\n"); fprintf(file, "\t\tthe->keyArray[i] = key;\n"); fprintf(file, "\t\tthe->nameTable[key->value.key.sum %% %ld] = key;\n", modulo); fprintf(file, "\t\tmxID(i) = key->ID;\n"); fprintf(file, "\t}\n"); fprintf(file, "\tthe->keyIndex = %d;\n", c); fprintf(file, "\tthe->keyOffset = %d;\n", c); fprintf(file, "}\n\n"); } fxWriteHosts(linker, file, modulo); fclose(file); file = NULL; } } else { if (linker->error != C_EINVAL) { #if mxWindows char buffer[2048]; FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, linker->error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buffer, sizeof(buffer), NULL); fprintf(stderr, "### %s\n", buffer); #else fprintf(stderr, "### %s\n", strerror(linker->error)); #endif } } if (file) fclose(file); fxTerminateLinker(linker); return linker->error; }
txMachine* fxCloneMachine(txCreation* theCreation, txMachine* theMachine, txString theName, void* theContext) { txMachine* the = (txMachine *)c_calloc(sizeof(txMachine), 1); if (the) { txJump aJump; aJump.nextJump = C_NULL; aJump.stack = C_NULL; aJump.scope = C_NULL; aJump.frame = C_NULL; aJump.code = C_NULL; aJump.flag = 0; the->firstJump = &aJump; if (c_setjmp(aJump.buffer) == 0) { txInteger anIndex; txSlot* aSlot; txSlot** aSlotAddress; txSlot* aSharedSlot; txSlot* aTemporarySlot; txID anID; #if __FSK_LAYER__ FskInstrumentedItemNew(the, theName, &gXSTypeInstrumentation); #endif #ifdef mxDebug the->echoSize = 1 * 1024; the->echoBuffer = (txString)c_malloc(the->echoSize); if (!the->echoBuffer) fxJump(the); //fxConnect(the); the->name = theName; the->sorter = (txSlot**)c_malloc(theCreation->keyCount * sizeof(txSlot*)); if (!the->sorter) fxJump(the); the->breakOnExceptionFlag = 1; #endif #ifdef mxProfile the->profileID = theMachine->profileID; the->profileBottom = c_malloc(XS_PROFILE_COUNT * sizeof(txProfileRecord)); if (!the->profileBottom) fxJump(the); the->profileCurrent = the->profileBottom; the->profileTop = the->profileBottom + XS_PROFILE_COUNT; #endif the->archive = theMachine->archive; the->dtoa = fxNew_dtoa(); if (!the->dtoa) fxJump(the); theCreation->keyCount = theMachine->keyCount; theCreation->nameModulo = theMachine->nameModulo; theCreation->symbolModulo = theMachine->symbolModulo; fxAllocate(the, theCreation); the->sharedMachine = theMachine; c_memcpy(the->nameTable, theMachine->nameTable, the->nameModulo * sizeof(txSlot *)); c_memcpy(the->symbolTable, theMachine->symbolTable, the->symbolModulo * sizeof(txSlot *)); c_memcpy(the->keyArray, theMachine->keyArray, the->keyCount * sizeof(txSlot *)); the->keyIndex = theMachine->keyIndex; the->keyOffset = the->keyIndex; the->aliasCount = theMachine->aliasCount; the->aliasArray = (txSlot **)c_calloc(the->aliasCount, sizeof(txSlot*)); if (!the->aliasArray) fxJump(the); /* mxGlobal */ fxNewInstance(the); aSlot = the->stack->value.reference; aSlot->flag = XS_VALUE_FLAG; aSlot->next = fxNewSlot(the); aSlot = aSlot->next; aSlot->value.table.address = (txSlot**)fxNewChunk(the, theCreation->keyCount * sizeof(txSlot*)); aSlot->value.table.length = theCreation->keyCount; aSlot->kind = XS_GLOBAL_KIND; c_memset(aSlot->value.table.address, 0, theCreation->keyCount * sizeof(txSlot*)); aSlotAddress = aSlot->value.table.address; aSharedSlot = theMachine->stackTop[-1].value.reference->next->next; while (aSharedSlot) { aSlot->next = aTemporarySlot = fxDuplicateSlot(the, aSharedSlot); anID = aTemporarySlot->ID & 0x7FFF; aSlotAddress[anID] = aTemporarySlot; aSharedSlot = aSharedSlot->next; aSlot = aSlot->next; } /* mxException */ mxPushUndefined(); for (anIndex = mxObjectPrototypeStackIndex; anIndex < mxModulePathsStackIndex; anIndex++) *(--the->stack) = theMachine->stackTop[-1 - anIndex]; /* mxModulePaths */ mxPushUndefined(); /* mxImportingModules */ fxNewInstance(the); /* mxLoadingModules */ fxNewInstance(the); /* mxLoadedModules */ fxNewInstance(the); /* mxResolvingModules */ fxNewInstance(the); /* mxRunningModules */ fxNewInstance(the); /* mxRequiredModules */ fxNewInstance(the); /* mxModules */ mxPushUndefined(); /* mxPendingJobs */ fxNewInstance(the); /* mxRunningJobs */ fxNewInstance(the); /* mxFiles */ mxPushList(); #ifdef mxDebug aSharedSlot = theMachine->stackTop[-1 - mxFilesStackIndex].value.list.first; aSlotAddress = &(the->stack->value.list.first); while (aSharedSlot) { *aSlotAddress = fxDuplicateSlot(the, aSharedSlot); aSharedSlot = aSharedSlot->next; aSlotAddress = &((*aSlotAddress)->next); } #endif /* mxBreakpoints */ mxPushList(); /* shared */ for (anIndex = mxHostsStackIndex; anIndex < mxStackIndexCount; anIndex++) *(--the->stack) = theMachine->stackTop[-1 - anIndex]; mxPush(mxSetPrototype); fxNewSetInstance(the); mxPull(mxModulePaths); mxPush(mxObjectPrototype); fxNewWeakSetInstance(the); mxPull(mxModules); the->collectFlag = XS_COLLECTING_FLAG; the->context = theContext; #ifdef mxDebug if (fxGetAutomatic(the)) fxLogin(the); #endif the->firstJump = C_NULL; } else { #if __FSK_LAYER__ FskInstrumentedItemDispose(the); #endif fxFree(the); c_free(the); the = NULL; } } return the; }
txMachine* fxCreateMachine(txCreation* theCreation, void* theArchive, txString theName, void* theContext) { txMachine* the = (txMachine* )c_calloc(sizeof(txMachine), 1); if (the) { txJump aJump; aJump.nextJump = C_NULL; aJump.stack = C_NULL; aJump.scope = C_NULL; aJump.frame = C_NULL; aJump.code = C_NULL; aJump.flag = 0; the->firstJump = &aJump; if (c_setjmp(aJump.buffer) == 0) { txInteger anIndex; #if __FSK_LAYER__ FskInstrumentedItemNew(the, NULL, &gXSTypeInstrumentation); #endif #ifdef mxDebug the->echoSize = 1 * 1024; the->echoBuffer = (txString)c_malloc(the->echoSize); if (!the->echoBuffer) fxJump(the); //fxConnect(the); the->connection = mxNoSocket; the->name = theName; the->sorter = (txSlot**)c_malloc(theCreation->keyCount * sizeof(txSlot*)); if (!the->sorter) fxJump(the); the->breakOnExceptionFlag = 1; #endif #ifdef mxProfile the->profileID = 1; the->profileBottom = c_malloc(XS_PROFILE_COUNT * sizeof(txProfileRecord)); if (!the->profileBottom) fxJump(the); the->profileCurrent = the->profileBottom; the->profileTop = the->profileBottom + XS_PROFILE_COUNT; #endif the->archive = theArchive; the->dtoa = fxNew_dtoa(); if (!the->dtoa) fxJump(the); fxAllocate(the, theCreation); /* mxGLobal */ mxPushUndefined(); /* mxException */ mxPushUndefined(); for (anIndex = mxObjectPrototypeStackIndex; anIndex < mxModulePathsStackIndex; anIndex++) mxPushUndefined(); /* mxModulePaths */ mxPushUndefined(); /* mxImportingModules */ fxNewInstance(the); /* mxLoadingModules */ fxNewInstance(the); /* mxLoadedModules */ fxNewInstance(the); /* mxResolvingModules */ fxNewInstance(the); /* mxRunningModules */ fxNewInstance(the); /* mxRequiredModules */ fxNewInstance(the); /* mxModules */ mxPushUndefined(); /* mxPendingJobs */ fxNewInstance(the); /* mxRunningJobs */ fxNewInstance(the); /* mxFiles */ mxPushList(); /* mxBreakpoints */ mxPushList(); /* mxHosts */ mxPushUndefined(); /* mxIDs */ mxPushUndefined(); /* mxEmptyCode */ mxPushUndefined(); the->stack->value.code = (txByte *)fxNewChunk(the, sizeof(gxNoCode)); c_memcpy(the->stack->value.code, gxNoCode, sizeof(gxNoCode)); the->stack->kind = XS_CODE_KIND; /* mxEmptyString */ mxPushStringC(""); /* mxBooleanString */ mxPushStringC("boolean"); /* mxDefaultString */ mxPushStringC("default"); /* mxFunctionString */ mxPushStringC("function"); /* mxNumberString */ mxPushStringC("number"); /* mxObjectString */ mxPushStringC("object"); /* mxStringString */ mxPushStringC("string"); /* mxSymbolString */ mxPushStringC("symbol"); /* mxUndefinedString */ mxPushStringC("undefined"); for (anIndex = mxGetArgumentFunctionStackIndex; anIndex < mxStackIndexCount; anIndex++) mxPushUndefined(); fxBuildKeys(the); fxBuildGlobal(the); fxBuildObject(the); fxBuildFunction(the); fxBuildGenerator(the); fxBuildArray(the); fxBuildString(the); fxBuildBoolean(the); fxBuildNumber(the); fxBuildDate(the); fxBuildMath(the); fxBuildRegExp(the); fxBuildError(the); fxBuildJSON(the); fxBuildDataView(the); fxBuildPromise(the); fxBuildSymbol(the); fxBuildProxy(the); fxBuildMapSet(the); fxBuildModule(the); fxBuildHost(the); mxPush(mxSetPrototype); fxNewSetInstance(the); mxPull(mxModulePaths); mxPush(mxObjectPrototype); fxNewWeakSetInstance(the); mxPull(mxModules); the->collectFlag = XS_COLLECTING_FLAG; /*{ int c = 32; while (--c) fxCollectGarbage(the); }*/ the->context = theContext; #ifdef mxDebug if (fxGetAutomatic(the)) fxLogin(the); #endif the->firstJump = C_NULL; } else { #if __FSK_LAYER__ FskInstrumentedItemDispose(the); #endif fxFree(the); c_free(the); the = NULL; } } return the; }