Exemplo n.º 1
0
txMachine* fxBeginHost(txMachine* the)
{
	/* ARGC */
	mxPushInteger(0);
	/* THIS */
	mxPush(mxGlobal);
	/* FUNCTION */
	mxPushUndefined();
	/* TARGET */
	mxPushUndefined();
	/* RESULT */
	mxPushUndefined();
	/* FRAME */
	--the->stack;
	the->stack->next = the->frame;
	the->stack->ID = XS_NO_ID;
	the->stack->flag = XS_C_FLAG;
	the->stack->kind = XS_FRAME_KIND;
	the->stack->value.frame.code = the->code;
	the->stack->value.frame.scope = the->scope;
	the->frame = the->stack;
	/* VARC */
	mxPushInteger(0);
	the->stack->next = C_NULL;
	the->stack->ID = XS_NO_ID;
	the->stack->kind = XS_INTEGER_KIND;
	the->scope = the->stack;
	the->code = mxIDs.value.code;
	return the;
}
Exemplo n.º 2
0
void fxLoadModuleXML(txMachine* the, txString path, txID moduleID)
{
	FskFileMapping map = NULL;
	txFileMapStream fileMapStream;
	txStringStream stringStream;
	txScript* script = NULL;
	
	mxTry(the) {
		fxBeginHost(the);
		xsThrowIfFskErr(FskFileMap(path, &fileMapStream.buffer, &fileMapStream.size, 0, &map));
		fileMapStream.offset = 0;
		mxPushInteger(0);
		mxPushInteger(0);
		mxPushInteger(0);
		mxPushInteger(0);
		mxPushInteger(3);
		fxParse(the, &fileMapStream, fxFileMapGetter, path, 1, xsSourceFlag | xsDebugFlag);
		fxCallID(the, fxID(the, "generate"));
		fxToString(the, the->stack);
		stringStream.slot = the->stack;
		stringStream.size = c_strlen(stringStream.slot->value.string);
		stringStream.offset = 0;
		script = fxParseScript(the, &stringStream, fxStringGetter, mxDebugFlag);
		fxEndHost(the);
	}
	mxCatch(the) {
		break;
	}
	FskFileDisposeMap(map);
	fxResolveModule(the, moduleID, script, NULL, NULL);
}
Exemplo n.º 3
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;
	}
}
Exemplo n.º 4
0
void fxSerializeJSONOwnProperty(txMachine* the, txSlot* theContext, txID id, txIndex index, txSlot* theProperty) 
{
	txJSONSerializer* theSerializer = theContext->value.regexp.code;
	txInteger* theFlag = theContext->value.regexp.offsets;
	if (id) {
		txSlot* key = fxGetKey(the, id);
		if (key && (key->flag & XS_DONT_ENUM_FLAG)) {
			if (key->kind == XS_KEY_KIND) {
				mxPushSlot(theProperty);
				mxPushString(key->value.key.string);
				fxSerializeJSONProperty(the, theSerializer, theFlag);
			}
			else {
				mxPushSlot(theProperty);
				mxPushStringX(key->value.key.string);
				fxSerializeJSONProperty(the, theSerializer, theFlag);
			}
		}
	}
	else {
		mxPushSlot(theProperty);
		mxPushInteger((txInteger)index);
		fxSerializeJSONProperty(the, theSerializer, theFlag);
	}
}
Exemplo n.º 5
0
void fx_Function_prototype_apply(txMachine* the)
{
    txInteger c, i;
    if ((mxArgc < 2) || (mxArgv(1)->kind == XS_UNDEFINED_KIND) || (mxArgv(1)->kind == XS_NULL_KIND))
        c = 0;
    else {
        fxToInstance(the, mxArgv(1));
        mxPushSlot(mxArgv(1));
        fxGetID(the, mxID(_length));
        c = fxToInteger(the, the->stack);
        the->stack++;
        for (i = 0; i < c; i++) {
            mxPushSlot(mxArgv(1));
            fxGetID(the, (txID)i);
        }
    }
    /* ARGC */
    mxPushInteger(c);
    /* THIS */
    if (mxArgc < 1)
        mxPushUndefined();
    else
        mxPushSlot(mxArgv(0));
    /* FUNCTION */
    mxPushSlot(mxThis);
    fxCall(the);
    mxPullSlot(mxResult);
}
Exemplo n.º 6
0
void fx_Function_prototype_bound(txMachine* the)
{
    txSlot* boundArguments;
    txInteger c, i;
    txSlot* argument;

    mxPush(*mxFunction);
    fxGetID(the, mxID(_boundArguments));
    boundArguments = fxGetInstance(the, the->stack);
    the->stack++;
    c = boundArguments->next->value.array.length;
    argument = boundArguments->next->value.array.address;
    for (i = 0; i < c; i++) {
        mxPushSlot(argument);
        argument++;
    }
    for (i = 0; i < mxArgc; i++) {
        mxPushSlot(mxArgv(i));
    }
    /* ARGC */
    mxPushInteger(c + mxArgc);
    /* THIS */
    mxPushSlot(mxFunction);
    fxGetID(the, mxID(_boundThis));
    /* FUNCTION */
    mxPushSlot(mxFunction);
    fxGetID(the, mxID(_boundFunction));
    fxCall(the);
    mxPullSlot(mxResult);
}
Exemplo n.º 7
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;
}
Exemplo n.º 8
0
txBoolean fxCallArrayItem(txMachine* the, txSlot* function, txSlot* array, txIndex index, txSlot* item)
{
	txSlot* slot = array->value.array.address + index;
	if (slot->ID) {
		/* ARG0 */
		mxPushSlot(slot);
		if (item) {
			item->kind = the->stack->kind;
			item->value = the->stack->value;
		}
		/* ARG1 */
		mxPushUnsigned(index);
		/* ARG2 */
		mxPushSlot(mxThis);
		/* ARGC */
		mxPushInteger(3);
		/* THIS */
		if (mxArgc > 1)
			mxPushSlot(mxArgv(1));
		else
			mxPushUndefined();
		/* FUNCTION */
		mxPushReference(function);
		fxCall(the);
		return 1;
	}
	return 0;
}
Exemplo n.º 9
0
void fxBuildHosts(txMachine* the, txInteger c, txHostFunctionBuilder* builder)
{
	mxPushInteger(c);
	mxPushInteger(1);
	mxPush(mxArrayPrototype);
	fxNewArrayInstance(the);
	fxArrayCacheBegin(the, the->stack);
	while (c) {
		if (builder->length >= 0)
			fxNewHostFunction(the, builder->callback, builder->length, (builder->id >= 0) ? ((txID*)(the->code))[builder->id] : XS_NO_ID);
		else
			fxNewHostObject(the, (txDestructor)builder->callback);
		fxArrayCacheItem(the, the->stack + 1, the->stack);
		the->stack++;
		c--;
		builder++;
	}
	fxArrayCacheEnd(the, the->stack);
}
Exemplo n.º 10
0
void fxRunForInProperty(txMachine* the, txSlot* limit, txInteger id, txSlot* property) 
{
	txSlot* slot = the->stack;
	while (slot < limit) {
		if (slot->value.integer == id)
			return;
		slot++;
	}
	mxPushInteger(id);
}
Exemplo n.º 11
0
void fxEnumerate(txMachine* the) 
{
	mxPushInteger(0);
	/* SWAP THIS */
	the->scratch = *(the->stack);
	*(the->stack) = *(the->stack + 1);
	*(the->stack + 1) = the->scratch;
	/* FUNCTION */
	mxPush(mxEnumeratorFunction);
	fxCall(the);
}
Exemplo n.º 12
0
void fx_Date_prototype_toPrimitive(txMachine* the)
{
	if (mxThis->kind == XS_REFERENCE_KIND) {
		txInteger hint = ((mxArgc > 0) && (c_strcmp(fxToString(the, mxArgv(0)), "number") == 0)) ? XS_NUMBER_HINT : XS_STRING_HINT;
		if (hint == XS_STRING_HINT) {
			mxPushInteger(0);
			mxPushSlot(mxThis);
			fxCallID(the, mxID(_toString));
			if (mxIsReference(the->stack)) {
        		the->stack++;
				mxPushInteger(0);
				mxPushSlot(mxThis);
				fxCallID(the, mxID(_valueOf));
			}
		}
		else {
			mxPushInteger(0);
			mxPushSlot(mxThis);
			fxCallID(the, mxID(_valueOf));
			if (mxIsReference(the->stack)) {
        		the->stack++;
				mxPushInteger(0);
				mxPushSlot(mxThis);
				fxCallID(the, mxID(_toString));
			}
		}
        if (mxIsReference(the->stack)) {
            if (hint == XS_STRING_HINT)
                mxTypeError("Cannot coerce object to string");
            else
                mxTypeError("Cannot coerce object to number");
        }
        mxResult->kind = the->stack->kind;
        mxResult->value = the->stack->value;
        the->stack++;
	}
	else {
		mxResult->kind = mxThis->kind;
		mxResult->value = mxThis->value;
	}
}
Exemplo n.º 13
0
void fxParseJSONObject(txMachine* the, txJSONParser* theParser)
{
	txSlot* anObject;
	txSlot* at;
	txSlot* aProperty;

	fxGetNextJSONToken(the, theParser);
	mxPush(mxObjectPrototype);
	anObject = fxNewObjectInstance(the);
	for (;;) {
		if (theParser->token == XS_JSON_TOKEN_RIGHT_BRACE)
			break;
		if (theParser->token != XS_JSON_TOKEN_STRING) {
			mxSyntaxError("missing name");
			break;
		}
		mxPushString(theParser->string->value.string);
		at = fxAt(the, the->stack);
		if (theParser->reviver)
			mxPushString(theParser->string->value.string);
		fxGetNextJSONToken(the, theParser);
		if (theParser->token != XS_JSON_TOKEN_COLON) {
			mxSyntaxError("missing :");
			break;
		}
		fxGetNextJSONToken(the, theParser);
		fxParseJSONValue(the, theParser);
		if (theParser->reviver) {
			mxPushInteger(2);
			mxPushReference(anObject);
			mxPushReference(theParser->reviver);
			fxCall(the);
		}
		if (the->stack->kind != XS_UNDEFINED_KIND) {
			aProperty = fxSetProperty(the, anObject, at->value.at.id, at->value.at.index, XS_OWN);
			aProperty->kind = the->stack->kind;
			aProperty->value = the->stack->value;
		}
		the->stack++;
		the->stack++;
		if (theParser->token != XS_JSON_TOKEN_COMMA)
			break;
		fxGetNextJSONToken(the, theParser);
	}
	if (theParser->token != XS_JSON_TOKEN_RIGHT_BRACE)
		mxSyntaxError("missing }");
	fxGetNextJSONToken(the, theParser);
}
Exemplo n.º 14
0
void fx_setTimeoutCallback(CFRunLoopTimerRef timer, void *info)
{
	txTimeoutData* data = info;
	txMachine* the = data->the;
	fxBeginHost(the);
	{
		mxPush(data->argument);
		/* ARGC */
		mxPushInteger(1);
		/* THIS */
		mxPushUndefined();
		/* FUNCTION */
		mxPush(data->function);
		fxCall(the);
		the->stack++;
	}
	fxEndHost(the);
}
Exemplo n.º 15
0
int fxCompareArrayItem(txMachine* the, txSlot* function, txSlot* array, txInteger i)
{
	txSlot* address = array->value.array.address;
	txSlot* a = address + i;
	txSlot* b = the->stack;
	int result;
	
	if (!(a->ID))
		result = (!(b->ID)) ? 0 : 1;
	else if (!(b->ID))
		result = -1;
	else if (a->kind == XS_UNDEFINED_KIND)
		result = (b->kind == XS_UNDEFINED_KIND) ? 0 : 1;
	else if (b->kind == XS_UNDEFINED_KIND)
		result = -1;
	else {
		mxPushSlot(a);
		mxPushSlot(b);
		if (function) {
			/* ARGC */
			mxPushInteger(2);
			/* THIS */
			mxPushSlot(mxThis);
			/* FUNCTION */
			mxPushReference(function);
			fxCall(the);
			if (the->stack->kind == XS_INTEGER_KIND)
				result = the->stack->value.integer;
			else {
				txNumber number = fxToNumber(the, the->stack);
				result = (number < 0) ? -1 :  (number > 0) ? 1 : 0;
			}
			the->stack++;
		}
		else {
			fxToString(the, the->stack + 1);
			fxToString(the, the->stack);
			result = c_strcmp((the->stack + 1)->value.string, the->stack->value.string);
			the->stack += 2;
		}
	}
	return result;
}
Exemplo n.º 16
0
void fxToPrimitive(txMachine* the, txSlot* theSlot, txInteger theHint)
{
	if (theSlot->kind == XS_REFERENCE_KIND) {
		fxBeginHost(the);
		if (theHint == XS_NO_HINT)
			mxPushString(mxDefaultString.value.string);
		else if (theHint == XS_NUMBER_HINT)
			mxPushString(mxNumberString.value.string);
		else
			mxPushString(mxStringString.value.string);
		mxPushInteger(1);
		mxPushSlot(theSlot);
		fxCallID(the, mxID(_Symbol_toPrimitive));
		theSlot->kind = the->stack->kind;
		theSlot->value = the->stack->value;
		the->stack++;
		fxEndHost(the);
	}
}
Exemplo n.º 17
0
void fx_Function_prototype_call(txMachine* the)
{
    txInteger c, i;
    c = mxArgc;
    i = 1;
    while (i < c) {
        mxPushSlot(mxArgv(i));
        i++;
    }
    /* ARGC */
    mxPushInteger(i - 1);
    /* THIS */
    if (mxArgc < 1)
        mxPushUndefined();
    else
        mxPushSlot(mxArgv(0));
    /* FUNCTION */
    mxPushSlot(mxThis);
    fxCall(the);
    mxPullSlot(mxResult);
}
Exemplo n.º 18
0
void fxReduceArrayItem(txMachine* the, txSlot* function, txSlot* array, txIndex index)
{
	txSlot* slot = array->value.array.address + index;
	if (slot->ID) {
		/* ARG0 */
		mxPushSlot(mxResult);
		/* ARG1 */
		mxPushSlot(slot);
		/* ARG2 */
		mxPushUnsigned(index);
		/* ARG3 */
		mxPushSlot(mxThis);
		/* ARGC */
		mxPushInteger(4);
		/* THIS */
		mxPushUndefined();
		/* FUNCTION */
		mxPushReference(function);
		fxCall(the);
		mxPullSlot(mxResult);
	}
}
Exemplo n.º 19
0
void fxParseJSONValue(txMachine* the, txJSONParser* theParser)
{
	switch (theParser->token) {
	case XS_JSON_TOKEN_FALSE:
		mxPushBoolean(0);
		fxGetNextJSONToken(the, theParser);
		break;
	case XS_JSON_TOKEN_TRUE:
		mxPushBoolean(1);
		fxGetNextJSONToken(the, theParser);
		break;
	case XS_JSON_TOKEN_NULL:
		mxPushNull();
		fxGetNextJSONToken(the, theParser);
		break;
	case XS_JSON_TOKEN_INTEGER:
		mxPushInteger(theParser->integer);
		fxGetNextJSONToken(the, theParser);
		break;
	case XS_JSON_TOKEN_NUMBER:
		mxPushNumber(theParser->number);
		fxGetNextJSONToken(the, theParser);
		break;
	case XS_JSON_TOKEN_STRING:
		mxPushString(theParser->string->value.string);
		fxGetNextJSONToken(the, theParser);
		break;
	case XS_JSON_TOKEN_LEFT_BRACE:
		fxParseJSONObject(the, theParser);
		break;
	case XS_JSON_TOKEN_LEFT_BRACKET:
		fxParseJSONArray(the, theParser);
		break;
	default:
		mxPushUndefined();
		mxSyntaxError("invalid value");
		break;
	}
}
Exemplo n.º 20
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;
	}
}
Exemplo n.º 21
0
void fxIncludeScript(txParser* parser, txString string) 
{
	txBoolean done = 0;
	char* base = NULL;
	char name[PATH_MAX];
	char* slash = NULL;
	char* dot = NULL;
	char* extension = NULL;
	char* url = NULL;
	char* path = NULL;
	FskFileInfo fileInfo;
	FskFileMapping map= NULL;
	txFileMapStream fileMapStream;
	txStringStream stringStream;
	txMachine* the = parser->console;
	fxBeginHost(the);
	{
		mxTry(the) {
			xsThrowIfFskErr(KprPathToURL(parser->path->string, &base));
			FskStrCopy(name, string);
			slash = FskStrRChr(name, '/');
			if (!slash)
				slash = name;
			dot = FskStrRChr(slash, '.');
			if (dot)
				extension = dot;
			else
				extension = name + FskStrLen(name);
			if (!dot)
				FskStrCopy(extension, ".js");
			if (!FskStrCompare(extension, ".js")) {
				xsThrowIfFskErr(KprURLMerge(base, name, &url));
				xsThrowIfFskErr(KprURLToPath(url, &path));
				if (kFskErrNone == FskFileGetFileInfo(path, &fileInfo)) {
					xsThrowIfFskErr(FskFileMap(path, (unsigned char**)&(fileMapStream.buffer), &(fileMapStream.size), 0, &map));
					fileMapStream.offset = 0;
					fxIncludeTree(parser, &fileMapStream, fxFileMapGetter, parser->flags, path);
					done = 1;
					FskFileDisposeMap(map);
					map = NULL;
				}
				FskMemPtrDisposeAt(&path);
				FskMemPtrDisposeAt(&url);
			}
			if (!dot)
				FskStrCopy(extension, ".xml");
			if (!FskStrCompare(extension, ".xml")) {
				xsThrowIfFskErr(KprURLMerge(base, name, &url));
				xsThrowIfFskErr(KprURLToPath(url, &path));
				if (kFskErrNone == FskFileGetFileInfo(path, &fileInfo)) {
					xsThrowIfFskErr(FskFileMap(path, &fileMapStream.buffer, &fileMapStream.size, 0, &map));
					fileMapStream.offset = 0;
					mxPushInteger(0);
					mxPushInteger(0);
					mxPushInteger(0);
					mxPushInteger(0);
					mxPushInteger(3);
					fxParse(the, &fileMapStream, fxFileMapGetter, path, 1, xsSourceFlag | xsDebugFlag);
					fxCallID(the, fxID(the, "generate"));
					fxToString(the, the->stack);
					stringStream.slot = the->stack;
					stringStream.size = c_strlen(stringStream.slot->value.string);
					stringStream.offset = 0;
					fxIncludeTree(parser, &stringStream, fxStringGetter, parser->flags, path);
					done = 1;
					FskFileDisposeMap(map);
					map = NULL;
				}
				FskMemPtrDisposeAt(&path);
				FskMemPtrDisposeAt(&url);
			}
			FskMemPtrDispose(base);
		}
		mxCatch(the) {
			FskFileDisposeMap(map);
			FskMemPtrDispose(path);
			FskMemPtrDispose(url);
			FskMemPtrDispose(base);
			break;
		}
	}
	fxEndHost(the);
	if (!done)	
		fxReportParserError(parser, "include file not found: %s", string);
}
Exemplo n.º 22
0
void fx_Array_from(txMachine* the)
{
	txSlot* list = fxNewInstance(the);
	txSlot* item = list;
	txIndex count = 0;
	txIndex index;
	txSlot* function = C_NULL;
	txSlot* _this = C_NULL;
	txSlot* resultArray;
	txSlot* resultSlot;
	if (mxArgc > 2)
		_this = mxArgv(2);
	if (mxArgc > 1) {
		txSlot* slot = mxArgv(1);
		if (slot->kind == XS_REFERENCE_KIND) {
			slot = slot->value.reference;
			if ((slot->next->kind == XS_CODE_KIND) || (slot->next->kind == XS_CALLBACK_KIND))
				function = slot;
		}
	}
	if (mxArgc > 0) {
		mxPushSlot(mxArgv(0));
		if (fxHasID(the, mxID(_Symbol_iterator))) {
			txSlot* iterator;
			txSlot* result;
			mxPushInteger(0);
			mxPushSlot(mxArgv(0));
			fxCallID(the, mxID(_Symbol_iterator));
			iterator = the->stack;
			{
				mxTry(the) {
					count = 0;
					for(;;) {
						mxCallID(iterator, mxID(_next), 0);
						result = the->stack;
						mxGetID(result, mxID(_done));
						if (fxToBoolean(the, the->stack))
							break;
						the->stack++;
						mxGetID(result, mxID(_value));
						if (function) {
							/* ARG1 */
							mxPushInteger(count);
							/* ARGC */
							mxPushInteger(2);
							/* THIS */
							if (_this)
								mxPushSlot(_this);
							else
								mxPushUndefined();
							/* FUNCTION */
							mxPushReference(function);
							fxCall(the);
						}
						item = fxNextSlotProperty(the, item, the->stack, XS_NO_ID, XS_NO_FLAG);
						the->stack++;
						count++;
					}
				}
				mxCatch(the) {
					mxCallID(iterator, mxID(_return), 0);
					fxJump(the);
				}
			}
			the->stack++;
		}
		else {
Exemplo n.º 23
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
}
Exemplo n.º 24
0
void fxPushCount(txMachine* the, txInteger count)
{
	mxPushInteger(count);
}