190190 YSI_g_sNPSReplace,
191191 YSI_g_sNPSStack;
192192
193+ static
194+ YSI_g_sTempRet;
195+
193196static stock YHNPS_Find (heap, end, value)
194197{
195198 new
@@ -353,6 +356,7 @@ public OnCodeInit()
353356 new
354357 Opcode: call = RelocateOpcode (OP_CALL),
355358 Opcode: nop = RelocateOpcode (OP_NOP),
359+ Opcode: proc = RelocateOpcode (OP_PROC),
356360 dctx[DisasmContext];
357361 DisasmInit (dctx);
358362 for ( ; ; )
@@ -365,10 +369,20 @@ public OnCodeInit()
365369 }
366370 case OP_SYSREQ_C:
367371 {
372+ // Check that the previous OP is `PUSH.C`. That reqpresents a real native call, not our
373+ // wrapper.
374+ if (Opcode: AMX_Read (DisasmGetCurIp (dctx) - 8 ) == proc)
375+ {
376+ continue ;
377+ }
368378 idx1 = YHNPS_Find (heap, nativeCount, DisasmGetOperand (dctx));
369379 }
370380 case OP_SYSREQ_D:
371381 {
382+ if (Opcode: AMX_Read (DisasmGetCurIp (dctx) - 8 ) == proc)
383+ {
384+ continue ;
385+ }
372386 idx1 = YHNPS_Find (heap + allocated * 16 , nativeCount, DisasmGetOperand (dctx));
373387 }
374388 case OP_CALL:
@@ -474,22 +488,22 @@ stock _yH@(compressedFormat)
474488 }
475489 case OP_SYSREQ_C:
476490 {
477- addr = DisasmGetOperand (dctx);
478- type = 2 ;
491+ addr = - DisasmGetOperand (dctx);
492+ type = - (YSI_g_sNPSTrampoline + 39 * cellbytes) ;
479493 break ;
480494 }
481495 case OP_SYSREQ_D:
482496 {
483- type = 3 ;
497+ type = - (YSI_g_sNPSTrampoline + 39 * cellbytes) ;
484498 break ;
485499 }
486500 }
487501 }
488- if (type == 2 )
489- {
490- // Native function call.
491- addr = - addr;
492- }
502+ // if (type < 0 )
503+ // {
504+ // // Native function call.
505+ // addr = -addr;
506+ // }
493507
494508 AsmInitPtr (ctx, YSI_g_sNPSTrampoline + AMX_HEADER_COD, YSI_g_sNPSReplace - YSI_g_sNPSTrampoline);
495509 // Forward the function, storing the chain data in the heap. Note that no
@@ -499,63 +513,75 @@ stock _yH@(compressedFormat)
499513 //
500514
501515 // Build the structure in the stack first.
502- @emit POP.pri
503- @emit PUSH.C compressedFormat
516+ @emit POP.pri // 1
517+ @emit PUSH.C compressedFormat // 3
504518
505519 // Chain the functions.
506520 if (YSI_g_sNPSBaseCall == addr)
507521 {
508- @emit PUSH.C YSI_g_sNPSStack
509- YSI_g_sNPSStack = YSI_g_sNPSTrampoline;
522+ @emit PUSH.C YSI_g_sNPSStack // 5
523+ YSI_g_sNPSStack = YSI_g_sNPSTrampoline; // Replace.
510524 }
511525 else if (YSI_g_sNPSBaseCall == cellmin)
512526 {
513- @emit PUSH.C addr
527+ @emit PUSH.C (type < 0 ? type : addr) // 5
514528 YSI_g_sNPSStack = YSI_g_sNPSTrampoline;
515529 }
516530 else
517531 {
518- @emit PUSH.C addr
532+ @emit PUSH.C (type < 0 ? type : addr) // 5
519533 }
520534
521- @emit PUSH.C 8
522- @emit PUSH.pri // Save the return address again.
523- @emit PUSH ref (YSI_g_sNPSStack)
535+ @emit PUSH.C 8 // 7
536+ @emit PUSH.pri // Save the return address again. // 8
537+ @emit PUSH ref (YSI_g_sNPSStack) // 10
524538
525539 // Copy 20 bytes over (includes the return address and fake param count).
526- @emit HEAP 20
527- @emit LCTRL 4
528- @emit MOVS 20
529- @emit STOR.alt ref (YSI_g_sNPSStack)
540+ @emit HEAP 20 // 12
541+ @emit LCTRL 4 // 14
542+ @emit MOVS 20 // 16
543+ @emit STOR.alt ref (YSI_g_sNPSStack) // 18
530544
531545 // Call, and return to here to clean up the heap.
532- @emit STACK 20
533- @emit CALL.abs YSI_g_sNPSReplace
546+ @emit STACK 20 // 20
547+ @emit CALL.abs YSI_g_sNPSReplace // 22
534548
535549 // Put data (and return value) on the stack.
536- @emit STACK - 20
537- @emit STACK 0
538- @emit PUSH.pri
550+ @emit STACK - 20 // 24
551+ @emit STACK 0 // 26
552+ @emit PUSH.pri // 27
539553
540554 // Copy from the heap.
541- @emit LOAD.pri ref (YSI_g_sNPSStack)
542- @emit MOVS 20
555+ @emit LOAD.pri ref (YSI_g_sNPSStack) // 29
556+ @emit MOVS 20 // 31
543557
544558 // Restore the return address and `continue` stack.
545- @emit POP.pri
546- @emit POP.alt
547- @emit STOR.alt ref (YSI_g_sNPSStack)
548- @emit HEAP - 20
559+ @emit POP.pri // 32
560+ @emit POP.alt // 33
561+ @emit STOR.alt ref (YSI_g_sNPSStack) // 35
562+ @emit HEAP - 20 // 37
549563
550564 // Return from this "function", with our fake parameters and return address.
551565 // We do this instead of using `SCTRL 6`, as is the normal way, to preserve
552566 // `pri` as the return value.
553- @emit PROC
554- @emit RETN
567+ @emit PROC // 38
568+ @emit RETN // 39
569+
570+ if (type < 0 )
571+ {
572+ // Missed this one apparently...
573+ @emit SYSREQ.C - addr
574+ // @emit SYSREQ.pri
575+
576+ // Returns to here.
577+ @emit PUSH.alt
578+ @emit PUSH ref (YSI_g_sTempRet)
579+ @emit RETN
580+ }
555581
556582 AsmEmitPadding (ctx);
557583
558- YSI_g_sNPSReplace = YSI_g_sNPSBaseCall;
584+ YSI_g_sNPSReplace = YSI_g_sNPSBaseCall; // Find
559585 YSI_g_sNPSBaseCall = addr;
560586
561587 // Do a double return - exit the calling function as well as this function,
@@ -629,22 +655,23 @@ static stock Hooks_GenerateContinue(GLOBAL_TAG_TYPES:...)
629655
630656 @emit Hooks_Continue_native:
631657
632- static RET;
633-
634658 // Save the bottom of the stack.
635659 @emit POP.alt
636- @emit STOR.alt ref (RET )
660+ @emit STOR.alt ref (YSI_g_sTempRet )
637661 @emit POP.alt
638662
639663 @emit NEG
640- // Missed this one apparently...
641- AsmEmitSysreqPri (ctx);
642- // @emit SYSREQ.pri
643-
644- // Returns to here.
645- @emit PUSH.alt
646- @emit PUSH ref (RET)
647- @emit RETN
664+ @emit LCTRL 8
665+ @emit SCTRL 6
666+
667+ // // Missed this one apparently...
668+ // AsmEmitSysreqPri(ctx);
669+ // //@emit SYSREQ.pri
670+ //
671+ // // Returns to here.
672+ // @emit PUSH.alt
673+ // @emit PUSH ref(YSI_g_sTempRet)
674+ // @emit RETN
648675
649676 AsmEmitPadding (ctx);
650677}
0 commit comments