SourcePawn Compiler 1.9 [Support #emit and goto]

komashchenko

Идиот
Сообщения
916
Реакции
2,570
Здравствуйте, от немного модифицированный компилятор SourcePawn с поддержкой #emit и goto

#emit - позволяет обращаться к виртуальной машине инструкциями языка ассемблера, всё доступные оптокоды SP смотрите тут
goto - оператор безусловного перехода (перехода к определённой точке функции, обозначенной меткой) [Использовать нужно довольно аккуратно, за состоянием стека приходиться следить вручную]

PHP:
#pragma semicolon 1

#pragma newdecls required

public void OnPluginStart()
{
    RegServerCmd("test_goto", Test_Goto);
}

public Action Test_Goto(int args)
{
    bool hello;
    char crab[] = "space crab";
    
    sample_label:
    
    char yam[] = "yams";
    
    PrintToServer("%s %s", crab, yam);

    if (!hello)
    {
        bool what = true;
        hello = what;
        yam = "what"; //но мы не увидим what так как yam иницилиаризируеться заново
        
        #emit stack 4// из-за гото what не удаляеться, так что удаляем вручную
        goto sample_label;
    }
    else PrintToServer(":)");
    
    PrintToServer("hello %d", hello);
    
    #emit stack 8 //удаляем вторую yam
    return Plugin_Handled;
}

PHP:
#pragma semicolon 1
#pragma newdecls required

public void OnPluginStart()
{
    RegServerCmd("test_emit", test_emit);
}

public Action test_emit(int args)
{
    emit1(8, 9, 5);
    emit2(5, 1, 6, 8);
}

public void emit1(any ...)
{
    PrintToServer("emit1");
    
    int num_args, arg;
    #emit LOAD.S.pri 8
    #emit STOR.S.pri num_args
    
    PrintToServer("num_args %d", num_args);
    
    for(int i, u = 12; i < num_args; i++, u+=4)
    {
        #emit ADDR.alt 0
        #emit LOAD.S.pri u
        #emit ADD
        #emit LOAD.i
        #emit LOAD.i
        #emit STOR.S.pri arg
        PrintToServer("arg %d %d", i, arg);
    }
}

public void emit2(any ...)
{
    PrintToServer("emit2");
    
    int num_args, arg_p;
    #emit LOAD.S.pri 8
    #emit STOR.S.pri num_args
    int[] args = new int[num_args];
    
    #emit break
    #emit ADDR.pri 12
    #emit STOR.S.pri arg_p
    for(int i; i < num_args; i++)
    {
        #emit break
        #emit LOAD.S.pri i
        #emit SMUL.c 4
        #emit PUSH.pri
        #emit LOAD.S.alt arg_p
        #emit ADD
        #emit LOAD.i
        #emit SWAP.pri
        #emit LOAD.S.alt args
        #emit ADD
        #emit MOVE.alt
        #emit POP.pri
        #emit MOVS 4
    }
    
    PrintToServer("num_args %d", num_args);
    for(int i; i < num_args; i++)
    {
        PrintToServer("arg %d %d", i, args[i]);
    }
}

Исходники
Скачать
 
N

NiGaByte

Т.е я могу из под SM обратиться к виртуальной машине, изменить какие-то биты и флаги? в смысле я могу закодить в самом низу? хд
 

V1adJkee

Участник
Сообщения
148
Реакции
81
При переходе по ссылкам выдает ошибку 404. Подскажите, где можно скачать этот компилятор?
 

DeathScore13

пирожок. пирожочек.
Сообщения
740
Реакции
409
на гите отсутствует поддержка goto(
но стек в приведённом примере можно чистить автоматически, т.к. есть глобальная переменная declared
Сообщения автоматически склеены:

а ещё лучше объявлять переменные в самом начале функции используя decl (или new, если нужно сразу инициализировать), тогда 100% не будет проблем с очисткой. правда, динамические массивы могут поплыть.. но их можно просто в { } йобнуть и сделать прыжок после закрытия скобки. даже в приведённом примере такое прокатит:
C-подобный:
#pragma semicolon 1

#pragma newdecls required

public void OnPluginStart()
{
    RegServerCmd("test_goto", Test_Goto);
}

public Action Test_Goto(int args)
{
    bool hello;
    char crab[] = "space crab";
  
    sample_label:
  
    char yam[] = "yams";
  
    PrintToServer("%s %s", crab, yam);

    if (!hello)
    {
        {
            bool what = true;
            hello = what;
            yam = "what";
        } // автоматическая очистка what
        goto sample_label;
    }
    else PrintToServer(":)");
  
    PrintToServer("hello %d", hello);
  
    // автоматическая очистка hello, crab, yam
    return Plugin_Handled;
}
 
Последнее редактирование:

Похожие темы

Ответы
6
Просмотры
Сверху Снизу