The Renaissance Programmer

Calling into Smalltalk from another Language

uring the past two years, IBM's Smalltalk Server for MVS has introduced and implemented an impressive list of useful, technologically sophisticated features. It has a interactive remote debugger that allows you to debug an image running on an MVS machine from your OS/2 or NT workstation. In addition, you can inspect objects in the image on the MVS machine and execute statements in this mainframe image from a workstation workspace. Images can be created and packaged for different target environments including Native, IMS and CICS on OS390, NT or OS/2 operating systems. Its precompiler can precompile static SQL in both embedded SQL and query specs on the workstation. Since it is able to be started up as a CICS transaction, CICS EXEC commands can be run interactively in the development environment. Using the PlatformFunction class, a Smalltalk program can share memory and pass parameters to a called C, COBOL or PL/I program. The latest innovation implemented in Smalltalk Server and one which developers have been waiting ten years for is to be able to call into Smalltalk from a PL/I, COBOL or C program. Messages can now be triggered in a Smalltalk image via calls from a high-level language (HLL) program to a Smalltalk virtual machine. This call-in facility is a significant enough development that it deserves an article (like this one) to explain how it works.

Why would you want to call Smalltalk from PL/I, COBOL or C? Think about how some Smalltalk projects have evolved over the last few years. Companies have developed sophisticated applications in Smalltalk for OS/2 or NT workstations that perform complex, business-critical applications. These killer apps run well on the workstation but organizations want to port them to a Smalltalk server machine for faster processing power and wider use. OS390 Mainframes give you performance, scalability, robust recovery capability and the ability to process millions of records over night in batch jobs. If complex portions of the system are written in Smalltalk, and you want to be able to have your legacy system call Smalltalk, then this call-in feature to Smalltalk is very useful. One Smalltalk application that has migrated from the workstation to the MVS host is a Smalltalk compensation engine that operates on rules for how policyholders should be compensated. There are different sets of rules for different types of policyholders. A HLL batch program that call into a flexible, Smalltalk compensation engine is a prime example of the usefulness of a call-in facility.

How can this legitimate need to call into Smalltalk be technologically possible? The logical steps to follow for calling in to Smalltalk are to (1) start a Smalltalk image running on a virtual machine (2) call into the virtual machine and request it to run parameterized messages with required parameters that process and return results and (3) when finished processing, stop the image. Consider the fact that a high level language is not designed to send messages. It is designed to make calls to other modules and pass parameters. A call to a virtual machine must contain parameters that include the name of the image, the name of the receiving class and the method to execute. The virtual machine must then translate this call into a message send. The single-image virtual machines that Smalltalk Server has for IMS, CICS and Native MVS have been enhanced to process callable requests. There are three calls the HLL programs make into the Smalltalk virtual machine that correspond to the three steps outlined above: VASTART, VARUN and VASTOP.

To enable calling into Smalltalk from the high-level language program, an HLL stub object module is built which enables VASTART, VARUN and VASTOP commands to execute correctly from the calling program. The High Level calling program is linkedited to the HLL stub that supports these three calls.

Let's take a brief look at these calls in the context of a calling PL/I program. C and COBOL programs would be similar.

VASTART starts up an image. PL/I code using this call looks like this:

CALL VASTART(ADDR(IMAGENAME),VHANDLE,VSTATUS);

IMAGENAME is the variable that contains the name of the image and VHANDLE is the address of the image. VSTATUS contains a return code.

VARUN causes the virtual machine to execute the image starting with a Class message. It also passes a general-purpose IOAREA storage area to the Smalltalk VM. The HLL program needs to know the message name and what object to send to it. In this case you can only send class methods to the image. PL/I code using this call looks like this:

CALL VARUN(VHANDLE,ADDR(RECEIVER), ADDR(SELECTOR), EMPLOYEE_IOAREALEN, ADDR(EMPLOYEE_IOAREA),VSTATUS, VRESULT);

VHANDLE is the handle containing the value returned from VASTART.

ADDR(RECEIVER) contains the Smalltalk class name.

ADDR(SELECTOR) contains the selector name of the Smalltalk class method.

EMPLOYEE_IOAREALEN contains the length of the io storage area. In this case we are passing an Employee record.

