txSlot* fxNewHostFunctionGlobal(txMachine* the, txCallback call, txInteger length, txID id, txFlag flag) { txSlot *function, *property; function = fxNewHostFunction(the, call, length, id); property = fxSetGlobalProperty(the, mxGlobal.value.reference, id, C_NULL); property->flag = flag; property->kind = the->stack->kind; property->value = the->stack->value; return function; }
void fxBuildHost(txMachine* the) { txSlot* property; txSlot* slot; fxNewHostAccessorGlobal(the, fx_get_sandbox, C_NULL, fxID(the, "sandbox"), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); property = fxLastProperty(the, mxObjectPrototype.value.reference); property = fxNextHostAccessorProperty(the, property, fx_Object_prototype_get_sandbox, C_NULL, fxID(the, "sandbox"), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); mxPush(mxObjectPrototype); property = fxLastProperty(the, fxNewObjectInstance(the)); property = fxNextHostFunctionProperty(the, property, fx_xs_execute, 1, fxID(the, "execute"), XS_GET_ONLY); property = fxNextHostFunctionProperty(the, property, fx_xs_isInstanceOf, 2, fxID(the, "isInstanceOf"), XS_GET_ONLY); property = fxNextHostFunctionProperty(the, property, fx_xs_newInstanceOf, 1, fxID(the, "newInstanceOf"), XS_GET_ONLY); property = fxNextHostFunctionProperty(the, property, fx_xs_script, 1, fxID(the, "script"), XS_GET_ONLY); #ifdef mxProfile property = fxNextHostFunctionProperty(the, property, fx_xs_isProfiling, 0, fxID(the, "isProfiling"), XS_GET_ONLY); property = fxNextHostFunctionProperty(the, property, fx_xs_getProfilingDirectory, 0, fxID(the, "getProfilingDirectory"), XS_GET_ONLY); property = fxNextHostFunctionProperty(the, property, fx_xs_setProfilingDirectory, 1, fxID(the, "setProfilingDirectory"), XS_GET_ONLY); property = fxNextHostFunctionProperty(the, property, fx_xs_startProfiling, 0, fxID(the, "startProfiling"), XS_GET_ONLY); property = fxNextHostFunctionProperty(the, property, fx_xs_stopProfiling, 0, fxID(the, "stopProfiling"), XS_GET_ONLY); #endif #ifdef mxDebug mxPush(mxObjectPrototype); slot = fxLastProperty(the, fxNewObjectInstance(the)); slot = fxNextHostFunctionProperty(the, slot, fx_xs_debug_getAddress, 0, fxID(the, "getAddress"), XS_GET_ONLY); slot = fxNextHostFunctionProperty(the, slot, fx_xs_debug_setAddress, 1, fxID(the, "setAddress"), XS_GET_ONLY); slot = fxNextHostFunctionProperty(the, slot, fx_xs_debug_getAutomatic, 0, fxID(the, "getAutomatic"), XS_GET_ONLY); slot = fxNextHostFunctionProperty(the, slot, fx_xs_debug_setAutomatic, 1, fxID(the, "setAutomatic"), XS_GET_ONLY); slot = fxNextHostFunctionProperty(the, slot, fx_xs_debug_getBreakOnException, 0, fxID(the, "getBreakOnException"), XS_GET_ONLY); slot = fxNextHostFunctionProperty(the, slot, fx_xs_debug_setBreakOnException, 1, fxID(the, "setBreakOnException"), XS_GET_ONLY); slot = fxNextHostFunctionProperty(the, slot, fx_xs_debug_getConnected, 0, fxID(the, "getConnected"), XS_GET_ONLY); slot = fxNextHostFunctionProperty(the, slot, fx_xs_debug_setConnected, 1, fxID(the, "setConnected"), XS_GET_ONLY); slot = fxNextHostFunctionProperty(the, slot, fx_xs_debug_clearAllBreakpoints, 0, fxID(the, "clearAllBreakpoints"), XS_GET_ONLY); slot = fxNextHostFunctionProperty(the, slot, fx_xs_debug_clearBreakpoint, 2, fxID(the, "clearBreakpoint"), XS_GET_ONLY); slot = fxNextHostFunctionProperty(the, slot, fx_xs_debug_setBreakpoint, 2, fxID(the, "setBreakpoint"), XS_GET_ONLY); property = fxNextSlotProperty(the, property, the->stack, fxID(the, "debug"), XS_GET_ONLY); the->stack++; #endif slot = fxSetGlobalProperty(the, mxGlobal.value.reference, fxID(the, "xs"), C_NULL); slot->flag = XS_GET_ONLY; slot->kind = the->stack->kind; slot->value = the->stack->value; the->stack++; }
txSlot* fxNewHostAccessorGlobal(txMachine* the, txCallback get, txCallback set, txID id, txFlag flag) { txSlot *getter = NULL, *setter = NULL, *property; if (get) getter = fxNewHostFunction(the, get, 0, id); if (set) getter = fxNewHostFunction(the, set, 1, id); property = fxSetGlobalProperty(the, mxGlobal.value.reference, id, C_NULL); property->flag = flag; property->kind = XS_ACCESSOR_KIND; property->value.accessor.getter = getter; property->value.accessor.setter = setter; if (set) the->stack++; if (get) the->stack++; return property; }
void fxBuildGlobal(txMachine* the) { static const txHostFunctionBuilder gx_global_builders[] = { { fx_decodeURI, 1, _decodeURI }, { fx_decodeURIComponent, 1, _decodeURIComponent }, { fx_encodeURI, 1, _encodeURI }, { fx_encodeURIComponent, 1, _encodeURIComponent }, { fx_escape, 1, _escape }, { fx_eval, 1, _eval }, { fx_trace, 1, _trace }, { fx_unescape, 1, _unescape }, { C_NULL, 0, 0 }, }; const txHostFunctionBuilder* builder; txSlot* slot; fxNewGlobalInstance(the); mxPull(mxGlobal); fxNewInstance(the); mxPull(mxObjectPrototype); mxPush(mxObjectPrototype); fxNewFunctionInstance(the, XS_NO_ID); mxPull(mxFunctionPrototype); 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(_undefined), C_NULL); slot->flag = XS_GET_ONLY; mxPush(mxObjectPrototype); slot = fxNewObjectInstance(the); slot = fxNextHostFunctionProperty(the, slot, fx_Iterator_iterator, 0, mxID(_Symbol_iterator), XS_DONT_ENUM_FLAG); mxPull(mxIteratorPrototype); mxPush(mxIteratorPrototype); slot = fxLastProperty(the, fxNewObjectInstance(the)); slot = fxNextHostFunctionProperty(the, slot, fx_Enumerator_next, 0, mxID(_next), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG); fxNewHostConstructor(the, fx_Enumerator, 0, XS_NO_ID); mxPull(mxEnumeratorFunction); }
void fxBuildJSON(txMachine* the) { static const txHostFunctionBuilder gx_JSON_builders[] = { { fx_JSON_parse, 2, _parse }, { fx_JSON_stringify, 3, _stringify }, { C_NULL, 0, 0 }, }; const txHostFunctionBuilder* builder; txSlot* slot; mxPush(mxObjectPrototype); slot = fxLastProperty(the, fxNewObjectInstance(the)); for (builder = gx_JSON_builders; builder->callback; builder++) slot = fxNextHostFunctionProperty(the, slot, builder->callback, builder->length, mxID(builder->id), XS_DONT_ENUM_FLAG); slot = fxNextStringXProperty(the, slot, "JSON", mxID(_Symbol_toStringTag), XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); slot = fxSetGlobalProperty(the, mxGlobal.value.reference, mxID(_JSON)); slot->flag = XS_DONT_ENUM_FLAG; slot->kind = the->stack->kind; slot->value = the->stack->value; the->stack++; }
txSlot* fxSetProperty(txMachine* the, txSlot* theInstance, txInteger theID, txFlag* theFlag) { txSlot* result; txSlot** instanceAddress; txSlot* prototype; txSlot* aProperty; mxCheck(the, theInstance->kind == XS_INSTANCE_KIND); if (theInstance->flag & XS_SHARED_FLAG) { txSlot* alias = the->aliasArray[theInstance->ID]; txSlot** aliasAddress = C_NULL; if (alias) { aliasAddress = &(alias->next); while ((result = *aliasAddress)) { if (result->ID == theID) return result; aliasAddress = &(result->next); } } aProperty = fxGetProperty(the, theInstance, theID); if (!theFlag && aProperty) { if (aProperty->kind == XS_ACCESSOR_KIND) return aProperty; if (aProperty->flag & XS_DONT_SET_FLAG) return aProperty; } if (theInstance->flag & XS_DONT_PATCH_FLAG) return C_NULL; if (!aliasAddress) { alias = fxNewSlot(the); alias->kind = XS_INSTANCE_KIND; alias->value.instance.garbage = C_NULL; alias->value.instance.prototype = C_NULL; the->aliasArray[theInstance->ID] = alias; aliasAddress = &(alias->next); } *aliasAddress = result = fxNewSlot(the); result->ID = (txID)theID; if (aProperty) { result->flag = aProperty->flag; result->kind = aProperty->kind; result->value = aProperty->value; } else { if (theFlag) result->flag = *theFlag; } return result; } if (theInstance->flag & XS_VALUE_FLAG) { if (theID < 0) { if (theInstance->next->kind == XS_GLOBAL_KIND) return fxSetGlobalProperty(the, theInstance, theID, theFlag); if (theInstance->next->kind == XS_STAR_KIND) return fxSetStarProperty(the, theInstance, theID); if (theInstance->next->kind == XS_PROXY_KIND) return fxSetProxyProperty(the, theInstance, theID); } else { if (theInstance->next->kind == XS_TYPED_ARRAY_KIND) return fxSetTypedArrayProperty(the, theInstance, theID); if (theInstance->next->kind == XS_STRING_KIND) return fxSetStringProperty(the, theInstance, theID); if (theInstance->next->kind == XS_PARAMETERS_KIND) return fxSetParametersProperty(the, theInstance, theID); if (theInstance->next->kind == XS_PROXY_KIND) return fxSetProxyProperty(the, theInstance, theID); } } if (theID >= 0) { instanceAddress = &(theInstance->next); while ((aProperty = *instanceAddress)) { if (aProperty->ID == XS_NO_ID) { if (aProperty->kind == XS_ARRAY_KIND) { return fxSetArrayProperty(the, aProperty, theID); } } else break; instanceAddress = &(aProperty->next); } *instanceAddress = result = fxNewSlot(the); result->next = aProperty; result->kind = XS_ARRAY_KIND; result->value.array.address = C_NULL; result->value.array.length = 0; return fxSetArrayProperty(the, result, theID); } instanceAddress = &(theInstance->next); while ((result = *instanceAddress)) { if (result->ID == theID) return result; instanceAddress = &(result->next); } prototype = theInstance->value.instance.prototype; if (prototype) aProperty = fxGetProperty(the, prototype, theID); else aProperty = C_NULL; if (!theFlag && aProperty) { if (aProperty->kind == XS_ACCESSOR_KIND) return aProperty; if (aProperty->flag & XS_DONT_SET_FLAG) return aProperty; } if (theInstance->flag & XS_DONT_PATCH_FLAG) return C_NULL; *instanceAddress = result = fxNewSlot(the); result->ID = (txID)theID; if (aProperty) { result->flag = aProperty->flag; result->kind = aProperty->kind; result->value = aProperty->value; } else { if (theFlag) result->flag = *theFlag; } return result; }
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++; }