예제 #1
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;
}
예제 #2
0
파일: xs6Array.c 프로젝트: openube/kinomajs
txSlot* fxConstructArrayResult(txMachine* the, txSlot* constructor, txUnsigned length)
{
	mxPushUnsigned(length);
	mxPushInteger(1);
	if (constructor) {
		mxPushSlot(constructor);
		fxGetID(the, mxID(_Symbol_species));
	}
	else {
		txSlot* instance = mxThis->value.reference;
		if (mxIsArray(instance)) {
			mxPushSlot(mxThis);
			fxGetID(the, mxID(_constructor));
			if (mxIsReference(the->stack) && mxIsFunction(the->stack->value.reference))
				fxGetID(the, mxID(_Symbol_species));
			else
				the->stack->kind = XS_UNDEFINED_KIND;
		}
		else
			mxPushUndefined();
	}
	if (the->stack->kind == XS_NULL_KIND)
		the->stack->kind = XS_UNDEFINED_KIND;
	if (the->stack->kind == XS_UNDEFINED_KIND) {
		*the->stack = mxGlobal;
		fxGetID(the, mxID(_Array));
	}
	fxNew(the);
	mxPullSlot(mxResult);
	return mxResult->value.reference->next;
}
예제 #3
0
void fx_Function_prototype_bound(txMachine* the)
{
    txSlot* boundArguments;
    txInteger c, i;
    txSlot* argument;

    mxPush(*mxFunction);
    fxGetID(the, mxID(_boundArguments));
    boundArguments = fxGetInstance(the, the->stack);
    the->stack++;
    c = boundArguments->next->value.array.length;
    argument = boundArguments->next->value.array.address;
    for (i = 0; i < c; i++) {
        mxPushSlot(argument);
        argument++;
    }
    for (i = 0; i < mxArgc; i++) {
        mxPushSlot(mxArgv(i));
    }
    /* ARGC */
    mxPushInteger(c + mxArgc);
    /* THIS */
    mxPushSlot(mxFunction);
    fxGetID(the, mxID(_boundThis));
    /* FUNCTION */
    mxPushSlot(mxFunction);
    fxGetID(the, mxID(_boundFunction));
    fxCall(the);
    mxPullSlot(mxResult);
}
예제 #4
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);
}
예제 #5
0
void fx_Error_toString(txMachine* the)
{
	txInteger aLength;
	
	mxPushSlot(mxThis);
	fxGetID(the, mxID(_name));
	if (the->stack->kind == XS_UNDEFINED_KIND) 
		fxCopyStringC(the, the->stack, "Error");
	else	
		fxToString(the, the->stack);
	mxPushSlot(mxThis);
	fxGetID(the, mxID(_message));
	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++;
		mxPullSlot(mxResult);
	}
}
예제 #6
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);
}
예제 #7
0
void fx_Error(txMachine* the)
{
	if (mxTarget->kind == XS_UNDEFINED_KIND) {
		mxPush(mxErrorPrototype);
		fxNewObjectInstance(the);
		mxPullSlot(mxResult);
	}
	fx_Error_aux(the);
}
예제 #8
0
void fx_Enumerator(txMachine* the)
{
	txSlot* iterator;
	if (mxThis->kind == XS_REFERENCE_KIND)
		fxEnumerateInstance(the, mxThis->value.reference);
	else {
		mxPushSlot(mxFunctionInstancePrototype(mxEnumeratorFunction.value.reference));
		iterator = fxNewIteratorInstance(the, mxThis);
		mxPullSlot(mxResult);
		iterator->next->next->next = C_NULL;
	}
}
예제 #9
0
파일: xs6Array.c 프로젝트: openube/kinomajs
void fx_Array(txMachine* the)
{
	txIndex count = (txIndex)mxArgc;
	txBoolean flag = 0;
	txSlot* instance;
	txSlot* array;
	txSlot* argument;
	txSlot* slot;
	if (mxTarget->kind == XS_UNDEFINED_KIND) {
		mxPush(mxArrayPrototype);
		instance = fxNewArrayInstance(the);
		mxPullSlot(mxResult);
		array = instance->next;	
	}
	else
		array = fxCoerceToArray(the, mxThis);
	flag = 0;
	if (count == 1) {
		argument = mxArgv(0);
		if (argument->kind == XS_INTEGER_KIND) {
			flag = 1;
			if ((0 <= argument->value.integer) && (argument->value.integer < XS_MAX_INDEX))
				count = (txIndex)argument->value.integer;
			else
				mxRangeError("invalid length");
		}
		else if (mxArgv(0)->kind == XS_NUMBER_KIND) {
			flag = 1;
			if ((0 <= argument->value.number) && (argument->value.number < XS_MAX_INDEX))
				count = (txIndex)argument->value.number;
			else
				mxRangeError("invalid length");
		}
	}
	array->value.array.address = (txSlot *)fxNewChunk(the, count * sizeof(txSlot));
	array->value.array.length = count;
	slot = array->value.array.address;
	if (flag) {
		c_memset(slot, 0, count * sizeof(txSlot));
	}
	else {
		txIndex index = 0;
		while (index < count) {
			txSlot* argument = mxArgv(index);
			slot->ID = XS_NO_ID;
			slot->kind = argument->kind;
			slot->value = argument->value;
			slot++;
			index++;
		}
	}
}
예제 #10
0
파일: xs6JSON.c 프로젝트: basuke/kinomajs
void fx_JSON_parse(txMachine* the)
{
	volatile txJSONParser* aParser = C_NULL;
	txSlot* slot;

	mxTry(the) {
		if (mxArgc < 1)
			mxSyntaxError("no buffer");
		aParser = c_malloc(sizeof(txJSONParser));
		if (NULL == aParser)
			mxUnknownError("out of memory");
		c_memset((txJSONParser*)aParser, 0, sizeof(txJSONParser));
		if (mxArgc > 1) {
			slot = mxArgv(1);
			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)))
					aParser->reviver = slot;
			}
		}
		slot = mxArgv(0);
		if (slot->kind == XS_REFERENCE_KIND) {
			slot = slot->value.reference->next;
			if (slot && (slot->flag & XS_INTERNAL_FLAG) && (slot->kind == XS_HOST_KIND)) {
				aParser->data = slot->value.host.data;
				aParser->offset = 0;
				mxPushSlot(mxArgv(0));
				fxGetID(the, mxID(_length));
				aParser->size = fxToInteger(the, the->stack++);
			}
		}
		if (!aParser->data) {
			fxToString(the, mxArgv(0));
			aParser->slot = mxArgv(0);
			aParser->offset = 0;
			aParser->size = c_strlen(aParser->slot->value.string);
		}
		fxParseJSON(the, (txJSONParser*)aParser);
		mxPullSlot(mxResult);
		c_free((txJSONParser*)aParser);
		// @@ reviver
	}
	mxCatch(the) {
		if (aParser)
			c_free((txJSONParser*)aParser);
		fxJump(the);
	}
}
예제 #11
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;
    }
}
예제 #12
0
void fx_Function_prototype_call(txMachine* the)
{
    txInteger c, i;
    c = mxArgc;
    i = 1;
    while (i < c) {
        mxPushSlot(mxArgv(i));
        i++;
    }
    /* ARGC */
    mxPushInteger(i - 1);
    /* THIS */
    if (mxArgc < 1)
        mxPushUndefined();
    else
        mxPushSlot(mxArgv(0));
    /* FUNCTION */
    mxPushSlot(mxThis);
    fxCall(the);
    mxPullSlot(mxResult);
}
예제 #13
0
파일: xs6Array.c 프로젝트: openube/kinomajs
void fxReduceArrayItem(txMachine* the, txSlot* function, txSlot* array, txIndex index)
{
	txSlot* slot = array->value.array.address + index;
	if (slot->ID) {
		/* ARG0 */
		mxPushSlot(mxResult);
		/* ARG1 */
		mxPushSlot(slot);
		/* ARG2 */
		mxPushUnsigned(index);
		/* ARG3 */
		mxPushSlot(mxThis);
		/* ARGC */
		mxPushInteger(4);
		/* THIS */
		mxPushUndefined();
		/* FUNCTION */
		mxPushReference(function);
		fxCall(the);
		mxPullSlot(mxResult);
	}
}
예제 #14
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();
}
예제 #15
0
파일: xs6JSON.c 프로젝트: basuke/kinomajs
void fxSerializeJSONProperty(txMachine* the, txJSONSerializer* theSerializer, txInteger* theFlag)
{
	txSlot* aWrapper = the->stack + 2;
	txSlot* aValue = the->stack + 1;
	txSlot* aKey = the->stack;
	txSlot* anInstance;
	txSlot* aProperty;
	txInteger aFlag;
	txIndex aLength, anIndex;
	
	if (mxIsReference(aValue)) {
		anInstance = fxGetInstance(the, aValue);
		if (anInstance->flag & XS_LEVEL_FLAG)
			mxTypeError("cyclic value");
		mxPushSlot(aKey);
		/* COUNT */
		mxPushInteger(1);
		/* THIS */
		mxPushSlot(aValue);
		/* FUNCTION */
		mxPushSlot(aValue);
		fxGetID(the, mxID(_toJSON));
		if (mxIsReference(the->stack) && mxIsFunction(the->stack->value.reference))  {
			fxCall(the);
			mxPullSlot(aValue);
		}
		else {
			the->stack = aKey;
		}
	}
	else
		anInstance = C_NULL;
	if (theSerializer->replacer) {
		mxPushSlot(aKey);
		mxPushSlot(aValue);
		/* COUNT */
		mxPushInteger(2);
		/* THIS */
		mxPushSlot(aWrapper);
		/* FUNCTION */
		mxPushSlot(theSerializer->replacer);
		fxCall(the);
		mxPullSlot(aValue);
	}
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:
	case XS_STRING_X_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;
			mxPushSlot(aProperty);
			mxPushInteger(anIndex);
			fxSerializeJSONProperty(the, theSerializer, &aFlag);
		}
		theSerializer->level--;
		fxSerializeJSONIndent(the, theSerializer);
		fxSerializeJSONChar(the, theSerializer, ']');
		anInstance->flag &= ~XS_LEVEL_FLAG;
		break;
	case XS_REFERENCE_KIND:
		anInstance = fxGetInstance(the, aValue);
		aValue = anInstance->next;
		if (aValue && (aValue->flag & XS_INTERNAL_FLAG) && (aValue->kind != XS_PROXY_KIND)) {
			goto again;
		}
		fxSerializeJSONName(the, theSerializer, theFlag);
		anInstance->flag |= XS_LEVEL_FLAG;
		if (fxIsArray(the, anInstance)) {
			fxSerializeJSONChar(the, theSerializer, '[');
			theSerializer->level++;
			fxSerializeJSONIndent(the, theSerializer);
			aFlag = 4;
			mxPushReference(anInstance);
			fxGetID(the, mxID(_length));
			aLength = fxToInteger(the, the->stack);
			mxPop();
			for (anIndex = 0; anIndex < aLength; anIndex++) {
				mxPushReference(anInstance);
				fxGetID(the, anIndex);
				mxPushInteger(anIndex);
				fxSerializeJSONProperty(the, theSerializer, &aFlag);
			}
			theSerializer->level--;
			fxSerializeJSONIndent(the, theSerializer);
			fxSerializeJSONChar(the, theSerializer, ']');
		}
		else {
			fxSerializeJSONChar(the, theSerializer, '{');
			theSerializer->level++;
			fxSerializeJSONIndent(the, theSerializer);
			aFlag = 2;
			{
				txSlot aContext;
				aContext.value.regexp.code = theSerializer;
				aContext.value.regexp.offsets = &aFlag;
				fxEachInstanceProperty(the, anInstance, XS_EACH_ENUMERABLE_FLAG | XS_EACH_STRING_FLAG | XS_STEP_GET_FLAG, fxSerializeJSONOwnProperty, &aContext, anInstance);
			}
			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
}