示例#1
0
txInteger fxToInteger(txMachine* the, txSlot* theSlot)
{
#if mxOptimize
	if (XS_INTEGER_KIND == theSlot->kind)
		return theSlot->value.integer;				// this is the case over 90% of the time, so avoid the switch
#endif

again:
	switch (theSlot->kind) {
	case XS_UNDEFINED_KIND:
	case XS_NULL_KIND:
		theSlot->kind = XS_INTEGER_KIND;
		theSlot->value.integer = 0;
		break;
	case XS_BOOLEAN_KIND:
		theSlot->kind = XS_INTEGER_KIND;
		if (theSlot->value.boolean == 0)
			theSlot->value.integer = 0;
		else
			theSlot->value.integer = 1;
		break;
	case XS_INTEGER_KIND:
		break;
	case XS_NUMBER_KIND:
		theSlot->kind = XS_INTEGER_KIND;
		switch (c_fpclassify(theSlot->value.number)) {
		case C_FP_INFINITE:
		case C_FP_NAN:
		case C_FP_ZERO:
			theSlot->value.integer = 0;
			break;
		default: {
			#define MODULO 4294967296.0
			txNumber aNumber = c_fmod(c_trunc(theSlot->value.number), MODULO);
			if (aNumber >= MODULO / 2)
				aNumber -= MODULO;
			else if (aNumber < -MODULO / 2)
				aNumber += MODULO;
			theSlot->value.integer = (txInteger)aNumber;
			} break;
		}
		break;
	case XS_STRING_KIND:
	case XS_STRING_X_KIND:
		theSlot->kind = XS_NUMBER_KIND;
		theSlot->value.number = fxStringToNumber(the->dtoa, theSlot->value.string, 1);
		goto again;
	case XS_SYMBOL_KIND:
		mxTypeError("Cannot coerce symbol to integer");
		break;
	case XS_REFERENCE_KIND:
		fxToPrimitive(the, theSlot, XS_NUMBER_HINT);
		goto again;
	default:
		mxTypeError("Cannot coerce to integer");
		break;
	}
	return theSlot->value.integer;
}
示例#2
0
void fx_xs_debug_setBreakpoint(txMachine* the)
{
	if ((mxArgc < 1) || (!mxIsStringPrimitive(mxArgv(0))))
		mxTypeError("file is no string");
	if ((mxArgc < 2) || (!mxIsStringPrimitive(mxArgv(1))))
		mxTypeError("line is no string");
	fxSetBreakpoint(the, mxArgv(0)->value.string, mxArgv(1)->value.string);
}
示例#3
0
void fx_xs_isInstanceOf(txMachine* the)
{
	if ((mxArgc < 1) || (mxArgv(0)->kind != XS_REFERENCE_KIND))
		mxTypeError("instance is no object");
	if ((mxArgc < 2) || (mxArgv(1)->kind != XS_REFERENCE_KIND))
		mxTypeError("prototype is no object");
	mxPushSlot(mxArgv(1));
	mxPushSlot(mxArgv(0));
	mxResult->value.boolean = fxIsInstanceOf(the);
	mxResult->kind = XS_BOOLEAN_KIND;
}
示例#4
0
txSlot* fxToInstance(txMachine* the, txSlot* theSlot)
{
	txSlot* anInstance = C_NULL;
	
	switch (theSlot->kind) {
	case XS_UNDEFINED_KIND:
		mxTypeError("cannot coerce undefined to object");
		break;
	case XS_NULL_KIND:
		mxTypeError("cannot coerce null to object");
		break;
	case XS_BOOLEAN_KIND:
		mxPush(mxBooleanPrototype);
		anInstance = fxNewBooleanInstance(the);
		anInstance->next->value.boolean = theSlot->value.boolean;
		mxPullSlot(theSlot);
		break;
	case XS_INTEGER_KIND:
		mxPush(mxNumberPrototype);
		anInstance = fxNewNumberInstance(the);
		anInstance->next->value.number = theSlot->value.integer;
		mxPullSlot(theSlot);
		break;
	case XS_NUMBER_KIND:
		mxPush(mxNumberPrototype);
		anInstance = fxNewNumberInstance(the);
		anInstance->next->value.number = theSlot->value.number;
		mxPullSlot(theSlot);
		break;
	case XS_STRING_KIND:
	case XS_STRING_X_KIND:
		mxPush(mxStringPrototype);
		anInstance = fxNewStringInstance(the);
		anInstance->next->value.string = theSlot->value.string;
		anInstance->next->next->next->value.integer = fxUnicodeLength(theSlot->value.string);
		mxPullSlot(theSlot);
		break;
	case XS_SYMBOL_KIND:
		mxPush(mxSymbolPrototype);
		anInstance = fxNewSymbolInstance(the);
		anInstance->next->value.ID = theSlot->value.ID;
		mxPullSlot(theSlot);
		break;
	case XS_REFERENCE_KIND:
		anInstance = theSlot->value.reference;
		break;
	default:
		mxTypeError("cannot coerce to instance");
		break;
	}
	return anInstance;
}
示例#5
0
void fx_Date_prototype_valueOf(txMachine* the)
{
	txSlot* slot = fxCheckDate(the, mxThis);
	if (!slot) mxTypeError("this is no date");
	mxResult->kind = XS_NUMBER_KIND;
	mxResult->value = slot->value;
}
示例#6
0
void fx_Boolean_prototype_valueOf(txMachine* the)
{
	txSlot* slot = fxCheckBoolean(the, mxThis);
	if (!slot) mxTypeError("this is no boolean");
	mxResult->kind = slot->kind;
	mxResult->value = slot->value;
}
示例#7
0
txSlot* fx_Date_prototype_getUTC_aux(txMachine* the, txTimeDescription* td)
{
	txSlot* slot = fxCheckDate(the, mxThis);
	txNumber number;
	c_time_t time;
	txInteger year = 0;

	if (!slot) mxTypeError("this is no date");
	number = slot->value.number;
	if (c_isnan(number)) {
		mxResult->value.number = C_NAN;
		mxResult->kind = XS_NUMBER_KIND;
		return C_NULL;
	}
	c_memset(td, 0, sizeof(txTimeDescription));
	td->tm.tm_mday = 1;
	td->ms = (int)c_floor(c_fmod(number, 1000.0));
	number /= 1000.0;
	//if ((number < gxMinTime) || (gxMaxTime < number))
	//	mxTypeError("invalid time");
	
	if(number > TIME_2032) { // 2032 <= number <= 2099
    	year = (int)((number - TIME_2032)/TIME_FourYear);
    	number -= TIME_FourYear * year;
    	year *= 4;
	}
	time = (c_time_t)c_floor(number);
	td->tm = *c_gmtime(&time);
	td->tm.tm_year += year;
	if( (td->ms < 0) && (td->ms > -1000) )
		td->ms = 1000 + td->ms;
	mxResult->kind = XS_INTEGER_KIND;	
	return slot;
}
示例#8
0
void fx_Function_prototype_hasInstance(txMachine* the)
{
    txSlot* instance;
    txSlot* prototype;
    mxResult->value.boolean = 0;
    mxResult->kind = XS_BOOLEAN_KIND;
    if (mxArgc == 0)
        return;
    instance = fxGetInstance(the, mxArgv(0));
    if (!instance)
        return;
    mxPushSlot(mxThis);
    fxGetID(the, mxID(_prototype));
    prototype = fxGetInstance(the, the->stack);
    if (!prototype)
        mxTypeError("prototype is no object");
    while (instance) {
        if (instance == prototype) {
            mxResult->value.boolean = 1;
            break;
        }
        instance = fxGetParent(the, instance);
    }
    the->stack++;
}
示例#9
0
void fx_Symbol_prototype_valueOf(txMachine* the)
{
    txSlot* slot = fxCheckSymbol(the, mxThis);
    if (!slot) mxTypeError("this is no symbol");
    mxResult->kind = slot->kind;
    mxResult->value = slot->value;
}
示例#10
0
void fx_Number_prototype_valueOf(txMachine* the)
{
	txSlot* slot = fxCheckNumber(the, mxThis);
	if (!slot) mxTypeError("this is no number");
	mxResult->kind = slot->kind;
	mxResult->value = slot->value;
}
示例#11
0
void fx_xs_newInstanceOf(txMachine* the)
{
	if ((mxArgc < 1) || (mxArgv(0)->kind != XS_REFERENCE_KIND))
		mxTypeError("prototype is no object");
	mxPushSlot(mxArgv(0));
	fxNewInstanceOf(the);
	mxPullSlot(mxResult);
}
示例#12
0
void fx_Number_prototype_toString(txMachine* the)
{
	char buffer[256];
	txInteger radix;
	txSlot* slot = fxCheckNumber(the, mxThis);
	if (!slot) mxTypeError("this is no number");
	if (mxArgc > 0) {
		radix = fxToInteger(the, mxArgv(0));
		if (radix) {
			if ((radix < 2) || (36 < radix))
				mxRangeError("invalid radix");
		}
		else	
			radix = 10;
	}
	else	
		radix = 10;
	mxResult->kind = slot->kind;
	mxResult->value = slot->value;
	if (radix == 10)
		fxToString(the, mxResult);
	else {
		static char gxDigits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
		txString string = buffer + sizeof(buffer);
		txNumber value;
		txBoolean minus;
		value = mxResult->value.number;
		switch (c_fpclassify(value)) {
		case C_FP_INFINITE:
			if (value < 0)
				fxCopyStringC(the, mxResult, "-Infinity");
			else
				fxCopyStringC(the, mxResult, "Infinity");
			break;
		case C_FP_NAN:
			fxCopyStringC(the, mxResult, "NaN");
			break;
		case C_FP_ZERO:
			fxCopyStringC(the, mxResult, "0");
			break;
		default:
			*(--string) = 0;
			if (value < 0) {
				minus = 1;
				value = -value;
			} 
			else
				minus = 0;
			do {
				*(--string) = gxDigits[(txInteger)c_fmod(value, radix)];
				value = value / radix;
			} while (value >= 1);
			if (minus)
				*(--string) = '-';
			fxCopyStringC(the, mxResult, string);
		}
	}
}
示例#13
0
void fx_xs_debug_setConnected(txMachine* the)
{
	if ((mxArgc < 1) || (mxArgv(0)->kind != XS_BOOLEAN_KIND))
		mxTypeError("argument is no boolean");
	if (mxArgv(0)->value.boolean)
		fxLogin(the);
	else
		fxLogout(the);
}
示例#14
0
txSlot* fxCheckFunctionInstance(txMachine* the, txSlot* slot)
{
    if (slot->kind == XS_REFERENCE_KIND) {
        slot = slot->value.reference;
        if ((slot->next->kind == XS_CALLBACK_KIND) || (slot->next->kind == XS_CODE_KIND) || (slot->next->kind == XS_CODE_X_KIND))
            return slot;
    }
    mxTypeError("this is no Function instance");
    return C_NULL;
}
示例#15
0
txNumber fxToNumber(txMachine* the, txSlot* theSlot)
{
again:
	switch (theSlot->kind) {
	case XS_UNDEFINED_KIND:
		theSlot->kind = XS_NUMBER_KIND;
		theSlot->value.number = C_NAN;
		break;
	case XS_NULL_KIND:
		theSlot->kind = XS_NUMBER_KIND;
		theSlot->value.number = 0;
		break;
	case XS_BOOLEAN_KIND:
		theSlot->kind = XS_NUMBER_KIND;
		if (theSlot->value.boolean == 0)
			theSlot->value.number = 0;
		else
			theSlot->value.number = 1;
		break;
	case XS_INTEGER_KIND:
		theSlot->kind = XS_NUMBER_KIND;
		theSlot->value.number = theSlot->value.integer;
		break;
	case XS_NUMBER_KIND:
		break;
	case XS_STRING_KIND:
	case XS_STRING_X_KIND:
		theSlot->kind = XS_NUMBER_KIND;
		theSlot->value.number = fxStringToNumber(the->dtoa, theSlot->value.string, 1);
		break;
	case XS_SYMBOL_KIND:
		mxTypeError("Cannot coerce symbol to number");
		break;
	case XS_REFERENCE_KIND:
		fxToPrimitive(the, theSlot, XS_NUMBER_HINT);
		goto again;
	default:
		mxTypeError("Cannot coerce to number");
		break;
	}
	return theSlot->value.number;
}
示例#16
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;
    }
}
示例#17
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;
	}
}
示例#18
0
void fxCall(txMachine* the)
{
	txSlot* aFunction;

	aFunction = fxGetInstance(the, the->stack);
	if (!mxIsFunction(aFunction))
		mxTypeError("C: xsCall: no function");
	/* TARGET */
	mxPushUndefined();
	/* RESULT */
	mxPushUndefined();
	fxRunID(the, C_NULL, XS_NO_ID);
}
示例#19
0
void fx_Number_prototype_toPrecision(txMachine* the)
{
	char buffer[256];
	int precision;
	txSlot* slot = fxCheckNumber(the, mxThis);
	if (!slot) mxTypeError("this is no number");
	if (mxArgc > 0) 
		precision = fxToInteger(the, mxArgv(0));
	else	
		precision = 0;
	fxNumberToString(the->dtoa, slot->value.number, buffer, sizeof(buffer), 'g', precision);
	fxCopyStringC(the, mxResult, buffer);
}
示例#20
0
txSlot* fxArgToCallback(txMachine* the, txInteger argi)
{
	if (mxArgc > argi) {
		txSlot* slot = mxArgv(argi);
		if (slot->kind == XS_REFERENCE_KIND) {
			slot = slot->value.reference;
			if (slot->next && ((slot->next->kind == XS_CODE_KIND) || (slot->next->kind == XS_CODE_X_KIND) || (slot->next->kind == XS_CALLBACK_KIND)))
				return slot;
		}
	}
	mxTypeError("callback is no function");
	return C_NULL;
}
示例#21
0
void fx_Symbol_keyFor(txMachine* the)
{
    txSlot* slot;
    txSlot* key;
    if (mxArgc < 1) mxSyntaxError("no sym parameter");
    slot = fxCheckSymbol(the, mxArgv(0));
    if (!slot) mxTypeError("sym is no symbol");
    key = fxGetKey(the, slot->value.ID);
    if (key && ((key->flag & XS_DONT_ENUM_FLAG) == 0)) {
        mxResult->kind = XS_STRING_KIND;
        mxResult->value.string = key->value.key.string;
    }
}
示例#22
0
txString fxToString(txMachine* the, txSlot* theSlot)
{
	char aBuffer[256];
again:
	switch (theSlot->kind) {
	case XS_UNDEFINED_KIND:
		fxCopyStringC(the, theSlot, "undefined");
		break;
	case XS_NULL_KIND:
		fxCopyStringC(the, theSlot, "null");
		break;
	case XS_BOOLEAN_KIND:
		if (theSlot->value.boolean == 0)
			fxCopyStringC(the, theSlot, "false");
		else
			fxCopyStringC(the, theSlot, "true");
		break;
	case XS_INTEGER_KIND:
		fxCopyStringC(the, theSlot, fxIntegerToString(the->dtoa, theSlot->value.integer, aBuffer, sizeof(aBuffer)));
		break;
	case XS_NUMBER_KIND:
		fxCopyStringC(the, theSlot, fxNumberToString(the->dtoa, theSlot->value.number, aBuffer, sizeof(aBuffer), 0, 0));
		break;
	case XS_SYMBOL_KIND:
		mxTypeError("Cannot coerce symbol to string");
		break;
	case XS_STRING_KIND:
	case XS_STRING_X_KIND:
		break;
	case XS_REFERENCE_KIND:
		fxToPrimitive(the, theSlot, XS_STRING_HINT);
		goto again;
	default:
		mxTypeError("Cannot coerce to string");
		break;
	}
	return theSlot->value.string;
}
示例#23
0
void fx_Function_prototype_get_prototype(txMachine* the)
{
    txSlot* instance = fxCheckFunctionInstance(the, mxThis);
    txSlot* slot = mxFunctionInstancePrototype(instance);
    if (slot->kind == XS_NULL_KIND) {
        if (slot->flag & XS_DONT_SET_FLAG)
            return;
        if (instance->flag & XS_SHARED_FLAG)
            mxTypeError("get \"prototype\": shared");
        fxDefaultFunctionPrototype(the, instance, slot);
    }
    mxResult->kind = slot->kind;
    mxResult->value = slot->value;
}
示例#24
0
txBoolean fxToBoolean(txMachine* the, txSlot* theSlot)
{
	switch (theSlot->kind) {
	case XS_UNDEFINED_KIND:
	case XS_NULL_KIND:
		theSlot->kind = XS_BOOLEAN_KIND;
		theSlot->value.boolean = 0;
		break;
	case XS_BOOLEAN_KIND:
		break;
	case XS_INTEGER_KIND:
		theSlot->kind = XS_BOOLEAN_KIND;
		theSlot->value.boolean = (theSlot->value.integer == 0) ? 0 : 1;
		break;
	case XS_NUMBER_KIND:
		theSlot->kind = XS_BOOLEAN_KIND;
		switch (c_fpclassify(theSlot->value.number)) {
		case FP_NAN:
		case FP_ZERO:
			theSlot->value.boolean = 0;
			break;
		default:
			theSlot->value.boolean = 1;
			break;
		}
		break;
	case XS_STRING_KIND:
	case XS_STRING_X_KIND:
		theSlot->kind = XS_BOOLEAN_KIND;
		if (c_strlen(theSlot->value.string) == 0)
			theSlot->value.boolean = 0;
		else
			theSlot->value.boolean = 1;
		break;
	case XS_SYMBOL_KIND:
	case XS_REFERENCE_KIND:
		theSlot->kind = XS_BOOLEAN_KIND;
		theSlot->value.boolean = 1;
		break;
	default:
		mxTypeError("Cannot coerce to boolean");
		break;
	}
	return theSlot->value.boolean;
}
示例#25
0
void fx_Date_prototype_setTime(txMachine* the)
{
	txSlot* slot = fxCheckDate(the, mxThis);
	if (!slot) mxTypeError("this is no date");
	if (mxArgc < 1)
		slot->value.number = C_NAN;
	else {
		txNumber number = fxToNumber(the, mxArgv(0));
		int fpclass = c_fpclassify(number);
		if (fpclass != FP_NAN) {
			if (c_fabs(number) > 8.64e15)
				number = C_NAN;
			else
				number = c_trunc(number);
		}
		slot->value.number = number;
	}
	mxResult->value.number = slot->value.number;
	mxResult->kind = XS_NUMBER_KIND;
}
示例#26
0
void fx_Symbol(txMachine* the)
{
    txID id = the->keyIndex;
    txSlot* description;
    if (mxTarget->kind != XS_UNDEFINED_KIND)
        mxTypeError("new Symbol");
    if (id == the->keyCount)
        mxUnknownError("not enough IDs");
    if (mxArgc > 0) {
        fxToString(the, mxArgv(0));
        description = fxNewSlot(the);
        description->kind = XS_STRING_KIND;
        description->value.string = mxArgv(0)->value.string;
    }
    else
        description = C_NULL;
    the->keyArray[id] = description;
    the->keyIndex++;
    mxResult->kind = XS_SYMBOL_KIND;
    mxResult->value.ID = 0x8000 | id;
}
示例#27
0
void fxNew(txMachine* the)
{
	txSlot* aFunction;

	aFunction = fxGetInstance(the, the->stack);
	if (!mxIsFunction(aFunction))
		mxTypeError("C: xsNew: no function");
	/* THIS */
	if (fxIsBaseFunctionInstance(the, aFunction))
		fxCreateInstance(the, aFunction);
	else
		mxPushUninitialized();
	/* FUNCTION */
	the->scratch = *(the->stack);
	*(the->stack) = *(the->stack + 1);
	*(the->stack + 1) = the->scratch;
	/* TARGET */
	--(the->stack);
	*(the->stack) = *(the->stack + 1);
	/* RESULT */
	--(the->stack);
	*(the->stack) = *(the->stack + 3);
	fxRunID(the, C_NULL, XS_NO_ID);
}
示例#28
0
txUnsigned fxToUnsigned(txMachine* the, txSlot* theSlot)
{
	txUnsigned result;
again:
	switch (theSlot->kind) {
	case XS_UNDEFINED_KIND:
	case XS_NULL_KIND:
		theSlot->kind = XS_INTEGER_KIND;
		result = theSlot->value.integer = 0;
		break;
	case XS_BOOLEAN_KIND:
		theSlot->kind = XS_INTEGER_KIND;
		if (theSlot->value.boolean == 0)
			result = theSlot->value.integer = 0;
		else
			result = theSlot->value.integer = 1;
		break;
	case XS_INTEGER_KIND:
		if (theSlot->value.integer >= 0)
			return (txUnsigned)theSlot->value.integer;
		theSlot->kind = XS_NUMBER_KIND;
		theSlot->value.number = theSlot->value.integer;
		// continue
	case XS_NUMBER_KIND:
		theSlot->kind = XS_INTEGER_KIND;
		switch (c_fpclassify(theSlot->value.number)) {
		case C_FP_INFINITE:
		case C_FP_NAN:
		case C_FP_ZERO:
			result = theSlot->value.integer = 0;
			break;
		default: {
			#define MODULO 4294967296.0
			txNumber aNumber = c_fmod(c_trunc(theSlot->value.number), MODULO);
			if (aNumber < 0)
				aNumber += MODULO;
			result = (txUnsigned)aNumber;
			if (((txInteger)result) >= 0) {
				theSlot->kind = XS_INTEGER_KIND;
				theSlot->value.integer = (txInteger)result;
			}
			else {
				theSlot->kind = XS_NUMBER_KIND;
				theSlot->value.number = aNumber;
			}
			} break;
		}
		break;
	case XS_STRING_KIND:
	case XS_STRING_X_KIND:
		theSlot->kind = XS_NUMBER_KIND;
		theSlot->value.number = fxStringToNumber(the->dtoa, theSlot->value.string, 1);
		goto again;
	case XS_SYMBOL_KIND:
		result = 0;
		mxTypeError("Cannot coerce symbol to unsigned");
		break;
	case XS_REFERENCE_KIND:
		fxToPrimitive(the, theSlot, XS_NUMBER_HINT);
		goto again;
	default:
		result = 0;
		mxTypeError("Cannot coerce to unsigned");
		break;
	}
	return result;
}
示例#29
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();
}
示例#30
0
void fx_Function_prototype_set_name(txMachine* the)
{
    if (the->frame->next->flag & XS_STRICT_FLAG)
        mxTypeError("set \"name\": const");
}