Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fixes several bugs associated with destructors #260

Merged
merged 4 commits into from Apr 24, 2018

Conversation

YashasSamaga
Copy link
Member

#256 #257

  1. destructors are not called for static locals
  2. destructors are called on implicit return (wasn't being called previously)
  3. destructors are called only for the data of the array (destructors were called for indirection tables previously)

The destructor operator takes an array with a single dimension on input, and this array holds all elements of a variable that must be destructed:

  • For simple variables, the variable is passed by reference, which makes it appear as an array with one element.
  • For arrays with one dimension, the array is passed without modification
  • For arrays with two or more dimensions, the destructor operator receives the address behind the “indirection tables” for the major dimensions. As documented above, a multi-dimensional array starts with vectors for the major dimensions that each hold the offsets to the dimension below itself. The data for the array itself is packed behind these offset arrays. By passing the address where the array data starts, the destructor operator can access the array elements as if it were an array with a single dimension.

The destructors for local variables were not being called when the function returns without the user expclitly giving a return statement.

This commit adds code to call the destructors for the local variables on an implicit return.
Currently, the destructors are triggered for each indirection level of the multi-dimensional array. The PAWN Implementer Guide states that the destructor must be triggered for the actual data only.

Apart from the above correction, this commit also fixes a typo which caused wrong sizes to be passed to the destructor.
@YashasSamaga
Copy link
Member Author

YashasSamaga commented Jan 14, 2018

Test script:

#include <a_samp>

operator~(Tag:data[], size) {
    new addr;
    #emit LOAD.S.pri data
    #emit STOR.S.pri addr
    printf("[destructor] address: %d, first-value: %d, size: %d", addr, _:data[0], size);
}

implicit_return(Tag:arg) {
    /*
     *  should trigger "symbol never used" for "arg" warning if destructors are
     *  not added as symbols which get destroyed are marked as read even if not
     *  directly accessed.
     */
}

#pragma naked
addressof(&Tag:arg) {
    #emit LOAD.S.pri arg
    #emit RETN
}

main () {
    /*
     *  should trigger "symbol never used" for all the symbols given below as
     *  the destructors are not supposed to be called for them (which leaves
     *  them as unused).
     */
    static Tag:destructor_shud_not_be_called1 = Tag:1;
    static const Tag:destructor_shud_not_be_called2 = Tag:2;
    
    const Tag:destructor_shud_not_be_called3 = Tag:3;
    
    static Tag:destructor_shud_not_be_called4[10];
    static Tag:destructor_shud_not_be_called5[10][5];
    
    /*
     *	should not trigger "symbol never used" for all the symbols given below
     *  as the destructors are supposed to be called for them (which leaves them
     *  as unused).
     */
    new Tag:destructor_should_be_called1 = Tag:3;
    new const Tag:destructor_should_be_called2 = Tag:4;
    
    /* test whether destructors are called for arguments for implicit return */
    implicit_return(Tag:100);
	
    /* test whether destructors are called correctly for multi-dimensional arrays */
    new Tag:one_dimensional_array[100],
            Tag:two_dimensional_array[10][10],
            Tag:three_dimensional_array[10][10][10],
            Tag:four_dimensional_array[5][5][5][5];
		
    printf("address of data of one_dimensional_array: %d", addressof(one_dimensional_array[0]));
    printf("address of data of two_dimensional_array: %d", addressof(two_dimensional_array[0][0]));
    printf("address of data of three_dimensional_array: %d", addressof(three_dimensional_array[0][0][0]));
    printf("address of data of four_dimensional_array: %d", addressof(four_dimensional_array[0][0][0][0]));
}

Compiler Output:

warning 203: symbol is never used: "destructor_shud_not_be_called5"
warning 203: symbol is never used: "destructor_shud_not_be_called4"
 warning 203: symbol is never used: "destructor_shud_not_be_called3"
 warning 203: symbol is never used: "destructor_shud_not_be_called2"
warning 203: symbol is never used: "destructor_shud_not_be_called1"

Console Output:

[destructor] address: 18684, first-value: 100, size: 1
address of data of one_dimensional_array: 18288
address of data of two_dimensional_array: 17888
address of data of three_dimensional_array: 13848
address of data of four_dimensional_array: 10908
[destructor] address: 10908, first-value: 0, size: 625
[destructor] address: 13848, first-value: 0, size: 1000
[destructor] address: 17888, first-value: 0, size: 100
[destructor] address: 18288, first-value: 0, size: 100
[destructor] address: 18688, first-value: 4, size: 1
[destructor] address: 18692, first-value: 3, size: 1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants