Skip to content

don't do implicit return tasks in naked functions #271

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

Merged
merged 1 commit into from
Apr 22, 2018

Conversation

YashasSamaga
Copy link
Member

@YashasSamaga YashasSamaga commented Jan 25, 2018

This commits prevents the compiler from calling destructors and adding the return instructions implicitly in naked functions.

fix for #262

This commits prevents the compiler from calling destructors and adding the return instructions implicitly in naked functions.
@Y-Less
Copy link
Member

Y-Less commented Jan 25, 2018

Does this still do them in places where return is used explicitly?

@YashasSamaga
Copy link
Member Author

YashasSamaga commented Jan 27, 2018

Yes.

#pragma warning disable 203

operator~(Tag:arr[], s) { }

#pragma naked
f(Tag:arg1) {
    #emit CONST.pri 1
	new Tag:loc1;
	{
	    #emit CONST.pri 2
	    new Tag:loc2;
		{
		    #emit CONST.pri 3
			new Tag:loc3;
			#emit CONST.pri 4
		}
		#emit CONST.pri 5
		return;
		#emit CONST.pri 6
	}
	#emit CONST.pri 7
}

#pragma naked
g() {

}

#pragma naked
h(a) for (new i; ; ) {}

normal() {
	new Tag:test;
	{
	    new Tag:test2;
	}
}

main () { f(Tag:5); g(); h(); normal(); }

should produce the following after implementing the suggestions:

CODE 0	; 0
;program exit point
	halt 0

	proc	; operator~(Tag:)
	; line 3
	;$lcl s 10
	;$lcl arr c
	zero.pri
	retn

	proc	; f
	; line 6
	;$lcl arg1 c
	const.pri 1
	; line 8
	break	; 20
	;$lcl loc1 fffffffc
	push.c 0
	;$exp
	const.pri 2
	; line b
	break	; 34
	;$lcl loc2 fffffff8
	push.c 0
	;$exp
	const.pri 3
	; line e
	break	; 48
	;$lcl loc3 fffffff4
	push.c 0
	;$exp
	const.pri 4
	push.pri
	push.c 1
	addr.pri fffffff4
	push.pri
	push.c 8
	call .~40000002	; operator~(Tag:)
	pop.pri
	stack 4
	const.pri 5
	; line 12
	break	; 98
	zero.pri
	push.pri
	push.c 1
	addr.pri fffffff8
	push.pri
	push.c 8
	call .~40000002	; operator~(Tag:)
	push.c 1
	addr.pri fffffffc
	push.pri
	push.c 8
	call .~40000002	; operator~(Tag:)
	push.c 1
	addr.pri c
	push.pri
	push.c 8
	call .~40000002	; operator~(Tag:)
	pop.pri
	stack 8
	retn
	const.pri 6
	const.pri 7

	proc	; g
	; line 19

	proc	; h
	; line 1e
	;$lcl a c
	; line 1e
	break	; 138
	;$lcl i fffffffc
	push.c 0
	;$exp
	jump 2
l.0		; 14c
	; line 1e
	break	; 14c
l.2
	jump 0
l.1		; 158
	stack 4

	proc	; normal
	; line 20
	; line 21
	break	; 164
	;$lcl test fffffffc
	push.c 0
	;$exp
	; line 23
	break	; 170
	;$lcl test2 fffffff8
	push.c 0
	;$exp
	push.pri
	push.c 1
	addr.pri fffffff8
	push.pri
	push.c 8
	call .~40000002	; operator~(Tag:)
	pop.pri
	stack 4
	push.pri
	push.c 1
	addr.pri fffffffc
	push.pri
	push.c 8
	call .~40000002	; operator~(Tag:)
	pop.pri
	stack 4
	zero.pri
	retn

	proc	; main
	; line 27
	; line 27
	break	; 1f0
	push.c 5
	;$par
	push.c 4
	call .f
	;$exp
	; line 27
	break	; 20c
	push.c 0
	call .g
	;$exp
	; line 27
	break	; 220
	push.c 4
	call .h
	;$exp
	; line 27
	break	; 234
	push.c 0
	call .normal
	;$exp
	zero.pri
	retn


STKSIZE 1000

@samphunter
Copy link

samphunter commented Jan 27, 2018

This looks dangerous. If you forget a return somewhere, you will start executing code of another function. On the other hand, having the implicit return there only costs 8 bytes of memory. I am not sure what the great advantage of this is...

@Y-Less
Copy link
Member

Y-Less commented Jan 27, 2018

If you forget a return somewhere, you will start executing code of another function.

Or to put it another way:

If you get your code wrong, your code will do the wrong thing.

Using things like #pragma naked is taking you out of the standard language limits and telling the compiler "I really know what I'm doing". If you do that then don't know what you're doing, more fool you.

@samphunter
Copy link

samphunter commented Jan 27, 2018

@Y-Less I would consider myself someone who knows, what they are doing, regarding this stuff. However, I still make mistakes sometimes. And my point is, that I really don't see the advantage.

@YashasSamaga
Copy link
Member Author

@samphunter You have the control. You are essentially telling the compiler that don't add instructions to handle implicit return by marking a function as naked. If you forget to add the return instructions to a naked function, then I think the problem lies on your side as you asked the compiler to not add it and you did not add it.

@samphunter
Copy link

@YashasSamaga fair enough. I guess I can always just add explicit return to suppress the warning without using naked.

@Southclaws
Copy link
Collaborator

Is this ready to be merged? The justification sounds fine and logical to me.

@Zeex Zeex merged commit 1d60153 into pawn-lang:master Apr 22, 2018
@YashasSamaga YashasSamaga deleted the fix-i262 branch October 11, 2020 11:41
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.

5 participants