MediaWiki:Blocklistline

From askoh.net wiki

Jump to: navigation, search

Contents

source

31 March 2010

Compile SqueakVM as DLL

Squeak.exe need to be compile as Squeak.dll, a main program will link against it. MainProgram.exe will have nothing but a main.c file. main.c will have the handle to Squeak.dll, reference to Squeak.dll functions. Squeak.dll will have some minor changes. It will be break into two main parts. First part will run from previous entry point(WinMain()) to the point right before interpret() -- SqueakInit(). Second part will be interpret() loop -- SqueakInterp(). Instead if interpret(void), my interpret() will take an argument-(char* sqExp), interpret(char* sqExp). The argument will have a smalltalk command sent from main to Squeak.dll side. At Squeak.dll, I add a global dllString, to ease the process of sqExp, from here on, sqExp will be refer to as dllString. Follows will be how it works.

  1. main setup to use Squeak.dll
  2. main will call SqueakInit() which will run Squeak.dll from entry point to right before interpret() loop
  3. main will prompt user for input(Smalltalk command), eg, "3 class" or "3 asFloat". And this input will be the sqExp to send to Squeak.dll
  4. main call SqueakInterp(sqExp), passing Smalltalk command to Squeak.dll
  5. main print the result when Squeak.dll returns with result string
  6. Again, main will prompt user for Smalltalk command, call SqueakInterp() etc.


primitiveCString

I start with writing a primitive to pass C String from C to Squeak. I learn from primitiveVMPath, as it passes vm path (C String) into Squeak. I choose a primitiveObsoleteIndexedPrimitive, 169, for no specific reason, and replace it with primitiveCString.

sqInt primitiveCString(void) {
    sqInt sz;
    sqInt s;

	sz = strlen(dllString);
	s = instantiateClassindexableSize(splObj(ClassString), sz);
	getCStringLength(s + BaseHeaderSize, sz);
	popthenPush(1, s);
}

processDLLString

A method is needed at Squeak-side to get string from C, process and return to main. For that I create a class named "SqueakDLL". "SqueakDLL" will have interface methods to primitives, and a method to process string.

processDLLString
	| str result dll |
	dll := SqueakDLL new.
	str := dll primCString.
	result := (Compiler evaluate: str) printString.
	dll primReturnString: result size: result size

primitiveReturnString

After execution, the result need to be send from Squeak to Squeak.dll, and then return to main.exe. For this, I have a primitiveReturnString to do the job(primitive 170).

sqInt primitiveReturnString(void){
	sqInt i,count;
	char* s;

	count = integerValueOf(popStack());
	s = popStack() + BaseHeaderSize;//get argument 1

	for (i= 0; i < count; i++)
		dllString[i]= s[i];
	dllString[count] = '\0';
}

After the primitive, result need to be return to main.exe. Therefore, I place a return at the end of bytecode 131(singleExtendedSendBytecode), with condition current primitive index is 170.

l47:	/* end internalExecuteNewMethod */;
	/* begin fetchNextBytecode */
	currentBytecode = byteAtPointer(++localIP);

	if(primitiveIndex == 170)
	return;

dllLoop

So far, if I run main.exe, main will have Squeak.dll runs, opens up a windows. I need to manually doIt "SqueakDLL processDLLString" to get the process going. For this, I add a method to the class SqueakDLL, which will processDLLString run infinitely as a process.

dllLoop
	[[true]
		whileTrue: [SqueakDLL processDLLString]]forkAt: 30

The process is place slightly below the priority of the Squeak GUI. I then doIt "SqueakDLL dllLoop", and save the image. Finally, I build Squeak.dll to be headless.


22 March 2010

  1. Make Squeak compile as a DLL, have a main program(CAD) link-against Squeak.dll.
  2. Start main program, main program will call the dll function SqueakInit(), which will have Squeak start up, *with image loaded*, etc.. Squeak.dll will return just right before it enter interpret() loop.
  3. Main program then call dll function SqueakInterp(squeakExpression) with a String-squeakExpression as its argument. squeakExpression will be the expression to be execute by Squeak.dll. Enter interp() loop.
  4. At this point of time, activeContext will have a method ready to process squeakExpression, or maybe a high priority process.
  5. The method, or process, will have to call a primitiveReadString to get squeakExpression from C(squeak.dll). Then, execute squeakExpression as perhaps just a DoIt. Method ends with a primitiveReturnString, return result as a String to the main program.
Personal tools
Navigation