pharo-vm icon indicating copy to clipboard operation
pharo-vm copied to clipboard

Use of Null Object pattern difficults stepping in the debugger

Open hernanmd opened this issue 2 years ago • 3 comments

The VMPluginCodeGenerator currently generates C code in the following method:

emitCCodeOn: aStream doInlining: inlineFlag doAssertions: assertionFlag
	"Generate twice; the first time to collect the used functions, the second to output the used functions."
	| savedHeaders |
	savedHeaders := headerFiles copy.
	[super emitCCodeOn: NullStream new doInlining: inlineFlag doAssertions: assertionFlag]
		on: MessageNotUnderstood
		do: [:ex|
				(#(newLine crtab: peekLast space tab tab:) includes: ex message selector) ifTrue:
					[ex resume: nil].
				ex pass].
	headerFiles := savedHeaders.
	super emitCCodeOn: aStream doInlining: inlineFlag doAssertions: assertionFlag

Here, the NullStream "eats" the message sends sent to the stream in a normal execution flow, but when used inside the Debugger it does not raise the exception block. This causes that subsequent steps to not work, after a newLine is sent to the stream, for example in the following:

emitCHeaderOn: aStream
	"Write a C file header onto the given stream, adding include files and some basic definitions."
	| standardHeaders |
	
	aStream nextPutAll: (self fileHeaderVersionStampForSourceClass: pluginClass); newLine; newLine.
     ...

Is there any alternative to use null object pattern here which does not difficult the use of the debugger?

hernanmd avatar Aug 01 '23 15:08 hernanmd

Yes, look at why this is like this.

The emitCCode is being called twice, the first one to record the functions that are being called. We should have a separate pass to do that, outside of the code emit

  • In terms of performance it will be the same, we are doing two passes anyways :D
  • It will also simplify the code, because then the emit will not need to record calls to be used in a subsequent call.

El 1 ago. 2023, a las 17:52, Hernán Morales Durand @.***> escribió:

The VMPluginCodeGenerator currently generates C code in the following method:

emitCCodeOn: aStream doInlining: inlineFlag doAssertions: assertionFlag "Generate twice; the first time to collect the used functions, the second to output the used functions." | savedHeaders | savedHeaders := headerFiles copy. [super emitCCodeOn: NullStream new doInlining: inlineFlag doAssertions: assertionFlag] on: MessageNotUnderstood do: [:ex| (#(newLine crtab: peekLast space tab tab:) includes: ex message selector) ifTrue: [ex resume: nil]. ex pass]. headerFiles := savedHeaders. super emitCCodeOn: aStream doInlining: inlineFlag doAssertions: assertionFlag Here, the NullStream "eats" the message sends sent to the stream in a normal execution flow, but when used inside the Debugger it does not raise the exception block. This causes that subsequent steps to not work, after a newLine is sent to the stream, for example in the following:

emitCHeaderOn: aStream "Write a C file header onto the given stream, adding include files and some basic definitions." | standardHeaders |

aStream nextPutAll: (self fileHeaderVersionStampForSourceClass: pluginClass); newLine; newLine. ... Is there any alternative to use null object pattern here which does not difficult the use of the debugger?

— Reply to this email directly, view it on GitHub https://github.com/pharo-project/pharo-vm/issues/665, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAFM5YTNBEXXKDSYKOETRTDXTEQ3NANCNFSM6AAAAAA277GBTI. You are receiving this because you are subscribed to this thread.

guillep avatar Aug 02 '23 09:08 guillep

Hello, I remember that we found out that this is actually a bug in the Debugger and not in the vm? Am I right? If yes, should we close this issue?

jordanmontt avatar Oct 06 '23 09:10 jordanmontt

I think we should do what I propose in my comment above, independently of the original issue

guillep avatar Oct 06 '23 11:10 guillep