Beispiel #1
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 #2
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);
}
Beispiel #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;
	}
}
Beispiel #4
0
txSlot* fxCoerceToArray(txMachine* the, txSlot* slot)
{
	txSlot* instance = fxToInstance(the, slot);
	txSlot** address = &(instance->next);
	txSlot* array = C_NULL;
	txSlot* property;
	while ((property = *address)) {
		if (property->ID == XS_NO_ID) {
			if ((property->kind == XS_ARRAY_KIND) || (property->kind == XS_PARAMETERS_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;
	}
	return array;
}
Beispiel #5
0
void fxRunForIn(txMachine* the)
{
	txSlot* limit = the->stack;
	txSlot* slot = fxToInstance(the, limit);
	while (slot) {
		fxEachInstanceProperty(the, slot, XS_EACH_ENUMERABLE_FLAG | XS_EACH_STRING_FLAG, fxRunForInProperty, limit, slot);
		slot = fxGetParent(the, slot);
	}
	slot = the->stack;
	while (slot < limit) {
		txInteger id = slot->value.integer;
		if (id < 0) {
			txSlot* key = fxGetKey(the, (txID)id);
			if (key && (key->flag & XS_DONT_ENUM_FLAG)) {
				if (key->kind == XS_KEY_KIND) {
					slot->kind = XS_STRING_KIND;
					slot->value.string = key->value.key.string;
				}
				else {
					slot->kind = XS_STRING_X_KIND;
					slot->value.string = key->value.key.string;
				}
			}
			else {
				slot->kind = XS_SYMBOL_KIND;
				slot->value.ID = (txID)id;
			}
		}
		slot++;
	}
	limit->kind = XS_NULL_KIND;
}
Beispiel #6
0
void fx_Function_apply(txMachine* the)
{
	txInteger aCount, anIndex;
	
	if ((mxArgc < 2) || (mxArgv(1)->kind == XS_UNDEFINED_KIND) || (mxArgv(1)->kind == XS_NULL_KIND))
		aCount = 0;
	else {
		fxToInstance(the, mxArgv(1));
		*(--the->stack) = *mxArgv(1);
		fxGetID(the, the->lengthID);
		aCount = fxToInteger(the, the->stack);
		the->stack++;
		for (anIndex = 0; anIndex < aCount; anIndex++) {
			*(--the->stack) = *mxArgv(1);
			fxGetID(the, (txID)anIndex);
		}
	}
	/* #PARAM */
	mxZeroSlot(--the->stack);
	the->stack->kind = XS_INTEGER_KIND;
	the->stack->value.integer = aCount;
	/* THIS */
	if (mxArgc < 1) {
		mxZeroSlot(--the->stack);
	}
	else
		*(--the->stack) = *mxArgv(0);
	/* FUNCTION */
	*(--the->stack) = *mxThis;
	/* RESULT */
	mxZeroSlot(--the->stack);
	fxRunID(the, XS_NO_ID);
	*mxResult = *(the->stack++);
}
Beispiel #7
0
void fxCopyObject(txMachine* the)
{
	txSlot* toInstance;
	txSlot* fromInstance;
	txSlot* toProperty;
	txSlot* fromProperty;
	txSlot** firstAddress;
	txSlot** lastAddress;

	fxToInstance(the, the->stack + 1);
	toInstance = fxGetInstance(the, the->stack + 1);
	fxToInstance(the, the->stack);
	fromInstance = fxGetInstance(the, the->stack);
	firstAddress = &toInstance->next;
	while ((toProperty = *firstAddress))
		firstAddress = &toProperty->next;
	lastAddress = firstAddress;
	fromProperty = fromInstance->next;
	while (fromProperty) {
		if (fromProperty->ID != XS_NO_ID) {
			toProperty = toInstance->next;
			while (toProperty != *firstAddress) {
				if (toProperty->ID == fromProperty->ID)
					break;
				toProperty = toProperty->next;
			}
			if (toProperty != *firstAddress) {
				toProperty->kind = fromProperty->kind;
				toProperty->value = fromProperty->value;
			}
			else {
				*lastAddress = toProperty = fxNewSlot(the);
				toProperty->ID = fromProperty->ID;
				toProperty->flag = fromProperty->flag;
				toProperty->kind = fromProperty->kind;
				toProperty->value = fromProperty->value;
				lastAddress = &toProperty->next;
			}
		}
		fromProperty = fromProperty->next;
	}	
	the->stack++;
}
Beispiel #8
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;
}
Beispiel #9
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;
	}
}
Beispiel #10
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 #11
0
void fx_Function_prototype_set_prototype(txMachine* the)
{
    txSlot* instance = fxCheckFunctionInstance(the, mxThis);
    txSlot* slot = mxFunctionInstancePrototype(instance);
    if (slot->flag & XS_DONT_SET_FLAG) {
        if (the->frame->next->flag & XS_STRICT_FLAG)
            mxTypeError("set \"prototype\": const");
        return;
    }
    if (instance->flag & XS_SHARED_FLAG)
        mxTypeError("set \"prototype\": shared");
    if ((mxArgc == 0) || (mxArgv(0)->kind == XS_UNDEFINED_KIND) || (mxArgv(0)->kind == XS_NULL_KIND)) {
        slot->kind = XS_NULL_KIND;
    }
    else {
        fxToInstance(the, mxArgv(0));
        slot->value = mxArgv(0)->value;
        slot->kind = mxArgv(0)->kind;
    }
}
Beispiel #12
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;
	}
}
Beispiel #13
0
void fx_Function_prototype_bind(txMachine* the)
{
    txSlot* instance = fxToInstance(the, mxThis);
    txSize length;
    txSlot* slot;
    txID id;
    txSlot* arguments;
    txSlot* argument;
    txSize c = mxArgc, i;

    if (!fxIsFunction(the, instance))
        mxTypeError("this is no Function instance");

    if (fxHasOwnProperty(the, instance, mxID(_length))) {
        mxPushSlot(mxThis);
        fxGetID(the, mxID(_length));
        length = fxToInteger(the, the->stack++);
        if (c > 1)
            length -= c - 1;
        if (length < 0)
            length = 0;
        mxPop();
    }
    else
        length = 0;

    mxPushSlot(mxThis);
    fxGetID(the, mxID(_name));
    mxPushStringC("bound ");
    fxConcatString(the, the->stack, the->stack + 1);
    slot = fxNewName(the, the->stack);
    id = slot->ID;
    mxPop();
    mxPop();

    mxPushReference(instance->value.instance.prototype);
    instance = fxNewFunctionInstance(the, id);
    mxPullSlot(mxResult);

    slot = mxFunctionInstanceCode(instance);
    slot->kind = XS_CALLBACK_KIND;
    slot->value.callback.address = fx_Function_prototype_bound;
    slot->value.callback.IDs = (txID*)mxIDs.value.code;

    slot = mxFunctionInstanceInfo(instance);
    slot->value.info.length = (txID)length;

    slot = fxLastProperty(the, instance);
    slot = fxNextSlotProperty(the, slot, mxThis, mxID(_boundFunction), XS_GET_ONLY);
    if (c > 0)
        slot = fxNextSlotProperty(the, slot, mxArgv(0), mxID(_boundThis), XS_GET_ONLY);
    else
        slot = fxNextUndefinedProperty(the, slot, mxID(_boundThis), XS_GET_ONLY);

    mxPush(mxArrayPrototype);
    arguments = fxNewArrayInstance(the);
    argument = arguments->next;
    for (i = 1; i < c; i++) {
        argument->next = fxNewSlot(the);
        argument = argument->next;
        argument->kind = mxArgv(i)->kind;
        argument->value = mxArgv(i)->value;
    }
    arguments->next->value.array.length = mxArgc - 1;
    fxCacheArray(the, arguments);
    slot = fxNextSlotProperty(the, slot, the->stack, mxID(_boundArguments), XS_GET_ONLY);
    mxPop();
}
Beispiel #14
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);
	}
}