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) {
void fx_Date_prototype_setMonth(txMachine* the) { txTimeDescription td; txSlot* slot = fx_Date_prototype_get_aux(the, &td); if (slot) { if (mxArgc < 1) slot->value.number = C_NAN; else { td.tm.tm_mon = fxToInteger(the, mxArgv(0)); if (mxArgc > 1) td.tm.tm_mday = fxToInteger(the, mxArgv(1)); fx_Date_prototype_set_aux(the, &td, slot); } } }
void fx_String_charCodeAt(txMachine* the) { txString aString; txInteger aLength; txInteger anOffset; aString = fxCoerceToString(the, mxThis); if (!aString) mxDebug0(the, XS_TYPE_ERROR, "String.prototype.charCodeAt: 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.integer = fxUnicodeCharacter(aString + anOffset); mxResult->kind = XS_INTEGER_KIND; } else { mxResult->value.number = C_NAN; mxResult->kind = XS_NUMBER_KIND; } } else { mxResult->value.number = C_NAN; mxResult->kind = XS_NUMBER_KIND; } }
void fx_Function_prototype_apply(txMachine* the) { txInteger c, i; if ((mxArgc < 2) || (mxArgv(1)->kind == XS_UNDEFINED_KIND) || (mxArgv(1)->kind == XS_NULL_KIND)) c = 0; else { fxToInstance(the, mxArgv(1)); mxPushSlot(mxArgv(1)); fxGetID(the, mxID(_length)); c = fxToInteger(the, the->stack); the->stack++; for (i = 0; i < c; i++) { mxPushSlot(mxArgv(1)); fxGetID(the, (txID)i); } } /* ARGC */ mxPushInteger(c); /* THIS */ if (mxArgc < 1) mxPushUndefined(); else mxPushSlot(mxArgv(0)); /* FUNCTION */ mxPushSlot(mxThis); fxCall(the); mxPullSlot(mxResult); }
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_Function_apply(txMachine* the) { txInteger aCount, anIndex; if ((mxArgc < 2) || (mxArgv(1)->kind == XS_UNDEFINED_KIND) || (mxArgv(1)->kind == XS_NULL_KIND)) aCount = 0; else { fxToInstance(the, mxArgv(1)); *(--the->stack) = *mxArgv(1); fxGetID(the, the->lengthID); aCount = fxToInteger(the, the->stack); the->stack++; for (anIndex = 0; anIndex < aCount; anIndex++) { *(--the->stack) = *mxArgv(1); fxGetID(the, (txID)anIndex); } } /* #PARAM */ mxZeroSlot(--the->stack); the->stack->kind = XS_INTEGER_KIND; the->stack->value.integer = aCount; /* THIS */ if (mxArgc < 1) { mxZeroSlot(--the->stack); } else *(--the->stack) = *mxArgv(0); /* FUNCTION */ *(--the->stack) = *mxThis; /* RESULT */ mxZeroSlot(--the->stack); fxRunID(the, XS_NO_ID); *mxResult = *(the->stack++); }
void fx_Date_prototype_setUTCMinutes(txMachine* the) { txTimeDescription td; txSlot* slot = fx_Date_prototype_getUTC_aux(the, &td); if (slot) { if (mxArgc < 1) slot->value.number = C_NAN; else { td.tm.tm_min = fxToInteger(the, mxArgv(0)); if (mxArgc > 1) td.tm.tm_sec = fxToInteger(the, mxArgv(1)); if (mxArgc > 2) td.ms = fxToInteger(the, mxArgv(2)); fx_Date_prototype_setUTC_aux(the, &td, slot); } } }
void fx_Number_prototype_toString(txMachine* the) { char buffer[256]; txInteger radix; txSlot* slot = fxCheckNumber(the, mxThis); if (!slot) mxTypeError("this is no number"); if (mxArgc > 0) { radix = fxToInteger(the, mxArgv(0)); if (radix) { if ((radix < 2) || (36 < radix)) mxRangeError("invalid radix"); } else radix = 10; } else radix = 10; mxResult->kind = slot->kind; mxResult->value = slot->value; if (radix == 10) fxToString(the, mxResult); else { static char gxDigits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; txString string = buffer + sizeof(buffer); txNumber value; txBoolean minus; value = mxResult->value.number; switch (c_fpclassify(value)) { case C_FP_INFINITE: if (value < 0) fxCopyStringC(the, mxResult, "-Infinity"); else fxCopyStringC(the, mxResult, "Infinity"); break; case C_FP_NAN: fxCopyStringC(the, mxResult, "NaN"); break; case C_FP_ZERO: fxCopyStringC(the, mxResult, "0"); break; default: *(--string) = 0; if (value < 0) { minus = 1; value = -value; } else minus = 0; do { *(--string) = gxDigits[(txInteger)c_fmod(value, radix)]; value = value / radix; } while (value >= 1); if (minus) *(--string) = '-'; fxCopyStringC(the, mxResult, string); } } }
void fx_Date_prototype_setYear(txMachine* the) { txTimeDescription td; txSlot* slot = fx_Date_prototype_get_aux(the, &td); if (slot) { if (mxArgc < 1) slot->value.number = C_NAN; else { txInteger year = fxToInteger(the, mxArgv(0)); if ((year < 0) || (99 < year)) year -= 1900; td.tm.tm_year = year; if (mxArgc > 1) td.tm.tm_mon = fxToInteger(the, mxArgv(1)); if (mxArgc > 2) td.tm.tm_mday = fxToInteger(the, mxArgv(2)); fx_Date_prototype_set_aux(the, &td, slot); } } }
void fxSerializeJSON(txMachine* the, txJSONSerializer* theSerializer) { txSlot* aSlot; txInteger aFlag; aSlot = fxGetInstance(the, mxThis); theSerializer->offset = 0; theSerializer->size = 1024; theSerializer->buffer = c_malloc(1024); if (!theSerializer->buffer) mxUnknownError("out of memory"); if (mxArgc > 1) { aSlot = mxArgv(1); if (mxIsReference(aSlot)) { aSlot = fxGetInstance(the, aSlot); if (mxIsFunction(aSlot)) theSerializer->replacer = mxArgv(1); else if (mxIsArray(aSlot)) mxSyntaxError("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++) theSerializer->indent[anIndex] = ' '; } else if (mxIsStringPrimitive(aSlot)) c_strncpy((char *)theSerializer->indent, aSlot->value.string, 10); } theSerializer->stack = the->stack; mxPush(mxObjectPrototype); fxNewObjectInstance(the); aFlag = 0; if (mxArgc > 0) mxPushSlot(mxArgv(0)); else mxPushUndefined(); mxPush(mxEmptyString); fxSerializeJSONProperty(the, theSerializer, &aFlag); the->stack++; }
void fx_Date_prototype_setMilliseconds(txMachine* the) { txTimeDescription td; txSlot* slot = fx_Date_prototype_get_aux(the, &td); if (slot) { if (mxArgc < 1) slot->value.number = C_NAN; else { td.ms = fxToInteger(the, mxArgv(0)); fx_Date_prototype_set_aux(the, &td, slot); } } }
void fx_Number_prototype_toPrecision(txMachine* the) { char buffer[256]; int precision; txSlot* slot = fxCheckNumber(the, mxThis); if (!slot) mxTypeError("this is no number"); if (mxArgc > 0) precision = fxToInteger(the, mxArgv(0)); else precision = 0; fxNumberToString(the->dtoa, slot->value.number, buffer, sizeof(buffer), 'g', precision); fxCopyStringC(the, mxResult, buffer); }
void fx_Number_toString(txMachine* the) { txSlot* aNumber; txSlot* aProperty; txInteger aRadix; aNumber = fxGetInstance(the, mxThis); mxCheckNumber(aNumber); aProperty = aNumber->next; if (mxArgc > 0) { aRadix = fxToInteger(the, mxArgv(0)); if (aRadix) { if ((aRadix < 2) || (36 < aRadix)) mxDebug0(the, XS_RANGE_ERROR, "invalid radix"); } else aRadix = 10; } else aRadix = 10; mxResult->kind = aProperty->kind; mxResult->value = aProperty->value; if (aRadix == 10) fxToString(the, mxResult); else { static char gxDigits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; char aBuffer[256]; txString aString; txNumber aValue; txBoolean aMinus; fxToNumber(the, mxResult); aString = aBuffer + sizeof(aBuffer); *(--aString) = 0; aValue = mxResult->value.number; if (aValue < 0) { aMinus = 1; aValue = -aValue; } else aMinus = 0; do { *(--aString) = gxDigits[(txInteger)c_fmod(aValue, aRadix)]; aValue = aValue / aRadix; } while (aValue >= 1); if (aMinus) *(--aString) = '-'; fxCopyStringC(the, mxResult, aString); } }
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_execute(txMachine* the) { if (mxArgc > 0) { txStringStream stream; txString path; txInteger line; fxToString(the, mxArgv(0)); stream.slot = mxArgv(0); stream.size = c_strlen(stream.slot->value.string); stream.offset = 0; path = (mxArgc > 1) ? fxToString(the, mxArgv(1)) : NULL; line = (mxArgc > 2) ? fxToInteger(the, mxArgv(2)) : 0; fxExecute(the, &stream, fxStringGetter, path, line); *mxResult = *the->stack; } }
void fx_Number_toPrecision(txMachine* the) { txSlot* aNumber; txSlot* aProperty; int aPrecision; char aBuffer[256]; aNumber = fxGetInstance(the, mxThis); mxCheckNumber(aNumber); aProperty = aNumber->next; if (mxArgc > 0) aPrecision = fxToInteger(the, mxArgv(0)); else aPrecision = 0; fxNumberToString(the, aProperty->value.number, aBuffer, sizeof(aBuffer), 'g', aPrecision); fxCopyStringC(the, mxResult, aBuffer); }
void fx_Date_UTC(txMachine* the) { txTimeDescription td; c_time_t time; txNumber number; if (mxArgc < 1) mxSyntaxError("no year parameter"); td.tm.tm_year = fxToInteger(the, mxArgv(0)); if ((td.tm.tm_year < 0) || (99 < td.tm.tm_year)) td.tm.tm_year -= 1900; if (mxArgc < 2) mxSyntaxError("no month parameter"); td.tm.tm_mon = fxToInteger(the, mxArgv(1)); if (mxArgc > 2) td.tm.tm_mday = fxToInteger(the, mxArgv(2)); else td.tm.tm_mday = 1; if (mxArgc > 3) td.tm.tm_hour = fxToInteger(the, mxArgv(3)); else td.tm.tm_hour = 0; if (mxArgc > 4) td.tm.tm_min = fxToInteger(the, mxArgv(4)); else td.tm.tm_min = 0; if (mxArgc > 5) td.tm.tm_sec = fxToInteger(the, mxArgv(5)); else td.tm.tm_sec = 0; if (mxArgc > 6) td.ms = fxToInteger(the, mxArgv(6)); else td.ms = 0; td.tm.tm_isdst = 0; time = c_mktime(&(td.tm)); if (time == -1) number = NAN; else { number = (time * 1000.0) + td.ms; number -= gxDeltaTime; } mxResult->value.number = number; mxResult->kind = XS_NUMBER_KIND; }
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 fx_Function_prototype_bind(txMachine* the) { txSlot* instance = fxToInstance(the, mxThis); txSize length; txSlot* slot; txID id; txSlot* arguments; txSlot* argument; txSize c = mxArgc, i; if (!fxIsFunction(the, instance)) mxTypeError("this is no Function instance"); if (fxHasOwnProperty(the, instance, mxID(_length))) { mxPushSlot(mxThis); fxGetID(the, mxID(_length)); length = fxToInteger(the, the->stack++); if (c > 1) length -= c - 1; if (length < 0) length = 0; mxPop(); } else length = 0; mxPushSlot(mxThis); fxGetID(the, mxID(_name)); mxPushStringC("bound "); fxConcatString(the, the->stack, the->stack + 1); slot = fxNewName(the, the->stack); id = slot->ID; mxPop(); mxPop(); mxPushReference(instance->value.instance.prototype); instance = fxNewFunctionInstance(the, id); mxPullSlot(mxResult); slot = mxFunctionInstanceCode(instance); slot->kind = XS_CALLBACK_KIND; slot->value.callback.address = fx_Function_prototype_bound; slot->value.callback.IDs = (txID*)mxIDs.value.code; slot = mxFunctionInstanceInfo(instance); slot->value.info.length = (txID)length; slot = fxLastProperty(the, instance); slot = fxNextSlotProperty(the, slot, mxThis, mxID(_boundFunction), XS_GET_ONLY); if (c > 0) slot = fxNextSlotProperty(the, slot, mxArgv(0), mxID(_boundThis), XS_GET_ONLY); else slot = fxNextUndefinedProperty(the, slot, mxID(_boundThis), XS_GET_ONLY); mxPush(mxArrayPrototype); arguments = fxNewArrayInstance(the); argument = arguments->next; for (i = 1; i < c; i++) { argument->next = fxNewSlot(the); argument = argument->next; argument->kind = mxArgv(i)->kind; argument->value = mxArgv(i)->value; } arguments->next->value.array.length = mxArgc - 1; fxCacheArray(the, arguments); slot = fxNextSlotProperty(the, slot, the->stack, mxID(_boundArguments), XS_GET_ONLY); mxPop(); }
void fx_parseInt(txMachine* the) { txInteger aRadix, aDigit; txNumber aSign, aResult; txString s, r; char c; if (mxArgc < 1) { mxResult->value.number = C_NAN; mxResult->kind = XS_NUMBER_KIND; return; } fxToString(the, mxArgv(0)); if (mxArgc > 1) { aRadix = fxToInteger(the, mxArgv(1)); if (aRadix) { if ((aRadix < 2) || (36 < aRadix)) { mxResult->kind = XS_NUMBER_KIND; mxResult->value.number = C_NAN; return; } } } else aRadix = 0; s = fxSkipSpaces(mxArgv(0)->value.string); c = *s; aSign = 1; if (c == '+') s++; else if (c == '-') { s++; aSign = -1; } if ((*s == '0') && ((*(s + 1) == 'x') || (*(s + 1) == 'X'))) { if ((aRadix == 0) || (aRadix == 16)) { aRadix = 16; s += 2; } } /*if (*s == '0') { if ((aRadix == 0) || (aRadix == 8)) { aRadix = 8; } }*/ if (aRadix == 0) aRadix = 10; aResult = 0; r = s; while ((c = *s)) { if (('0' <= c) && (c <= '9')) aDigit = c - '0'; else if (('a' <= c) && (c <= 'z')) aDigit = 10 + c - 'a'; else if (('A' <= c) && (c <= 'Z')) aDigit = 10 + c - 'A'; else break; if (aDigit >= aRadix) break; aResult = (aResult * aRadix) + aDigit; s++; } if (r == s) { mxResult->kind = XS_NUMBER_KIND; mxResult->value.number = C_NAN; } else { aResult *= aSign; aRadix = (txInteger)aResult; aSign = aRadix; if (aSign == aResult) { mxResult->value.integer = aRadix; mxResult->kind = XS_INTEGER_KIND; } else { mxResult->value.number = aResult; mxResult->kind = XS_NUMBER_KIND; } } }
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 { mxPushSlot(mxArgv(0)); fxGetID(the, mxID(_length)); count = fxToInteger(the, the->stack++); index = 0; while (index < count) { /* ARG0 */ mxPushSlot(mxArgv(0)); fxGetID(the, index); if (function) { /* ARG1 */ mxPushInteger(index); /* ARGC */ mxPushInteger(2); /* THIS */ if (_this) mxPushSlot(_this); else mxPushUndefined();
void fx_Date(txMachine* the) { txTimeDescription td; c_timeval tv; char buffer[256]; c_time_t time; txNumber number; if ((mxThis->kind == XS_REFERENCE_KIND) && ((mxThis->value.reference->flag & XS_SHARED_FLAG) == 0)) { txSlot* anInstance = mxThis->value.reference; if (mxIsDate(anInstance)) { if (mxArgc > 1) { td.tm.tm_year = fxToInteger(the, mxArgv(0)); if ((td.tm.tm_year < 0) || (99 < td.tm.tm_year)) td.tm.tm_year -= 1900; td.tm.tm_mon = fxToInteger(the, mxArgv(1)); if (mxArgc > 2) td.tm.tm_mday = fxToInteger(the, mxArgv(2)); else td.tm.tm_mday = 1; if (mxArgc > 3) td.tm.tm_hour = fxToInteger(the, mxArgv(3)); else td.tm.tm_hour = 0; if (mxArgc > 4) td.tm.tm_min = fxToInteger(the, mxArgv(4)); else td.tm.tm_min = 0; if (mxArgc > 5) td.tm.tm_sec = fxToInteger(the, mxArgv(5)); else td.tm.tm_sec = 0; if (mxArgc > 6) td.ms = fxToInteger(the, mxArgv(6)); else td.ms = 0; td.tm.tm_isdst = -1; time = c_mktime(&(td.tm)); if (time == -1) number = NAN; else number = (time * 1000.0) + td.ms; } else if (mxArgc > 0) { number = fxToNumber(the, mxArgv(0)); } else { c_gettimeofday(&tv, NULL); // According to 15.9.1.1, time precision in JS is milliseconds number = ((txNumber)(tv.tv_sec) * 1000.0) + ((txNumber)(tv.tv_usec / 1000)); } anInstance->next->value.number = number; *mxResult = *mxThis; } return; } { c_time_t sec; c_gettimeofday(&tv, NULL); sec = tv.tv_sec; // necessary because on Windows tv.tv_sec is a long (32 bits), which is diffrent from time_t (64 bits) td.tm = *c_localtime(&sec); c_strftime(buffer, sizeof(buffer), "%a, %d %b %Y %H:%M:%S", &(td.tm)); fxCopyStringC(the, mxResult, buffer); } }
txInteger fxArgToInteger(txMachine* the, txInteger i, txInteger value) { if (mxArgc > i) return fxToInteger(the, mxArgv(i)); return value; }
void fxSerializeJSONProperty(txMachine* the, txJSONSerializer* theSerializer, txInteger* theFlag) { txSlot* aWrapper = the->stack + 2; txSlot* aValue = the->stack + 1; txSlot* aKey = the->stack; txSlot* anInstance; txSlot* aProperty; txInteger aFlag; txIndex aLength, anIndex; if (mxIsReference(aValue)) { anInstance = fxGetInstance(the, aValue); if (anInstance->flag & XS_LEVEL_FLAG) mxTypeError("cyclic value"); mxPushSlot(aKey); /* COUNT */ mxPushInteger(1); /* THIS */ mxPushSlot(aValue); /* FUNCTION */ mxPushSlot(aValue); fxGetID(the, mxID(_toJSON)); if (mxIsReference(the->stack) && mxIsFunction(the->stack->value.reference)) { fxCall(the); mxPullSlot(aValue); } else { the->stack = aKey; } } else anInstance = C_NULL; if (theSerializer->replacer) { mxPushSlot(aKey); mxPushSlot(aValue); /* COUNT */ mxPushInteger(2); /* THIS */ mxPushSlot(aWrapper); /* FUNCTION */ mxPushSlot(theSerializer->replacer); fxCall(the); mxPullSlot(aValue); } again: switch (aValue->kind) { case XS_NULL_KIND: fxSerializeJSONName(the, theSerializer, theFlag); fxSerializeJSONChars(the, theSerializer, "null"); break; case XS_BOOLEAN_KIND: fxSerializeJSONName(the, theSerializer, theFlag); fxSerializeJSONChars(the, theSerializer, aValue->value.boolean ? "true" : "false"); break; case XS_INTEGER_KIND: fxSerializeJSONName(the, theSerializer, theFlag); fxSerializeJSONInteger(the, theSerializer, aValue->value.integer); break; case XS_NUMBER_KIND: fxSerializeJSONName(the, theSerializer, theFlag); fxSerializeJSONNumber(the, theSerializer, aValue->value.number); break; case XS_STRING_KIND: case XS_STRING_X_KIND: fxSerializeJSONName(the, theSerializer, theFlag); fxSerializeJSONString(the, theSerializer, aValue->value.string); break; case XS_ARRAY_KIND: fxSerializeJSONName(the, theSerializer, theFlag); anInstance->flag |= XS_LEVEL_FLAG; fxSerializeJSONChar(the, theSerializer, '['); theSerializer->level++; fxSerializeJSONIndent(the, theSerializer); aFlag = 4; aLength = aValue->value.array.length; for (anIndex = 0; anIndex < aLength; anIndex++) { aProperty = aValue->value.array.address + anIndex; mxPushSlot(aProperty); mxPushInteger(anIndex); fxSerializeJSONProperty(the, theSerializer, &aFlag); } theSerializer->level--; fxSerializeJSONIndent(the, theSerializer); fxSerializeJSONChar(the, theSerializer, ']'); anInstance->flag &= ~XS_LEVEL_FLAG; break; case XS_REFERENCE_KIND: anInstance = fxGetInstance(the, aValue); aValue = anInstance->next; if (aValue && (aValue->flag & XS_INTERNAL_FLAG) && (aValue->kind != XS_PROXY_KIND)) { goto again; } fxSerializeJSONName(the, theSerializer, theFlag); anInstance->flag |= XS_LEVEL_FLAG; if (fxIsArray(the, anInstance)) { fxSerializeJSONChar(the, theSerializer, '['); theSerializer->level++; fxSerializeJSONIndent(the, theSerializer); aFlag = 4; mxPushReference(anInstance); fxGetID(the, mxID(_length)); aLength = fxToInteger(the, the->stack); mxPop(); for (anIndex = 0; anIndex < aLength; anIndex++) { mxPushReference(anInstance); fxGetID(the, anIndex); mxPushInteger(anIndex); fxSerializeJSONProperty(the, theSerializer, &aFlag); } theSerializer->level--; fxSerializeJSONIndent(the, theSerializer); fxSerializeJSONChar(the, theSerializer, ']'); } else { fxSerializeJSONChar(the, theSerializer, '{'); theSerializer->level++; fxSerializeJSONIndent(the, theSerializer); aFlag = 2; { txSlot aContext; aContext.value.regexp.code = theSerializer; aContext.value.regexp.offsets = &aFlag; fxEachInstanceProperty(the, anInstance, XS_EACH_ENUMERABLE_FLAG | XS_EACH_STRING_FLAG | XS_STEP_GET_FLAG, fxSerializeJSONOwnProperty, &aContext, anInstance); } theSerializer->level--; fxSerializeJSONIndent(the, theSerializer); fxSerializeJSONChar(the, theSerializer, '}'); } anInstance->flag &= ~XS_LEVEL_FLAG; break; default: if (*theFlag & 4) { if (*theFlag & 1) { fxSerializeJSONChars(the, theSerializer, ","); fxSerializeJSONIndent(the, theSerializer); } else *theFlag |= 1; fxSerializeJSONChars(the, theSerializer, "null"); } break; } the->stack++; // POP VALUE }