Monday, September 17, 2007

I'm trying to figure out how the CLR type system will work with Lisp. My script does a simple thing of calling .write on the document object. It is currently erroring out because `.write' is undefined. Fair enough, I didn't define it. But it ought to be defined when I try to invoke it on the document object. Hmm.... maybe that's the key....

This just keeps getting better and better! Now I can't debug because something is timing out the script and aborting the process before I can look at what is going on.

Weekend update

Over the weekend I changed the script project to launch the script within a browser rather than from the command line. This allows me to debug from the IDE directly. I spent a fair amount of time trying to get the browser to stop complaining that my script language was an untrusted ActiveX control, but I had no luck. I implemented IObjectSafety, but then the browser stopped trying to run my script altogether. I added a reader to the Lisp engine so now the script can be turned into list structure. I'm adding a minimal evaluator so I can test out function calling. I haven't quite figured out how to integrate the package system with everything, but there is something minimal in place.

Thursday, September 13, 2007

Past that hurdle

The problem wasn't necessarily an out-of-memory issue, it was a mismatch in how native COM objects are marshaled to managed CLR objects. I wrote a custom marshaler that emits debugging messages and used it to figure out which argument was having problems. A little fussing around and I got it working just fine. At this point, the scripting host starts the scripting engine, calls `AddNamedObject' a couple of times, calls `ParseScriptText' with the source code of the script, and tells the engine to go. I need to suck some meta-data out of the named objects so that I can use them. That seems a little clunky, and I'm surprised that it isn't quite built in to the interop code. A little poking around in how VisualBasic and JScript do it lead me to believe that there isn't a good canonical mechanism. It is amazing this stuff works so well. It's impressive that it works at all. The code is on my code site at http://jrm-code-project.googlecode.com/svn/trunk/LScript/

Tuesday, September 11, 2007

Got it!

Apparently the scripting hosts were sending the strings over in ANSI format rather than Unicode. I'm not quite sure why this causes an out of memory error (maybe something was trying to copy the string and misread the initial characters as a size parameter?). Changing the MarshalAs attribute in the declaration of IActiveScript solved the problem.

Monday, September 10, 2007

A Clue

I downloaded ComSpy and found that when the Script host (WScript) is about to call IActiveScript::Method9 (which is AddNamedItem) it gets an HRESULT of 0x8007000E (Not enough storage is available to complete this operation.) Looking at the VM size of the WScript process, it gets up to 30MB by the time it tries to call that method. The CLR is clearly taking up quite a bit of room, but how do I persuade WScript to let it? There should be plenty more room.

More fooling around with scripting

Over the weekend I wrote a scripting engine for windows in c#. It doesn't do anything yet, it just implements the scripting API. The only problem is that it doesn't completely work. It doesn't completely fail, either. That's weird because I'd expect an all or nothing response. When I run the script under the cscript host, it creates an instance of the engine and calls the SetScriptSite and InitNew methods. Then it craps out with an error `CScript Error: Can't find script engine "LScript" for script. I suspect the actual error message is a red herring. I bet that the engine initialization code is located in a try/catch/finally block and the message comes from that block. What is weird is that since the SetScriptSite and InitNew methods are being invoked, it is clear that a whole lot of the machinery is working. Clearly the CLR runtime is being loaded, the engine assembly is loaded, the engine class is created and the com-callable wrapper for both the IActiveScript and IActiveScriptParse interfaces is being correctly created and delivered to the script host. So why does it fail? I ran the server from two different hosts: CScript and from within Internet Explorer. Both seem to be able to call the first few methods. A hint is that the next method each should call is AddNamedItem. Neither host seems to invoke that. I can't see what cscript is trying to do (the stack trace is truncated), so I wrote my own scripting host in C++. Unfortunately it seems to work with no problem. I also tried Hugh Brown's NullScript engine, and that seems to work just fine, too. For a while I thought I was on to something because I noticed that a typelib that was being generated was missing some entries. It made no difference when I corrected the problem, though. In any case, I put the code up at http://jrm-code-project.googlecode.com/svn/trunk/LScript/ and I'll probably play with it a bit more before I give up completely.

Saturday, September 8, 2007

Playing around

I decided to try making a scripting engine stub in C#. I got it partway working. The various scripting hosts can start the stub and invoke a few of the methods in it, but for some reason, they all fail at some point or another. It is a bit mysterious because I don't have a debugger that can handle this, so I'm relying on print statements. But one scripting host just stops calling the engine after initializing it. There doesn't seem to be an error, it just hangs up. I suspect it is a failed query for an interface, but I'm not sure how to go about finding out which interface.

Friday, September 7, 2007

I wonder

Why can't I script my windows box with Lisp or Scheme instead of VBScript or JScript?