예제 #1
0
void fx_Number_toString(txMachine* the)
{
	txSlot* aNumber;
	txSlot* aProperty;
	txInteger aRadix;
	
	aNumber = fxGetInstance(the, mxThis);
	mxCheckNumber(aNumber);
	aProperty = aNumber->next;
	if (mxArgc > 0) {
		aRadix = fxToInteger(the, mxArgv(0));
		if (aRadix) {
			if ((aRadix < 2) || (36 < aRadix))
				mxDebug0(the, XS_RANGE_ERROR, "invalid radix");
		}
		else	
			aRadix = 10;
	}
	else	
		aRadix = 10;
	mxResult->kind = aProperty->kind;
	mxResult->value = aProperty->value;
	if (aRadix == 10)
		fxToString(the, mxResult);
	else {
		static char gxDigits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
		char aBuffer[256];
		txString aString;
		txNumber aValue;
		txBoolean aMinus;
		
		fxToNumber(the, mxResult);
		aString = aBuffer + sizeof(aBuffer);
		*(--aString) = 0;
		aValue = mxResult->value.number;
		if (aValue < 0) {
			aMinus = 1;
			aValue = -aValue;
		} 
		else
			aMinus = 0;
		do {
			*(--aString) = gxDigits[(txInteger)c_fmod(aValue, aRadix)];
			aValue = aValue / aRadix;
		} while (aValue >= 1);
		if (aMinus)
			*(--aString) = '-';
		fxCopyStringC(the, mxResult, aString);
	}
}
예제 #2
0
void fx_Function_get_length(txMachine* the)
{	
	txSlot* aFunction;
	txSlot* aSlot;

	aFunction = fxGetInstance(the, mxThis);
	mxCheckFunction(aFunction);
	aSlot = aFunction->next;
	if (aSlot->kind == XS_CODE_KIND)
		mxResult->value.integer = *(aSlot->value.code + 4);
	else
		mxResult->value.integer = aSlot->value.callback.length;
	mxResult->kind = XS_INTEGER_KIND;
}
예제 #3
0
txBoolean fxHasOwnID(txMachine* the, txInteger theID)
{
	txSlot* anInstance;
	txSlot* aProperty;

	fxToInstance(the, the->stack);
	anInstance = fxGetInstance(the, the->stack);
	aProperty = fxGetOwnProperty(the, anInstance, theID);
	the->stack++;
	if (aProperty) {
		the->scratch.kind = aProperty->kind;
		the->scratch.value = aProperty->value;
		return 1;
	}
	the->scratch.kind = XS_UNDEFINED_KIND;
	return 0;
}
예제 #4
0
void fx_Number_toPrecision(txMachine* the)
{
	txSlot* aNumber;
	txSlot* aProperty;
	int aPrecision;
	char aBuffer[256];
	
	aNumber = fxGetInstance(the, mxThis);
	mxCheckNumber(aNumber);
	aProperty = aNumber->next;
	if (mxArgc > 0) 
		aPrecision = fxToInteger(the, mxArgv(0));
	else	
		aPrecision = 0;
	fxNumberToString(the, aProperty->value.number, aBuffer, sizeof(aBuffer), 'g', aPrecision);
	fxCopyStringC(the, mxResult, aBuffer);
}
예제 #5
0
void fx_Function_set_prototype(txMachine* the)
{	
	txSlot* aFunction;
	txSlot* aSlot;

	aFunction = fxGetInstance(the, mxThis);
	mxCheckFunction(aFunction);
	aSlot = aFunction->next->next->next;
	if (aSlot->flag & XS_DONT_SET_FLAG)
		mxDebug0(the, XS_NO_ERROR, "set prototype: no permission");
	else {
		if (aFunction->flag & XS_SHARED_FLAG)
			mxDebug0(the, XS_TYPE_ERROR, "Function.set prototype: this is shared");
		fxToInstance(the, mxArgv(0));
		aSlot->value = mxArgv(0)->value;
		aSlot->kind = mxArgv(0)->kind;
	}
}
예제 #6
0
txSlot* fxNewHostConstructor(txMachine* the, txCallback theCallback, txInteger theLength, txInteger name)
{
	txSlot* aStack;
	txSlot* instance;
	txSlot* property;

	fxToInstance(the, the->stack);
	aStack = the->stack;
	instance = fxNewHostFunction(the, theCallback, theLength, name);
	property = fxLastProperty(the, instance);
	fxNextSlotProperty(the, property, aStack, mxID(_prototype), XS_GET_ONLY);
	property = fxSetProperty(the, fxGetInstance(the, aStack), mxID(_constructor), C_NULL);
	property->flag = XS_DONT_ENUM_FLAG;
	property->kind = the->stack->kind;
	property->value = the->stack->value;
	*aStack = *the->stack;
	the->stack++;
	return instance;
}
예제 #7
0
void fx_Enumerator_next(txMachine* the)
{
	txSlot* iterator = fxGetInstance(the, mxThis);
	txSlot* result = iterator->next;
	txSlot* iterable = result->next;
	txSlot* index = iterable->next;
	txSlot* value = result->value.reference->next;
	txSlot* done = value->next;
	if (index) {
		value->kind = index->kind;
		value->value = index->value;
		iterable->next = index->next;
	}
	else {
		value->kind = XS_UNDEFINED_KIND;
		done->value.boolean = 1;
	}
	mxResult->kind = result->kind;
	mxResult->value = result->value;
}
예제 #8
0
void fx_Error_toString(txMachine* the)
{
	txSlot* anError;
	txSlot* aProperty;
	txInteger aLength;
	
	anError = fxGetInstance(the, mxThis);
	aProperty = fxGetProperty(the, anError, fxID(the, "name"));
	--the->stack;
	the->stack->kind = aProperty->kind;
	the->stack->value = aProperty->value;
	if (the->stack->kind == XS_UNDEFINED_KIND) 
		fxCopyStringC(the, the->stack, "Error");
	else	
		fxToString(the, the->stack);
	aProperty = fxGetProperty(the, anError, fxID(the, "message"));
	--the->stack;
	the->stack->kind = aProperty->kind;
	the->stack->value = aProperty->value;
	if (the->stack->kind == XS_UNDEFINED_KIND) 
		fxCopyStringC(the, the->stack, "");
	else	
		fxToString(the, the->stack);
	aLength = c_strlen(the->stack->value.string);
	if (aLength) {
		aLength += c_strlen((the->stack + 1)->value.string) + 2;
		mxResult->value.string = (txString)fxNewChunk(the, aLength + 1);
		mxResult->kind = XS_STRING_KIND;
		c_strcpy(mxResult->value.string, (the->stack + 1)->value.string);
		c_strcat(mxResult->value.string, ": ");
		c_strcat(mxResult->value.string, the->stack->value.string);
		the->stack++;
		the->stack++;
	}
	else {
		the->stack++;
		*mxResult = *(the->stack++);
	}
}
예제 #9
0
void fx_Function_bound(txMachine* the)
{
	txSlot* boundArguments;
	txInteger aCount, anIndex;
	txSlot* aParameter;
	
	mxPush(*mxFunction);
	fxGetID(the, fxID(the, "boundArguments")); 
	boundArguments = fxGetInstance(the, the->stack);
	the->stack++;
	aCount = boundArguments->next->value.array.length;
	aParameter = boundArguments->next->value.array.address;
	for (anIndex = 0; anIndex < aCount; anIndex++) {
		mxZeroSlot(--the->stack);
		the->stack->kind = aParameter->kind;
		the->stack->value = aParameter->value;
		aParameter++;
	}
	for (anIndex = 0; anIndex < mxArgc; anIndex++) {
		mxZeroSlot(--the->stack);
		the->stack->kind = mxArgv(anIndex)->kind;
		the->stack->value = mxArgv(anIndex)->value;
	}
	/* #PARAM */
	mxZeroSlot(--the->stack);
	the->stack->kind = XS_INTEGER_KIND;
	the->stack->value.integer = aCount + mxArgc;
	/* THIS */
	mxPush(*mxFunction);
	fxGetID(the, fxID(the, "boundThis"));
	/* FUNCTION */
	mxPush(*mxFunction);
	fxGetID(the, fxID(the, "boundFunction"));
	/* RESULT */
	mxZeroSlot(--the->stack);
	fxRunID(the, XS_NO_ID);
	*mxResult = *(the->stack++);
}
예제 #10
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;
	}
}
예제 #11
0
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;
}
예제 #12
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);
}
예제 #13
0
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);
	}
}
예제 #14
0
파일: xs6JSON.c 프로젝트: basuke/kinomajs
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
}
예제 #15
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);
	}
}
예제 #16
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
}
예제 #17
0
void fx_Function(txMachine* the)
{	
	txSlot* aFunction;
	txInteger aCount, anIndex, aFileIndex, aLineIndex;
	txFlag aFlag;
	txSlot* aSlot;
	txStringStream aStream;
	txByte* aCode;
	txSlot* aProperty;
	
	if (mxResult->kind == XS_UNDEFINED_KIND) {
		mxPush(mxFunctionPrototype);
		aFunction = fxNewFunctionInstance(the);
		*mxResult = *(the->stack++);
	}
	else
		aFunction = fxGetOwnInstance(the, mxResult);
	mxCheckFunction(aFunction);

	aCount = mxArgc;
	anIndex = 0;
	aFileIndex = aCount - 2;
	aLineIndex = aCount - 1;
	aFlag = XS_NO_FLAG;
	if ((aCount >= 4) && (mxArgv(aLineIndex)->kind == XS_INTEGER_KIND)) {
		aCount -= 2;
		aFlag |= XS_DEBUG_FLAG;
	}
	aSlot = fxGetInstance(the, mxThis);
	if (aSlot && (aSlot->flag & XS_SANDBOX_FLAG))
		aFlag |= XS_SANDBOX_FLAG;
	else
		aFlag |= the->frame->next->flag & XS_SANDBOX_FLAG;
	
	mxZeroSlot(--the->stack);
	fxCopyStringC(the, the->stack, "(");
	while (aCount > 1) {
		fxToString(the, mxArgv(anIndex));
		fxConcatString(the, the->stack, mxArgv(anIndex));
		if (aCount > 2)
			fxConcatStringC(the, the->stack, ", ");
		aCount--;
		anIndex++;
	}
	fxConcatStringC(the, the->stack, "){");
	if (aCount > 0) {
		fxToString(the, mxArgv(anIndex));
		fxConcatString(the, the->stack, mxArgv(anIndex));
	}
	fxConcatStringC(the, the->stack, "}");
		
	aStream.slot = the->stack;
	aStream.offset = 0;
	aStream.size = c_strlen(the->stack->value.string);
#ifdef mxDebug
	if (aFlag & XS_DEBUG_FLAG) 
		aCode = fxParseScript(the, &aStream, fxStringGetter, 
				fxNewFile(the, mxArgv(aFileIndex)), mxArgv(aLineIndex)->value.integer, 
				aFlag, C_NULL);
	else
#endif
		aCode = fxParseScript(the, &aStream, fxStringGetter, C_NULL, 0, 
				aFlag, C_NULL);
	
	aFunction->next->value.code = aCode;
	
	aProperty = fxSetProperty(the, aFunction, the->bodyID, C_NULL);
	aProperty->flag = XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG;
	aProperty->value.string = mxArgv(anIndex)->value.string;
	aProperty->kind = mxArgv(anIndex)->kind;
	the->stack++;
}