void* fxAllocateChunks(txMachine* the, txSize theSize) { txByte* aData; txBlock* aBlock; if ((theSize < the->minimumChunksSize) && !(the->collectFlag & XS_SKIPPED_COLLECT_FLAG)) theSize = the->minimumChunksSize; theSize += sizeof(txBlock); aData = (txByte *)c_malloc(theSize); if (!aData) fxJump(the); aBlock = (txBlock*)aData; aBlock->nextBlock = the->firstBlock; aBlock->current = aData + sizeof(txBlock); aBlock->limit = aData + theSize; aBlock->temporary = C_NULL; the->firstBlock = aBlock; the->maximumChunksSize += theSize; #if mxReport fxReport(the, "# Chunk allocation: reserved %ld used %ld peak %ld bytes\n", the->maximumChunksSize, the->currentChunksSize, the->peakChunksSize); #endif #if __FSK_LAYER__ FskInstrumentedItemSendMessageNormal(the, kFskXSInstrAllocateChunks, the); #endif return aData; }
void fxThrow(txMachine* the, txString path, txInteger line) { #ifdef mxDebug fxDebugThrow(the, path, line, "C: xsThrow"); #endif fxJump(the); }
void fxThrowMessage(txMachine* the, txString path, txInteger line, txError error, txString format, ...) { char message[128] = ""; txInteger length = 0; va_list arguments; txSlot* slot; fxBufferFrameName(the, message, sizeof(message), the->frame, ": "); length = c_strlen(message); va_start(arguments, format); vsnprintf(message + length, sizeof(message) - length, format, arguments); va_end(arguments); if ((error <= XS_NO_ERROR) || (XS_ERROR_COUNT <= error)) error = XS_UNKNOWN_ERROR; slot = fxNewSlot(the); slot->kind = XS_INSTANCE_KIND; slot->value.instance.garbage = C_NULL; slot->value.instance.prototype = mxErrorPrototypes(error).value.reference; mxException.kind = XS_REFERENCE_KIND; mxException.value.reference = slot; slot = fxNextStringProperty(the, slot, message, mxID(_message), XS_DONT_ENUM_FLAG); #ifdef mxDebug fxDebugThrow(the, path, line, message); #endif fxJump(the); }
txSlot* fxAllocateSlots(txMachine* the, txSize theCount) { txSlot* result; result = (txSlot *)c_malloc(theCount * sizeof(txSlot)); if (!result) fxJump(the); return result; }
void fxThrowError(txMachine* the, txError theError) { if ((theError <= XS_NO_ERROR) || (XS_ERROR_COUNT <= theError)) theError = XS_UNKNOWN_ERROR; mxPush(mxErrorPrototypes(theError)); fxNewObjectInstance(the); mxException = *(the->stack++); fxJump(the); }
void fxOverflow(txMachine* the, txInteger theCount, txString thePath, txInteger theLine) { #if mxBoundsCheck txSlot* aStack = the->stack + theCount; if (theCount < 0) { if (aStack < the->stackBottom) { fxReport(the, "stack overflow (%ld)!\n", (the->stack - the->stackBottom) + theCount); fxJump(the); } } else if (theCount > 0) { if (aStack > the->stackTop) { fxReport(the, "stack overflow (%ld)!\n", theCount - (the->stackTop - the->stack)); fxJump(the); } } #endif }
void fxThrowMessage(txMachine* the, txError theError, txString theMessage) { if ((theError <= XS_NO_ERROR) || (XS_ERROR_COUNT <= theError)) theError = XS_UNKNOWN_ERROR; mxPush(mxErrorPrototypes(theError)); fxNewObjectInstance(the); mxPushStringC(theMessage); fxQueueID(the, fxID(the, "message"), XS_DONT_ENUM_FLAG); mxException = *(the->stack++); fxJump(the); }
void fx_JSON_parse(txMachine* the) { volatile txJSONParser* aParser = C_NULL; txSlot* slot; mxTry(the) { if (mxArgc < 1) mxSyntaxError("no buffer"); aParser = c_malloc(sizeof(txJSONParser)); if (NULL == aParser) mxUnknownError("out of memory"); c_memset((txJSONParser*)aParser, 0, sizeof(txJSONParser)); if (mxArgc > 1) { slot = mxArgv(1); if (slot->kind == XS_REFERENCE_KIND) { slot = slot->value.reference; if (slot->next && ((slot->next->kind == XS_CODE_KIND) || (slot->next->kind == XS_CODE_X_KIND) || (slot->next->kind == XS_CALLBACK_KIND))) aParser->reviver = slot; } } slot = mxArgv(0); if (slot->kind == XS_REFERENCE_KIND) { slot = slot->value.reference->next; if (slot && (slot->flag & XS_INTERNAL_FLAG) && (slot->kind == XS_HOST_KIND)) { aParser->data = slot->value.host.data; aParser->offset = 0; mxPushSlot(mxArgv(0)); fxGetID(the, mxID(_length)); aParser->size = fxToInteger(the, the->stack++); } } if (!aParser->data) { fxToString(the, mxArgv(0)); aParser->slot = mxArgv(0); aParser->offset = 0; aParser->size = c_strlen(aParser->slot->value.string); } fxParseJSON(the, (txJSONParser*)aParser); mxPullSlot(mxResult); c_free((txJSONParser*)aParser); // @@ reviver } mxCatch(the) { if (aParser) c_free((txJSONParser*)aParser); fxJump(the); } }
void fx_xs_setProfilingDirectory(txMachine* the) { if (the->profileDirectory) { c_free(the->profileDirectory); the->profileDirectory = C_NULL; } if (mxArgc > 0) { mxPushSlot(mxArgv(0)); if (fxRunTest(the)) { txString aString = fxToString(the, mxArgv(0)); txInteger aLength = c_strlen(aString) + 1; the->profileDirectory = c_malloc(aLength); if (!the->profileDirectory) fxJump(the); c_memcpy(the->profileDirectory, aString, aLength); } } }
void fx_JSON_stringify(txMachine* the) { volatile txJSONSerializer aSerializer; mxTry(the) { c_memset((txJSONSerializer*)&aSerializer, 0, sizeof(aSerializer)); fxSerializeJSON(the, (txJSONSerializer*)&aSerializer); if (aSerializer.offset) { fxSerializeJSONChar(the, (txJSONSerializer*)&aSerializer, 0); mxResult->value.string = (txString)fxNewChunk(the, aSerializer.offset); c_memcpy(mxResult->value.string, aSerializer.buffer, aSerializer.offset); mxResult->kind = XS_STRING_KIND; } c_free(aSerializer.buffer); } mxCatch(the) { if (aSerializer.buffer) c_free(aSerializer.buffer); fxJump(the); } }
void fx_JSON_stringify(txMachine* the) { txSlot* aSlot; volatile txJSONSerializer aSerializer; txFlag aFlag; mxTry(the) { aSlot = fxGetInstance(the, mxThis); if (aSlot->flag & XS_SANDBOX_FLAG) the->frame->flag |= XS_SANDBOX_FLAG; else the->frame->flag |= the->frame->next->flag & XS_SANDBOX_FLAG; c_memset((txJSONSerializer*)&aSerializer, 0, sizeof(aSerializer)); aSerializer.offset = 0; aSerializer.size = 1024; aSerializer.buffer = c_malloc(1024); if (!aSerializer.buffer) fxThrowError(the, XS_RANGE_ERROR); if (mxArgc > 1) { aSlot = mxArgv(1); if (mxIsReference(aSlot)) { aSlot = fxGetInstance(the, aSlot); if (mxIsFunction(aSlot)) aSerializer.replacer = mxArgv(1); else if (mxIsArray(aSlot)) mxDebug0(the, XS_SYNTAX_ERROR, "not yet implememented"); } } if (mxArgc > 2) { aSlot = mxArgv(2); if (mxIsReference(aSlot)) { aSlot = fxGetInstance(the, aSlot); if (mxIsNumber(aSlot) || mxIsString(aSlot)) aSlot = aSlot->next; } if ((aSlot->kind == XS_INTEGER_KIND) || (aSlot->kind == XS_NUMBER_KIND)) { txInteger aCount = fxToInteger(the, aSlot), anIndex; if (aCount < 0) aCount = 0; else if (aCount > 10) aCount = 10; for (anIndex = 0; anIndex < aCount; anIndex++) aSerializer.indent[anIndex] = ' '; } else if (aSlot->kind == XS_STRING_KIND) c_strncpy((char *)aSerializer.indent, aSlot->value.string, 10); } aSerializer.stack = the->stack; *(--the->stack) = mxObjectPrototype; fxNewObjectInstance(the); aFlag = 0; if (mxArgc > 0) *(--the->stack) = *mxArgv(0); else mxZeroSlot(--the->stack); *(--the->stack) = mxEmptyString; fxSerializeJSONProperty(the, (txJSONSerializer*)&aSerializer, &aFlag); the->stack++; if (aSerializer.offset) { mxResult->value.string = (txString)fxNewChunk(the, aSerializer.offset + 1); c_memcpy(mxResult->value.string, aSerializer.buffer, aSerializer.offset); mxResult->value.string[aSerializer.offset] = 0; mxResult->kind = XS_STRING_KIND; } c_free(aSerializer.buffer); } mxCatch(the) { if (aSerializer.buffer) c_free(aSerializer.buffer); fxJump(the); } }
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; }
void fx_Array_from(txMachine* the) { txSlot* list = fxNewInstance(the); txSlot* item = list; txIndex count = 0; txIndex index; txSlot* function = C_NULL; txSlot* _this = C_NULL; txSlot* resultArray; txSlot* resultSlot; if (mxArgc > 2) _this = mxArgv(2); if (mxArgc > 1) { txSlot* slot = mxArgv(1); if (slot->kind == XS_REFERENCE_KIND) { slot = slot->value.reference; if ((slot->next->kind == XS_CODE_KIND) || (slot->next->kind == XS_CALLBACK_KIND)) function = slot; } } if (mxArgc > 0) { mxPushSlot(mxArgv(0)); if (fxHasID(the, mxID(_Symbol_iterator))) { txSlot* iterator; txSlot* result; mxPushInteger(0); mxPushSlot(mxArgv(0)); fxCallID(the, mxID(_Symbol_iterator)); iterator = the->stack; { mxTry(the) { count = 0; for(;;) { mxCallID(iterator, mxID(_next), 0); result = the->stack; mxGetID(result, mxID(_done)); if (fxToBoolean(the, the->stack)) break; the->stack++; mxGetID(result, mxID(_value)); if (function) { /* ARG1 */ mxPushInteger(count); /* ARGC */ mxPushInteger(2); /* THIS */ if (_this) mxPushSlot(_this); else mxPushUndefined(); /* FUNCTION */ mxPushReference(function); fxCall(the); } item = fxNextSlotProperty(the, item, the->stack, XS_NO_ID, XS_NO_FLAG); the->stack++; count++; } } mxCatch(the) { mxCallID(iterator, mxID(_return), 0); fxJump(the); } } the->stack++; } else {