Example #1
0
void fx_Function_prototype_get_length(txMachine* the)
{
    txSlot* instance = fxCheckFunctionInstance(the, mxThis);
    txSlot* code = mxFunctionInstanceCode(instance);
    if ((code->kind == XS_CODE_KIND) || (code->kind == XS_CODE_X_KIND))
        mxResult->value.integer = *(code->value.code + 1);
    else
        mxResult->value.integer = mxFunctionInstanceInfo(instance)->value.info.length;
    mxResult->kind = XS_INTEGER_KIND;
}
Example #2
0
void fx_Function(txMachine* the)
{
    txInteger c, i;
    txStringStream stream;

    c = mxArgc;
    i = 0;
    mxPushStringC("(function anonymous(");
    while (c > 1) {
        fxToString(the, mxArgv(i));
        fxConcatString(the, the->stack, mxArgv(i));
        if (c > 2)
            fxConcatStringC(the, the->stack, ", ");
        c--;
        i++;
    }
    fxConcatStringC(the, the->stack, "){");
    if (c > 0) {
        fxToString(the, mxArgv(i));
        fxConcatString(the, the->stack, mxArgv(i));
    }
    fxConcatStringC(the, the->stack, "})");
    stream.slot = the->stack;
    stream.offset = 0;
    stream.size = c_strlen(the->stack->value.string);
    fxRunScript(the, fxParseScript(the, &stream, fxStringGetter, mxProgramFlag), C_NULL, C_NULL, C_NULL, C_NULL);
    if (mxTarget->kind == XS_UNDEFINED_KIND)
        mxPullSlot(mxResult);
    else {
        txSlot* from = fxGetInstance(the, the->stack++);
        txSlot* to = fxGetInstance(the, mxThis);
        txSlot* fromProperty;
        txSlot* toProperty;
        to->next->value.code = from->next->value.code;
        fromProperty = mxFunctionInstancePrototype(from);
        toProperty = mxFunctionInstancePrototype(to);
        *toProperty = *fromProperty;
        fromProperty = mxFunctionInstanceInfo(from);
        toProperty = mxFunctionInstanceInfo(to);
        *toProperty = *fromProperty;
    }
}
Example #3
0
void fx_Function_prototype_get_name(txMachine* the)
{
    txSlot* instance = fxCheckFunctionInstance(the, mxThis);
    txSlot* info = mxFunctionInstanceInfo(instance);
    txSlot* key = fxGetKey(the, info->value.info.name);
    if (key) {
        if (key->kind == XS_KEY_KIND) {
            mxResult->kind = XS_STRING_KIND;
            mxResult->value.string = key->value.key.string;
        }
        else if (key->kind == XS_KEY_X_KIND) {
            mxResult->kind = XS_STRING_X_KIND;
            mxResult->value.string = key->value.key.string;
        }
        else {
            fxCopyStringC(the, mxResult, "[");
            fxConcatStringC(the, mxResult, key->value.string);
            fxConcatStringC(the, mxResult, "]");
        }
        return;
    }
    *mxResult = mxEmptyString;
}
Example #4
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();
}
Example #5
0
txBoolean fxNewProperty(txMachine* the, txSlot* instance, txInteger ID, txFlag flag, txSlot* slot) 
{
	txSlot** address = &(instance->next);
	txSlot* property;
	
	if (ID >= 0) {
		txSlot* array = C_NULL;
		while ((property = *address)) {
			if (property->ID == XS_NO_ID) {
				if (property->kind == XS_ARRAY_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;
		}
		property = fxSetArrayProperty(the, array, ID);
		property->kind = slot->kind;
		property->value = slot->value;
		return 1;
	}
	while ((property = *address)) {
		if (property->ID == ID)
			break;
		address = &(property->next);
	}
	if (property) {
		if (property->flag & XS_DONT_DELETE_FLAG) {
			if (!(flag  & XS_DONT_DELETE_FLAG))
				return 0;
			if ((property->flag & XS_DONT_ENUM_FLAG) != (flag & XS_DONT_ENUM_FLAG))
				return 0;
			if (flag & XS_ACCESSOR_FLAG) {
				if (property->kind != XS_ACCESSOR_KIND)
					return 0;
				if (flag & XS_GETTER_FLAG) {
					if (property->value.accessor.getter != slot->value.reference)
						return 0;
				}
				if (flag & XS_SETTER_FLAG) {
					if (property->value.accessor.setter != slot->value.reference)
						return 0;
				}
			}
			else {
				if (property->kind == XS_ACCESSOR_KIND)
					return 0;
				if (property->flag & XS_DONT_SET_FLAG) {
					if (!(flag  & XS_DONT_DELETE_FLAG))
						return 0;
					if (!fxIsSameSlot(the, property, slot))
						return 0;
				}
			}
		}
	}
	else {
		if (instance->flag & XS_DONT_PATCH_FLAG)
			return 0;
		*address = property = fxNewSlot(the);
		property->ID = (txID)ID;
	}
	if (flag & XS_ACCESSOR_FLAG) {
		if (property->kind != XS_ACCESSOR_KIND) {
			property->kind = XS_ACCESSOR_KIND;
			property->value.accessor.getter = C_NULL;
			property->value.accessor.setter = C_NULL;
		}
		property->flag = flag & ~XS_ACCESSOR_FLAG;
		if (flag & XS_GETTER_FLAG)
			property->value.accessor.getter = slot->value.reference;
		else
			property->value.accessor.setter = slot->value.reference;
		slot = mxFunctionInstancePrototype(slot->value.reference);
		slot->flag = XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG;
	}
	else {
		property->flag = flag;
		property->kind = slot->kind;
		property->value = slot->value;
		if (slot->kind == XS_REFERENCE_KIND) {
			slot = slot->value.reference;
			if (mxIsFunction(slot)) {
				property = mxFunctionInstanceInfo(slot);
				if (property->value.info.name == XS_NO_ID)
					property->value.info.name = (txID)ID;
			}
		}
	}
	return 1;
}