txSlot* fxNewNumberInstance(txMachine* the) { txSlot* anInstance; txSlot* aProperty; anInstance = fxNewSlot(the); anInstance->next = C_NULL; anInstance->flag = XS_VALUE_FLAG; anInstance->kind = XS_INSTANCE_KIND; anInstance->value.instance.garbage = C_NULL; anInstance->value.instance.prototype = C_NULL; if (the->stack->kind == XS_ALIAS_KIND) anInstance->ID = the->stack->value.alias; else anInstance->value.instance.prototype = the->stack->value.reference; the->stack->value.reference = anInstance; the->stack->kind = XS_REFERENCE_KIND; aProperty = anInstance->next = fxNewSlot(the); aProperty->next = C_NULL; aProperty->ID = XS_NO_ID; aProperty->flag = XS_NO_FLAG; aProperty->kind = XS_NUMBER_KIND; aProperty->value.number = 0; return anInstance; }
txSlot* fxNewHostObject(txMachine* the, txDestructor theDestructor) { txSlot* anInstance; txSlot* aProperty; mxPushUndefined(); anInstance = fxNewSlot(the); anInstance->flag = XS_VALUE_FLAG; anInstance->kind = XS_INSTANCE_KIND; anInstance->value.instance.garbage = C_NULL; anInstance->value.instance.prototype = mxObjectPrototype.value.reference; the->stack->value.reference = anInstance; the->stack->kind = XS_REFERENCE_KIND; aProperty = anInstance->next = fxNewSlot(the); aProperty->ID = XS_NO_ID; aProperty->flag = XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG; aProperty->kind = XS_HOST_KIND; aProperty->value.host.data = C_NULL; aProperty->value.host.variant.destructor = theDestructor; if (the->frame && (mxFunction->kind == XS_REFERENCE_KIND)) { txSlot* slot = mxFunctionInstanceModule(mxFunction->value.reference); aProperty = aProperty->next = fxNewSlot(the); aProperty->flag = XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG; aProperty->kind = slot->kind; aProperty->value = slot->value; } return anInstance; }
txSlot* fxNewBooleanInstance(txMachine* the) { txSlot* anInstance; txSlot* aProperty; anInstance = fxNewSlot(the); anInstance->next = C_NULL; anInstance->flag = XS_VALUE_FLAG; anInstance->kind = XS_INSTANCE_KIND; anInstance->value.instance.garbage = C_NULL; anInstance->value.instance.prototype = C_NULL; if (the->stack->kind == XS_ALIAS_KIND) anInstance->ID = the->stack->value.alias; else anInstance->value.instance.prototype = the->stack->value.reference; the->stack->value.reference = anInstance; the->stack->kind = XS_REFERENCE_KIND; aProperty = anInstance->next = fxNewSlot(the); aProperty->next = C_NULL; aProperty->ID = XS_NO_ID; aProperty->flag = XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG; aProperty->kind = XS_BOOLEAN_KIND; aProperty->value.boolean = 0; return anInstance; }
void fxNewProgramInstance(txMachine* the) { txSlot* anInstance; txSlot* aProperty; fxNewInstance(the); anInstance = the->stack->value.reference; /* CODE */ aProperty = anInstance->next = fxNewSlot(the); *aProperty = *(the->stack + 1); aProperty->ID = XS_NO_ID; aProperty->flag = XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG; /* CLOSURE */ aProperty = aProperty->next = fxNewSlot(the); aProperty->flag = XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG; aProperty->kind = XS_NULL_KIND; /* PROTOTYPE */ aProperty = aProperty->next = fxNewSlot(the); aProperty->flag = XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG; #ifdef mxProfile /* PROFILE */ aProperty = aProperty->next = fxNewSlot(the); aProperty->flag = XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG; aProperty->kind = XS_INTEGER_KIND; aProperty->value.integer = the->profileID; the->profileID++; #endif *(the->stack + 1) = *(the->stack); the->stack++; }
txSlot* fxNewStringInstance(txMachine* the) { txSlot* anInstance; txSlot* aProperty; anInstance = fxNewSlot(the); anInstance->next = C_NULL; anInstance->flag = XS_VALUE_FLAG; anInstance->kind = XS_INSTANCE_KIND; anInstance->value.instance.garbage = C_NULL; anInstance->value.instance.prototype = C_NULL; if (the->stack->kind == XS_ALIAS_KIND) anInstance->ID = the->stack->value.alias; else anInstance->value.instance.prototype = the->stack->value.reference; the->stack->value.reference = anInstance; the->stack->kind = XS_REFERENCE_KIND; aProperty = anInstance->next = fxNewSlot(the); aProperty->next = C_NULL; aProperty->ID = XS_NO_ID; aProperty->flag = XS_NO_FLAG; aProperty->kind = mxEmptyString.kind; aProperty->value.string = mxEmptyString.value.string; aProperty = aProperty->next = fxNewSlot(the); aProperty->next = C_NULL; aProperty->ID = the->lengthID; aProperty->flag = XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG; aProperty->kind = XS_INTEGER_KIND; aProperty->value.integer = 0; return anInstance; }
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 fxParseJSONArray(txScriptParser* theParser) { txMachine* the = theParser->the; txSlot* anArray; txIndex aLength; txSlot* anItem; fxGetNextJSONToken(theParser); *(--the->stack) = mxArrayPrototype; anArray = fxNewArrayInstance(the); aLength = 0; anItem = anArray->next; for (;;) { if (theParser->token == XS_TOKEN_RIGHT_BRACKET) break; fxParseJSONValue(theParser); aLength++; anItem->next = fxNewSlot(the); anItem = anItem->next; anItem->kind = the->stack->kind; anItem->value = the->stack->value; the->stack++; if (theParser->token != XS_TOKEN_COMMA) break; fxGetNextJSONToken(theParser); } anArray->next->value.array.length = aLength; fxCacheArray(the, anArray); if (theParser->token != XS_TOKEN_RIGHT_BRACKET) fxReportParserError(theParser, "missing ]"); fxGetNextJSONToken(theParser); }
void fxThrowMessage(txMachine* the, txString path, txInteger line, txError error, txString format, ...) { char message[128] = ""; txInteger length = 0; va_list arguments; txSlot* slot; fxBufferFrameName(the, message, sizeof(message), the->frame, ": "); length = c_strlen(message); va_start(arguments, format); vsnprintf(message + length, sizeof(message) - length, format, arguments); va_end(arguments); if ((error <= XS_NO_ERROR) || (XS_ERROR_COUNT <= error)) error = XS_UNKNOWN_ERROR; slot = fxNewSlot(the); slot->kind = XS_INSTANCE_KIND; slot->value.instance.garbage = C_NULL; slot->value.instance.prototype = mxErrorPrototypes(error).value.reference; mxException.kind = XS_REFERENCE_KIND; mxException.value.reference = slot; slot = fxNextStringProperty(the, slot, message, mxID(_message), XS_DONT_ENUM_FLAG); #ifdef mxDebug fxDebugThrow(the, path, line, message); #endif fxJump(the); }
txSlot* fxNextHostAccessorProperty(txMachine* the, txSlot* property, txCallback get, txCallback set, txID id, txFlag flag) { txSlot *getter = NULL, *setter = NULL, *home = the->stack, *slot; if (get) { getter = fxNewHostFunction(the, get, 0, id); slot = mxFunctionInstanceHome(getter); slot->kind = home->kind; slot->value = home->value; } if (set) { setter = fxNewHostFunction(the, set, 1, id); slot = mxFunctionInstanceHome(setter); slot->kind = home->kind; slot->value = home->value; } property = property->next = fxNewSlot(the); property->flag = flag; property->ID = id; 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 fxDefaultFunctionPrototype(txMachine* the, txSlot* function, txSlot* prototype) { txSlot* instance; txSlot* property; instance = fxNewSlot(the); instance->kind = XS_INSTANCE_KIND; instance->value.instance.garbage = C_NULL; instance->value.instance.prototype = mxObjectPrototype.value.reference; prototype->kind = XS_REFERENCE_KIND; prototype->value.reference = instance; property = instance->next = fxNewSlot(the); property->flag = XS_DONT_ENUM_FLAG; property->ID = mxID(_constructor); property->kind = XS_REFERENCE_KIND; property->value.reference = function; }
void fxParseJSONArray(txMachine* the, txJSONParser* theParser) { txSlot* anArray; txIndex aLength; txSlot* anItem; fxGetNextJSONToken(the, theParser); mxPush(mxArrayPrototype); anArray = fxNewArrayInstance(the); aLength = 0; anItem = fxLastProperty(the, anArray); for (;;) { if (theParser->token == XS_JSON_TOKEN_RIGHT_BRACKET) break; fxParseJSONValue(the, theParser); aLength++; anItem->next = fxNewSlot(the); anItem = anItem->next; anItem->kind = the->stack->kind; anItem->value = the->stack->value; the->stack++; if (theParser->token != XS_JSON_TOKEN_COMMA) break; fxGetNextJSONToken(the, theParser); } anArray->next->value.array.length = aLength; fxCacheArray(the, anArray); if (theParser->token != XS_JSON_TOKEN_RIGHT_BRACKET) mxSyntaxError("missing ]"); fxGetNextJSONToken(the, theParser); }
txSlot* fxCoerceToArray(txMachine* the, txSlot* slot) { txSlot* instance = fxToInstance(the, slot); txSlot** address = &(instance->next); txSlot* array = C_NULL; txSlot* property; while ((property = *address)) { if (property->ID == XS_NO_ID) { if ((property->kind == XS_ARRAY_KIND) || (property->kind == XS_PARAMETERS_KIND)) { array = property; break; } } else break; address = &(property->next); } if (!array) { array = *address = fxNewSlot(the); array->next = property; array->kind = XS_ARRAY_KIND; array->value.array.address = C_NULL; array->value.array.length = 0; } return array; }
txSlot* fxNextNullProperty(txMachine* the, txSlot* property, txID id, txFlag flag) { property = property->next = fxNewSlot(the); property->flag = flag; property->ID = id; property->kind = XS_NULL_KIND; return property; }
txSlot* fxNextUndefinedProperty(txMachine* the, txSlot* property, txID id, txFlag flag) { property = property->next = fxNewSlot(the); property->flag = flag; property->ID = id; property->kind = XS_UNDEFINED_KIND; return property; }
txSlot* fxNextStringProperty(txMachine* the, txSlot* property, txString string, txID id, txFlag flag) { property = property->next = fxNewSlot(the); property->flag = flag; property->ID = id; fxCopyStringC(the, property, string); return property; }
txSlot* fxNewInstance(txMachine* the) { txSlot* instance = fxNewSlot(the); instance->kind = XS_INSTANCE_KIND; instance->value.instance.garbage = C_NULL; instance->value.instance.prototype = C_NULL; mxPushReference(instance); return instance; }
txSlot* fxNextTypeDispatchProperty(txMachine* the, txSlot* property, txTypeDispatch* dispatch, txID id, txFlag flag) { property = property->next = fxNewSlot(the); property->flag = flag; property->ID = id; property->kind = XS_TYPED_ARRAY_KIND; property->value.typedArray = dispatch; return property; }
txSlot* fxNextIntegerProperty(txMachine* the, txSlot* property, txInteger integer, txID id, txFlag flag) { property = property->next = fxNewSlot(the); property->flag = flag; property->ID = id; property->kind = XS_INTEGER_KIND; property->value.integer = integer; return property; }
txSlot* fxNextBooleanProperty(txMachine* the, txSlot* property, txBoolean boolean, txID id, txFlag flag) { property = property->next = fxNewSlot(the); property->flag = flag; property->ID = id; property->kind = XS_BOOLEAN_KIND; property->value.boolean = boolean; return property; }
txSlot* fxNextSymbolProperty(txMachine* the, txSlot* property, txID symbol, txID id, txFlag flag) { property = property->next = fxNewSlot(the); property->flag = flag; property->ID = id; property->kind = XS_SYMBOL_KIND; property->value.ID = symbol; return property; }
txSlot* fxNextNumberProperty(txMachine* the, txSlot* property, txNumber number, txID id, txFlag flag) { property = property->next = fxNewSlot(the); property->flag = flag; property->ID = id; property->kind = XS_NUMBER_KIND; property->value.number = number; return property; }
txSlot* fxNextSlotProperty(txMachine* the, txSlot* property, txSlot* slot, txID id, txFlag flag) { property = property->next = fxNewSlot(the); property->flag = flag; property->ID = id; property->kind = slot->kind; property->value = slot->value; return property; }
void fxArrayCacheItem(txMachine* the, txSlot* reference, txSlot* item) { txSlot* array = reference->value.reference->next; txSlot* slot = fxNewSlot(the); slot->next = array->next; slot->kind = item->kind; slot->value = item->value; array->next = slot; array->value.array.length++; }
void fx_Function_bind(txMachine* the) { txSlot* aFunction; txSlot* aProperty; txSlot* anArray; txSlot* anItem; txSize aCount, anIndex; aFunction = fxGetInstance(the, mxThis); if (!mxIsFunction(aFunction)) mxDebug0(the, XS_TYPE_ERROR, "this is no Function"); if (mxArgc < 1) mxDebug0(the, XS_SYNTAX_ERROR, "Function.prototype.bind: no this parameter"); aProperty = aFunction->next; if (aProperty->kind == XS_CODE_KIND) aCount = *(aProperty->value.code + 4); else aCount = aProperty->value.callback.length; aCount -= mxArgc - 1; if (aCount < 0) aCount = 0; mxPush(mxFunctionPrototype); aFunction = fxNewFunctionInstance(the); *mxResult = *(the->stack++); aProperty = aFunction->next; aProperty->kind = XS_CALLBACK_KIND; aProperty->value.callback.address = fx_Function_bound; aProperty->value.callback.length = aCount; aProperty = fxSetProperty(the, aFunction, fxID(the, "boundFunction"), C_NULL); aProperty->kind = mxThis->kind; aProperty->value = mxThis->value; aProperty = fxSetProperty(the, aFunction, fxID(the, "boundThis"), C_NULL); aProperty->kind = mxArgv(0)->kind; aProperty->value = mxArgv(0)->value; aProperty = fxSetProperty(the, aFunction, fxID(the, "boundArguments"), C_NULL); mxPush(mxArrayPrototype); anArray = fxNewArrayInstance(the); aProperty->kind = the->stack->kind; aProperty->value = the->stack->value; the->stack++; anItem = anArray->next; for (anIndex = 1; anIndex < mxArgc; anIndex++) { anItem->next = fxNewSlot(the); anItem = anItem->next; anItem->kind = mxArgv(anIndex)->kind; anItem->value = mxArgv(anIndex)->value; } anArray->next->value.array.length = mxArgc - 1; fxCacheArray(the, anArray); }
txSlot* fxNewArrayInstance(txMachine* the) { txSlot* instance; txSlot* property; instance = fxNewObjectInstance(the); instance->flag |= XS_VALUE_FLAG; property = instance->next = fxNewSlot(the); property->kind = XS_ARRAY_KIND; property->value.array.length = 0; property->value.array.address = C_NULL; return instance; }
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; }
txSlot* fxNewHostInstance(txMachine* the) { txSlot* aPrototype; txSlot* anInstance; txSlot* aProperty; aPrototype = fxGetInstance(the, the->stack); anInstance = fxNewSlot(the); anInstance->flag = XS_VALUE_FLAG; anInstance->kind = XS_INSTANCE_KIND; anInstance->value.instance.garbage = C_NULL; anInstance->value.instance.prototype = aPrototype; the->stack->value.reference = anInstance; the->stack->kind = XS_REFERENCE_KIND; aProperty = anInstance->next = fxNewSlot(the); aProperty->ID = XS_NO_ID; aProperty->flag = aPrototype->next->flag & ~XS_SHARED_FLAG; aProperty->kind = XS_HOST_KIND; aProperty->value.host.data = C_NULL; aProperty->value.host.variant.destructor = aPrototype->next->value.host.variant.destructor; return anInstance; }
txSlot* fxNextHostFunctionProperty(txMachine* the, txSlot* property, txCallback call, txInteger length, txID id, txFlag flag) { txSlot *function, *home = the->stack, *slot; function = fxNewHostFunction(the, call, length, id); slot = mxFunctionInstanceHome(function); slot->kind = home->kind; slot->value = home->value; property = property->next = fxNewSlot(the); property->flag = flag; property->ID = id; property->kind = the->stack->kind; property->value = the->stack->value; the->stack++; return property; }
txSlot* fxNewFunctionInstance(txMachine* the) { txSlot* anInstance; txSlot* aProperty; txSlot* aPrototype; anInstance = fxNewSlot(the); anInstance->flag = XS_VALUE_FLAG; anInstance->kind = XS_INSTANCE_KIND; anInstance->value.instance.garbage = C_NULL; anInstance->value.instance.prototype = C_NULL; if (the->stack->kind == XS_ALIAS_KIND) anInstance->ID = the->stack->value.alias; else anInstance->value.instance.prototype = the->stack->value.reference; the->stack->value.reference = anInstance; the->stack->kind = XS_REFERENCE_KIND; /* CODE */ aProperty = anInstance->next = fxNewSlot(the); aProperty->flag = XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG; aProperty->kind = mxEmptyCode.kind; aProperty->value.code = mxEmptyCode.value.code; /* CLOSURE */ aProperty = aProperty->next = fxNewSlot(the); aProperty->flag = XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG; aProperty->kind = XS_NULL_KIND; /* PROTOTYPE */ aProperty = aProperty->next = fxNewSlot(the); aProperty->flag = XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG; aPrototype = fxNewSlot(the); aPrototype->ID = mxObjectPrototype.value.alias; aPrototype->next = C_NULL; aPrototype->flag = XS_NO_FLAG; aPrototype->kind = XS_INSTANCE_KIND; aPrototype->value.instance.garbage = C_NULL; aPrototype->value.instance.prototype = C_NULL; aProperty->kind = XS_REFERENCE_KIND; aProperty->value.reference = aPrototype; #ifdef mxProfile /* PROFILE */ aProperty = aProperty->next = fxNewSlot(the); aProperty->flag = XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG; aProperty->kind = XS_INTEGER_KIND; aProperty->value.integer = the->profileID; the->profileID++; #endif return anInstance; }
txSlot* fxNewFunctionInstance(txMachine* the, txID name) { txSlot* instance; txSlot* property; instance = fxNewObjectInstance(the); instance->flag |= XS_VALUE_FLAG; /* CODE */ property = instance->next = fxNewSlot(the); property->flag = XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG; property->kind = mxEmptyCode.kind; property->value.code = mxEmptyCode.value.code; /* CLOSURE */ property = property->next = fxNewSlot(the); property->flag = XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG; property->kind = XS_NULL_KIND; /* PROTOTYPE */ property = property->next = fxNewSlot(the); property->flag = XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG; property->kind = XS_NULL_KIND; /* HOME */ property = property->next = fxNewSlot(the); property->flag = XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG; property->kind = XS_NULL_KIND; /* INFO */ property = property->next = fxNewSlot(the); property->flag = XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG; property->kind = XS_INFO_KIND; property->value.info.length = -1; property->value.info.name = name; #ifdef mxProfile property->value.info.profileID = the->profileID; the->profileID++; #endif /* MODULE */ property = property->next = fxNewSlot(the); property->flag = XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG; if (the->frame && (mxFunction->kind == XS_REFERENCE_KIND) && (mxIsFunction(mxFunction->value.reference))) { txSlot* slot = mxFunctionInstanceModule(mxFunction->value.reference); property->kind = slot->kind; property->value = slot->value; } else property->kind = XS_NULL_KIND; return instance; }