Beispiel #1
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);
}
Beispiel #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;
	}
}
Beispiel #3
0
void fxPutID(txMachine* the, txInteger theID, txFlag theFlag, txFlag theMask)
{
	txSlot* anInstance;
	txSlot* aProperty;
	txFlag aFlag = theFlag & ~XS_ACCESSOR_FLAG;
	txFlag aMask = theMask & ~XS_ACCESSOR_FLAG;

	fxToInstance(the, the->stack);
	anInstance = fxGetInstance(the, the->stack);
	if (!anInstance)
		mxDebugID(XS_TYPE_ERROR, "set %s: shared instance", theID);
	aProperty = fxSetProperty(the, anInstance, theID, &aFlag);
	the->stack++;
	aProperty->flag = (aProperty->flag & ~aMask) | aFlag;
	if (theFlag & XS_ACCESSOR_FLAG) {
		if (aProperty->kind != XS_ACCESSOR_KIND) {
			aProperty->kind = XS_ACCESSOR_KIND;
			aProperty->value.accessor.getter = C_NULL;
			aProperty->value.accessor.setter = C_NULL;
		}
		if (theFlag & XS_GETTER_FLAG)
			aProperty->value.accessor.getter = the->stack->value.reference;
		else
			aProperty->value.accessor.setter = the->stack->value.reference;
	}
	else {
		aProperty->kind = the->stack->kind;
		aProperty->value = the->stack->value;
	}
}
Beispiel #4
0
void fx_Error_aux(txMachine* the)
{
	txSlot* aProperty;

	if ((mxArgc > 0) && (mxArgv(0)->kind != XS_UNDEFINED_KIND)) {
		aProperty = fxSetProperty(the, fxGetInstance(the, mxResult), mxID(_message), C_NULL);
		aProperty->value.string = fxToString(the, mxArgv(0));
		aProperty->kind = mxArgv(0)->kind;
	}
}
Beispiel #5
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);
}
Beispiel #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;
}
Beispiel #7
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++;
}