txSlot* fxToInstance(txMachine* the, txSlot* theSlot) { txSlot* anInstance = C_NULL; switch (theSlot->kind) { case XS_UNDEFINED_KIND: mxTypeError("cannot coerce undefined to object"); break; case XS_NULL_KIND: mxTypeError("cannot coerce null to object"); break; case XS_BOOLEAN_KIND: mxPush(mxBooleanPrototype); anInstance = fxNewBooleanInstance(the); anInstance->next->value.boolean = theSlot->value.boolean; mxPullSlot(theSlot); break; case XS_INTEGER_KIND: mxPush(mxNumberPrototype); anInstance = fxNewNumberInstance(the); anInstance->next->value.number = theSlot->value.integer; mxPullSlot(theSlot); break; case XS_NUMBER_KIND: mxPush(mxNumberPrototype); anInstance = fxNewNumberInstance(the); anInstance->next->value.number = theSlot->value.number; mxPullSlot(theSlot); break; case XS_STRING_KIND: case XS_STRING_X_KIND: mxPush(mxStringPrototype); anInstance = fxNewStringInstance(the); anInstance->next->value.string = theSlot->value.string; anInstance->next->next->next->value.integer = fxUnicodeLength(theSlot->value.string); mxPullSlot(theSlot); break; case XS_SYMBOL_KIND: mxPush(mxSymbolPrototype); anInstance = fxNewSymbolInstance(the); anInstance->next->value.ID = theSlot->value.ID; mxPullSlot(theSlot); break; case XS_REFERENCE_KIND: anInstance = theSlot->value.reference; break; default: mxTypeError("cannot coerce to instance"); break; } return anInstance; }
void fxBuildNumber(txMachine* the) { mxPush(mxGlobal); mxPush(mxObjectPrototype); fxNewNumberInstance(the); fxNewHostFunction(the, fx_Number_toExponential, 1); fxQueueID(the, fxID(the, "toExponential"), XS_DONT_ENUM_FLAG); fxNewHostFunction(the, fx_Number_toFixed, 1); fxQueueID(the, fxID(the, "toFixed"), XS_DONT_ENUM_FLAG); fxNewHostFunction(the, fx_Number_toString, 0); fxQueueID(the, fxID(the, "toLocaleString"), XS_DONT_ENUM_FLAG); fxNewHostFunction(the, fx_Number_toPrecision, 1); fxQueueID(the, fxID(the, "toPrecision"), XS_DONT_ENUM_FLAG); fxNewHostFunction(the, fx_Number_toString, 1); fxQueueID(the, fxID(the, "toString"), XS_DONT_ENUM_FLAG); fxNewHostFunction(the, fx_Number_valueOf, 0); fxQueueID(the, fxID(the, "valueOf"), XS_DONT_ENUM_FLAG); fxAliasInstance(the, the->stack); mxNumberPrototype = *the->stack; fxNewHostConstructor(the, fx_Number, 1); mxPushNumber(C_DBL_MAX); fxQueueID(the, fxID(the, "MAX_VALUE"), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); mxPushNumber(C_DBL_MIN); fxQueueID(the, fxID(the, "MIN_VALUE"), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); mxPushNumber(C_NAN); fxQueueID(the, fxID(the, "NaN"), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); mxPushNumber(-C_INFINITY); fxQueueID(the, fxID(the, "NEGATIVE_INFINITY"), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); mxPushNumber(C_INFINITY); fxQueueID(the, fxID(the, "POSITIVE_INFINITY"), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); //fxAliasInstance(the, the->stack); the->stack->value.reference->next->next->next->flag |= XS_DONT_SET_FLAG; *(--the->stack) = mxNumberPrototype; fxPutID(the, fxID(the, "constructor"), XS_DONT_ENUM_FLAG, XS_DONT_ENUM_FLAG); fxQueueID(the, fxID(the, "Number"), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); the->stack++; }
void fxNewInstanceOf(txMachine* the) { txSlot* aParent; if (the->stack->kind == XS_NULL_KIND) { txSlot* instance = fxNewSlot(the); instance->kind = XS_INSTANCE_KIND; instance->value.instance.garbage = C_NULL; instance->value.instance.prototype = C_NULL; the->stack->value.reference = instance; the->stack->kind = XS_REFERENCE_KIND; } else { fxToInstance(the, the->stack); aParent = fxGetInstance(the, the->stack); if (aParent->flag & XS_VALUE_FLAG) { switch (aParent->next->kind) { case XS_CALLBACK_KIND: case XS_CODE_KIND: fxNewFunctionInstance(the, XS_NO_ID); break; case XS_ARRAY_KIND: fxNewArrayInstance(the); break; case XS_STRING_KIND: case XS_STRING_X_KIND: fxNewStringInstance(the); break; case XS_BOOLEAN_KIND: fxNewBooleanInstance(the); break; case XS_NUMBER_KIND: fxNewNumberInstance(the); break; case XS_DATE_KIND: fxNewDateInstance(the); break; case XS_REGEXP_KIND: fxNewRegExpInstance(the); break; case XS_SYMBOL_KIND: fxNewSymbolInstance(the); break; case XS_HOST_KIND: fxNewHostInstance(the); break; case XS_PROMISE_KIND: fxNewPromiseInstance(the); break; case XS_PROXY_KIND: fxNewProxyInstance(the); break; case XS_MAP_KIND: fxNewMapInstance(the); break; case XS_SET_KIND: fxNewSetInstance(the); break; case XS_WEAK_MAP_KIND: fxNewWeakMapInstance(the); break; case XS_WEAK_SET_KIND: fxNewWeakSetInstance(the); break; case XS_ARRAY_BUFFER_KIND: fxNewArrayBufferInstance(the); break; case XS_DATA_VIEW_KIND: fxNewDataViewInstance(the); break; case XS_TYPED_ARRAY_KIND: fxNewTypedArrayInstance(the, aParent->next->value.typedArray); break; case XS_STACK_KIND: fxNewGeneratorInstance(the); break; default: mxSyntaxError("C: xsNewInstanceOf: invalid prototype"); break; } } else fxNewObjectInstance(the); } }
void fxBuildNumber(txMachine* the) { static const txHostFunctionBuilder gx_global_builders[] = { { fx_isFinite, 1, _isFinite }, { fx_isNaN, 1, _isNaN }, { fx_parseFloat, 1, _parseFloat }, { fx_parseInt, 2, _parseInt }, { C_NULL, 0, 0 }, }; static const txHostFunctionBuilder gx_Number_prototype_builders[] = { { fx_Number_prototype_toExponential, 1, _toExponential }, { fx_Number_prototype_toFixed, 1, _toFixed }, { fx_Number_prototype_toString, 0, _toLocaleString }, { fx_Number_prototype_toPrecision, 1, _toPrecision }, { fx_Number_prototype_toString, 1, _toString }, { fx_Number_prototype_valueOf, 0, _valueOf }, { C_NULL, 0, 0 }, }; static const txHostFunctionBuilder gx_Number_builders[] = { { fx_Number_isFinite, 1, _isFinite }, { fx_Number_isInteger, 1, _isInteger }, { fx_Number_isNaN, 1, _isNaN }, { fx_Number_isSafeInteger, 1, _isSafeInteger }, { fx_parseFloat, 1, _parseFloat }, { fx_parseInt, 1, _parseInt }, { C_NULL, 0, 0 }, }; const txHostFunctionBuilder* builder; txSlot* slot; for (builder = gx_global_builders; builder->callback; builder++) { fxNewHostFunctionGlobal(the, builder->callback, builder->length, mxID(builder->id), XS_DONT_ENUM_FLAG); the->stack++; } slot = fxSetGlobalProperty(the, mxGlobal.value.reference, mxID(_Infinity), C_NULL); slot->flag = XS_GET_ONLY; slot->kind = XS_NUMBER_KIND; slot->value.number = (txNumber)C_INFINITY; slot = fxSetGlobalProperty(the, mxGlobal.value.reference, mxID(_NaN), C_NULL); slot->flag = XS_GET_ONLY; slot->kind = XS_NUMBER_KIND; slot->value.number = C_NAN; mxPush(mxObjectPrototype); slot = fxLastProperty(the, fxNewNumberInstance(the)); for (builder = gx_Number_prototype_builders; builder->callback; builder++) slot = fxNextHostFunctionProperty(the, slot, builder->callback, builder->length, mxID(builder->id), XS_DONT_ENUM_FLAG); mxNumberPrototype = *the->stack; slot = fxLastProperty(the, fxNewHostConstructorGlobal(the, fx_Number, 1, mxID(_Number), XS_DONT_ENUM_FLAG)); for (builder = gx_Number_builders; builder->callback; builder++) slot = fxNextHostFunctionProperty(the, slot, builder->callback, builder->length, mxID(builder->id), XS_DONT_ENUM_FLAG); slot = fxNextNumberProperty(the, slot, C_EPSILON, mxID(_EPSILON), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); slot = fxNextNumberProperty(the, slot, C_MAX_SAFE_INTEGER, mxID(_MAX_SAFE_INTEGER), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); slot = fxNextNumberProperty(the, slot, C_DBL_MAX, mxID(_MAX_VALUE), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); slot = fxNextNumberProperty(the, slot, C_MIN_SAFE_INTEGER, mxID(_MIN_SAFE_INTEGER), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); slot = fxNextNumberProperty(the, slot, C_DBL_MIN, mxID(_MIN_VALUE), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); slot = fxNextNumberProperty(the, slot, C_NAN, mxID(_NaN), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); slot = fxNextNumberProperty(the, slot, -((txNumber)C_INFINITY), mxID(_NEGATIVE_INFINITY), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); slot = fxNextNumberProperty(the, slot, (txNumber)C_INFINITY, mxID(_POSITIVE_INFINITY), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); the->stack++; }