ftp.nice.ch/pub/next/developer/languages/smalltalk/smalltalk.1.2.alpha5.s.tar.gz#/smalltalk-1.2.alpha5/objc/Notes

Email.rtf
[View Email.rtf] 
Explanations.diagram2/
 
Explanations~.diagram2/
 
NS Functions
 
NS_GNU_mst_alpha_testers
 
Notes.rtf
[View Notes.rtf] 
README
 
README.NEXTSTEP
 
README.rtf
[View README.rtf] 
README.rtfd/
 
Smalltalk.NeXT.install
 
Unix Functions
 
ns.c
[View ns.c] 
unix.c
[View unix.c] 

README

10 Step program to build NeXTified GNU Smalltalk 1.2Alpha3

1.	gunzip smalltalk-1.2.alpha3.ns.tar.gz
2	tar xf smalltalk-1.2.alpha3.ns.tar
3.	cd smalltalk-1.2.alpha3.ns
4.	./configure
5.	make
6.	cd objc
7.	make						<- Will generate some warnings, ignore them
8.	./mst -qiV					<- should work no problem on any hardware platform, (Control-d) to exit mst
9.	./mst -qV OCObject.st		<- Known to fail on motorolla
10	./mst -qV browser/STBrowser.st		<- the big test

	or

10	./mst -qV browser/Main.st			<- the big test
	
Step 8 builds the original kernel image.  Once you have created an image it is unwise to move it
around.  The same goes for the executable, mst, and the kernel smalltalk files.

Step 9 will take anywhere from 4 to 15 minutes depending on the hardware.  On my pentium 90 it takes
a little longer than 4 minutes, usually.

README.NEXTSTEP

Installing

	If you're going to be trying to run this on an architecture
other than intel you may want to first backup all the makefiles
and then run configure.  If you're on an intel machine you should 
just type 'make'.  If not on intel then diff the new makefiles
with the backups and insert the changes I made.   The changes I
made are mainy

	o Compiling with the -ObjC flag (use cc not gcc)
	o Linking with NEXSTEP libaries
	o Building and linking with a new library called libOCCode.a.

Once mst is built do the following

	machine> ./mst -Viq
	st> OCInterface createInterface!   	"<- on my pentium 90 this takes
									   	 well over 4 minutes.  I have
										 also had problem where mst crashes
										 with a floating point error
										 but have never bothered to track 
										 it down.  If this happens please
										 let me know so that I know its
										 not my computer. "
	st> Smalltalk snapshot!
	st> Smalltalk quitPrimitive! 		" or control d"
	machine> ./mst -qV STBrowser.st		
	  
A simple browser should popup in a moment or two.  It is not
currently very functional.  All you can do is browse the class
heirarchy while looking at the class's categories and methods. 
There is no support for compiling changes to the methods.  It
wouldn't have been hard to add but I couldn't think of a way of
setting it up so that it looked right.  If you want to add something
feel free to do so.

Under the tools menu you'll find a Workspace menu button, pushing this
brings up a panel in which you can enter pieces of code and have them
executed.  The result will be appended to the current bit of text in
the window.  This works.

The console doens't not work and I don't know why.

Look through the file STBrowser.st to see what I have done.  There
is an example of a new subclass of View called TextScrollView that is
written entirely in smalltalk but made from objective-c objects.
Smalltalk subclasses of the delegate classes found in ./OCInterfaceSupport
that support a 2-way interface with smalltalk and objc. Somethings to note
are
	o Never pass a smalltalk object to an objc object as in
	  text setDelegate: self.  Everything will die.  The above
	  should be text setDelegate: (self id).  So that the value
	  forwarded to the objc object is really an objc object.
	o If you subclass any objc object through smalltalk and override
	  the init method make sure to call its super's init method.
	o If you're getting crashes and can't figure it out, run mst
	  from gdb and when it crashes do a where to see what was
	  being executed.

Feel free to email (jehu@vt.edu) with your suggestions.  I have hi 
hopes for this little baby.

Future

The code that creates the interface between smalltalk and objective-c
is in the file OCObject.st.  The instanceless class OCInterface
is responsible for this undertaking.  Stuff still to be done
	o When creating the interface or maybe updating it, only have
	  it compile the methods for a class if they haven't already
	  been compile.  Maybe add the option to rescan a selected class.
	o Give each class a generic comment.
	o Try and make it faster some how.
	  
The library libOCCode.a contains objective-c objects that supports a
two way interface with smalltalk.  Currently most of these objects
are delegate objects which forward the delegate methods to their 
smalltalk twin.  I am working on writing a palette with the standard
NS objects that will support this interface while allowing a user to 
use IB when doing the interface.  The nib would then be controlled
by an object that will scan the content view of window (only 1 window
per nib would be allowed) and return a list of UI objects with an
associated name.  From there they could be used from smalltalk.

	John Stanhope
	jehu@vt.edu