ADDR(EMPLOYEE_IOAREA) is a user defined storage area containing the data to be passed to and returned from the called Smalltalk program. In this case, we pass an Employee record. This area is defined in PL/I as follows.
DCL 1 EMPLOYEE_IOAREA, 2 EMPNO CHAR(06), 2 FIRSTNM, 3 LENGTH_FIRST REAL FIXED BINARY(15,0), 3 FIRSTNME CHAR(12), 2 MIDINIT CHAR(01), 2 SEX CHAR(1), 2 LASTNAM, 3 LENGTH_LAST REAL FIXED BINARY(15,0), 3 LASTNAME CHAR(15), 2 WORKDEPT CHAR(03), 2 PHONENO CHAR(04), 2 HIREDATE CHAR(10), 2 JOB CHAR(08), 2 EDLEVEL REAL FIXED BINARY(15,0), 2 BIRTHDATE CHAR(10), 2 SALARY FIXED DEC(11,2), 2 BONUS FIXED DEC(11,2), 2 COMM FIXED DEC(11,2);

VSTATUS is where a return code can be placed.

VRESULT contents are currently undefined.

After the VARUN call is made, the calling HLL program can use what has been returned in the IOAREA by the Smalltalk application.

VASTOP initiates image shutdown. PL/I code using this call looks like this:
CALL VASTOP(VHANDLE,VSTATUS);

In getting the HLL program to successfully call a Smalltalk image, both sides have to be developed concurrently.

The Smalltalk development side involves the following steps:

(1) Add the CallInSupport Application as a prerequisite for the application you want to call in to.

(2) If the calling application passes a record structure, create a subclass of OSPtr to use in sharing information for the passed parameters. In the example code discussed here we are passing an Employee structure. In Smalltalk, we parse a copy book or header file to create an Employee class that is a subclass of OSPtr.

(3) Ensure there is a class method to service the call in your application.

To get the arguments of the call given in VARUN, you must send the message AbtCallinSupport arguments. To handle the passing of the Employee data and create a populated Employee object, you get the address of the passed block of shared memory and send the address: message to the Employee class. The Smalltalk code that accomplishes this follows.
callInArea := AbtCallinSupport arguments.

employeeFromCaller := Employee address: callInArea callerData reference.

…….. messages to manipulate Employee values ………..

The Smalltalk methods can then update the Employee as required. In our classroom example we have the HLL program pass an Employee record that contains the latest education level of the employee. The Smalltalk program updates the employee's salary based on the latest education level.

(4) Package for call-in support, upload the image to MVS and create the load module using a batch job.

The High Level Language development side steps are:

(1) Rewrite the calling program to use VASTART, VARUN, VASTOP to call the Smalltalk image and send messages to it. The HLL program must know the image name and what class methods to call with parameters.

(2) Rewrite the program to pass the parameters

(3) Create the stub and the HLL load module using a JCL proc.

The general procedure to create a load module for execution is shown in Figure 1 below.

The JCL proc ACTXCALM, creates a HLL stub for call in to Smalltalk. This job initializes the image, converts the image to an object module and link edits the image with the HLL Stub, which supports VASTART, VARUN and VASTOP. This stub can be for C, PL/I or COBOL programs, in either CICS, IMS or MVS Native batch applications, calling in to Smalltalk. A second step is to compile the High Level Language Module with the stub to create a load module.



Figure 1 - Creating a load module.

Below is the JCL portion to produce the STUB for PL/I in an IMS environment.

/CALLSTUB EXEC PROC=ABTXCALM,OBJMOD=PLICALIN,

// INFILE=USER.IMAGE.LIBRARY,

// OUTFILE=USER.LOADLIB,

// STAKDUMP=USER.STAKDUMP,

// IMAGE=PLICALIN, "Image name"

// ENV=I, " Environment is IMS"

// LANG=PLI "Language is PL/I"

For legacy systems written on MVS in COBOL, PL/I or C /370,

call-in support using standard calling conventions is currently available. The workstation capability is not currently available. Any class method in Smalltalk can be called. Subsequent to that, any instance method in the image can be executed. The image can be started and stopped numerous times without initialization overhead and parameters can be passed back and forth between the HLL program and the Smalltalk image. The year 2000 problem is the theme of this edition of Eye-On-Objects. The Call-in facilities of VisualAge for Smalltalk Server may be able to help with this. It can be used in situations where a high-level language program doing date calculations, can call into a smart Smalltalk program which recognizes and resolves any inconsistencies. I will leave it as an exercise to the reader on how this can be accomplished.

Special Acknowledgment: Thanks to Holger Schwarzer of IBM for help with this article.

Enjoy the article? Subscribe to Eye on Objects!

Bruce Whitenack is a Software Writer in Residence with The Object People, U.S. in Raleigh, North Carolina. He is the author of RAPPeL (Requirements Analysis Process Pattern Language) and co-author of Crossing Chasms as well as the course developer for VisualAge for Smalltalk Server: Transaction Managed Objects and TOPLink, a relational database to objects framework . He welcomes your comments..

Home Page