Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
	}
}
Ejemplo n.º 3
0
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++;
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
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);
}
Ejemplo n.º 6
0
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);
}
Ejemplo n.º 7
0
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);
}
Ejemplo n.º 8
0
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;
	}
}
Ejemplo n.º 9
0
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);
}
Ejemplo n.º 10
0
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
}
Ejemplo n.º 11
0
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);
	}
}
Ejemplo n.º 12
0
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
}
Ejemplo n.º 13
0
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;
}