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