Subj : Re: SpiderMonkey: JS_InitStandardClasses allways fails To : netscape.public.mozilla.jseng From : "Franky Braem" Date : Mon May 05 2003 10:52 pm This is how I turn a jsval into a std::string JSString *s = JS_ValueToString(cx, v); std::string str(JS_GetStringBytes(s), JS_GetStringLength(s)); You can do this also for types that you don't support. JS_ValueToString will always try to convert the jsval into a String representation. Why do you use LAZY_STANDARD_CLASSES? I think you have to make a JS_ResolveStub for the global class, so that when somebody uses a standard class for the first time, the class gets initialized. Franky. "Georg Maaß" wrote in message news:b967cm$g2bgl$1@ID-3551.news.dfncis.de... > Hi, > > I have problems to make SpiderMonkey work correctly when called from my > application (C++). > > 1. problem: JS_InitStandardClasses allways fails (return value is > false). In js.c from js1.5rc5 there is a macro flag called > LAZY_STANDARD_CLASSES, which triggers whether this function is used > there or not. The macro flag is set, which causes JS_InitStandardClasses > not to be called. Because of allways failing of JS_InitStandardClasses I > defined this macro flag too in my own attempt, to circumvent that function. > > 2. problem: any name insiede JavaScript code causes the whole script to > fail without any error message. Scripts like "2*3;" are evaluated > perfectly resulting in "6". Scripts like "10;0815;" result as expected > in an error message: "test.js:4711: warning: > 08 is not a legal ECMA-262 octal constant: > test.js:4711: warning: 15;0815; > test.js:4711: warning: ...^"; > This means my function ErrorReporter is connected correctly to the > engine and seams to work correctly. But scripts like "Math.max(1,2)" > fail without error message. Also scripts like "var a = 1; 2 * 3 + a;" > fail without error message, when JS_EvaluateScript is called. The > behaviour is the same when first failing with JS_InitStandardClasses or > just not calling JS_InitStandardClasses. > > I assume, that I did something simple but essential wrong, but I have no > idea, what I did wrong. > > 3. problem: how can I get a std::string or at least a char* from a JSVAL > that is a JSVAL_STRING. The JSString struct is different to std::string > and also not a real char*. But char* is also not really nice, because > this expects 0 as end mark and not als legal character, where > std::string also allows 0 as character. > > > I've pasted two functions. init sets up SpiderMonkey and does a test > call to the second function evaluateJavaScript to evaluate a small test > script and transfer the result into the variables of my application. > > > I hope one of you can help me to solve the problems. > > > bool init() // globale Initialisierung der Mozilla-Engine > { // > available = false; // Flag löschen, da wir noch nicht > wisssen, ob die Mozilla- > // Engine tatsächlich funktioniert. > version = JSVERSION_DEFAULT; // Mozilla-Engine > JavaScript-Version festlegen > if(runtime) JS_DestroyRuntime(runtime); // Falls wir schon eine > Runtime-Umgebung haben, entsorgen wir sie > // if(runtime = JS_Init(8L * 1024L * 1024L)) // Runtime-Umgebung > initialisieren. > if(runtime = JS_NewRuntime(8L * 1024L * 1024L)) // > Runtime-Umgebung initialisieren. > { > if(global_context = JS_NewContext(runtime, STACK_CHUNK_SIZE)) > { > JS_SetErrorReporter(global_context, ErrorReporter); // > Error-Reporter anschließen > #ifdef __mozilla_stub__ > if(global_object = JS_NewObject ( // Das globale Objekt > initialisieren > global_context > , &global_class > , 0 > , 0 > )) > { > #ifdef LAZY_STANDARD_CLASSES > JS_SetGlobalObject ( // JavaScript-Objekte intialisieren > und festhalten, ob die > // Mozilla-Engine funktioniert. > global_context > , global_object > ); > available = true; // Da wir keine Information über Erfolg > oder Mißerfolg > // erhalten, gehen wir vom Erfolg aus. > evaluateJavaScript("2*3;","test.js",4711); // TEST > #else > available = JS_InitStandardClasses ( // JavaScript-Objekte > intialisieren und festhalten, ob die > // Mozilla-Engine funktioniert. > global_context > , global_object > ); > if(!available) ERRORS.push_back ( // Beim Versuch, die > JavaScript-Objekte zu initialisieren, > Error ( // trat ein Fehler auf. > "gmL_mozilla::init" > , Error_failed_setup_js_javascript_objects > ) > ); > #endif > } > else ERRORS.push_back ( // Beim Versuch das Globale-Object > der Mozilla-Engine zu > Error ( // initialisieren, trat ein Fehler auf. > "gmL_mozilla::init" > , Error_failed_setup_js_global_object > ) > ); > #else > #endif > } > else ERRORS.push_back ( // Beim Versuch einen Context der > Mozilla-Engine zu > Error ( // initialisieren, trat ein Fehler auf. > "gmL_mozilla::init" > , Error_failed_setup_js_context > ) > ); > } > else ERRORS.push_back ( // Beim Versuch die Runtime-Umgebung > der Mozilla-Engine zu > Error ( // initialisieren, trat ein Fehler auf. > "gmL_mozilla::init" > , Error_failed_setup_js_runtime > ) > ); > pair pa = > GLOBALS.insert(pair("mozilla_enabled",0)); > if(pa.first->second) // Wurde eine bestehende Variable mit > einem Wert-Objekt gefunden? > { // JA, also müssen wir ihren Typ nun aufbool festlegen > pa.first->second->setType(Wert_bool); > } > else > { // NEIN, ein Zeiger für eine neue Variable wurde > angelegt > // oder ein Zeiger für eine gelöschte Variable gefunden. > pa.first->second = new Wert(Wert_bool); // Neue Variable > erzeugen und dem Zeiger zuweisen > } > pa.first->second->setValue(available); // festhalten, ob die > Mozilla-Engine funktioniert > return available; > } > > > > > > Wert* evaluateJavaScript ( > const std::string& Quelltext > , const std::string& Datei > , unsigned long Zeile > ) > { > jsval rval; > bool ok = JS_EvaluateScript ( > global_context > , global_object > , Quelltext.c_str() > , Quelltext.size() > , Datei.c_str() > , Zeile > , &rval > ); > pair pa = > GLOBALS.insert(pair("mozilla_result",0)); > switch(JS_TypeOfValue(global_context, rval)) > { > case JSTYPE_VOID: > { > if(pa.first->second) pa.first->second->setType(0); // Typ auf > "undefined" setzen > else pa.first->second = new Wert(0); // Variable mit Typ > "undefined" erzeugen und Zeiger zuweisen > break; > } > case JSTYPE_BOOLEAN: > { > if(pa.first->second) pa.first->second->setType(Wert_bool); // Typ > auf bool setzen > else pa.first->second = new Wert(Wert_bool); // Variable mit Typ > bool erzeugen und Zeiger zuweisen > pa.first->second->setValue(JSVAL_TO_BOOLEAN(rval)); // Wert speichern > break; > } > case JSTYPE_NUMBER: > { > if(JSVAL_IS_INT(rval)) > { > if(pa.first->second) pa.first->second->setType(Wert_int); // Typ > auf int setzen > else pa.first->second = new Wert(Wert_int); // Variable mit Typ > int erzeugen und Zeiger zuweisen > pa.first->second->setValue(JSVAL_TO_INT(rval)); // Wert speichern > } > else > { > jsdouble d; > ok = JS_ValueToNumber(global_context, rval, &d); > if(pa.first->second) pa.first->second->setType(Wert_double); // > Typ auf double setzen > else pa.first->second = new Wert(Wert_double); // Variable mit > Typ double erzeugen und Zeiger zuweisen > if(ok) pa.first->second->setValue(d); // Wenn wie einen Wert > erhielten, Wert speichern; > else pa.first->second->setType(0); // sonst Typ auf > "undefined" setzen > } > break; > } > case JSTYPE_STRING: > { > /* > Das funktioniert nicht! JSVAL_TO_STRING erzeugt keinen char* > if(pa.first->second) pa.first->second->setType(Wert_string); // Typ > auf string setzen > else pa.first->second = new Wert(Wert_string); // Variable mit > Typ string erzeugen und Zeiger zuweisen > pa.first->second->setValue(JSVAL_TO_STRING(rval)); // Wert speichern > break; > */ > } > case JSTYPE_OBJECT: > { > //### ToDo ### Hier soll ein Quelltext-Literal des Objektes entstehen > (uneval) > // break; > } > case JSTYPE_FUNCTION: > { > //### ToDo ### Hier soll ein Quelltext-Literal der Funktion entstehen > (uneval) > // break; > } > default: > { > // Autsch! Es ist irgend ein Typ, den wir nicht unterstützen > if(pa.first->second) pa.first->second->setType(0); // Typ auf > "undefined" setzen > else pa.first->second = new Wert(0); // Variable mit Typ > "undefined" erzeugen und Zeiger zuweisen > } > } > if(ok) return pa.first->second; // Wir geben einen Zeiger > auf das Result-Objekt zurück > } > if(!ok) > { > std::ostringstream oS; > oS << Zeile; > ERRORS.push_back ( // Ein unbekannter JavaScript-Fehler > trat auf. > Error ( > "gmL_mozilla::evaluateJavaScript" > , Error_js_error > , Quelltext // problematischer Quelltext > , Datei // Datei > , oS.str() // Zeilennummer > ) > ); > } > return 0; // Wir signalisieren den Fehler durch einen > null-Zeiger > } > > > > -- > Georg Maaß - bioshop.de D-93466 Chamerau, Roßbergweg 42 > JavaScript, C++ Engineering > - The ultimative DHTML engine: http://gml-modul.sourceforge.net - > http://sourceforge.net/projects/gml-modul > .