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); }
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; } }
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; } }
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; } }
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); }
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; }
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++; }