txSlot* fxConstructArrayResult(txMachine* the, txSlot* constructor, txUnsigned length) { mxPushUnsigned(length); mxPushInteger(1); if (constructor) { mxPushSlot(constructor); fxGetID(the, mxID(_Symbol_species)); } else { txSlot* instance = mxThis->value.reference; if (mxIsArray(instance)) { mxPushSlot(mxThis); fxGetID(the, mxID(_constructor)); if (mxIsReference(the->stack) && mxIsFunction(the->stack->value.reference)) fxGetID(the, mxID(_Symbol_species)); else the->stack->kind = XS_UNDEFINED_KIND; } else mxPushUndefined(); } if (the->stack->kind == XS_NULL_KIND) the->stack->kind = XS_UNDEFINED_KIND; if (the->stack->kind == XS_UNDEFINED_KIND) { *the->stack = mxGlobal; fxGetID(the, mxID(_Array)); } fxNew(the); mxPullSlot(mxResult); return mxResult->value.reference->next; }
void fxSetID(txMachine* the, txInteger theID) { txSlot* anInstance; txSlot* aProperty; txSlot* aFunction; fxToInstance(the, the->stack); anInstance = fxGetInstance(the, the->stack); if (!anInstance) mxDebugID(XS_TYPE_ERROR, "C: xsSet %s: shared instance", theID); aProperty = fxSetProperty(the, anInstance, theID, C_NULL); if (!aProperty) mxDebugID(XS_TYPE_ERROR, "C: xsSet %s: not extensible", theID); if (aProperty->kind == XS_ACCESSOR_KIND) { mxPushInteger(1); /* SWAP THIS */ the->scratch = *(the->stack); *(the->stack) = *(the->stack + 1); *(the->stack + 1) = the->scratch; /* FUNCTION */ aFunction = aProperty->value.accessor.setter; if (!mxIsFunction(aFunction)) mxDebugID(XS_TYPE_ERROR, "C: xsCall set %s: no function", theID); mxPushReference(aFunction); fxCall(the); } else { the->stack++; if (aProperty->flag & XS_DONT_SET_FLAG) mxDebugID(XS_TYPE_ERROR, "C: xsSet %s: no permission", theID); aProperty->kind = the->stack->kind; aProperty->value = the->stack->value; } }
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++; }
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; }
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); }
void fxCall(txMachine* the) { txSlot* aFunction; aFunction = fxGetInstance(the, the->stack); if (!mxIsFunction(aFunction)) mxTypeError("C: xsCall: no function"); /* TARGET */ mxPushUndefined(); /* RESULT */ mxPushUndefined(); fxRunID(the, C_NULL, XS_NO_ID); }
void fxBufferFrameName(txMachine* the, txString buffer, txSize size, txSlot* frame, txString suffix) { txSlot* target = frame + 2; txSlot* function = frame + 3; txSlot* _this = frame + 4; if (function->kind == XS_REFERENCE_KIND) { function = function->value.reference; if (mxIsFunction(function)) { if (target->kind == XS_UNDEFINED_KIND) { txSlot* home = mxFunctionInstanceHome(function); if (home->kind == XS_REFERENCE_KIND) { home = home->value.reference; if (mxIsFunction(home)) { fxBufferFunctionName(the, buffer, size, home, "."); } else { txSlot* constructor = fxGetOwnProperty(the, home, mxID(_constructor)); if (constructor) { if (constructor->kind == XS_REFERENCE_KIND) { constructor = constructor->value.reference; if (mxIsFunction(constructor)) fxBufferFunctionName(the, buffer, size, constructor, ".prototype."); } } else if (_this->kind == XS_REFERENCE_KIND) { fxBufferObjectName(the, buffer, size, _this->value.reference, "."); } } } } fxBufferFunctionName(the, buffer, size, function, ""); } } else c_strncat(buffer, "(host)", size - c_strlen(buffer) - 1); c_strncat(buffer, suffix, size - c_strlen(buffer) - 1); }
void fxGetID(txMachine* the, txInteger theID) { txSlot* anInstance; txSlot* aProperty; txSlot* aFunction; fxToInstance(the, the->stack); anInstance = fxGetInstance(the, the->stack); aProperty = fxGetProperty(the, anInstance, theID); if (!aProperty) { the->stack->kind = XS_UNDEFINED_KIND; //mxDebugID(XS_NO_ERROR, "C: xsGet %s: no property", theID); } else if (aProperty->kind == XS_ACCESSOR_KIND) { aFunction = aProperty->value.accessor.getter; if (mxIsFunction(aFunction)) { mxPushInteger(0); /* SWAP THIS */ the->scratch = *(the->stack); *(the->stack) = *(the->stack + 1); *(the->stack + 1) = the->scratch; /* FUNCTION */ aFunction = aProperty->value.accessor.getter; if (!mxIsFunction(aFunction)) mxDebugID(XS_TYPE_ERROR, "C: xsCall get %s: no function", theID); mxPushReference(aFunction); fxCall(the); } else the->stack->kind = XS_UNDEFINED_KIND; } else { the->stack->kind = aProperty->kind; the->stack->value = aProperty->value; } }
void fxNew(txMachine* the) { txSlot* aFunction; aFunction = fxGetInstance(the, the->stack); if (!mxIsFunction(aFunction)) mxTypeError("C: xsNew: no function"); /* THIS */ if (fxIsBaseFunctionInstance(the, aFunction)) fxCreateInstance(the, aFunction); else mxPushUninitialized(); /* FUNCTION */ the->scratch = *(the->stack); *(the->stack) = *(the->stack + 1); *(the->stack + 1) = the->scratch; /* TARGET */ --(the->stack); *(the->stack) = *(the->stack + 1); /* RESULT */ --(the->stack); *(the->stack) = *(the->stack + 3); fxRunID(the, C_NULL, XS_NO_ID); }
void fxSerializeJSONProperty(txMachine* the, txJSONSerializer* theSerializer, txFlag* theFlag) { txSlot* aWrapper = the->stack + 2; txSlot* aValue = the->stack + 1; txSlot* aKey = the->stack; txSlot* anInstance; txSlot* aProperty; txFlag aFlag; txIndex aLength, anIndex; txFlag aMask; if (mxIsReference(aValue)) { anInstance = fxGetInstance(the, aValue); if (anInstance->flag & XS_LEVEL_FLAG) fxSerializeJSONError(the, theSerializer, XS_TYPE_ERROR); aProperty = fxGetProperty(the, anInstance, the->toJSONID); if (aProperty && mxIsReference(aProperty) && mxIsFunction(fxGetInstance(the, aProperty))) { *(--the->stack) = *aKey; mxInitSlot(--the->stack, XS_INTEGER_KIND); the->stack->value.integer = 1; /* THIS */ *(--the->stack) = *aValue; /* FUNCTION */ *(--the->stack) = *aProperty; /* RESULT */ mxZeroSlot(--the->stack); fxRunID(the, the->toJSONID); *aValue = *(the->stack++); } } else anInstance = C_NULL; if (theSerializer->replacer) { *(--the->stack) = *aKey; *(--the->stack) = *aValue; mxInitSlot(--the->stack, XS_INTEGER_KIND); the->stack->value.integer = 2; /* THIS */ *(--the->stack) = *aWrapper; /* FUNCTION */ *(--the->stack) = *theSerializer->replacer; /* RESULT */ mxZeroSlot(--the->stack); fxRunID(the, XS_NO_ID); *aValue = *(the->stack++); } 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: 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; mxInitSlot(--the->stack, aProperty->kind); the->stack->value = aProperty->value; mxInitSlot(--the->stack, XS_INTEGER_KIND); the->stack->value.integer = anIndex; fxSerializeJSONProperty(the, theSerializer, &aFlag); } theSerializer->level--; fxSerializeJSONIndent(the, theSerializer); fxSerializeJSONChar(the, theSerializer, ']'); anInstance->flag &= ~XS_LEVEL_FLAG; break; case XS_REFERENCE_KIND: case XS_ALIAS_KIND: anInstance = fxGetInstance(the, aValue); if (anInstance->flag & XS_VALUE_FLAG) { aValue = anInstance->next; goto again; } fxSerializeJSONName(the, theSerializer, theFlag); fxSerializeJSONChar(the, theSerializer, '{'); theSerializer->level++; fxSerializeJSONIndent(the, theSerializer); aFlag = 2; if ((the->frame->flag & XS_SANDBOX_FLAG) || (anInstance->flag & XS_SANDBOX_FLAG)) { if (anInstance->flag & XS_SANDBOX_FLAG) anInstance = anInstance->value.instance.prototype; aMask = XS_DONT_ENUM_FLAG | XS_DONT_SCRIPT_FLAG; } else aMask = XS_DONT_ENUM_FLAG | XS_SANDBOX_FLAG; anInstance->flag |= XS_LEVEL_FLAG; aProperty = anInstance->next; while (aProperty) { if (!(aProperty->flag & aMask)) { txID anID = aProperty->ID; if (anID != XS_NO_ID) { mxInitSlot(--the->stack, aProperty->kind); the->stack->value = aProperty->value; if (anID < 0) { txSlot *aSymbol = fxGetSymbol(the, aProperty->ID); mxInitSlot(--the->stack, XS_STRING_KIND); the->stack->value.string = aSymbol->value.symbol.string; } else { mxInitSlot(--the->stack, XS_INTEGER_KIND); the->stack->value.integer = anID; } fxSerializeJSONProperty(the, theSerializer, &aFlag); } } aProperty = aProperty->next; } 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 }
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 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 }
txBoolean fxNewProperty(txMachine* the, txSlot* instance, txInteger ID, txFlag flag, txSlot* slot) { txSlot** address = &(instance->next); txSlot* property; if (ID >= 0) { txSlot* array = C_NULL; while ((property = *address)) { if (property->ID == XS_NO_ID) { if (property->kind == XS_ARRAY_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; } property = fxSetArrayProperty(the, array, ID); property->kind = slot->kind; property->value = slot->value; return 1; } while ((property = *address)) { if (property->ID == ID) break; address = &(property->next); } if (property) { if (property->flag & XS_DONT_DELETE_FLAG) { if (!(flag & XS_DONT_DELETE_FLAG)) return 0; if ((property->flag & XS_DONT_ENUM_FLAG) != (flag & XS_DONT_ENUM_FLAG)) return 0; if (flag & XS_ACCESSOR_FLAG) { if (property->kind != XS_ACCESSOR_KIND) return 0; if (flag & XS_GETTER_FLAG) { if (property->value.accessor.getter != slot->value.reference) return 0; } if (flag & XS_SETTER_FLAG) { if (property->value.accessor.setter != slot->value.reference) return 0; } } else { if (property->kind == XS_ACCESSOR_KIND) return 0; if (property->flag & XS_DONT_SET_FLAG) { if (!(flag & XS_DONT_DELETE_FLAG)) return 0; if (!fxIsSameSlot(the, property, slot)) return 0; } } } } else { if (instance->flag & XS_DONT_PATCH_FLAG) return 0; *address = property = fxNewSlot(the); property->ID = (txID)ID; } if (flag & XS_ACCESSOR_FLAG) { if (property->kind != XS_ACCESSOR_KIND) { property->kind = XS_ACCESSOR_KIND; property->value.accessor.getter = C_NULL; property->value.accessor.setter = C_NULL; } property->flag = flag & ~XS_ACCESSOR_FLAG; if (flag & XS_GETTER_FLAG) property->value.accessor.getter = slot->value.reference; else property->value.accessor.setter = slot->value.reference; slot = mxFunctionInstancePrototype(slot->value.reference); slot->flag = XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG; } else { property->flag = flag; property->kind = slot->kind; property->value = slot->value; if (slot->kind == XS_REFERENCE_KIND) { slot = slot->value.reference; if (mxIsFunction(slot)) { property = mxFunctionInstanceInfo(slot); if (property->value.info.name == XS_NO_ID) property->value.info.name = (txID)ID; } } } return 1; }