Saturday, September 03, 2005

The lookup code generated for the proxy class is based on the strategy outlined in the previous post. First, some code snippets, followed by a discussion:


class HelloClass;
class HelloClassProxy;

typedef JSBool(HelloClassProxy::*JSSIG_HelloClass)(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);

class HelloClassProxy {
public:
HelloClassProxy();
~HelloClassProxy();
JSSIG_HelloClass
GetEntryPoint(const string& name);
JSBool
Get_age(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
JSBool
Set_age(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
JSBool
Hello(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
private:
HelloClass *m_impl;
};

extern "C" HelloClassProxy *NewHelloClassProxy();
extern "C" void DeleteHelloClassProxy(HelloClassProxy *ptr);
extern "C" JSSIG_HelloClass HelloClassProxyLookup(HelloClassProxy *ptr, const string& name);


The typedef JSSIG_HelloClass represents a pointer to a HelloClassProxy member function with the prototype mandated by the mozilla JavaScript engine. For each class in the component, a similar typedef is generated by the layout engine.

GetEntryPoint() is a new member function that returns a pointer to a HelloClassProxy member function that matches the name passed in. Here is the code that is now being generated for that particular function by iterating the DOM for functions and properties implemented by HelloClassProxy:


JSSIG_HelloClass
HelloClassProxy::GetEntryPoint(const string& name)
{
if (name == "Hello")
return &HelloClassProxy::Hello;
if (name == "Get_age")
return &HelloClassProxy::Get_age;
if (name == "Set_age")
return &HelloClassProxy::Set_age;
return NULL;
}


As you can see, all this function does is perform a simple check for a matching string, and return a pointer to a member function if a match is found. Notice the interesting way by which a pointer to a member function is obtained; this takes some getting used to if you and an old-timer C programmer (like I was). Yes, I could have put the names and functions into an STL map, but this code was more straightforward to implement in the layout code generator.

The final function generated by the layout engine to support lookups is a simple extern "C" function that allows the layout engine to call into the component and invoke GetEntryPoint() thru the class object that it holds:


extern "C" JSSIG_HelloClass
HelloClassProxyLookup(HelloClassProxy *ptr, const string& name)
{
if (!ptr)
return NULL;
return ptr->GetEntryPoint(name);
}


That's pretty much it. This should be all that is needed for the layout engine to populate the JavaScript object with entry points into the proxy classes. The next step is to add code to the layout engine that does just that.

0 Comments:

Post a Comment

<< Home