diff --git a/xs/includes/xs.h b/xs/includes/xs.h index 246e3eafe5..260c17ee2f 100644 --- a/xs/includes/xs.h +++ b/xs/includes/xs.h @@ -916,11 +916,11 @@ struct xsHostBuilderRecord { fxPop()) #define xsNewHostFunction(_CALLBACK,_LENGTH) \ - (fxNewHostFunction(the, _CALLBACK, _LENGTH, xsNoID), \ + (fxNewHostFunction(the, _CALLBACK, _LENGTH, xsNoID, xsNoID), \ fxPop()) #define xsNewHostFunctionObject(_CALLBACK,_LENGTH, _NAME) \ - (fxNewHostFunction(the, _CALLBACK, _LENGTH, _NAME), \ + (fxNewHostFunction(the, _CALLBACK, _LENGTH, _NAME, xsNoID), \ fxPop()) #define xsNewHostInstance(_PROTOTYPE) \ @@ -1197,7 +1197,7 @@ struct xsCreationRecord { }; #define xsCreateMachine(_CREATION,_NAME,_CONTEXT) \ - fxCreateMachine(_CREATION, _NAME, _CONTEXT) + fxCreateMachine(_CREATION, _NAME, _CONTEXT, xsNoID) #define xsDeleteMachine(_THE) \ fxDeleteMachine(_THE) @@ -1251,7 +1251,7 @@ struct xsCreationRecord { } while(1) enum { - xsNoID = -1, + xsNoID = 0, xsDefault = 0, xsDontDelete = 2, xsDontEnum = 4, @@ -1373,7 +1373,7 @@ mxImport void fxArrayCacheItem(xsMachine*, xsSlot*, xsSlot*); mxImport void fxBuildHosts(xsMachine*, xsIntegerValue, xsHostBuilder*); mxImport void fxNewHostConstructor(xsMachine*, xsCallback, xsIntegerValue, xsIntegerValue); -mxImport void fxNewHostFunction(xsMachine*, xsCallback, xsIntegerValue, xsIntegerValue); +mxImport void fxNewHostFunction(xsMachine*, xsCallback, xsIntegerValue, xsIntegerValue, xsIntegerValue); mxImport void fxNewHostInstance(xsMachine*); mxImport xsSlot* fxNewHostObject(xsMachine*, xsDestructor); mxImport xsIntegerValue fxGetHostBufferLength(xsMachine*, xsSlot*); @@ -1430,7 +1430,7 @@ mxImport void fxBubble(xsMachine*, xsIntegerValue, void*, xsIntegerValue, xsStri mxImport void fxDebugger(xsMachine*, xsStringValue, xsIntegerValue); mxImport void fxReport(xsMachine*, xsStringValue, ...); -mxImport xsMachine* fxCreateMachine(xsCreation*, xsStringValue, void*); +mxImport xsMachine* fxCreateMachine(xsCreation*, xsStringValue, void*, xsIdentifier); mxImport void fxDeleteMachine(xsMachine*); mxImport xsMachine* fxCloneMachine(xsCreation*, xsMachine*, xsStringValue, void*); mxImport xsMachine* fxPrepareMachine(xsCreation*, void*, xsStringValue, void*, void*); diff --git a/xs/sources/xsAPI.c b/xs/sources/xsAPI.c index 7cf666f7fd..d9cbc6506d 100644 --- a/xs/sources/xsAPI.c +++ b/xs/sources/xsAPI.c @@ -549,7 +549,7 @@ void fxBuildHosts(txMachine* the, txInteger c, const txHostFunctionBuilder* buil the->stack->value.hostFunction.profileID = the->profileID; the->profileID++; #else - fxNewHostFunction(the, builder->callback, builder->length, builder->id); + fxNewHostFunction(the, builder->callback, builder->length, builder->id, XS_NO_ID); #endif } else @@ -570,7 +570,7 @@ txSlot* fxNewHostConstructor(txMachine* the, txCallback theCallback, txInteger t fxToInstance(the, the->stack); aStack = the->stack; - instance = fxNewHostFunction(the, theCallback, theLength, name); + instance = fxNewHostFunction(the, theCallback, theLength, name, XS_NO_ID); instance->flag |= XS_CAN_CONSTRUCT_FLAG; property = fxLastProperty(the, instance); fxNextSlotProperty(the, property, aStack, mxID(_prototype), XS_GET_ONLY); @@ -583,7 +583,7 @@ txSlot* fxNewHostConstructor(txMachine* the, txCallback theCallback, txInteger t return instance; } -txSlot* fxNewHostFunction(txMachine* the, txCallback theCallback, txInteger theLength, txInteger name) +txSlot* fxNewHostFunction(txMachine* the, txCallback theCallback, txInteger theLength, txInteger name, txInteger profileID) { txSlot* instance; txSlot* property; @@ -606,8 +606,10 @@ txSlot* fxNewHostFunction(txMachine* the, txCallback theCallback, txInteger theL /* HOME */ property = property->next = fxNewSlot(the); - property->ID = the->profileID; - the->profileID++; + if (profileID != XS_NO_ID) + property->ID = profileID; + else + property->ID = fxGenerateProfileID(the); property->flag = XS_INTERNAL_FLAG; property->kind = XS_HOME_KIND; property->value.home.object = C_NULL; @@ -1344,7 +1346,7 @@ void fxDebugger(txMachine* the, txString thePath, txInteger theLine) const txByte gxNoCode[3] ICACHE_FLASH_ATTR = { XS_CODE_BEGIN_STRICT, 0, XS_CODE_END }; -txMachine* fxCreateMachine(txCreation* theCreation, txString theName, void* theContext) +txMachine* fxCreateMachine(txCreation* theCreation, txString theName, void* theContext, txID profileID) { txMachine* the = (txMachine* )c_calloc(sizeof(txMachine), 1); if (the) { @@ -1371,7 +1373,7 @@ txMachine* fxCreateMachine(txCreation* theCreation, txString theName, void* theC #ifdef mxDebug the->name = theName; #endif - the->profileID = 2; + the->profileID = (profileID != XS_NO_ID) ? profileID : mxBaseProfileID; fxAllocate(the, theCreation); c_memset(the->nameTable, 0, the->nameModulo * sizeof(txSlot *)); diff --git a/xs/sources/xsAll.h b/xs/sources/xsAll.h index 47f4df4f4d..d118d787cb 100644 --- a/xs/sources/xsAll.h +++ b/xs/sources/xsAll.h @@ -583,7 +583,7 @@ mxExport void fxArrayCacheItem(txMachine*, txSlot*, txSlot*); mxExport void fxBuildHosts(txMachine*, txInteger, const txHostFunctionBuilder*); mxExport txSlot* fxNewHostConstructor(txMachine*, txCallback, txInteger, txInteger); -mxExport txSlot* fxNewHostFunction(txMachine*, txCallback, txInteger, txInteger); +mxExport txSlot* fxNewHostFunction(txMachine*, txCallback, txInteger, txInteger, txInteger); mxExport txSlot* fxNewHostInstance(txMachine* the); mxExport txSlot* fxNewHostObject(txMachine*, txDestructor); mxExport txInteger fxGetHostBufferLength(txMachine* the, txSlot* slot); @@ -648,7 +648,7 @@ mxExport void fxThrowMessage(txMachine* the, txString thePath, txInteger theLine mxExport void fxDebugger(txMachine* the, txString thePath, txInteger theLine); mxExport const txByte gxNoCode[] ICACHE_FLASH_ATTR; -mxExport txMachine* fxCreateMachine(txCreation* theCreation, txString theName, void* theContext); +mxExport txMachine* fxCreateMachine(txCreation* theCreation, txString theName, void* theContext, txID profileID); mxExport void fxDeleteMachine(txMachine*); mxExport txMachine* fxCloneMachine(txCreation* theCreation, txMachine* theMachine, txString theName, void* theContext); mxExport txMachine* fxPrepareMachine(txCreation* creation, txPreparation* preparation, txString name, void* context, void* archive); @@ -2697,9 +2697,36 @@ extern txSlot* fxBuildHostFunction(txMachine* the, txCallback theCallback, txInt #else #define mxCallback(CALLBACK) CALLBACK #define fxBuildHostConstructor(THE, CALLBACK, LENGTH, NAME) fxNewHostConstructor(THE, CALLBACK, LENGTH, NAME) -#define fxBuildHostFunction(THE, CALLBACK, LENGTH, NAME) fxNewHostFunction(THE, CALLBACK, LENGTH, NAME) +#define fxBuildHostFunction(THE, CALLBACK, LENGTH, NAME) fxNewHostFunction(THE, CALLBACK, LENGTH, NAME, XS_NO_ID) #endif +enum { + mxHostProfileID, + mxGarbageCollectorProfileID, + mx_Promise_prototype_finallyAuxProfileID, + mx_Promise_prototype_finallyReturnProfileID, + mx_Promise_prototype_finallyThrowProfileID, + mx_Proxy_revokeProfileID, + mxAsyncGeneratorRejectAwaitProfileID, + mxAsyncGeneratorRejectYieldProfileID, + mxAsyncGeneratorResolveAwaitProfileID, + mxAsyncGeneratorResolveYieldProfileID, + mxAsyncFromSyncIteratorDoneProfileID, + mxCombinePromisesCallbackProfileID, + mxExecuteModulesFulfilledProfileID, + mxExecuteModulesRejectedProfileID, + mxExecuteVirtualModuleSourceProfileID, + mxExecuteVirtualModuleSourceImportProfileID, + mxLoadModulesFulfilledProfileID, + mxLoadModulesRejectedProfileID, + mxNewPromiseCapabilityCallbackProfileID, + mxRejectAwaitProfileID, + mxRejectPromiseProfileID, + mxResolveAwaitProfileID, + mxResolvePromiseProfileID, + mxBaseProfileID +}; + #ifdef __cplusplus } #endif diff --git a/xs/sources/xsArray.c b/xs/sources/xsArray.c index 178763bdac..1dd5185cc2 100644 --- a/xs/sources/xsArray.c +++ b/xs/sources/xsArray.c @@ -87,8 +87,8 @@ void fxBuildArray(txMachine* the) txSlot* property; txSlot* unscopable; - fxNewHostFunction(the, mxCallback(fxArrayLengthGetter), 0, XS_NO_ID); - fxNewHostFunction(the, mxCallback(fxArrayLengthSetter), 1, XS_NO_ID); + fxNewHostFunction(the, mxCallback(fxArrayLengthGetter), 0, XS_NO_ID, XS_NO_ID); + fxNewHostFunction(the, mxCallback(fxArrayLengthSetter), 1, XS_NO_ID, XS_NO_ID); mxPushUndefined(); the->stack->flag = XS_DONT_DELETE_FLAG; the->stack->kind = XS_ACCESSOR_KIND; diff --git a/xs/sources/xsCode.c b/xs/sources/xsCode.c index 733d942d05..574bad0fdf 100644 --- a/xs/sources/xsCode.c +++ b/xs/sources/xsCode.c @@ -274,6 +274,7 @@ txScript* fxParserCode(txParser* parser) case XS_CODE_SET_SUPER: case XS_CODE_SET_VARIABLE: case XS_CODE_SYMBOL: + case XS_CODE_PROFILE: size += 1 + sizeof(txID); break; @@ -444,6 +445,9 @@ txScript* fxParserCode(txParser* parser) symbol->usage++; size += 1 + sizeof(txID); break; + case XS_CODE_PROFILE: + size += 1 + sizeof(txID); + break; case XS_CODE_CONST_CLOSURE_1: case XS_CODE_CONST_LOCAL_1: @@ -648,6 +652,10 @@ txScript* fxParserCode(txParser* parser) id = XS_NO_ID; mxEncodeID(p, id); break; + case XS_CODE_PROFILE: + id = fxGenerateProfileID(parser->console); + mxEncodeID(p, id); + break; case XS_CODE_ARGUMENT: case XS_CODE_ARGUMENTS: @@ -3179,6 +3187,8 @@ void fxFunctionNodeCode(void* it, void* param) fxCoderAddSymbol(param, 1, XS_CODE_FUNCTION, name); else fxCoderAddSymbol(param, 1, XS_CODE_CONSTRUCTOR_FUNCTION, name); + if (coder->parser->flags & mxDebugFlag) + fxCoderAddByte(param, 0, XS_CODE_PROFILE); fxCoderAddBranch(param, 0, XS_CODE_CODE_1, target); if (self->flags & mxFieldFlag) fxCoderAddIndex(param, 0, XS_CODE_BEGIN_STRICT_FIELD, fxCoderCountParameters(coder, self->params)); @@ -3519,6 +3529,8 @@ void fxModuleNodeCode(void* it, void* param) } if (count) { fxCoderAddSymbol(param, 1, XS_CODE_FUNCTION, name); + if (coder->parser->flags & mxDebugFlag) + fxCoderAddByte(param, 0, XS_CODE_PROFILE); fxCoderAddBranch(param, 0, XS_CODE_CODE_1, target); fxCoderAddIndex(param, 0, XS_CODE_BEGIN_STRICT, 0); coder->path = C_NULL; @@ -3557,6 +3569,8 @@ void fxModuleNodeCode(void* it, void* param) fxCoderAddSymbol(param, 1, XS_CODE_ASYNC_FUNCTION, name); else fxCoderAddSymbol(param, 1, XS_CODE_FUNCTION, name); + if (coder->parser->flags & mxDebugFlag) + fxCoderAddByte(param, 0, XS_CODE_PROFILE); fxCoderAddBranch(param, 0, XS_CODE_CODE_1, target); fxCoderAddIndex(param, 0, XS_CODE_BEGIN_STRICT, 0); coder->path = C_NULL; diff --git a/xs/sources/xsCommon.c b/xs/sources/xsCommon.c index d1579ecf36..2745d0cd43 100644 --- a/xs/sources/xsCommon.c +++ b/xs/sources/xsCommon.c @@ -277,7 +277,8 @@ const txString gxCodeNames[XS_CODE_COUNT] = { /* XS_CODE_VOID */ "void", /* XS_CODE_WITH */ "with", /* XS_CODE_WITHOUT */ "without", - /* XS_CODE_YIELD */ "yield" + /* XS_CODE_YIELD */ "yield", + /* XS_CODE_PROFILE */ "profile" }; const txS1 gxCodeSizes[XS_CODE_COUNT] ICACHE_FLASH_ATTR = { @@ -516,7 +517,12 @@ const txS1 gxCodeSizes[XS_CODE_COUNT] ICACHE_FLASH_ATTR = { 1 /* XS_CODE_VOID */, 1 /* XS_CODE_WITH */, 1 /* XS_CODE_WITHOUT */, - 1 /* XS_CODE_YIELD */ + 1 /* XS_CODE_YIELD */, +#ifdef mx32bitID + 5 /* XS_CODE_PROFILE */ +#else + 3 /* XS_CODE_PROFILE */ +#endif }; #if mxUseDefaultCStackLimit diff --git a/xs/sources/xsCommon.h b/xs/sources/xsCommon.h index aec3ec030e..4f38e492c6 100644 --- a/xs/sources/xsCommon.h +++ b/xs/sources/xsCommon.h @@ -374,6 +374,7 @@ enum { XS_CODE_WITH, XS_CODE_WITHOUT, XS_CODE_YIELD, + XS_CODE_PROFILE, XS_CODE_COUNT }; @@ -453,6 +454,7 @@ txFlag fxStringToIndex(void* dtoa, txString theString, txIndex* theIndex); /* ? */ mxExport char* fxCStackLimit(); +mxExport txID fxGenerateProfileID(void* console); mxExport void fxGenerateTag(void* console, txString buffer, txInteger bufferSize, txString path); mxExport void fxVReport(void* console, txString theFormat, c_va_list theArguments); mxExport void fxVReportError(void* console, txString thePath, txInteger theLine, txString theFormat, c_va_list theArguments); diff --git a/xs/sources/xsDataView.c b/xs/sources/xsDataView.c index 03a71f05f2..6644e99a13 100644 --- a/xs/sources/xsDataView.c +++ b/xs/sources/xsDataView.c @@ -247,8 +247,8 @@ void fxBuildDataView(txMachine* the) mxDataViewConstructor = *the->stack; mxPop(); - fxNewHostFunction(the, mxCallback(fxTypedArrayGetter), 0, XS_NO_ID); - fxNewHostFunction(the, mxCallback(fxTypedArraySetter), 1, XS_NO_ID); + fxNewHostFunction(the, mxCallback(fxTypedArrayGetter), 0, XS_NO_ID, XS_NO_ID); + fxNewHostFunction(the, mxCallback(fxTypedArraySetter), 1, XS_NO_ID, XS_NO_ID); mxPushUndefined(); the->stack->flag = XS_DONT_DELETE_FLAG; the->stack->kind = XS_ACCESSOR_KIND; diff --git a/xs/sources/xsDebug.c b/xs/sources/xsDebug.c index 0bdaf88d62..f3a32bf66d 100644 --- a/xs/sources/xsDebug.c +++ b/xs/sources/xsDebug.c @@ -2191,6 +2191,14 @@ void fxReportWarning(txMachine* the, txString thePath, txInteger theLine, txStri #endif } +txID fxGenerateProfileID(void* console) +{ + txMachine* the = console; + txID id = the->profileID; + the->profileID++; + return id; +} + void fxGenerateTag(void* console, txString buffer, txInteger bufferSize, txString path) { txMachine* the = console; diff --git a/xs/sources/xsFunction.c b/xs/sources/xsFunction.c index 4bd8c4ddf9..86caa4d2ac 100644 --- a/xs/sources/xsFunction.c +++ b/xs/sources/xsFunction.c @@ -143,8 +143,6 @@ txSlot* fxNewFunctionInstance(txMachine* the, txID name) /* HOME */ property = property->next = fxNewSlot(the); - property->ID = the->profileID; - the->profileID++; property->flag = XS_INTERNAL_FLAG; property->kind = XS_HOME_KIND; property->value.home.object = C_NULL; @@ -633,13 +631,13 @@ txSlot* fxNewAsyncInstance(txMachine* the) mxPop(); mxPop(); - function = fxNewHostFunction(the, fxResolveAwait, 1, XS_NO_ID); + function = fxNewHostFunction(the, fxResolveAwait, 1, XS_NO_ID, mxResolveAwaitProfileID); home = mxFunctionInstanceHome(function); home->value.home.object = instance; property = fxNextSlotProperty(the, property, the->stack, XS_NO_ID, XS_INTERNAL_FLAG); mxPop(); - function = fxNewHostFunction(the, fxRejectAwait, 1, XS_NO_ID); + function = fxNewHostFunction(the, fxRejectAwait, 1, XS_NO_ID, mxRejectAwaitProfileID); home = mxFunctionInstanceHome(function); home->value.home.object = instance; property = fxNextSlotProperty(the, property, the->stack, XS_NO_ID, XS_INTERNAL_FLAG); diff --git a/xs/sources/xsGenerator.c b/xs/sources/xsGenerator.c index 1b1593108b..568be6a468 100644 --- a/xs/sources/xsGenerator.c +++ b/xs/sources/xsGenerator.c @@ -543,25 +543,25 @@ txSlot* fxNewAsyncGeneratorInstance(txMachine* the) property->value.list.first = C_NULL; property->value.list.last = C_NULL; - function = fxNewHostFunction(the, fxAsyncGeneratorResolveAwait, 1, XS_NO_ID); + function = fxNewHostFunction(the, fxAsyncGeneratorResolveAwait, 1, XS_NO_ID, mxAsyncGeneratorResolveAwaitProfileID); home = mxFunctionInstanceHome(function); home->value.home.object = instance; property = fxNextSlotProperty(the, property, the->stack, XS_NO_ID, XS_INTERNAL_FLAG); mxPop(); - function = fxNewHostFunction(the, fxAsyncGeneratorRejectAwait, 1, XS_NO_ID); + function = fxNewHostFunction(the, fxAsyncGeneratorRejectAwait, 1, XS_NO_ID, mxAsyncGeneratorRejectAwaitProfileID); home = mxFunctionInstanceHome(function); home->value.home.object = instance; property = fxNextSlotProperty(the, property, the->stack, XS_NO_ID, XS_INTERNAL_FLAG); mxPop(); - function = fxNewHostFunction(the, fxAsyncGeneratorResolveYield, 1, XS_NO_ID); + function = fxNewHostFunction(the, fxAsyncGeneratorResolveYield, 1, XS_NO_ID, mxAsyncGeneratorResolveYieldProfileID); home = mxFunctionInstanceHome(function); home->value.home.object = instance; property = fxNextSlotProperty(the, property, the->stack, XS_NO_ID, XS_INTERNAL_FLAG); mxPop(); - function = fxNewHostFunction(the, fxAsyncGeneratorRejectYield, 1, XS_NO_ID); + function = fxNewHostFunction(the, fxAsyncGeneratorRejectYield, 1, XS_NO_ID, mxAsyncGeneratorRejectYieldProfileID); home = mxFunctionInstanceHome(function); home->value.home.object = instance; property = fxNextSlotProperty(the, property, the->stack, XS_NO_ID, XS_INTERNAL_FLAG); @@ -751,7 +751,7 @@ txSlot* fxNewAsyncFromSyncIteratorInstance(txMachine* the) slot = fxNextSlotProperty(the, slot, the->stack, XS_NO_ID, XS_INTERNAL_FLAG); mxPop(); - function = fxNewHostFunction(the, fxAsyncFromSyncIteratorDone, 1, XS_NO_ID); + function = fxNewHostFunction(the, fxAsyncFromSyncIteratorDone, 1, XS_NO_ID, mxAsyncFromSyncIteratorDoneProfileID); home = mxFunctionInstanceHome(function); home->value.home.object = instance; slot = fxNextSlotProperty(the, slot, the->stack, XS_NO_ID, XS_INTERNAL_FLAG); diff --git a/xs/sources/xsGlobal.c b/xs/sources/xsGlobal.c index c511498843..8bd26eaeeb 100644 --- a/xs/sources/xsGlobal.c +++ b/xs/sources/xsGlobal.c @@ -157,7 +157,7 @@ void fxBuildGlobal(txMachine* the) fxNewHostConstructor(the, mxCallback(fx_Enumerator), 0, XS_NO_ID); mxPull(mxEnumeratorFunction); - fxNewHostFunction(the, mxCallback(fxThrowTypeError), 0, XS_NO_ID); + fxNewHostFunction(the, mxCallback(fxThrowTypeError), 0, XS_NO_ID, XS_NO_ID); mxThrowTypeErrorFunction = *the->stack; slot = the->stack->value.reference; slot->flag |= XS_DONT_PATCH_FLAG; diff --git a/xs/sources/xsLockdown.c b/xs/sources/xsLockdown.c index 6964922645..c905988ec6 100644 --- a/xs/sources/xsLockdown.c +++ b/xs/sources/xsLockdown.c @@ -41,7 +41,7 @@ void fxSetHostFunctionProperty(txMachine* the, txSlot* property, txCallback call, txInteger length, txID id) { txSlot* home = the->stack; - txSlot* function = fxNewHostFunction(the, call, length, id); + txSlot* function = fxNewHostFunction(the, call, length, id, XS_NO_ID); txSlot* slot = mxFunctionInstanceHome(function); slot->value.home.object = home->value.reference; property->kind = the->stack->kind; diff --git a/xs/sources/xsModule.c b/xs/sources/xsModule.c index 406c92deb9..ed578de62e 100644 --- a/xs/sources/xsModule.c +++ b/xs/sources/xsModule.c @@ -163,7 +163,7 @@ void fxBuildModule(txMachine* the) { txSlot* slot; - fxNewHostFunction(the, mxCallback(fxModuleGetter), 0, XS_NO_ID); + fxNewHostFunction(the, mxCallback(fxModuleGetter), 0, XS_NO_ID, XS_NO_ID); mxPushUndefined(); the->stack->flag = XS_DONT_DELETE_FLAG; the->stack->kind = XS_ACCESSOR_KIND; @@ -305,12 +305,12 @@ void fxExecuteModules(txMachine* the, txSlot* queue) mxGetID(mxID(_then)); mxCall(); - function = fxNewHostFunction(the, fxExecuteModulesFulfilled, 1, XS_NO_ID); + function = fxNewHostFunction(the, fxExecuteModulesFulfilled, 1, XS_NO_ID, mxExecuteModulesFulfilledProfileID); home = mxFunctionInstanceHome(function); home->value.home.object = queue; home->value.home.module = module->value.reference; - function = fxNewHostFunction(the, fxExecuteModulesRejected, 1, XS_NO_ID); + function = fxNewHostFunction(the, fxExecuteModulesRejected, 1, XS_NO_ID, mxExecuteModulesRejectedProfileID); home = mxFunctionInstanceHome(function); home->value.home.object = queue; home->value.home.module = module->value.reference; @@ -433,7 +433,7 @@ void fxExecuteVirtualModuleSource(txMachine* the) /* ARGUMENTS */ mxPushReference(closures); if (internal->flag & XS_IMPORT_FLAG) { - function = fxNewHostFunction(the, fxExecuteVirtualModuleSourceImport, 1, XS_NO_ID); + function = fxNewHostFunction(the, fxExecuteVirtualModuleSourceImport, 1, XS_NO_ID, mxExecuteVirtualModuleSourceImportProfileID); mxFunctionInstanceHome(function)->value.home.module = module; } else @@ -918,12 +918,12 @@ void fxLoadModules(txMachine* the, txSlot* queue) mxGetID(mxID(_then)); mxCall(); - function = fxNewHostFunction(the, fxLoadModulesFulfilled, 1, XS_NO_ID); + function = fxNewHostFunction(the, fxLoadModulesFulfilled, 1, XS_NO_ID, mxLoadModulesFulfilledProfileID); home = mxFunctionInstanceHome(function); home->value.home.object = queue; home->value.home.module = module->value.reference; - function = fxNewHostFunction(the, fxLoadModulesRejected, 1, XS_NO_ID); + function = fxNewHostFunction(the, fxLoadModulesRejected, 1, XS_NO_ID, mxLoadModulesRejectedProfileID); home = mxFunctionInstanceHome(function); home->value.home.object = queue; home->value.home.module = module->value.reference; @@ -1105,7 +1105,7 @@ void fxLoadVirtualModuleSource(txMachine* the, txSlot* record, txSlot* instance) if (!fxIsCallable(the, slot)) mxTypeError("execute is no function"); } - function = fxNewHostFunction(the, fxExecuteVirtualModuleSource, 0, XS_NO_ID); + function = fxNewHostFunction(the, fxExecuteVirtualModuleSource, 0, XS_NO_ID, mxExecuteVirtualModuleSourceProfileID); property = mxFunctionInstanceHome(function); property->value.home.object = fxToInstance(the, record); property->value.home.module = instance; diff --git a/xs/sources/xsObject.c b/xs/sources/xsObject.c index 4bd8548218..4120788e8b 100644 --- a/xs/sources/xsObject.c +++ b/xs/sources/xsObject.c @@ -40,13 +40,13 @@ void fxBuildObject(txMachine* the) { txSlot* slot; - fxNewHostFunction(the, mxCallback(fx_Object_assign), 2, XS_NO_ID); + fxNewHostFunction(the, mxCallback(fx_Object_assign), 2, XS_NO_ID, XS_NO_ID); mxAssignObjectFunction = *the->stack; mxPop(); - fxNewHostFunction(the, mxCallback(fx_Object_copy), 2, XS_NO_ID); + fxNewHostFunction(the, mxCallback(fx_Object_copy), 2, XS_NO_ID, XS_NO_ID); mxCopyObjectFunction = *the->stack; mxPop(); - fxNewHostFunction(the, mxCallback(fxOrdinaryToPrimitive), 2, XS_NO_ID); + fxNewHostFunction(the, mxCallback(fxOrdinaryToPrimitive), 2, XS_NO_ID, XS_NO_ID); mxOrdinaryToPrimitiveFunction = *the->stack; mxPop(); diff --git a/xs/sources/xsProfile.c b/xs/sources/xsProfile.c index 5bde0bbb5c..3fdda28528 100644 --- a/xs/sources/xsProfile.c +++ b/xs/sources/xsProfile.c @@ -35,7 +35,12 @@ * limitations under the License. */ + +#define _GNU_SOURCE #include "xsAll.h" +#if mxMacOSX || mxLinux +#include +#endif #ifdef mxProfile @@ -63,6 +68,7 @@ struct sxProfilerRecord { txID constructorID; txID prototypeID; txID functionID; + txCallback functionAddress; txID file; txInteger line; txInteger hitCount; @@ -190,6 +196,7 @@ txProfilerRecord* fxFrameToProfilerRecord(txMachine* the, txSlot* frame) if (function->kind == XS_REFERENCE_KIND) { function = function->value.reference; if (mxIsFunction(function)) { + txSlot* code = mxFunctionInstanceCode(function); txSlot* home = mxFunctionInstanceHome(function); txID recordID = home->ID; txProfilerRecord* record = C_NULL; @@ -198,8 +205,8 @@ txProfilerRecord* fxFrameToProfilerRecord(txMachine* the, txSlot* frame) if (record) return record; record = fxNewProfilerRecord(the, recordID); - record->functionID = mxFunctionInstanceCode(function)->ID; - home = mxFunctionInstanceHome(function)->value.home.object; + record->functionID = code->ID; + home = home->value.home.object; if (home) { if (mxIsFunction(home)) { record->constructorID = mxFunctionInstanceCode(home)->ID; @@ -237,7 +244,6 @@ txProfilerRecord* fxFrameToProfilerRecord(txMachine* the, txSlot* frame) } } } - txSlot* code = mxFunctionInstanceCode(function); if ((code->kind == XS_CODE_KIND) || (code->kind == XS_CODE_X_KIND)) { txByte* p = code->value.code.address + 2; if (*p == XS_CODE_FILE) { @@ -250,7 +256,10 @@ txProfilerRecord* fxFrameToProfilerRecord(txMachine* the, txSlot* frame) record->file = file; record->line = line; } + record->functionAddress = C_NULL; } + else + record->functionAddress = code->value.callback.address; return record; } } @@ -393,7 +402,11 @@ void fxPrintProfiler(txMachine* the) if (recordIndex > 0) fprintf(file, ","); fprintf(file, "{\"id\":%d,\"callFrame\":{\"functionName\":\"", record->recordID); - if (record->functionID != XS_NO_ID) { + if (recordIndex == 0) + fprintf(file, "(host)"); + else if (recordIndex == 1) + fprintf(file, "(garbage collector)"); + else if (record->functionID != XS_NO_ID) { if (record->constructorID != XS_NO_ID) { fxPrintID(the, file, record->constructorID); fprintf(file, "."); @@ -404,10 +417,17 @@ void fxPrintProfiler(txMachine* the) } fxPrintID(the, file, record->functionID); } - else if (recordIndex == 0) - fprintf(file, "(host)"); - else if (recordIndex == 1) - fprintf(file, "(garbage collector)"); + else if (record->functionAddress) { +#if mxMacOSX || mxLinux + Dl_info info; + if (dladdr(record->functionAddress, &info) && info.dli_sname) + fprintf(file, "@%s",info.dli_sname ); + else +#endif + fprintf(file, "@anonymous"); + } + else + fprintf(file, "(anonymous)"); fprintf(file, "\",\"scriptId\":\"0\",\"url\":\""); if (record->file != XS_NO_ID) @@ -531,4 +551,6 @@ txU8 fxTicksToMicroseconds(txU8 ticks) #endif } + + #endif /* mxProfile */ diff --git a/xs/sources/xsPromise.c b/xs/sources/xsPromise.c index 67b62ea332..97a4d73e19 100644 --- a/xs/sources/xsPromise.c +++ b/xs/sources/xsPromise.c @@ -73,13 +73,13 @@ void fxBuildPromise(txMachine* the) slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Promise_resolve), 1, mxID(_resolve), XS_DONT_ENUM_FLAG); slot = fxNextHostAccessorProperty(the, slot, mxCallback(fx_species_get), C_NULL, mxID(_Symbol_species), XS_DONT_ENUM_FLAG); mxPop(); - fxNewHostFunction(the, mxCallback(fxOnRejectedPromise), 1, XS_NO_ID); + fxNewHostFunction(the, mxCallback(fxOnRejectedPromise), 1, XS_NO_ID, XS_NO_ID); mxOnRejectedPromiseFunction = *the->stack; mxPop(); - fxNewHostFunction(the, mxCallback(fxOnResolvedPromise), 1, XS_NO_ID); + fxNewHostFunction(the, mxCallback(fxOnResolvedPromise), 1, XS_NO_ID, XS_NO_ID); mxOnResolvedPromiseFunction = *the->stack; mxPop(); - fxNewHostFunction(the, mxCallback(fxOnThenable), 1, XS_NO_ID); + fxNewHostFunction(the, mxCallback(fxOnThenable), 1, XS_NO_ID, XS_NO_ID); mxOnThenableFunction = *the->stack; mxPop(); } @@ -141,7 +141,7 @@ txSlot* fxNewPromiseCapability(txMachine* the, txSlot* resolveFunction, txSlot* txSlot* slot; txSlot* function; mxNew(); - resolveFunction->value.reference = fxNewHostFunction(the, fxNewPromiseCapabilityCallback, 2, XS_NO_ID); + resolveFunction->value.reference = fxNewHostFunction(the, fxNewPromiseCapabilityCallback, 2, XS_NO_ID, mxNewPromiseCapabilityCallbackProfileID); resolveFunction->kind = XS_REFERENCE_KIND; mxRunCount(1); capability = resolveFunction->value.reference; @@ -440,7 +440,7 @@ txSlot* fxNewCombinePromisesFunction(txMachine* the, txInteger which, txSlot* al txSlot* result; txSlot* instance; txSlot* property; - result = fxNewHostFunction(the, fxCombinePromisesCallback, 1, XS_NO_ID); + result = fxNewHostFunction(the, fxCombinePromisesCallback, 1, XS_NO_ID, mxCombinePromisesCallbackProfileID); instance = fxNewInstance(the); property = fxNextIntegerProperty(the, instance, which, XS_NO_ID, XS_NO_FLAG); property = property->next = fxNewSlot(the); @@ -612,8 +612,8 @@ void fxPushPromiseFunctions(txMachine* the, txSlot* promise) txSlot* reject; txSlot* object; txSlot* slot; - resolve = fxNewHostFunction(the, fxResolvePromise, 1, XS_NO_ID); - reject = fxNewHostFunction(the, fxRejectPromise, 1, XS_NO_ID); + resolve = fxNewHostFunction(the, fxResolvePromise, 1, XS_NO_ID, mxResolvePromiseProfileID); + reject = fxNewHostFunction(the, fxRejectPromise, 1, XS_NO_ID, mxRejectPromiseProfileID); slot = object = fxNewInstance(the); slot = object->next = fxNewSlot(the); slot->kind = XS_BOOLEAN_KIND; @@ -960,7 +960,7 @@ void fx_Promise_prototype_finally(txMachine* the) mxCall(); if (mxArgc > 0) { if (mxIsReference(mxArgv(0)) && mxIsCallable(mxArgv(0)->value.reference)) { - txSlot* function = fxNewHostFunction(the, fx_Promise_prototype_finallyAux, 1, XS_NO_ID); + txSlot* function = fxNewHostFunction(the, fx_Promise_prototype_finallyAux, 1, XS_NO_ID, mx_Promise_prototype_finallyAuxProfileID); txSlot* object = fxNewInstance(the); txSlot* slot = object->next = fxNewSlot(the); slot->kind = XS_REFERENCE_KIND; @@ -975,7 +975,7 @@ void fx_Promise_prototype_finally(txMachine* the) slot->value.home.object = object; mxPop(); - function = fxNewHostFunction(the, fx_Promise_prototype_finallyAux, 1, XS_NO_ID); + function = fxNewHostFunction(the, fx_Promise_prototype_finallyAux, 1, XS_NO_ID, mx_Promise_prototype_finallyAuxProfileID); object = fxNewInstance(the); slot = object->next = fxNewSlot(the); slot->kind = XS_REFERENCE_KIND; @@ -1045,9 +1045,9 @@ void fx_Promise_prototype_finallyAux(txMachine* the) mxCall(); if (success->value.boolean) - function = fxNewHostFunction(the, fx_Promise_prototype_finallyReturn, 0, XS_NO_ID); + function = fxNewHostFunction(the, fx_Promise_prototype_finallyReturn, 0, XS_NO_ID, mx_Promise_prototype_finallyReturnProfileID); else - function = fxNewHostFunction(the, fx_Promise_prototype_finallyThrow, 0, XS_NO_ID); + function = fxNewHostFunction(the, fx_Promise_prototype_finallyThrow, 0, XS_NO_ID, mx_Promise_prototype_finallyThrowProfileID); object = fxNewInstance(the); slot = object->next = fxNewSlot(the); slot->kind = mxArgv(0)->kind; diff --git a/xs/sources/xsProperty.c b/xs/sources/xsProperty.c index 004d87cfde..a1a07c0c4b 100644 --- a/xs/sources/xsProperty.c +++ b/xs/sources/xsProperty.c @@ -77,7 +77,7 @@ txSlot* fxNextHostAccessorProperty(txMachine* the, txSlot* property, txCallback txSlot* fxNextHostFunctionProperty(txMachine* the, txSlot* property, txCallback call, txInteger length, txID id, txFlag flag) { txSlot *function, *home = the->stack, *slot; - function = fxNewHostFunction(the, call, length, id); + function = fxNewHostFunction(the, call, length, id, XS_NO_ID); slot = mxFunctionInstanceHome(function); slot->value.home.object = home->value.reference; property = property->next = fxNewSlot(the); diff --git a/xs/sources/xsProxy.c b/xs/sources/xsProxy.c index ea001877ce..e5795556a3 100644 --- a/xs/sources/xsProxy.c +++ b/xs/sources/xsProxy.c @@ -78,8 +78,8 @@ void fxBuildProxy(txMachine* the) { txSlot* slot; - fxNewHostFunction(the, mxCallback(fxProxyGetter), 0, XS_NO_ID); - fxNewHostFunction(the, mxCallback(fxProxySetter), 1, XS_NO_ID); + fxNewHostFunction(the, mxCallback(fxProxyGetter), 0, XS_NO_ID, XS_NO_ID); + fxNewHostFunction(the, mxCallback(fxProxySetter), 1, XS_NO_ID, XS_NO_ID); mxPushUndefined(); the->stack->flag = XS_DONT_DELETE_FLAG; the->stack->kind = XS_ACCESSOR_KIND; @@ -828,7 +828,7 @@ void fx_Proxy_revocable(txMachine* the) slot->value.proxy.handler = handler; property = fxNextSlotProperty(the, property, the->stack, mxID(_proxy), XS_GET_ONLY); - slot = fxLastProperty(the, fxNewHostFunction(the, mxCallback(fx_Proxy_revoke), 0, XS_NO_ID)); + slot = fxLastProperty(the, fxNewHostFunction(the, mxCallback(fx_Proxy_revoke), 0, XS_NO_ID, XS_NO_ID)); slot = fxNextSlotProperty(the, slot, the->stack + 1, mxID(_proxy), XS_GET_ONLY); property = fxNextSlotProperty(the, property, the->stack, mxID(_revoke), XS_GET_ONLY); diff --git a/xs/sources/xsRegExp.c b/xs/sources/xsRegExp.c index 3596cf5b3b..db0c8679a3 100644 --- a/xs/sources/xsRegExp.c +++ b/xs/sources/xsRegExp.c @@ -76,7 +76,7 @@ void fxBuildRegExp(txMachine* the) slot = fxLastProperty(the, slot); slot = fxNextHostAccessorProperty(the, slot, mxCallback(fx_species_get), C_NULL, mxID(_Symbol_species), XS_DONT_ENUM_FLAG); mxPop(); - fxNewHostFunction(the, mxCallback(fxInitializeRegExp), 2, XS_NO_ID); + fxNewHostFunction(the, mxCallback(fxInitializeRegExp), 2, XS_NO_ID, XS_NO_ID); mxInitializeRegExpFunction = *the->stack; mxPush(mxIteratorPrototype); diff --git a/xs/sources/xsRun.c b/xs/sources/xsRun.c index 40dc5afc87..20e731c31e 100644 --- a/xs/sources/xsRun.c +++ b/xs/sources/xsRun.c @@ -636,6 +636,7 @@ void fxRunID(txMachine* the, txSlot* generator, txInteger count) &&XS_CODE_WITH, &&XS_CODE_WITHOUT, &&XS_CODE_YIELD, + &&XS_CODE_PROFILE, }; register void * const *bytes = gxBytes; #endif @@ -2694,6 +2695,12 @@ void fxRunID(txMachine* the, txSlot* generator, txInteger count) mxRestoreState; mxNextCode(1 + sizeof(txID)); mxBreak; + mxCase(XS_CODE_PROFILE) + offset = mxRunID(1); + variable = mxFunctionInstanceHome(mxStack->value.reference); + variable->ID = offset; + mxNextCode(1 + sizeof(txID)); + mxBreak; mxCase(XS_CODE_NAME) offset = mxRunID(1); #ifdef mxTrace @@ -4833,6 +4840,7 @@ void fxRunScript(txMachine* the, txScript* script, txSlot* _this, txSlot* _targe instance->next->value.code.address = script->codeBuffer; instance->next->value.code.closures = closures; property = mxFunctionInstanceHome(instance); + property->ID = fxGenerateProfileID(the); property->value.home.object = object; property->value.home.module = module; /* TARGET */ diff --git a/xs/sources/xsString.c b/xs/sources/xsString.c index 0d7ec8d308..a87a2c554a 100644 --- a/xs/sources/xsString.c +++ b/xs/sources/xsString.c @@ -91,8 +91,8 @@ void fxBuildString(txMachine* the) { txSlot* slot; - fxNewHostFunction(the, mxCallback(fxStringAccessorGetter), 0, XS_NO_ID); - fxNewHostFunction(the, mxCallback(fxStringAccessorSetter), 1, XS_NO_ID); + fxNewHostFunction(the, mxCallback(fxStringAccessorGetter), 0, XS_NO_ID, XS_NO_ID); + fxNewHostFunction(the, mxCallback(fxStringAccessorSetter), 1, XS_NO_ID, XS_NO_ID); mxPushUndefined(); the->stack->flag = XS_DONT_DELETE_FLAG; the->stack->kind = XS_ACCESSOR_KIND; diff --git a/xs/sources/xsType.c b/xs/sources/xsType.c index e50984a3c3..3658293bc1 100644 --- a/xs/sources/xsType.c +++ b/xs/sources/xsType.c @@ -248,7 +248,7 @@ txSlot* fxToInstance(txMachine* the, txSlot* theSlot) #ifdef mxHostFunctionPrimitive case XS_HOST_FUNCTION_KIND: { const txHostFunctionBuilder* builder = theSlot->value.hostFunction.builder; - anInstance = fxNewHostFunction(the, builder->callback, builder->length, builder->id); + anInstance = fxNewHostFunction(the, builder->callback, builder->length, builder->id, theSlot->value.hostFunction.profileID); mxPullSlot(theSlot); } break; #endif diff --git a/xs/tools/xsc.c b/xs/tools/xsc.c index 9dd777f3f6..ad6c3b52ed 100644 --- a/xs/tools/xsc.c +++ b/xs/tools/xsc.c @@ -57,6 +57,11 @@ static void fxWriteIDs(txScript* script, FILE* file); #ifndef XSTOOLS +txID fxGenerateProfileID(void* console) +{ + return XS_NO_ID; +} + void fxGenerateTag(void* console, txString buffer, txInteger bufferSize, txString path) { static txInteger gxTag = 0; diff --git a/xs/tools/xsl.c b/xs/tools/xsl.c index 9836098d1e..6fe272f847 100644 --- a/xs/tools/xsl.c +++ b/xs/tools/xsl.c @@ -312,6 +312,8 @@ int main(int argc, char* argv[]) fxWriteArchive(linker, path, &file); } else { + linker->profileID = mxBaseProfileID; + c_strcpy(path, base); c_strcat(path, name); c_strcat(path, ".xsi"); @@ -333,13 +335,13 @@ int main(int argc, char* argv[]) } fxBufferSymbols(linker); fxWriteSymbols(linker, path, &file); - + linker->base = url; linker->baseLength = mxStringLength(url); - + creation->nameModulo = linker->creation.nameModulo; creation->symbolModulo = linker->creation.symbolModulo; - the = xsCreateMachine(creation, "xsl", linker); + the = fxCreateMachine(creation, "xsl", linker, linker->profileID); mxThrowElse(the); fxNewLinkerCallback(the, fx_Function_prototype_bound, "fx_Function_prototype_bound"); @@ -408,8 +410,7 @@ int main(int argc, char* argv[]) property = mxFunctionInstanceCode(the->stack->value.reference); property->value.callback.address = callback; property = mxFunctionInstanceHome(the->stack->value.reference); - property->ID = the->profileID; - the->profileID++; + property->ID = fxGenerateProfileID(the); fxNewLinkerBuilder(linker, callback, 7, mxID(_Date)); property = mxBehaviorGetProperty(the, the->stack->value.reference, mxID(_now), 0, XS_OWN); diff --git a/xs/tools/xsl.h b/xs/tools/xsl.h index 8f8dc233df..b30b40c143 100644 --- a/xs/tools/xsl.h +++ b/xs/tools/xsl.h @@ -86,7 +86,7 @@ struct sxLinker { txLinkerResource* firstResource; - txMachine* realm; + txID profileID; txLinkerScript* currentScript; txLinkerScript* firstScript; txSize scriptCount; diff --git a/xs/tools/xslBase.c b/xs/tools/xslBase.c index 5d643b0dbc..c295557f33 100644 --- a/xs/tools/xslBase.c +++ b/xs/tools/xslBase.c @@ -272,7 +272,14 @@ void fxMapCode(txLinker* linker, txLinkerScript* script, txID* theIDs) gxCodeUsages[code]++; offset = (txS1)sizes[code]; if (0 < offset) { - p += offset; + if (linker->profileID && (XS_CODE_PROFILE == code)) { + p++; + id = linker->profileID; + linker->profileID++; + mxEncodeID(p, id); + } + else + p += offset; } else if (0 == offset) { p++; diff --git a/xs/tools/xslSlot.c b/xs/tools/xslSlot.c index f979c51f17..16015db1d1 100644 --- a/xs/tools/xslSlot.c +++ b/xs/tools/xslSlot.c @@ -111,7 +111,7 @@ txSlot* fxBuildHostFunction(txMachine* the, txCallback call, txInteger length, t { txLinker* linker = (txLinker*)(the->context); fxNewLinkerBuilder(linker, call, length, id); - return fxNewHostFunction(the, call, length, id); + return fxNewHostFunction(the, call, length, id, XS_NO_ID); } txInteger fxCheckAliases(txMachine* the) @@ -490,8 +490,7 @@ void fxLinkerScriptCallback(txMachine* the) mxPushUndefined(); the->stack->kind = XS_HOST_FUNCTION_KIND; the->stack->value.hostFunction.builder = builder; - the->stack->value.hostFunction.profileID = the->profileID; - the->profileID++; + the->stack->value.hostFunction.profileID = fxGenerateProfileID(the); } fxArrayCacheItem(the, the->stack + 1, the->stack); mxPop(); @@ -583,14 +582,14 @@ txSlot* fxNextHostAccessorProperty(txMachine* the, txSlot* property, txCallback txSlot *getter = NULL, *setter = NULL, *home = the->stack, *slot; if (get) { fxNewLinkerBuilder(linker, get, 0, id); - getter = fxNewHostFunction(the, get, 0, XS_NO_ID); + getter = fxNewHostFunction(the, get, 0, XS_NO_ID, XS_NO_ID); slot = mxFunctionInstanceHome(getter); slot->value.home.object = home->value.reference; fxRenameFunction(the, getter, id, 0, XS_NO_ID, "get "); } if (set) { fxNewLinkerBuilder(linker, set, 1, id); - setter = fxNewHostFunction(the, set, 1, XS_NO_ID); + setter = fxNewHostFunction(the, set, 1, XS_NO_ID, XS_NO_ID); slot = mxFunctionInstanceHome(setter); slot->value.home.object = home->value.reference; fxRenameFunction(the, setter, id, 0, XS_NO_ID, "set "); @@ -1380,12 +1379,11 @@ void fxSetHostFunctionProperty(txMachine* the, txSlot* property, txCallback call if (linker->stripFlag) { property->kind = XS_HOST_FUNCTION_KIND; property->value.hostFunction.builder = fxNewLinkerBuilder(linker, call, length, id); - property->value.hostFunction.profileID = the->profileID; - the->profileID++; + property->value.hostFunction.profileID = fxGenerateProfileID(the); } else { txSlot* home = the->stack; - txSlot* function = fxNewHostFunction(the, call, length, id); + txSlot* function = fxNewHostFunction(the, call, length, id, XS_NO_ID); txSlot* slot = mxFunctionInstanceHome(function); slot->value.home.object = home->value.reference; property->kind = the->stack->kind; diff --git a/xs/tools/xst.c b/xs/tools/xst.c index 9c753fd7f7..d7417e9d70 100644 --- a/xs/tools/xst.c +++ b/xs/tools/xst.c @@ -2006,8 +2006,8 @@ void fxRunModuleFile(txMachine* the, txString path) mxDub(); fxGetID(the, mxID(_then)); mxCall(); - fxNewHostFunction(the, fxFulfillModuleFile, 1, XS_NO_ID); - fxNewHostFunction(the, fxRejectModuleFile, 1, XS_NO_ID); + fxNewHostFunction(the, fxFulfillModuleFile, 1, XS_NO_ID, XS_NO_ID); + fxNewHostFunction(the, fxRejectModuleFile, 1, XS_NO_ID, XS_NO_ID); mxRunCount(2); mxPop(); }