示例#1
0
/*
 *     Copyright (C) 2010-2015 Marvell International Ltd.
 *     Copyright (C) 2002-2010 Kinoma, Inc.
 *
 *     Licensed under the Apache License, Version 2.0 (the "License");
 *     you may not use this file except in compliance with the License.
 *     You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *     Unless required by applicable law or agreed to in writing, software
 *     distributed under the License is distributed on an "AS IS" BASIS,
 *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *     See the License for the specific language governing permissions and
 *     limitations under the License.
 */
void fxBuildJSON(txMachine* the)
{
	txSlot* xs;
	
	mxPush(mxGlobal);
	mxPush(mxObjectPrototype);
	fxNewObjectInstance(the);
	fxNewHostFunction(the, fx_JSON_parse, 2);
	fxQueueID(the, fxID(the, "parse"), XS_DONT_ENUM_FLAG);
	fxNewHostFunction(the, fx_JSON_stringify, 3);
	fxQueueID(the, fxID(the, "stringify"), XS_DONT_ENUM_FLAG);
	fxQueueID(the, fxID(the, "JSON"), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG);
	the->stack++;
	
	xs = fxGetProperty(the, mxGlobal.value.reference, fxID(the, "xs"));
	mxPush(*xs);
	
	mxPush(mxObjectPrototype);
	fxNewObjectInstance(the);
	fxNewHostFunction(the, fx_JSON_parse, 1);
	fxQueueID(the, fxID(the, "parse"), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG);
	fxNewHostFunction(the, fx_JSON_stringify, 1);
	fxQueueID(the, fxID(the, "serialize"), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG);
	fxQueueID(the, fxID(the, "json"), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG);
	
	the->stack++;
}
示例#2
0
void fxBufferFunctionName(txMachine* the, txString buffer, txSize size, txSlot* function, txString suffix)
{
	txSlot* slot = fxGetProperty(the, function, mxID(_name));
	if (slot && ((slot->kind == XS_STRING_KIND) || (slot->kind == XS_STRING_X_KIND))) {
		c_strncat(buffer, slot->value.string, size - c_strlen(buffer) - 1);
		c_strncat(buffer, suffix, size - c_strlen(buffer) - 1);
	}
}
示例#3
0
void fxBufferObjectName(txMachine* the, txString buffer, txSize size, txSlot* object, txString suffix)
{
	txSlot* slot = fxGetProperty(the, object, mxID(_Symbol_toStringTag));
	if (slot && ((slot->kind == XS_STRING_KIND) || (slot->kind == XS_STRING_X_KIND))) {
		c_strncat(buffer, slot->value.string, size - c_strlen(buffer) - 1);
		c_strncat(buffer, suffix, size - c_strlen(buffer) - 1);
	}
}
示例#4
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++);
	}
}
示例#5
0
txBoolean fxHasID(txMachine* the, txInteger theID)
{
	txSlot* anInstance;
	txSlot* aProperty;

	fxToInstance(the, the->stack);
	anInstance = fxGetInstance(the, the->stack);
	aProperty = fxGetProperty(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;
}
示例#6
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;
	}
}
示例#7
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
}
示例#8
0
txSlot* fxSetProperty(txMachine* the, txSlot* theInstance, txInteger theID, txFlag* theFlag) 
{
	txSlot* result;
	txSlot** instanceAddress;
	txSlot* prototype;
	txSlot* aProperty;
	
	mxCheck(the, theInstance->kind == XS_INSTANCE_KIND);
	if (theInstance->flag & XS_SHARED_FLAG) {
		txSlot* alias = the->aliasArray[theInstance->ID];
		txSlot** aliasAddress = C_NULL;
		if (alias) {
			aliasAddress = &(alias->next);
			while ((result = *aliasAddress)) {
				if (result->ID == theID)
					return result;
				aliasAddress = &(result->next);
			}
		}
		aProperty = fxGetProperty(the, theInstance, theID);
		if (!theFlag && aProperty) {
			if (aProperty->kind == XS_ACCESSOR_KIND)
				return aProperty;
			if (aProperty->flag & XS_DONT_SET_FLAG)
				return aProperty;
		}
		if (theInstance->flag & XS_DONT_PATCH_FLAG)
			return C_NULL;
		if (!aliasAddress) {
			alias = fxNewSlot(the);
			alias->kind = XS_INSTANCE_KIND;
			alias->value.instance.garbage = C_NULL;
			alias->value.instance.prototype = C_NULL;
			the->aliasArray[theInstance->ID] = alias;
			aliasAddress = &(alias->next);
		}
		*aliasAddress = result = fxNewSlot(the);
		result->ID = (txID)theID;
		if (aProperty) {
			result->flag = aProperty->flag;
			result->kind = aProperty->kind;
			result->value = aProperty->value;
		}
		else {
			if (theFlag)
				result->flag = *theFlag;
		}
		return result;
	}
	if (theInstance->flag & XS_VALUE_FLAG) {
		if (theID < 0) {
			if (theInstance->next->kind == XS_GLOBAL_KIND)
				return fxSetGlobalProperty(the, theInstance, theID, theFlag);
			if (theInstance->next->kind == XS_STAR_KIND)
				return fxSetStarProperty(the, theInstance, theID);
			if (theInstance->next->kind == XS_PROXY_KIND)
				return fxSetProxyProperty(the, theInstance, theID);
		}
		else {
			if (theInstance->next->kind == XS_TYPED_ARRAY_KIND)
				return fxSetTypedArrayProperty(the, theInstance, theID);
			if (theInstance->next->kind == XS_STRING_KIND)
				return fxSetStringProperty(the, theInstance, theID);
			if (theInstance->next->kind == XS_PARAMETERS_KIND)
				return fxSetParametersProperty(the, theInstance, theID);
			if (theInstance->next->kind == XS_PROXY_KIND)
				return fxSetProxyProperty(the, theInstance, theID);
		}
	}
	if (theID >= 0) {
		instanceAddress = &(theInstance->next);
		while ((aProperty = *instanceAddress)) {
			if (aProperty->ID == XS_NO_ID) {
				if (aProperty->kind == XS_ARRAY_KIND) {
					return fxSetArrayProperty(the, aProperty, theID);
				}
			}
			else
				break;
			instanceAddress = &(aProperty->next);
		}
		*instanceAddress = result = fxNewSlot(the);
		result->next = aProperty;
		result->kind = XS_ARRAY_KIND;
		result->value.array.address = C_NULL;
		result->value.array.length = 0;
		return fxSetArrayProperty(the, result, theID);
	}
	
	instanceAddress = &(theInstance->next);
	while ((result = *instanceAddress)) {
		if (result->ID == theID)
			return result;
		instanceAddress = &(result->next);
	}
	prototype = theInstance->value.instance.prototype;
	if (prototype)
		aProperty = fxGetProperty(the, prototype, theID);
	else
		aProperty = C_NULL;
	if (!theFlag && aProperty) {
		if (aProperty->kind == XS_ACCESSOR_KIND)
			return aProperty;
		if (aProperty->flag & XS_DONT_SET_FLAG)
			return aProperty;
	}
	if (theInstance->flag & XS_DONT_PATCH_FLAG)
		return C_NULL;
	*instanceAddress = result = fxNewSlot(the);
	result->ID = (txID)theID;
	if (aProperty) {
		result->flag = aProperty->flag;
		result->kind = aProperty->kind;
		result->value = aProperty->value;
	}
	else {
		if (theFlag)
			result->flag = *theFlag;
	}
	return result;
}
示例#9
0
txBoolean fxHasProperty(txMachine* the, txSlot* theInstance, txInteger theID) 
{
	if ((theInstance->flag & XS_VALUE_FLAG) && (theInstance->next->kind == XS_PROXY_KIND))
		return fxHasProxyProperty(the, theInstance, theID);
	return (fxGetProperty(the, theInstance, theID)) ? 1 : 0;
}