void fxSlotToID(txMachine* the, txSlot* slot, txInteger* id) { txString string; txSlot* key; again: if ((slot->kind == XS_INTEGER_KIND) && fxIntegerToIndex(the->dtoa, slot->value.integer, id)) return; if ((slot->kind == XS_NUMBER_KIND) && fxNumberToIndex(the->dtoa, slot->value.number, id)) return; if (slot->kind == XS_SYMBOL_KIND) { *id = slot->value.ID; return; } if (slot->kind == XS_REFERENCE_KIND) { fxToPrimitive(the, slot, XS_STRING_HINT); goto again; } string = fxToString(the, slot); if (!fxStringToIndex(the->dtoa, string, id)) { if (slot->kind == XS_STRING_X_KIND) key = fxNewNameX(the, string); else key = fxNewName(the, slot); *id = key->ID; } }
txSlot* fxAt(txMachine* the, txSlot* slot) { txIndex index; txString string; txSlot* key; again: if ((slot->kind == XS_INTEGER_KIND) && fxIntegerToIndex(the->dtoa, slot->value.integer, &index)) { slot->value.at.id = 0; slot->value.at.index = index; } else if ((slot->kind == XS_NUMBER_KIND) && fxNumberToIndex(the->dtoa, slot->value.number, &index)) { slot->value.at.id = 0; slot->value.at.index = index; } else if (slot->kind == XS_SYMBOL_KIND) { slot->value.at.id = slot->value.symbol; slot->value.at.index = XS_NO_ID; } else { if (slot->kind == XS_REFERENCE_KIND) { fxToPrimitive(the, slot, XS_STRING_HINT); goto again; } string = fxToString(the, slot); if (fxStringToIndex(the->dtoa, string, &index)) { slot->value.at.id = 0; slot->value.at.index = index; } else { if (slot->kind == XS_STRING_X_KIND) key = fxNewNameX(the, string); else key = fxNewName(the, slot); slot->value.at.id = key->ID; slot->value.at.index = XS_NO_ID; } } slot->kind = XS_AT_KIND; return slot; }
txInteger fxSlotToIndex(txMachine* the, txSlot* slot, txIndex* index) { txString string; txSlot* key; again: if ((slot->kind == XS_INTEGER_KIND) && fxIntegerToIndex(the->dtoa, slot->value.integer, index)) return 0; if ((slot->kind == XS_NUMBER_KIND) && fxNumberToIndex(the->dtoa, slot->value.number, index)) return 0; if (slot->kind == XS_SYMBOL_KIND) return slot->value.symbol; if (slot->kind == XS_REFERENCE_KIND) { fxToPrimitive(the, slot, XS_STRING_HINT); goto again; } string = fxToString(the, slot); if (fxStringToIndex(the->dtoa, string, index)) return 0; if (slot->kind == XS_STRING_X_KIND) key = fxNewNameX(the, string); else key = fxNewName(the, slot); return key->ID; }
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(); }