void fx_Function_set_prototype(txMachine* the) { txSlot* aFunction; txSlot* aSlot; aFunction = fxGetInstance(the, mxThis); mxCheckFunction(aFunction); aSlot = aFunction->next->next->next; if (aSlot->flag & XS_DONT_SET_FLAG) mxDebug0(the, XS_NO_ERROR, "set prototype: no permission"); else { if (aFunction->flag & XS_SHARED_FLAG) mxDebug0(the, XS_TYPE_ERROR, "Function.set prototype: this is shared"); fxToInstance(the, mxArgv(0)); aSlot->value = mxArgv(0)->value; aSlot->kind = mxArgv(0)->kind; } }
void fx_Date_prototype_setHours(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_hour = fxToInteger(the, mxArgv(0)); if (mxArgc > 1) td.tm.tm_min = fxToInteger(the, mxArgv(1)); if (mxArgc > 2) td.tm.tm_sec = fxToInteger(the, mxArgv(2)); if (mxArgc > 3) td.ms = fxToInteger(the, mxArgv(3)); fx_Date_prototype_set_aux(the, &td, slot); } } }
void fx_isNaN(txMachine* the) { int fpclass; txNumber number = (mxArgc < 1) ? C_NAN : fxToNumber(the, mxArgv(0)); mxResult->kind = XS_BOOLEAN_KIND; mxResult->value.boolean = 0; fpclass = c_fpclassify(number); if (fpclass == FP_NAN) mxResult->value.boolean = 1; }
void fx_Symbol_for(txMachine* the) { txString string; txU1* p; txU4 sum; txU4 modulo; txSlot* result; txID index; if (mxArgc < 1) mxSyntaxError("no key parameter"); string = fxToString(the, mxArgv(0)); p = (txU1*)string; sum = 0; while(*p != 0) { sum = (sum << 1) + *p++; } sum &= 0x7FFFFFFF; modulo = sum % the->symbolModulo; result = the->symbolTable[modulo]; while (result != C_NULL) { if (result->value.key.sum == sum) if (c_strcmp(result->value.key.string, string) == 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->symbolTable[modulo]; result->kind = XS_KEY_KIND; result->ID = 0x8000 | index; result->value.key.string = mxArgv(0)->value.string; result->value.key.sum = sum; the->keyArray[index] = result; the->keyIndex++; the->symbolTable[modulo] = result; } mxResult->kind = XS_SYMBOL_KIND; mxResult->value.ID = result->ID; }
void fx_Function(txMachine* the) { txInteger c, i; txStringStream stream; c = mxArgc; i = 0; mxPushStringC("(function anonymous("); while (c > 1) { fxToString(the, mxArgv(i)); fxConcatString(the, the->stack, mxArgv(i)); if (c > 2) fxConcatStringC(the, the->stack, ", "); c--; i++; } fxConcatStringC(the, the->stack, "){"); if (c > 0) { fxToString(the, mxArgv(i)); fxConcatString(the, the->stack, mxArgv(i)); } fxConcatStringC(the, the->stack, "})"); stream.slot = the->stack; stream.offset = 0; stream.size = c_strlen(the->stack->value.string); fxRunScript(the, fxParseScript(the, &stream, fxStringGetter, mxProgramFlag), C_NULL, C_NULL, C_NULL, C_NULL); if (mxTarget->kind == XS_UNDEFINED_KIND) mxPullSlot(mxResult); else { txSlot* from = fxGetInstance(the, the->stack++); txSlot* to = fxGetInstance(the, mxThis); txSlot* fromProperty; txSlot* toProperty; to->next->value.code = from->next->value.code; fromProperty = mxFunctionInstancePrototype(from); toProperty = mxFunctionInstancePrototype(to); *toProperty = *fromProperty; fromProperty = mxFunctionInstanceInfo(from); toProperty = mxFunctionInstanceInfo(to); *toProperty = *fromProperty; } }
void fx_Function_prototype_set_prototype(txMachine* the) { txSlot* instance = fxCheckFunctionInstance(the, mxThis); txSlot* slot = mxFunctionInstancePrototype(instance); if (slot->flag & XS_DONT_SET_FLAG) { if (the->frame->next->flag & XS_STRICT_FLAG) mxTypeError("set \"prototype\": const"); return; } if (instance->flag & XS_SHARED_FLAG) mxTypeError("set \"prototype\": shared"); if ((mxArgc == 0) || (mxArgv(0)->kind == XS_UNDEFINED_KIND) || (mxArgv(0)->kind == XS_NULL_KIND)) { slot->kind = XS_NULL_KIND; } else { fxToInstance(the, mxArgv(0)); slot->value = mxArgv(0)->value; slot->kind = mxArgv(0)->kind; } }
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 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); }
void fx_Function_prototype_call(txMachine* the) { txInteger c, i; c = mxArgc; i = 1; while (i < c) { mxPushSlot(mxArgv(i)); i++; } /* ARGC */ mxPushInteger(i - 1); /* THIS */ if (mxArgc < 1) mxPushUndefined(); else mxPushSlot(mxArgv(0)); /* FUNCTION */ mxPushSlot(mxThis); fxCall(the); mxPullSlot(mxResult); }
void fx_Number_isNaN(txMachine* the) { int fpclass; txSlot* slot = (mxArgc < 1) ? C_NULL : fxCheckNumber(the, mxArgv(0)); mxResult->kind = XS_BOOLEAN_KIND; mxResult->value.boolean = 0; if (slot) { fpclass = c_fpclassify(slot->value.number); if (fpclass == FP_NAN) mxResult->value.boolean = 1; } }
void fx_Symbol(txMachine* the) { txID id = the->keyIndex; txSlot* description; if (mxTarget->kind != XS_UNDEFINED_KIND) mxTypeError("new Symbol"); if (id == the->keyCount) mxUnknownError("not enough IDs"); if (mxArgc > 0) { fxToString(the, mxArgv(0)); description = fxNewSlot(the); description->kind = XS_STRING_KIND; description->value.string = mxArgv(0)->value.string; } else description = C_NULL; the->keyArray[id] = description; the->keyIndex++; mxResult->kind = XS_SYMBOL_KIND; mxResult->value.ID = 0x8000 | id; }
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_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_Number(txMachine* the) { if (mxResult->kind == XS_UNDEFINED_KIND) { if (mxArgc > 0) { txInteger anInteger; txNumber aNumber; fxToNumber(the, mxArgv(0)); anInteger = (txInteger)mxArgv(0)->value.number; aNumber = anInteger; if (mxArgv(0)->value.number == aNumber) { mxResult->value.integer = anInteger; mxResult->kind = XS_INTEGER_KIND; } else *mxResult = *mxArgv(0); } else { mxResult->kind = XS_NUMBER_KIND; mxResult->value.number = 0; } } else { txSlot* aNumber = fxGetInstance(the, mxResult); mxCheckNumber(aNumber); if (mxArgc > 0) { fxToNumber(the, mxArgv(0)); aNumber->next->value.number = mxArgv(0)->value.number; } } }
void fx_Boolean(txMachine* the) { txSlot* slot = fxCheckBoolean(the, mxThis); txBoolean value = 0; if (mxArgc > 0) value = fxToBoolean(the, mxArgv(0)); if (slot) slot->value.boolean = value; else { mxResult->kind = XS_BOOLEAN_KIND; mxResult->value.boolean = value; } }
void fx_Date_prototype_setDate(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_mday = fxToInteger(the, mxArgv(0)); fx_Date_prototype_set_aux(the, &td, slot); } } }
void fx_Symbol_keyFor(txMachine* the) { txSlot* slot; txSlot* key; if (mxArgc < 1) mxSyntaxError("no sym parameter"); slot = fxCheckSymbol(the, mxArgv(0)); if (!slot) mxTypeError("sym is no symbol"); key = fxGetKey(the, slot->value.ID); if (key && ((key->flag & XS_DONT_ENUM_FLAG) == 0)) { mxResult->kind = XS_STRING_KIND; mxResult->value.string = key->value.key.string; } }
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); }
txSlot* fxArgToCallback(txMachine* the, txInteger argi) { if (mxArgc > argi) { txSlot* slot = mxArgv(argi); 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))) return slot; } } mxTypeError("callback is no function"); return C_NULL; }
void fx_Function_bound(txMachine* the) { txSlot* boundArguments; txInteger aCount, anIndex; txSlot* aParameter; mxPush(*mxFunction); fxGetID(the, fxID(the, "boundArguments")); boundArguments = fxGetInstance(the, the->stack); the->stack++; aCount = boundArguments->next->value.array.length; aParameter = boundArguments->next->value.array.address; for (anIndex = 0; anIndex < aCount; anIndex++) { mxZeroSlot(--the->stack); the->stack->kind = aParameter->kind; the->stack->value = aParameter->value; aParameter++; } for (anIndex = 0; anIndex < mxArgc; anIndex++) { mxZeroSlot(--the->stack); the->stack->kind = mxArgv(anIndex)->kind; the->stack->value = mxArgv(anIndex)->value; } /* #PARAM */ mxZeroSlot(--the->stack); the->stack->kind = XS_INTEGER_KIND; the->stack->value.integer = aCount + mxArgc; /* THIS */ mxPush(*mxFunction); fxGetID(the, fxID(the, "boundThis")); /* FUNCTION */ mxPush(*mxFunction); fxGetID(the, fxID(the, "boundFunction")); /* RESULT */ mxZeroSlot(--the->stack); fxRunID(the, XS_NO_ID); *mxResult = *(the->stack++); }
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); } }
txIndex fxArgToArrayLimit(txMachine* the, txInteger argi) { if (mxArgc > argi) { txNumber i = c_trunc(fxToNumber(the, mxArgv(argi))); if (c_isnan(i)) i = 0; else if (i < 0) i = 0; else if (i > XS_MAX_INDEX) i = XS_MAX_INDEX; return (txIndex)i; } return XS_MAX_INDEX; }
void fx_String(txMachine* the) { if ((mxThis->kind == XS_REFERENCE_KIND) && ((mxThis->value.reference->flag & XS_SHARED_FLAG) == 0)) { txSlot* anInstance = mxThis->value.reference; if (mxIsString(anInstance)) { if (mxArgc > 0) { txString aString = fxToString(the, mxArgv(0)); anInstance->next->value.string = aString; anInstance->next->next->value.integer = fxUnicodeLength(aString); } *mxResult = *mxThis; } return; } if (mxArgc > 0) { *mxResult = *mxArgv(0); fxToString(the, mxResult); } else { mxResult->value.string = mxEmptyString.value.string; mxResult->kind = mxEmptyString.kind; } }
void fx_Number_isInteger(txMachine* the) { int fpclass; txSlot* slot = (mxArgc < 1) ? C_NULL : fxCheckNumber(the, mxArgv(0)); mxResult->kind = XS_BOOLEAN_KIND; mxResult->value.boolean = 0; if (slot) { fpclass = c_fpclassify(slot->value.number); if ((fpclass != FP_NAN) && (fpclass != FP_INFINITE)) { txNumber check = c_trunc(slot->value.number); if (slot->value.number == check) mxResult->value.boolean = 1; } } }
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); }
txIndex fxArgToIndex(txMachine* the, txInteger argi, txIndex index, txIndex length) { if (mxArgc > argi) { txNumber c = length; txNumber i = c_trunc(fxToNumber(the, mxArgv(argi))); if (c_isnan(i)) i = 0; if (i < 0) { i = c + i; if (i < 0) i = 0; } else if (i > c) i = c; index = (txIndex)i; } return index; }
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_Date_prototype_setTime(txMachine* the) { txSlot* slot = fxCheckDate(the, mxThis); if (!slot) mxTypeError("this is no date"); if (mxArgc < 1) slot->value.number = C_NAN; else { txNumber number = fxToNumber(the, mxArgv(0)); int fpclass = c_fpclassify(number); if (fpclass != FP_NAN) { if (c_fabs(number) > 8.64e15) number = C_NAN; else number = c_trunc(number); } slot->value.number = number; } mxResult->value.number = slot->value.number; mxResult->kind = XS_NUMBER_KIND; }
void fx_Date_prototype_toPrimitive(txMachine* the) { if (mxThis->kind == XS_REFERENCE_KIND) { txInteger hint = ((mxArgc > 0) && (c_strcmp(fxToString(the, mxArgv(0)), "number") == 0)) ? XS_NUMBER_HINT : XS_STRING_HINT; if (hint == XS_STRING_HINT) { mxPushInteger(0); mxPushSlot(mxThis); fxCallID(the, mxID(_toString)); if (mxIsReference(the->stack)) { the->stack++; mxPushInteger(0); mxPushSlot(mxThis); fxCallID(the, mxID(_valueOf)); } } else { mxPushInteger(0); mxPushSlot(mxThis); fxCallID(the, mxID(_valueOf)); if (mxIsReference(the->stack)) { the->stack++; mxPushInteger(0); mxPushSlot(mxThis); fxCallID(the, mxID(_toString)); } } if (mxIsReference(the->stack)) { if (hint == XS_STRING_HINT) mxTypeError("Cannot coerce object to string"); else mxTypeError("Cannot coerce object to number"); } mxResult->kind = the->stack->kind; mxResult->value = the->stack->value; the->stack++; } else { mxResult->kind = mxThis->kind; mxResult->value = mxThis->value; } }
void fx_Number(txMachine* the) { txSlot* slot = fxCheckNumber(the, mxThis); txNumber value = 0; if (mxArgc > 0) value = fxToNumber(the, mxArgv(0)); if (slot) slot->value.number = value; else { txInteger integer = (txInteger)value; txNumber number = integer; if (number == value) { mxResult->kind = XS_INTEGER_KIND; mxResult->value.integer = integer; } else { mxResult->kind = XS_NUMBER_KIND; mxResult->value.number = value; } } }