void fxBuildKeys(txMachine* the) { txArchive* archive = the->archive; if (archive && archive->keys) (*archive->keys)(the); else { #ifdef mxParse txSlot* code = &mxIDs; txID c, i; if (archive) { c = archive->symbolCount; code->value.code = (txByte *)fxNewChunk(the, c * sizeof(txID)); code->kind = XS_CODE_KIND; for (i = 0; i < XS_SYMBOL_ID_COUNT; i++) { txString string = archive->symbols[i]; txID id = the->keyIndex; txSlot* description = fxNewSlot(the); description->flag = XS_DONT_ENUM_FLAG; fxCopyStringC(the, description, string); the->keyArray[id] = description; the->keyIndex++; mxID(i) = 0x8000 | id; } for (; i < c; i++) { txString string = archive->symbols[i]; mxID(i) = fxNewNameX(the, string)->ID; } } else { code->value.code = (txByte *)fxNewChunk(the, XS_ID_COUNT * sizeof(txID)); code->kind = XS_CODE_KIND; for (i = 0; i < XS_SYMBOL_ID_COUNT; i++) { txID id = the->keyIndex; txSlot* description = fxNewSlot(the); description->flag = XS_DONT_ENUM_FLAG; fxCopyStringC(the, description, gxIDStrings[i]); the->keyArray[id] = description; the->keyIndex++; mxID(i) = 0x8000 | id; } for (; i < XS_ID_COUNT; i++) { mxID(i) = fxID(the, gxIDStrings[i]); } } #else fxCheck(the, __FILE__, __LINE__); #endif } }
void fx_String_charAt(txMachine* the) { txString aString; txInteger aLength; txInteger anOffset; aString = fxCoerceToString(the, mxThis); if (!aString) mxDebug0(the, XS_TYPE_ERROR, "String.prototype.charAt: this is null or undefined"); aLength = fxUnicodeLength(aString); if ((mxArgc > 0) && (mxArgv(0)->kind != XS_UNDEFINED_KIND)) anOffset = fxToInteger(the, mxArgv(0)); else anOffset = -1; if ((0 <= anOffset) && (anOffset < aLength)) { anOffset = fxUnicodeToUTF8Offset(aString, anOffset); aLength = fxUnicodeToUTF8Offset(aString + anOffset, 1); if ((anOffset >= 0) && (aLength > 0)) { mxResult->value.string = (txString)fxNewChunk(the, aLength + 1); c_memcpy(mxResult->value.string, mxThis->value.string + anOffset, aLength); mxResult->value.string[aLength] = 0; mxResult->kind = XS_STRING_KIND; } else { mxResult->value.string = mxEmptyString.value.string; mxResult->kind = mxEmptyString.kind; } } else { mxResult->value.string = mxEmptyString.value.string; mxResult->kind = mxEmptyString.kind; } }
void fx_Error_toString(txMachine* the) { txInteger aLength; mxPushSlot(mxThis); fxGetID(the, mxID(_name)); if (the->stack->kind == XS_UNDEFINED_KIND) fxCopyStringC(the, the->stack, "Error"); else fxToString(the, the->stack); mxPushSlot(mxThis); fxGetID(the, mxID(_message)); if (the->stack->kind == XS_UNDEFINED_KIND) fxCopyStringC(the, the->stack, ""); else fxToString(the, the->stack); aLength = c_strlen(the->stack->value.string); if (aLength) { aLength += c_strlen((the->stack + 1)->value.string) + 2; mxResult->value.string = (txString)fxNewChunk(the, aLength + 1); mxResult->kind = XS_STRING_KIND; c_strcpy(mxResult->value.string, (the->stack + 1)->value.string); c_strcat(mxResult->value.string, ": "); c_strcat(mxResult->value.string, the->stack->value.string); the->stack++; the->stack++; } else { the->stack++; mxPullSlot(mxResult); } }
void fx_String_fromCharCode(txMachine* the) { txInteger aLength; txInteger aCount; txInteger anIndex; txU4 c; txU1* p; aLength = 0; aCount = mxArgc; for (anIndex = 0; anIndex < aCount; anIndex++) { c = fxToInteger(the, mxArgv(anIndex)) & 0x0000FFFF; if (c < 0x80) aLength++; else if (c < 0x800) aLength += 2; else if (c < 0x10000) aLength += 3; else aLength += 4; } mxResult->value.string = (txString)fxNewChunk(the, aLength + 1); mxResult->kind = XS_STRING_KIND; p = (txU1*)mxResult->value.string; for (anIndex = 0; anIndex < aCount; anIndex++) { c = fxToInteger(the, mxArgv(anIndex)) & 0x0000FFFF; if (c < 0x80) { *p++ = (txU1)c; } else if (c < 0x800) { *p++ = (txU1)(0xC0 | (c >> 6)); *p++ = (txU1)(0x80 | (c & 0x3F)); } else if (c < 0x10000) {
txString fxCopyStringC(txMachine* the, txSlot* a, txString b) { txSize bSize = c_strlen(b); txString result = (txString)fxNewChunk(the, bSize + 1); c_memcpy(result, b, bSize + 1); a->value.string = result; a->kind = XS_STRING_KIND; return result; }
void fxStringBuffer(txMachine* the, txSlot* theSlot, txString theValue, txSize theSize) { theSlot->value.string = (txString)fxNewChunk(the, theSize + 1); if (theValue) c_memcpy(theSlot->value.string, theValue, theSize); else theSlot->value.string[0] = 0; theSlot->value.string[theSize] = 0; theSlot->kind = XS_STRING_KIND; }
void fxIDs(txMachine* the, txInteger count, txString* names) { txInteger i; txID* IDs = fxNewChunk(the, count * sizeof(txID)); mxFunction->value.reference->next->value.callback.IDs = IDs; the->code = (txByte*)IDs; for (i = 0; i < count; i++) { ((txID*)the->code)[i] = fxID(the, names[i]); } }
txString fxConcatString(txMachine* the, txSlot* a, txSlot* b) { txSize aSize = c_strlen(a->value.string); txSize bSize = c_strlen(b->value.string); txString result = (txString)fxNewChunk(the, aSize + bSize + 1); c_memcpy(result, a->value.string, aSize); c_memcpy(result + aSize, b->value.string, bSize + 1); a->value.string = result; a->kind = XS_STRING_KIND; return result; }
void fx_Array(txMachine* the) { txIndex count = (txIndex)mxArgc; txBoolean flag = 0; txSlot* instance; txSlot* array; txSlot* argument; txSlot* slot; if (mxTarget->kind == XS_UNDEFINED_KIND) { mxPush(mxArrayPrototype); instance = fxNewArrayInstance(the); mxPullSlot(mxResult); array = instance->next; } else array = fxCoerceToArray(the, mxThis); flag = 0; if (count == 1) { argument = mxArgv(0); if (argument->kind == XS_INTEGER_KIND) { flag = 1; if ((0 <= argument->value.integer) && (argument->value.integer < XS_MAX_INDEX)) count = (txIndex)argument->value.integer; else mxRangeError("invalid length"); } else if (mxArgv(0)->kind == XS_NUMBER_KIND) { flag = 1; if ((0 <= argument->value.number) && (argument->value.number < XS_MAX_INDEX)) count = (txIndex)argument->value.number; else mxRangeError("invalid length"); } } array->value.array.address = (txSlot *)fxNewChunk(the, count * sizeof(txSlot)); array->value.array.length = count; slot = array->value.array.address; if (flag) { c_memset(slot, 0, count * sizeof(txSlot)); } else { txIndex index = 0; while (index < count) { txSlot* argument = mxArgv(index); slot->ID = XS_NO_ID; slot->kind = argument->kind; slot->value = argument->value; slot++; index++; } } }
txSlot* fxNewGlobalInstance(txMachine* the) { txSlot* instance; txSlot* property; instance = fxNewInstance(the); instance->flag |= XS_VALUE_FLAG; property = instance->next = fxNewSlot(the); property->value.table.address = (txSlot**)fxNewChunk(the, the->keyCount * sizeof(txSlot*)); c_memset(property->value.table.address, 0, the->keyCount * sizeof(txSlot*)); property->value.table.length = the->keyCount; property->kind = XS_GLOBAL_KIND; return instance; }
txString fxConcatStringC(txMachine* the, txSlot* a, txString b) { txSize aSize = c_strlen(a->value.string); txSize bSize = c_strlen(b); txSize resultSize = aSize + bSize + 1; txString result = C_NULL; if (a->kind == XS_STRING_KIND) result = (txString)fxRenewChunk(the, a->value.string, resultSize); if (!result) { result = (txString)fxNewChunk(the, resultSize); c_memcpy(result, a->value.string, aSize); a->value.string = result; a->kind = XS_STRING_KIND; } c_memcpy(result + aSize, b, bSize + 1); return result; }
txString fxResizeString(txMachine* the, txSlot* a, txSize theSize) { txString result = C_NULL; if (a->kind == XS_STRING_KIND) result = (txString)fxRenewChunk(the, a->value.string, theSize); if (!result) { txChunk* aChunk = (txChunk*)(a->value.string - sizeof(txChunk)); txSize aSize = aChunk->size - sizeof(txChunk); result = (txString)fxNewChunk(the, theSize); aChunk = (txChunk*)(result - sizeof(txChunk)); theSize = aChunk->size - sizeof(txChunk); c_memcpy(result, a->value.string, (aSize < theSize) ? aSize : theSize); a->value.string = result; a->kind = XS_STRING_KIND; } return result; }
void fxQueuePattern(txMachine* the, txKind theKind, txID theNamespaceID, txID theNameID, txID theID, txFlag theFlag) { txPatternData* aPatternData; aPatternData = fxNewChunk(the, sizeof(txPatternData)); aPatternData->alias = the->stack->value.alias; aPatternData->count = 1; aPatternData->parts[0].namespaceID = theNamespaceID; aPatternData->parts[0].nameID = theNameID; the->stack->value.pattern = aPatternData; the->stack->kind = theKind; if (theID == XS_SAME_ID) fxQueueID(the, theNameID, theFlag); else fxQueueID(the, theID, theFlag); }
txString fxAdornStringC(txMachine* the, txString prefix, txSlot* string, txString suffix) { txSize stringSize = c_strlen(string->value.string); txSize prefixSize = prefix ? c_strlen(prefix) : 0; txSize suffixSize = suffix ? c_strlen(suffix) : 0; txSize resultSize = stringSize + prefixSize + suffixSize + 1; txString result = (txString)fxNewChunk(the, resultSize); if (prefix && prefixSize) c_memcpy(result, prefix, prefixSize); if (stringSize) c_memcpy(result + prefixSize, string->value.string, stringSize); if (suffix && suffixSize) c_memcpy(result + prefixSize + stringSize, suffix, suffixSize); result[prefixSize + stringSize + suffixSize] = 0; string->kind = XS_STRING_KIND; string->value.string = result; return result; }
void fxArrayCacheEnd(txMachine* the, txSlot* reference) { txSlot* array = reference->value.reference->next; txInteger length = array->value.array.length; if (length) { txSlot *srcSlot, *dstSlot; array->value.array.address = (txSlot*)fxNewChunk(the, length * sizeof(txSlot)); srcSlot = array->next; dstSlot = array->value.array.address + length; while (srcSlot) { dstSlot--; dstSlot->ID = XS_NO_ID; dstSlot->flag = XS_NO_FLAG; dstSlot->kind = srcSlot->kind; dstSlot->value = srcSlot->value; srcSlot = srcSlot->next; } array->next = C_NULL; } }
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 fxCacheArray(txMachine* the, txSlot* instance) { txSlot* array = instance->next; txIndex length = array->value.array.length; if (length) { txSlot* address = (txSlot *)fxNewChunk(the, length * sizeof(txSlot)); txSlot* srcSlot = instance->next->next; txSlot* dstSlot = address; while (srcSlot) { dstSlot->ID = XS_NO_ID; dstSlot->flag = XS_NO_FLAG; dstSlot->kind = srcSlot->kind; dstSlot->value = srcSlot->value; srcSlot = srcSlot->next; dstSlot++; } instance->next->value.array.address = address; instance->next->next = C_NULL; } }
void fx_String_concat(txMachine* the) { txString aString; txInteger aCount; txInteger aLength; txInteger anIndex; aString = fxCoerceToString(the, mxThis); if (!aString) mxDebug0(the, XS_TYPE_ERROR, "String.prototype.concat: this is null or undefined"); aCount = mxArgc; aLength = c_strlen(mxThis->value.string); for (anIndex = 0; anIndex < aCount; anIndex++) aLength += c_strlen(fxToString(the, mxArgv(anIndex))); mxResult->value.string = (txString)fxNewChunk(the, aLength + 1); mxResult->kind = XS_STRING_KIND; c_strcpy(mxResult->value.string, mxThis->value.string); for (anIndex = 0; anIndex < aCount; anIndex++) c_strcat(mxResult->value.string, mxArgv(anIndex)->value.string); }
txSlot* fxNewNameC(txMachine* the, txString theString) { txU1* string; txU4 sum; txU4 modulo; txSlot* result; txID index; string = (txU1*)theString; sum = 0; while(*string != 0) { sum = (sum << 1) + *string++; } sum &= 0x7FFFFFFF; modulo = sum % the->nameModulo; result = the->nameTable[modulo]; while (result != C_NULL) { if (result->value.key.sum == sum) if (c_strcmp(result->value.key.string, theString) == 0) break; result = result->next; } if (result == C_NULL) { index = the->keyIndex; if (index == the->keyCount) mxUnknownError("not enough IDs"); result = fxNewSlot(the); result->next = the->nameTable[modulo]; result->flag = XS_DONT_ENUM_FLAG; result->kind = XS_KEY_KIND; result->ID = 0x8000 | index; result->value.key.string = C_NULL; result->value.key.sum = sum; the->keyArray[index] = result; the->keyIndex++; the->nameTable[modulo] = result; result->value.key.string = (txString)fxNewChunk(the, c_strlen(theString) + 1); c_strcpy(result->value.key.string, theString); } return result; }
void fx_Error_toString(txMachine* the) { txSlot* anError; txSlot* aProperty; txInteger aLength; anError = fxGetInstance(the, mxThis); aProperty = fxGetProperty(the, anError, fxID(the, "name")); --the->stack; the->stack->kind = aProperty->kind; the->stack->value = aProperty->value; if (the->stack->kind == XS_UNDEFINED_KIND) fxCopyStringC(the, the->stack, "Error"); else fxToString(the, the->stack); aProperty = fxGetProperty(the, anError, fxID(the, "message")); --the->stack; the->stack->kind = aProperty->kind; the->stack->value = aProperty->value; if (the->stack->kind == XS_UNDEFINED_KIND) fxCopyStringC(the, the->stack, ""); else fxToString(the, the->stack); aLength = c_strlen(the->stack->value.string); if (aLength) { aLength += c_strlen((the->stack + 1)->value.string) + 2; mxResult->value.string = (txString)fxNewChunk(the, aLength + 1); mxResult->kind = XS_STRING_KIND; c_strcpy(mxResult->value.string, (the->stack + 1)->value.string); c_strcat(mxResult->value.string, ": "); c_strcat(mxResult->value.string, the->stack->value.string); the->stack++; the->stack++; } else { the->stack++; *mxResult = *(the->stack++); } }
void fxSetArrayLength(txMachine* the, txSlot* array, txIndex target) { txIndex length = array->value.array.length; txSlot* address = array->value.array.address; if (length != target) { if (address) address = (txSlot*)fxRenewChunk(the, address, target * sizeof(txSlot)); if (address) { if (length < target) c_memset(address + length, 0, (target - length) * sizeof(txSlot)); } else { address = (txSlot*)fxNewChunk(the, target * sizeof(txSlot)); if (length < target) { c_memcpy(address, array->value.array.address, length * sizeof(txSlot)); c_memset(address + length, 0, (target - length) * sizeof(txSlot)); } else c_memcpy(address, array->value.array.address, target * sizeof(txSlot)); } array->value.array.length = target; array->value.array.address = address; } }
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; }
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); } }
void fxGetNextJSONToken(txMachine* the, txJSONParser* theParser) { txString p; txString q; txString r; txString s; char c; txInteger i; txBoolean escaped; txNumber number; txU4 size; txU4 value; const txUTF8Sequence* sequence; txString string; theParser->integer = 0; theParser->number = 0; theParser->string->value.string = mxEmptyString.value.string; theParser->token = XS_NO_JSON_TOKEN; r = (theParser->data) ? theParser->data : theParser->slot->value.string; p = r + theParser->offset; q = r + theParser->size; c = (p < q) ? *p : 0; while (theParser->token == XS_NO_JSON_TOKEN) { switch (c) { case 0: theParser->token = XS_JSON_TOKEN_EOF; break; case '\n': case '\r': case '\t': case ' ': c = (++p < q) ? *p : 0; break; case '-': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': s = p; if (c == '-') c = (++p < q) ? *p : 0; if (('0' <= c) && (c <= '9')) { if (c == '0') { c = (++p < q) ? *p : 0; } else { c = (++p < q) ? *p : 0; while (('0' <= c) && (c <= '9')) { c = (++p < q) ? *p : 0; } } if (c == '.') { c = (++p < q) ? *p : 0; if (('0' <= c) && (c <= '9')) { c = (++p < q) ? *p : 0; while (('0' <= c) && (c <= '9')) { c = (++p < q) ? *p : 0; } } else mxSyntaxError("invalid character in number"); } if ((c == 'e') || (c == 'E')) { c = (++p < q) ? *p : 0; if ((c== '+') || (c == '-')) { c = (++p < q) ? *p : 0; } if (('0' <= c) && (c <= '9')) { c = (++p < q) ? *p : 0; while (('0' <= c) && (c <= '9')) { c = (++p < q) ? *p : 0; } } else mxSyntaxError("invalid character in number"); } size = p - s; if ((size + 1) > sizeof(the->nameBuffer)) mxSyntaxError("number overflow"); c_memcpy(the->nameBuffer, s, size); the->nameBuffer[size] = 0; theParser->number = fxStringToNumber(the->dtoa, the->nameBuffer, 0); theParser->integer = (txInteger)theParser->number; number = theParser->integer; if (theParser->number == number) theParser->token = XS_JSON_TOKEN_INTEGER; else theParser->token = XS_JSON_TOKEN_NUMBER; } else mxSyntaxError("invalid character in number"); break; case ',': p++; theParser->token = XS_JSON_TOKEN_COMMA; break; case ':': p++; theParser->token = XS_JSON_TOKEN_COLON; break; case '[': p++; theParser->token = XS_JSON_TOKEN_LEFT_BRACKET; break; case ']': p++; theParser->token = XS_JSON_TOKEN_RIGHT_BRACKET; break; case '{': p++; theParser->token = XS_JSON_TOKEN_LEFT_BRACE; break; case '}': p++; theParser->token = XS_JSON_TOKEN_RIGHT_BRACE; break; case '"': c = (++p < q) ? *p : 0; s = p; escaped = 0; size = 0; for (;;) { if ((0 <= c) && (c < 32)) { mxSyntaxError("invalid character in string"); break; } else if (c == '"') { break; } else if (c == '\\') { escaped = 1; c = (++p < q) ? *p : 0; switch (c) { case '"': case '/': case '\\': case 'b': case 'f': case 'n': case 'r': case 't': size++; c = (++p < q) ? *p : 0; break; case 'u': value = 0; for (i = 0; i < 4; i++) { c = (++p < q) ? *p : 0; if (('0' <= c) && (c <= '9')) value = (value * 16) + (c - '0'); else if (('a' <= c) && (c <= 'f')) value = (value * 16) + (10 + c - 'a'); else if (('A' <= c) && (c <= 'F')) value = (value * 16) + (10 + c - 'A'); else mxSyntaxError("invalid character in string"); } // surrogate pair? for (sequence = gxUTF8Sequences; sequence->size; sequence++) if (value <= sequence->lmask) break; size += sequence->size; c = (++p < q) ? *p : 0; break; default: mxSyntaxError("invalid character in string"); break; } } else { size++; c = (++p < q) ? *p : 0; } } { txSize after = p - r; txSize before = s - r; string = theParser->string->value.string = (txString)fxNewChunk(the, size + 1); r = (theParser->data) ? theParser->data : theParser->slot->value.string; p = r + after; q = r + theParser->size; s = r + before; } if (escaped) { p = s; c = *p; for (;;) { if (c == '"') { break; } else if (c == '\\') { p++; c = *p; switch (c) { case '"': case '/': case '\\': *string++ = c; p++; c = *p; break; case 'b': *string++ = '\b'; p++; c = *p; break; case 'f': *string++ = '\f'; p++; c = *p; break; case 'n': *string++ = '\n'; p++; c = *p; break; case 'r': *string++ = '\r'; p++; c = *p; break; case 't': *string++ = '\t'; p++; c = *p; break; case 'u': value = 0; for (i = 0; i < 4; i++) { p++; c = *p; if (('0' <= c) && (c <= '9')) value = (value * 16) + (c - '0'); else if (('a' <= c) && (c <= 'f')) value = (value * 16) + (10 + c - 'a'); else value = (value * 16) + (10 + c - 'A'); } // surrogate pair? string = (txString)fsX2UTF8(value, (txU1*)string, 0x7FFFFFFF); p++; c = *p; break; } } else { *string++ = c; p++; c = *p; } } *string = 0; } else { c_memcpy(string, s, size); string[size] = 0; } p++; theParser->token = XS_JSON_TOKEN_STRING; break; default: if ((q - p >= 5) && (!c_strncmp(p, "false", 5))) { p += 5; theParser->token = XS_JSON_TOKEN_FALSE; } else if ((q - p >= 4) && (!c_strncmp(p, "null", 4))) { p += 4; theParser->token = XS_JSON_TOKEN_NULL; } else if ((q - p >= 4) && (!c_strncmp(p, "true", 4))) { p += 4; theParser->token = XS_JSON_TOKEN_TRUE; } else mxSyntaxError("invalid character"); break; } } theParser->offset = p - r; }
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_escape(txMachine* the) { static char gxSet[128] = { /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1x */ 0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,1, /* 2x !"#$%&'()*+,-./ */ 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0, /* 3x 0123456789:;<=>? */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4x @ABCDEFGHIJKLMNO */ 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1, /* 5X PQRSTUVWXYZ[\]^_ */ 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6x `abcdefghijklmno */ 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0 /* 7X pqrstuvwxyz{|}~ */ }; txString string; txU1 *src; txInteger length; txU4 c; const txUTF8Sequence *sequence; txInteger size; txString result; txU1 *dst; if (mxArgc < 1) string = mxUndefinedString.value.string; else { string = fxToString(the, mxArgv(0)); } src = (txU1*)string; length = 0; while ((c = *src++)) { for (sequence = gxUTF8Sequences; sequence->size; sequence++) { if ((c & sequence->cmask) == sequence->cval) break; } size = sequence->size - 1; while (size > 0) { size--; c = (c << 6) | (*src++ & 0x3F); } c &= sequence->lmask; if ((c < 128) && (gxSet[(int)c])) length += 1; else if (c < 256) length += 3; else length += 6; } length += 1; if (length == (src - (txU1*)string)) { mxResult->value.string = string; mxResult->kind = XS_STRING_KIND; return; } result = fxNewChunk(the, length); src = (txU1*)string; dst = (txU1*)result; while ((c = *src++)) { for (sequence = gxUTF8Sequences; sequence->size; sequence++) { if ((c & sequence->cmask) == sequence->cval) break; } size = sequence->size - 1; while (size > 0) { size--; c = (c << 6) | (*src++ & 0x3F); } c &= sequence->lmask; if ((c < 128) && (gxSet[(int)c])) *dst++ = (txU1)c; else if (c < 256) { *dst++ = '%'; *dst++ = gxURIHexa[c >> 4]; *dst++ = gxURIHexa[c & 15]; } else {