README.rtf

GNU Smalltalk 1.2 alpha 3 <-> NeXT Objective-c Interface Explanations, Guidelines, and Hints

A Crappy Explanation Of How The Interface Works.  If you read this and it makes no sense to you please email me with suggestions.  Its kind of hard to explain this crap.

Table of 

pure smalltalk object
pure objective-c object

Abstract



Creating the Classes

What this interface does is create a new smalltalk classes for each class in the appkit by quering the objective-c runtime system using a few functions written by me or snagged from other code and adopted for this evil purpose.  Starting with objective-c's Object and mapping it to smalltalk's OCObject the entire objective-c class heirarchy is duplicated (well not all, I wrote some smalltalk code that ignores most of the undocumented appkit classes). Each class has a single class variable to the objectice-c class and an inherited instance var which points to the id of the objective-c objects, once it has been instantiated.

See the file OCInterface.st and cfunc.c to see the C and smalltalk code used to create the interface.

Creating the Methods

The methods are created by querying the objective-c runtime system with some special functions and then
creating smalltalk code to invoke the objective-c method.  The actual methods are sent using the function objc_msgSend().  For each new method a class needs to implement it creates a special call to the function objc_msgSend using the following smalltalk code

	Behavior defineCFunc: 'msgSend'
		withSelectorArgs: 'cObjectMsgSend1: anId sel: aSelector argSmalltalk: arg0'
		forClass: OCInterface class
		returning: #cObject
		args: #(cObject cObject smalltalk).

The value 'msgSend' in the first line tells smalltalk to associate the next line with the C function objc_msgSend().  The next line is created by some C code that looks at the objective-c selector to see what its return type is and args are and then creates a unique string to represent this smalltalk callout to C code.
The forClass: field tells smalltalk to add this method as a class method to OCInterface.  BTW OCInterface is a instances less class used to create the smalltalk<->objective-c interface.  The last two lines tell smalltalk host to convert the args passed to  cObjectMsgSend1 to C types.  The cObject type is a pointer and is used to pass objective-c's id type around.

But you you're saying I don't want every method to go through OCInterface and have these horrid names.  But wait it gets better.  The new Class method to OCInterface is then used by a automatically created class like so  

	setOOP: arg0 
		| anId aSelector rValue | 
		anId _ id.
		aSelector _ OCInterface getUid: 'setOOP:'.
		rValue _ OCInterface cObjectMsgSend1: anId sel: aSelector argSmalltalk: arg0.
		((OCInterface id: id equalTo: rValue) = 1)
			ifTrue: [ ^self ]
			ifFalse: [ ^OCObject newFromId: rValue. ].

The code from above is for the smalltalk version of the objective-c class STObject.  This code is (usually) automatically generated for each method.  Notice that is checks to see what the return type is, if its a cObject (maybe an id) we check to see if it is equal to our id, if it is we return our smalltalk self.  If its not equal to our id then it wraps the object in another smalltalk object using OCObject's class method newFromId:.  If the value returned is a pointer to a structure or something along those lines, things will die.  Luckily appkit functions almost never return any pointers via return but by reference.  Passing stuff by reference will work but you need to get a handle to the pointer first.  We'll discuss how that works later though.



To forward an objective-c message to smalltalk works a little different.  In order for an objective-c object to forward a method to a smalltalk object it must know it exists and it also needs a way to tell the code that creates the interface between the two languages that certain objective-c methods aren't to be wrapped by smalltalk.  For this to work a new objective-c class was created called STObject.  It has an OOP type (the type OOP is how smalltalk objects are represented in the C smalltalk interpreter) ivar that has to be set  explicitly or things will not work.   The OOP ivar, named stObejct, is set using the setOOP: method and can be called from smalltalk code as

		self setOOP: self.
		
This work because the self setOOP part sends the setOOP: message to the id and passes self (Internally represented as an OOP in the smalltalk interpreter) as an OOP to the  objective-c method.

If this is confusing dont' worry I don't think you'll need to understand it to be able to use it.

Problems, Make Sure You Aren't Doing the Following

1.	Avoid doing this
		browser setDelegate: aDelegate.
	because your telling an objective-c object (NXBrowser) that its delegate is
	a smalltalk object.  What you meant was
		browser setDelegate: aDelegate id.
	The #id method returns the actual id value of a smalltalk/objective-c object.
	
2.	If you're subclass STObject of one of the STDelegate subclasses make sure you call
	super's init method since it is this method that properly sets up the 2-way communication.

README.rtfd


These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.