spiderMonkeyClass = new (metadata) JS2SpiderMonkeyClass(&world->identifiers[widenCString("SpiderMonkey")]);
spiderMonkeyClass = new (metadata) JS2SpiderMonkeyClass(world->identifiers[widenCString("SpiderMonkey")]);
static LRESULT CALLBACK PluginWinProc(HWND, UINT, WPARAM, LPARAM);static WNDPROC lpOldProc = NULL;using namespace JavaScript;using namespace MetaData;void report(Exception x){    String s = x.fullMessage();	std::string str(s.length(), char());	std::transform(s.begin(), s.end(), str.begin(), narrow);    printf(str.c_str());}NPBool nsPluginInstance::init(NPWindow* aWindow){  if(aWindow == NULL)    return FALSE;  mhWnd = (HWND)aWindow->window;  if(mhWnd == NULL)    return FALSE;  // subclass window so we can intercept window messages and  // do our drawing to it  lpOldProc = SubclassWindow(mhWnd, (WNDPROC)PluginWinProc);  // associate window with our nsPluginInstance object so we can access   // it in the window procedure  SetWindowLong(mhWnd, GWL_USERDATA, (LONG)this);  printf("Pandora: starting up\n");  world = new World();  metadata = new JavaScript::MetaData::JS2Metadata(*world);  spiderMonkeyClass = new (metadata) JS2SpiderMonkeyClass(&world->identifiers[widenCString("SpiderMonkey")]);  printf("Pandora: done starting up\n");   mInitialized = TRUE;  return TRUE;}void nsPluginInstance::shut(){  // subclass it back  SubclassWindow(mhWnd, lpOldProc);  mhWnd = NULL;  mInitialized = FALSE;  try {      printf("Pandora: shutting down\n");      if (metadata) {        delete metadata;        metadata = NULL;      }      if (world) {        world->identifiers.clear();        delete world;        world = NULL;      }      printf("Pandora: done shutting down\n");  }  catch (Exception x) {    report(x);  }}NPBool nsPluginInstance::isInitialized(){  return mInitialized;}void nsPluginInstance::invoke(const char *target, char **_retval){    js2val rval = metadata->invokeFunction(target);    const JavaScript::String *valstr = metadata->toString(rval);    std::string str(valstr->length(), char());    std::transform(valstr->begin(), valstr->end(), str.begin(), narrow);    *_retval = (char *)NPN_MemAlloc(strlen(str.c_str()) + 1);    strcpy(*_retval, str.c_str());}void nsPluginInstance::GetDocument(nsISupports * *aDocument){    *aDocument = doc;}void nsPluginInstance::SetDocument(nsISupports *aDocument){    printf("Pandora: setting document\n");    NS_ADDREF(aDocument);    doc = aDocument;    // stash the wrapped JSObject from the document as    // a SpiderMonkeyInstance named 'document' in the (JS2) global object    nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID());    if (xpc) {        nsIXPCNativeCallContext *aCurrentNativeCallContext;        if (NS_SUCCEEDED(xpc->GetCurrentNativeCallContext(&aCurrentNativeCallContext))) {            JSContext *aJSContext;            if (NS_SUCCEEDED(aCurrentNativeCallContext->GetJSContext(&aJSContext))) {                nsIXPConnectJSObjectHolder *wrappedDoc;                if (NS_SUCCEEDED(xpc->WrapNative(aJSContext, aJSContext->globalObject, doc, nsIDOMDocument::GetIID(), &wrappedDoc))) {                    JSObject *obj;                    if (NS_SUCCEEDED(wrappedDoc->GetJSObject(&obj))) {                        SpiderMonkeyInstance *smInst = new (metadata) SpiderMonkeyInstance(metadata, metadata->objectClass->prototype, spiderMonkeyClass);                        smInst->jsObject = obj;                        smInst->pluginInstance = this;                        metadata->createDynamicProperty(metadata->glob, "document", OBJECT_TO_JS2VAL(smInst), ReadWriteAccess, true, false);                        printf("Pandora: done setting document\n");                    }                }                NS_RELEASE(aCurrentNativeCallContext);            }        }    }}NPError nsPluginInstance::NewStream(NPMIMEType type, NPStream* stream,                             NPBool seekable, uint16* stype){    *stype = NP_ASFILEONLY;    return NPERR_NO_ERROR; }void nsPluginInstance::StreamAsFile(NPStream* stream, const char* fname){    printf("Pandora: compiling source\n");    // compile the file, error reports need to go to the JS console    // if succesful, script level functions get proxies generated    try {        metadata->readEvalFile(fname);            for (LocalBindingIterator bi = metadata->glob->localBindings.begin(), 				    bend = metadata->glob->localBindings.end(); (bi != bend); bi++) {            LocalBindingEntry *lbe = *bi;            for (LocalBindingEntry::NS_Iterator i = lbe->begin(), end = lbe->end(); (i != end); i++) {                LocalBindingEntry::NamespaceBinding ns = *i;                LocalMember *m = checked_cast<LocalMember *>(ns.second->content);                switch (m->memberKind) {                case Member::FrameVariableMember:                    {                        FrameVariable *fv = checked_cast<FrameVariable *>(m);					    js2val v = (*metadata->glob->frameSlots)[fv->frameSlot];					    if (JS2VAL_IS_OBJECT(v) 							    && (JS2VAL_TO_OBJECT(v)->kind == SimpleInstanceKind)							    && (checked_cast<SimpleInstance *>(JS2VAL_TO_OBJECT(v))->type == metadata->functionClass)							    ) {						    FunctionInstance *fnInst = checked_cast<FunctionInstance *>(JS2VAL_TO_OBJECT(v));						    String fnName = lbe->name;                    						    std::string fstr(fnName.length(), char());						    std::transform(fnName.begin(), fnName.end(), fstr.begin(), narrow);                            printf("Pandora: adding wrapper for \"%s\"\n", fstr.c_str());                						    StringFormatter sf;						    printFormat(sf, "JavaScript:function %s() { return document.js2.invoke(\"%s\"); }", fstr.c_str(), fstr.c_str());						    std::string str(sf.getString().length(), char());						    std::transform(sf.getString().begin(), sf.getString().end(), str.begin(), narrow);						    NPN_GetURL(mInstance, str.c_str(), NULL);					    }					                        }                    break;			    }            }		            }        printf("Pandora: done compiling source\n");    }    catch (Exception x) {        report(x);    }}// ==============================// ! Scriptability related code !// ==============================//// here the plugin is asked by Mozilla to tell if it is scriptable// we should return a valid interface id and a pointer to // nsScriptablePeer interface which we should have implemented// and which should be defined in the corressponding *.xpt file// in the bin/components folderNPError	nsPluginInstance::GetValue(NPPVariable aVariable, void *aValue){  NPError rv = NPERR_NO_ERROR;  if (aVariable == NPPVpluginScriptableInstance) {    // addref happens in getter, so we don't addref here    nsIPandora * scriptablePeer = getScriptablePeer();    if (scriptablePeer) {      *(nsISupports **)aValue = scriptablePeer;    } else      rv = NPERR_OUT_OF_MEMORY_ERROR;  }  else if (aVariable == NPPVpluginScriptableIID) {    static nsIID scriptableIID = NS_IPANDORA_IID;    nsIID* ptr = (nsIID *)NPN_MemAlloc(sizeof(nsIID));    if (ptr) {        *ptr = scriptableIID;        *(nsIID **)aValue = ptr;    } else      rv = NPERR_OUT_OF_MEMORY_ERROR;  }  return rv;}// ==============================// ! Scriptability related code !// ==============================//// this method will return the scriptable object (and create it if necessary)nsScriptablePeer* nsPluginInstance::getScriptablePeer(){  if (!mScriptablePeer) {    mScriptablePeer = new nsScriptablePeer(this);    if(!mScriptablePeer)      return NULL;    NS_ADDREF(mScriptablePeer);  }  // add reference for the caller requesting the object  NS_ADDREF(mScriptablePeer);  return mScriptablePeer;}static LRESULT CALLBACK PluginWinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){  switch (msg) {    case WM_PAINT:      {/*        // draw a frame and display the string        PAINTSTRUCT ps;        HDC hdc = BeginPaint(hWnd, &ps);        RECT rc;        GetClientRect(hWnd, &rc);        FrameRect(hdc, &rc, GetStockBrush(BLACK_BRUSH));        // get our plugin instance object and ask it for the version string        nsPluginInstance *plugin = (nsPluginInstance *)GetWindowLong(hWnd, GWL_USERDATA);        if (plugin)          DrawText(hdc, plugin->mString, strlen(plugin->mString), &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER);        else {          char string[] = "Error occured";          DrawText(hdc, string, strlen(string), &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER);        }        EndPaint(hWnd, &ps);*/      }      break;    default:      break;  }  return DefWindowProc(hWnd, msg, wParam, lParam);}