Eoferror eof read where object code expects

SpiderMonkey

The Mozilla JavaScript Engine

[the first lines]

First we download the sources from Mozilla and compile the shared libraries.

The archive: http://ftp.mozilla.org/pub/mozilla.org/js/js185-1.0.0.tar.gz

The directory: http://ftp.mozilla.org/pub/mozilla.org/js/ also contains Rhino, among other things.

Latest Version: http://hg.mozilla.org/mozilla-central

http://developer.mozilla.org/en-US/docs/SpiderMonkey/Getting_SpiderMonkey_source_code (getting new and old sources)

Installation is easier than expected. It compiles without errors and installs itself. The corridor is the usual one. Configure, Make, Make Install, Done.

cd /js-1.8.5/js/src ./configure make make install

That would be done.

# make install /js-1.8.5/js/src/config/nsinstall -t js-config / usr / local / bin /js-1.8.5/js/src/config/nsinstall -t libjs_static.a / usr / local / lib mv -f /usr/local/lib/libjs_static.a /usr/local/lib/libmozjs185-1.0.a /js-1.8.5/js/src/config/nsinstall -t libmozjs185.so / usr / local / lib mv -f /usr/local/lib/libmozjs185.so /usr/local/lib/libmozjs185.so.1.0.0 ln -s /usr/local/lib/libmozjs185.so.1.0.0 / usr / local / lib / libmozjs185.so.1.0 ln -s /usr/local/lib/libmozjs185.so.1.0 /usr/local/lib/libmozjs185.so

First information

https://developer.mozilla.org/en-US/docs/SpiderMonkey

There are rumors about after 1.8.5. http://developer.mozilla.org/en-US/docs/SpiderMonkey/1.8.8

The current version is available with the Firefox source code or in Mozilla Central, I think, since I've now examined all sources. To build the current version and also Gecko, I'm not that far yet.

I'll get to the Gecko Rendering Engine soon if I want the DOM. As you can see, SpiderMonkey without DOM is ready for use with a few megabytes for the compiled sources. I'm going to show you some awesome things now.

SpiderMonkey coding conventions

  • The SpiderMonkey project owners enforce coding conventions pretty strictly during code reviews.
  • Naming conventions
  • Public function names begin with JS_ followed by capitalized "intercaps", e.g. JS_NewObject.
  • Extern but library-private function names use a js_ prefix and mixed case, e.g. js_SearchScope.
  • Most static function names have unprefixed, mixed-case names: GetChar.
  • But static native methods of JS objects have lowercase, underscore-separated or intercaps names, e.g., str_indexOf.
  • And library-private and static data use underscores, not intercaps (but library-private data do use a js_ prefix).
  • Scalar type names are lowercase and js-prefixed: jsdouble.
  • Aggregate type names are JS-prefixed and mixed-case: JSObject.
  • Macros are generally ALL_CAPS and underscored, to call out potential side effects, multiple uses of a formal argument, etc.
  • Linkage
  • DLL entry points have their return type expanded within a JS_PUBLIC_API () macro call, to get the right Windows secret type qualifiers in the right places for all build variants.
  • DLL entry points that are not public APIs use JS_FRIEND_API () instead.
  • So see
  • SpiderMonkey C ++ Coding Style on wikimo

http://developer.mozilla.org/en-US/docs/SpiderMonkey_conding_conventions

Stolen Hello World

By Brendan Eich the creator of the language

Copy + Paste: This example is copied from https://developer.mozilla.org/en-US/docs/How_to_embed_the_JavaScript_engine.

cat >> /hello.cpp # A middle mouse click pastes Source in the clipboard # Ctrl-D

I have copied this text here directly.

The original is by Brendan Eich (see original page on Mozilla)

/ * * This define is for Windows only, it is a work-around for bug 661663. * / #ifdef _MSC_VER # define XP_WIN #endif / * Include the JSAPI header file to get access to SpiderMonkey. * / #include "jsapi.h" / * The class of the global object. * / static JSClass global_class = {"global", JSCLASS_GLOBAL_FLAGS, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub, JS_EnumerateStub, JS_ResolveStub, JS_ResolveStub, JS_ResolveStub, JS_Convert_FonvertStub} / * The error reporter callback. * / void reportError (JSContext * cx, const char * message, JSErrorReport * report) {fprintf (stderr, "% s:% u:% s \ n", report-> filename? report-> filename: "

I then compiled it with this command.

g ++ -I / js-1.8.5 / js / src / dist / include -L / js-1.8.5 / js / src / dist / bin -lmozjs185 hello.cpp -o hello

et voila

> ./hello Hello World!

Now you can read through the Hello World Code and find out something first.

The Hello World was replaced by 'Hello' + 'World!' composed. If you give e.g. "hello" + "world!" one, comes also "hello world!" Out.

So a concatenation was carried out with the plus operator and the return value was output with printf ("% s", ..) after JS_EvaluateScript, JS_ValueToString, JS_EncodeString were running.

Note jsval: This is the ultimate important data type (the JavaScript values) for every evaluation, every function call, the return code of a function is set with a jsval, the arguments are jsvals, and and and ...

Above, first you have to declare JS_Runtime, JS_Context, etc. I have to analyze that first.

Is different from V8, but heavier or more or less in no way. That's about the same.

Will definitely be fun.

JSAPI

Let's find out which functions are already running in the first example, and what they mean ...

Types

  • JSRuntime * rt

    JSRuntime has to be assigned a heap. How much memory JavaScript needs, or how that is meant. I should find out.

    JSRuntime * rt; rt = JS_NewRuntime (8192 * 1024); // ??? Find out what and how much. if (rt! = NULL) {// ok, create contexts, or whatever. } else {// Handle Error // sprintf (stderr, "Can not create JSRuntime! \ n"); } JS_DestroyRuntime (rt);
  • JSContext * cx

    The context in which your script is running. For example, an engine can manage scripts from various sources in its own interpreter. This means that your own script environments for web workers, processes, iframes, windows are made possible. You then have to pass the context during the operations. It then serves as an orientation for whom, or with what the JS_EvaluateScript is then executed and where the result will go.

    JSContext * cx = JS_NewContext (rt, 8192); JS_DestroyContext (cx);
  • JSObject * obj
  • JSString * str JSString * jstr; size_t len; jsval v; jstr = JSVAL_TO_STRING (v); len = JS_GetStringLength (jstr);
  • JSFunction * fun // JSFunction * JS_NewFunction (JSContext * cx, JSNative call, uintN nargs, uintN flags, JSObject * parent, const char * name); JSFunction * fun; JSBool nativeCall (JSContext * cx, uintN argc, fun = JS_NewFunction (cx, nativeCall, 0, 0, & global, "nativeCall"); // nativeCall (); in JavaScript (obsolete)
  • JSScript * script
  • JSBool ok
  • jsval rval
  • JSClass global_object

    The following example is a JSClass console_class, so I use JS_DefineObject and JS_DefineFunctions to create a Console Object [object Console] with a "log" function (console_Log).

    // The console.log JS_DefineFunctions (cx, console, console_functions);
  • JSPropertySpec JSPropertySpec foo = {"foo", // name 0, // tinyid (enum) if not used, then 0 JSPROP_READONLY, // flags NULL, // getter NULL // setter}; // JS_DefineProperty (cx, obj, foo);
  • JSFunctionSpec static JSFunctionSpec console_functions [] = {{"log", console_Log, 1, 0}, // == JS_FS ("log", console_Log, 1, 0), {0,0,0,0}};
  • JSNative

Functions

  • JS_NewRuntime creates a new JSRuntime
  • JS_NewContext creates a new JSContext
  • JS_SetOptions allows you to set options that determine the behavior of Spidermonkey. JS_SetOptions (cx, JSOPTION_VAROBJFIX | JSOPTION_JIT | JSOPTION_METHODJIT); // You can set options on-the-fly JS_SetOptions (cx, JS_GetOptions (cx) | JSOPTION_STRICT); // Turn strict mode ON | JS_SetOptions (cx, JS_GetOptions (cx) & JSOPTION_STRICT); // Turn strict mode OFF &
    JSOPTION_VAROBJFIX
    JSOPTION_JIT
    JSOPTION_METHODJIT
    JSOPTION_STRICTWarn on dubious practice.
    JSOPTION_WERRORConvert Warnings to Errors.
    JSOPTION_PRIVATE_IS_NSISUPPORTSMozilla Extension. When Spiderman is built with XPConnect.
    JSOPTION_COMPILE_N_GOCaller from JS_CompileScript and Co promising to execute the script only once. The caller must not modify any objects in the scope chain between compilation and exception. This enables compile-time scope chain resolution of consts (a performance optimization).
    JSOPTION_ATLINE// @ line number ["filename"]. The option is supported for XUL preprocessors and things like that.
    JSOPTION_XMLObsolete since JSAPI 15: Generate a token for the tags in script blocks, the option is not backwards compatible with the hack to skip the comments in the script block.
    JSOPTION_ALLOW_XMLIf off, E4X is not supported, regardless of which version number is set.
    JSOPTION_MOAR_XMLParsing <- -> as a token, not compatible with the HTML Script Tag Comment-Hiding Hack. Only with JSOPTION_ALLOW_XML.
    JSOPTION_NATIVE_BRANCH_CALLBACKWith the option JS_SetBranchCallBack you could set and call a NULL script pointer in code that loops very intensively.
    JSOPTION_DONT_REPORT_UNCAUGHT
    JSOPTION_RELIMITThrows an exception if a RegExp backtracks more than n ^ 3 times, where n is the length of the input string.
    JSOPTION_ANONUFUNFIXProhibits a function () {} statement without a name as in ES3.
    JSOPTION_NO_SCRIPT_EVALThe application promises the compiler to pass a null rval out-param to each JS_ExecuteScript call.
    JSOPTION_UNROOTED_GLOBALTells the GC not to see the global object of the context as a root. The application must ensure that the global object can then survive as long as the JSContext.
  • JS_SetVersion - set to ES5 or ES3 or UNKNOWN (JSVERSION_LATEST == JSVERSION_ECMA_5) JS_SetVersion (cx, JSVERSION_LATEST); // JSVERSION_LATEST == JSVERSION_ECMA_5
    JSVERSION_LATEST
    JSVERSION_ECMA_5EcmaScript, 5th Edition
    JSVERSION_ECMA_3EcmaScript, 3rd Edition
    JSVERSION_UNKNOWN
    ...
  • JS_SetErrorReporter - sets an error callback, returns the previous one, or NULL if there was no previous one. JS_SetErrorReporter (cx, reportError); // returns the previous reportError callback or NULL JS_ReportError (cx, "Can't compare the strings."); // calls the error reporter
  • JS_SetPendingException
  • JS_NewCompartmentAndGlobalObject - initializes the global object in a new compartment

    Spidermonkey_compartments: The concept of compartments is used to create several heaps so as not to have just one heap for all objects. Each compartment is a single heap. A compartment is therefore a heap.

    "http://developer.mozilla.org/en-US/docs/SpiderMonkey/JSAPI_Reference/JS_NewCompartmentAndGlobalObject">JS_NewCompartmentAndGlobalObject - initializes the global object in a new compartment // The JSClass for the global object is used as memory for the information // the variable environment and the other global object functionality. / * The class of the global object. * / static JSClass global_class = {"global", JSCLASS_GLOBAL_FLAGS, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub, JS_EnumerateStub, JS_ResolveStub, JS_ResolveStub, JS_ResolveStub, JS_Convert_FOPTION} // In the function in which the context is created / * * Create the global object in a new compartment. * You always need a global object per context. * / JSObject * global; global = JS_NewCompartmentAndGlobalObject (cx, & global_class, NULL); if (global == NULL) return 1;
  • JS_InitStandardClasses - initializes Object, Function, Date, String, Boolean, etc. // The function creates JavaScript objects such as Math, Date, RegExp, Object, Array, Function, Boolean, String, Number if (! JS_InitStandardClasses (cx, global) ) {return log ("Can not initialize standard JS Classes"); } else {log ("Created all Default JavaScript Objects like Math, RegExp, Proxy."); }
  • JS_EvaluateScript (cx, global, script, strlen (script), filename, lineno, & rval); - executes the source string. char * script = "'Hello' + 'World!'"; jsval rval; JSString * str; JSBool ok; const char * filename = "noname"; uintN lineno = 0; ok = JS_EvaluateScript (cx, global, script, strlen (script), filename, lineno, & rval); if (rval == NULL | rval == JS_FALSE) return 1;
  • JS_CompileFile // Converts a .js file into a JSObject * scriptObj.
  • JS_ExecuteScript // Takes a * scriptObj JSObject (instead of a string like JS_EvaluateScript) jsval rval; const char * filename = "spiderman.js"; // JS_CompileFile turns a .js file into a JSObject * script JSObject * scriptObj = JS_CompileFile (cx, global, filename); // JS_ExecuteScript executes the JSObject * script JSBool ok = JS_ExecuteScript (cx, global, scriptObj, & rval); // The result of the entire operation is stored in rval.
  • JS_ValueToString str = JS_ValueToString (cx, rval);
  • JS_EncodeString printf ("% s \ n", JS_EncodeString (cx, str));
  • JS_DestroyRuntime - the three functions are used to clean up. JS_DestroyRuntime (rt);
  • JS_DestroyContext JS_DetroyContext (cx);
  • JS_ShutDown JS_ShutDown ();

(or a few more)

  • JS_mlloc // Returns a (void *) pointer to a memory area of ​​nbytes. void * JS_malloc (JSContext * cx, size_t nbytes);
  • JS_realloc // Reallocate more or less or new memory nbytes to the pointer p void * JS_realloc (JSContext * cx, void * p, size_t nbytes);
  • JS_free // release the memory behind pointer p again void JS_free (JSContext * cx, void * p);
  • JS_strdup // duplicate the string and return a new pointer to the copy !! char * JS_strdup (JSContext * cx, const char * s);
  • JS_ReportAllocationOverflow
  • JS_ReportPendingException

Macros

  • JS_FS #define JS_FS (name, call, nargs, flags, extra) / * JSFunctionSpec Initializer * / #define JS_FS (name, fastcall, nargs, flags) / * JSFunctionSpec Initializer * / #define JS_FS_END / * Obsolete since 1.8.5 - defined end of a JSFunctionSpec Array * /

My first own example

When I have read and understood all of this and can memorize the few commands from the first example (or a few more).

I did that briefly this morning. I just linked a little bit of the reference part. And then just added a REPL prompt to the example. At some point on the way I thought of Spiderman. Because I was wearing a Spiderman wool hat that I found on the subway one day.

// My first anchor I throw. Spiderman> Object.getOwnPropertyNames (this); // Find out what is defined on the global object // Without JS_InitStandardClasses, nothing

Grin. I already looked in the reference for how to call functions and so on. From then on you can already build an API on the Spidermonkey Library. For example, there is no console interface with console.log or .dir or .time or .warn or .error if I noticed correctly. That and much more would be a good idea. Then of course. I would be stupid if I didn't take a lib like libuv.

#include #include #include static JSClass global_class = { "global" JSCLASS_GLOBAL_FLAGS, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub, JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub, JSCLASS_NO_OPTIONAL_MEMBERS}; void reportError (JSContext * cs, const char * message, JSErrorReport * report) {std :: cout << (report-> filename? report-> filename: "") << ":" << (unsigned int) report- > lineno << ":" << (char *) message << std :: endl; } int log (const char * str, int rc = 1) {std :: cout << str << std :: endl; return rc; } void prompt () {// my REPL is now called spiderman std :: cout << "Spiderman>"; } int main (int argc, char ** argv) {JSRuntime * rt; JSContext * cx; JSObject * global; // generate runtime rt = JS_NewRuntime (8 * 1024 * 1024); if (rt == NULL) {return log ("Can not create JSRuntime, returning 1;"); } else {log ("Created JSRuntime"); } // create context cx = JS_NewContext (rt, 8192); if (cx == NULL) {return log ("Can not create JSContext, returning 1;"); } else {log ("Created JSContent"); } // Set Error Reporter - The function returns the previous callback if (JS_SetErrorReporter (cx, reportError) == NULL) {log ("No previous Error Reporter has been set."); } // I now test whether the function is also returned. The answer is: YES. if (JS_SetErrorReporter (cx, reportError) == reportError) {log ("The previous Error Reporter is correctly returned."); } JS_SetOptions (cx, JSOPTION_VAROBJFIX | JSOPTION_JIT | JSOPTION_METHODJIT); JS_SetVersion (cx, JSVERSION_LATEST); // Set the GLOBAL OBJECT global = JS_NewCompartmentAndGlobalObject (cx, & global_class, NULL); if (global == NULL) {return log ("Error creating global object with new compartment."); } // Now initialize String, Object, Array, Date // Attention: There is no Console.log interface. I can write that, etc. pp. If (! JS_InitStandardClasses (cx, global)) {return log ("Can not initialize standard JS Classes"); } else {log ("success JS_InitStandardClasses"); } // This is the place where my application code goes // Here I try to fit a loop from STDIN to the processor // The rest is taken from the Hello World Example, because I still // have no idea how to continue goes. log ("Enter some SpiderMonkey JavaScript and stop with Ctrl-D (EOF):"); std :: string s; jsval rval; JSString * str; JSBool ok; const char * filename = "noname"; uintN lineno = 0; char c; prompt(); while (true) {c = std :: cin.get (); if (std :: cin.eof ()) break; s + = c; if (c == '\ n') prompt (); } ok = JS_EvaluateScript (cx, global, s.c_str (), s.length (), filename, lineno, & rval); if (rval == NULL | rval == JS_FALSE) {return log ("Error executing script: jsval rval is NULL or JS_FALSE"); } str = JS_ValueToString (cx, rval); log (JS_EncodeString (cx, str)); // cleaning up // the program JS_DestroyContext (cx); JS_DestroyRuntime (rt); JS_ShutDown (); return 0; }

smfirst.cpp - the source code as a file.

Result

Created JSRuntime Created JSContent No previous Error Reporter has been set. The previous Error Reporter is correctly returned. success JS_InitStandardClasses Enter some SpiderMonkey JavaScript and stop with Ctrl-D (EOF): Spiderman> function f () {return "Yeah"; } Spiderman> f (); Spiderman> [ctrl-d] Yeah

I think in JSVal the LAST return value is being saved in the game ...

I then compiled that.

g ++ -I / js-1.8.5 / js / src / dist / include -L / js-1.8.5 / js / src / dist / bin -lmozjs185 smfirst.cpp -o smfirst

You can then enter JavaScript on the standard input and it will then be executed.

I modified the example. I was out of the house for a couple of hours. Today at noon there was no prompt and I found out that print does not exist, as well as console.log does not exist in the jsshell.

Created JSRuntime Created JSContent No previous Error Reporter has been set. The previous Error Reporter is correctly returned. success JS_InitStandardClasses Enter some SpiderMonkey JavaScript and stop with Ctrl-D (EOF): noname: 0: ReferenceError: print is not defined undefined

Functions like that of the JSShell, for example, do not yet exist in the code. There is a ReferenceError if the thing is then executed.

reference

Overview: http://developer.mozilla.org/en-US/docs/SpiderMonkey

Walkthrough (from the overview): http://developer.mozilla.org/en-US/docs/SpiderMonkey/Internals

Since the original JavaScript engine was developed by Brendan Eich, today it is of course a joint project, and he went from Netscape to Mozilla, he is now CTO at Mozilla, the full JSAPI documentation is of course also available in the MDN.

http://developer.mozilla.org/en-US/docs/SpiderMonkey

User Guide

There are many documents in the MDN that describe SpiderMonkey or the JSAPI, such as the JSAPI_User_Guide.

http://developer.mozilla.org/en-US/docs/SpiderMonkey/JSAPI_User_Guide

jsval

JavaScript values

What works in JavaScript with a command sometimes has to be converted in C. jsval saves all JavaScript values, i.e. Objects, Functions, Numbers, Strings, Booleans, Null, Undefined and the JSAPI offers macros and functions for easy conversion. You just have to learn it, then you have a complete utility set to access the values ​​in JavaScript or in the code from every page.

// JavaScript return 23; // SpiderMonkey (in the native function I set the return value with JS_SET_RVAL) // In V8 it is more comfortable with scope.Close (rval); but that doesn't matter, it just looks like this JS_SET_RVAL (cx, vp, INT_TO_JSVAL (23)); return JS_TRUE;

The most widely used and versatile guy in Spidermonkey.

Hold the JavaScript values. Number, String, Boolean, Object, Function, Null, Undefined.

// For example in a native function static JSBool nativeFunc (JSContext * cx, unsigned argc, jsval * vp) {jsval * argv = JS_ARGV (cx, vp); // Outputs all function arguments separated by spaces for demo on stdout for (int i = 0; i 0) std :: cout << ""; std :: cout << JS_EncodeString (cx, JS_ValueToString (cx, argv [i])); } std :: cout << std :: endl; JS_SET_RVAL (cx, vp, JSVAL_VOID); return JS_TRUE; // signal OK} // how to get this native function global.nativeFunction = function nativeFunction (); makes JSFunction * fn; // If you don't need a pointer, you can omit it in the code if ((fn = JS_DefineFunction (cx, global, "nativeFunction", nativeFunction, 0, 0)) == NULL) {// error} // else fn assigned

At the beginning the following text is a quasi-translation of the http://developer.mozilla.org/en-US/docs/SpiderMonkey/JSAPI_Reference/jsval page.

jsval is the type of JavaScript values ​​in the JSAPI.

A C / C ++ variable of type jsval can hold exactly the same value as a JavaScript var or property (string, number, object, boolean, null, undefined. Arrays, functions and errors are objects.)

jsval is a varying type, the exact representation of which depends on the architecture of the machine. That is why you shouldn't rely on such details when embedding.

jsvals are not properly type-safe.

JSVAL_MACROS

type test type constants / constructors accessors
JSVAL_IS_NULL (v) zero JSVAL_NULL
JSVAL_IS_VOID (v) undefined JSVAL_VOID
JSVAL_IS_BOOLEAN (v) boolean JSVAL_TRUE, JSVAL_FALSE, BOOLEAN_TO_JSVAL (b) JSVAL_TO_BOOLEAN (v)
JSVAL_IS_NUMBER (v), JSVAL_IS_INT (v), JSVAL_IS_DOUBLE (v) number JSVAL_ZERO, JSVAL_ONE, INT_TO_JSVAL (i), DOUBLE_TO_JSVAL (d) JSVAL_TO_INT (v), JSVAL_TO_DOUBLE (v
JSVAL_IS_STRING (v) string STRING_TOP_JSVAL (str) JSVAL_TO_STRING (v), JS_GetStringChars (str), JS_GetStringLength (str)
! JSVAL_IS_PRIMITIVE (v) object OBJECT_TO_JSVAL (obj) JSVAL_TO_OBJECT

Warning: The JSVAL_TO_x functions use C casts and bit twiddling (twiddling?). You are only sure if you already know that the jsval corresponds exactly to the correct type. For example, if you call JSVAL_TO_DOUBLE on an int jsval, unpredictable behavior and a crash can occur. [Translated from SpiderMonkey / JSAPI_Reference / jsval]

jsvals could point to a string or an object that is already in the GC heap. The GC picks up everything that is not somehow nailed to the floor, this can also affect your JSObject. The solution is to tell SpiderMonkey to use the item and to notify it later when you are done.

http://developer.mozilla.org/en-US/docs/SpiderMonkey/JSAPI_Reference/jsval

jsint

If you want to know how many integer types there are here. What you MUST know.

jsint and jsuint are 32-bit integer types.

jsword and jsuword are pointer-large integer types

intN and uintN are integer types with the same size as the platform's native int types.

http://developer.mozilla.org/en-US/docs/SpiderMonkey/JSAPI_Reference/jsint

jsid

ID of the property that is being accessed.

http://developer.mozilla.org/en-US/docs/SpiderMonkey/JSAPI_Reference/jsid

A couple of methods use jsid instead of jsval.

Exceptions

JSExceptionState * state;

sets the exception which should then be thrown in context cx.

void JS_SetPendingException (JSContext * cx, jsval v);

Compartments

The concept of having several heaps instead of one for all objects is filled with the compartments. This is the word for a separate heap each. More information is available on the pages. And instead of calling, I usually call.

Garbage collection

Internals

http://developer.mozilla.org/en-US/docs/SpiderMonkey/Internals/Garbage_Collection

http://developer.mozilla.org/en-US/docs/SpiderMonkey/Internals/GC/Exact_Stack_Rooting

Simple statistics that the GC records at runtime: http://developer.mozilla.org/en-US/docs/SpiderMonkey/Internals/GC/Statistics_API

Rooting Guide

http://developer.mozilla.org/en-US/docs/SpiderMonkey/GC_Rooting_Guide

Tips

http://developer.mozilla.org/en/SpiderMonkey_Garbage_Collection_Tips

Garbage collector functions

After the links to the documents, here is the overview of the functions.

JS_GC

Carry out a full garbage collection in the JS memory pool: JS_GC

// void JS_GC (JSContext * cx); // ... code ... JS_GC (cx); // ... code ...

With JS_SetGCCallback you can add hooks that are carried out during garbage collection.

// JSGCCallback JS_SetGCCallback (JSRuntime * rt, JSGCCallback cb); // Returns the last callback, a new one is set. old_cb = JS_SetGCCallback (rt, new_cb); typedef enum JSGCStatus {JSGC_BEGIN, // Start of GC JSGC_END, // End of GC JSGC_MARK_END, // End of Marking JSGC_FINALIZE_END / * Obsolete since JSAPI 13 * /} JSGCStatus; typedef JSBool (* JSGCCallback) (JSContext * cx, JSGCStatus status);

The callback can use JS_IsAboutToBeFinalized to clear up weak references to JSObjects, these are pointers that cannot be traced by the GC.

JS_MaybeGC

A typical JSAPI application should also run garbage collection periodically. An application can do this by periodically calling JS_MaybeGC

// code is running // let's take a quick look ... JS_MaybeGC (cx); // code continues ...

Called from JSBranchCallbacks and JSOperationCallbacks, JS_MaybeGC can keep memory consumption down and improve performance.

JSRuntime

http://developer.mozilla.org/en-US/docs/SpiderMonkey/JSAPI_Reference/JSRuntime

JSContext

http://developer.mozilla.org/en-US/docs/SpiderMonkey/JSAPI_Reference/JSRuntime

JSGlobal

http://developer.mozilla.org/en-US/docs/SpiderMonkey/JSAPI_Reference/JSGlobal

JSNative

JSNative is the data type for the native implementation of JavaScript functions.

APIs like http://developer.mozilla.org/en-US/docs/SpiderMonkey/JSAPI_Reference/JS_InitClass and http://developer.mozilla.org/en-US/docs/SpiderMonkey/JSAPI_Reference/JS_DefineFunctions generate methods on JavaScript objects , which are returned as JSNative callbacks ...

typedef JSBool (* JSNative) (JSContext * cx, uintN argc, jsval * vp);

JSNative also has a few macros.

JS_CALLEE (cx, vp) Returns the function object in the form of a jsval. Native methods may NOT call JS_CALLEE after JS_SET_RVAL because this is stored in the same stack.
JS_THIS (cx, vp) Returns the this argument, or NULL on error.
JS_THIS_OBJECT (cx, vp) Returns JSObject *, or NULL on error. Native methods are not allowed to call the function after JS_SET_RVAL. JS_THIS_OBJECT can call JS_CALLEE.
JS_ARGV (cx, vp) Returns the argv pointer. Points to element 0 of the argc jsvals array, the arguments given by the caller.
JS_RVAL (cx, vp) The jsval, which is currently in the return-value slot
JS_SET_RVAL (cx, vp, value) Sets the return value of the native function. You can call the thing several times with one call with JSNative, if JSNative returns JS_TRUE, the last value that was used is returned to the caller.

http://developer.mozilla.org/en-US/docs/SpiderMonkey/JSAPI_Reference/JSNative

I think this is where the function docs end up.

// From the Phrasebook // JavaScript: // 1. Simply in one step function j4f () {} // C / C ++: // 1. The native function JSBool j4f (JSContext * cx, uintN argc, jsval * vp) {JS_SET_RVAL (cx, vp, JSVAL_NULL); return JS_TRUE; } // 2. And you still have to set it up if (! JS_DefineFunction (cx, global, "j4f", & j4f, 0, 0)) {fprintf (stderr, "Error defining function j4f () \ n"); } // Function definition (native) static JSBool myFunction (JSContext * cx, unsigned int argc, jsval * vp) {jsval * argv = JS_ARGV (cx, vp); // I don't need (no args) if (true) {// Return value (return) of my function is set, not determined by return. JS_SET_RVAL (cx, vp, STRING_TO_JSVAL ((JSString *) "Return value of the function")); // cout << JSVAL_TO_STRING (argv [0]); return JS_TRUE; // indicates success} else {return JS_FALSE; // indicates that the function went wrong}} // Definition of the JavaScript interface (global.myfunction) const int minargs = 0; if (! JS_DefineFunction (cx, global, "myFunction", myFunction, minargs, 0)) {/ * error * /}

give back.

JSFunction * JS_NewFunction (JSContext * cx, JSNative call, uintN nargs, uintN flags, JSObject * parent, const char * name); // cx = context // call = native C function with the JSAPI (static JSBool nativeFunc (JSContext * cx, ...) // nargs = number of arguments // flags = reserved. Always enter 0 for this argument // parent = Pointer to the parent object of the function, if NULL a default object is used // name = function name or NULL, if no name // --- // NULL = error // JSFunction * fun = success

Name of function received

JSString * JS_GetFunctionId (JSFunction * fun);

EvaluateScript and much more

JS_CompileFunction and JS_CompileScript, as well as JS_EvaluateScript

  • JS_CompileFunction

    JS_CompileFunction and turn a string into a JavaScript function. This is compiled to the context and installed in the specified object and the address is returned as JSFunction *.

    const char * fname = "myXYZ"; const char * fbody = "var x = 10, \ n \ ŧy = 25, z = 33; \ nreturn x * y / z; \ n"; size_t length = strlen (fbody); const char * filename = "source.js"; uintN lineno = 1; JSFunction * fun; fun = JS_CompileFunction (cx, obj, fname, 0, NULL, fbody, length, filename, lineno);
  • JS_CompileFunctionForPrincipals
  • JS_CompileScript
  • JS_CompileScriptForPrincipals
  • JS_EvaluateScript
  • JS_EvaluateScriptForPrincipals

There is also decompile

Decompiling function

  • JS_DecompileFunction

    JS_DecompileFunction makes it possible to generate a source code from a JavaScript function, which can then be evaluated. With a native function, on the other hand, this is no longer possible, and instead of the source code, [native code] is output against which the string can be checked in order to make a decision.

    JSString * source = JS_DecompileFunction (cx, fun, 8); // cx = context // fun = JSFunction * fun // 8 = uintN spaces to indent
  • JS_DecompileFunctionBody

    makes it possible to get the FunctionBody without and}. Native functions output [native code], which you should check for when deciding what to do with the code.

    JSString * srouce = JS_DecompileFunctionBody (cx, fun, 8); // cx = context // fun = JSFunction * fun // 8 = uintN spaces to indent

Function callback

Introduced in JS 1.8.5

JS_SetFunctionCallback enables function tracing (see User Guide)

// Call a callback whenever a function is invoked or exited // This can be used to trace the execution void JS_SetFunctionCallback (JSContext * cs, JSFunctionCallback fcb);

The callback syntax (this is how you have to declare your function)

// JSFunctionCallback typedef void (* JSFunctionCallback) (const JSFunction * fun, const JSScript * scr, const JSContext * cx, JSBool entering);
  • JSFunction
  • JSFunctionCallback
  • JS_SetFunctionCallback
  • JSScript

    Calling function

    From the cookbook. foo is a global function.

    // foo is a global function // JS var r = foo (); // foo is a global function jsval r; if (! JS_CallFunctionName (cx, JS_GetGlobalObject (cx), "foo", 0, NULL, & r)) {// err return JS__FALSE; }

    f is a local variable. Here, too, there are differences in how to call them up.

    // f is local variable var r = f () jsval r; if (! JS_CallFunctionValue (cx, NULL, f, 0, NULL, & r)) {// FunctionValue = jsval (a function as jsval) return JS_FALSE; }
    • JS_CallFunction JSBool JS_CallFunction (JSContext * cx, JSObject * obj, JSFunction * fun, uintN argc, jsval * argv, jsval * rval); // cx = The context in which this should run // obj = The this object, where the function can be found // fun = The function that should be called // argc = The arguments counter // argv = The arguments vector // rval = contains the return value of the function after execution (the one that was set with e.g. JS_SET_RVAL in the function that is called)
    • JS_CallFunctionName // Call function (object method or global) by its name // Corresponds to object.meineFunction (); (myFunction == global.myfunction) JSBool JS_CallFunctionName (JSContext * cx, JSObject * obj, const char * name, uintN argc, jsval * argv, jval * rval); // --- // cx = the context // obj = the this object // name = // argc = number of arguments of the function // argv = arguments of the function // rval = the return value of the function after // --- // returns JS_TRUE on success // or JS_FALSE on failure
    • JS_CallFunctionValue // JS_CallFunctionValue (call JavaScript function (== function value)) // Corresponds to fval.apply (obj, [] .slice.call (argv, 0, argc)) in JavaScript JSBool JS_CallFunctionValue (JSContext * cx, JSObject * obj, jsval fval, uintN argc, jsval * argv, jsval * rval); // --- // cx = Context // obj = The "this" argument // fval = The function that you want to call // argc = The number of arguments to pass // argv = Pointer to the arguments, or argc == 0, then argv = NULL // rval = Contains the return value of the JavaScript function that is called after calling JS_CallFunctionValue // --- // returns JS_TRUE, if successful // or JS_FALSE if failure (then rval unspecified)

    Read out the name of a function.

    JSString * functionName = JS_GetFunctionId (fun);

    Convert to

    JSFunction * JS_ValueToFunction (JSContext * cx, jsval v); // cx = context // v = value to convert jsval * argv; JSFunction * fun; fun = JS_ValueToFunction (cx, argv [0]);

    Function definition

    DefineFunctions can be used to define functions on an object (global or local). You can define a function with, or several with.

    • JS_NewFunction

      The following code is roughly equivalent.

      // JSFunction * JS_NewFunction (JSContext * cx, JSNative call, uintN nargs, uintN flags, JSObject * parent, const char * name); // The native function static JSBool functionBody (JSContext * cx, uintN argv, jsval * vp) {jsval * argv = JS_ARGV (cx, vp); JS_SET_RVAL (cx, vp, JSVAL_VOID); // return undefined return JS_TRUE; } // bind the function. JSFunction * fun = JS_NewFunction (cx, functionBody, 0, 0, & global, "functionName");

    There is also Value To Function

    LocalRootScope - prevents the GC from clearing away what the pointer is pointing to.

    • JS_EnterLocalRootScope

      A rooted variable is not cleared away by the GC. Local root scopes protect new objects, strings, doubles without having to report every variable to the engine.

      JSBool my_GetProperty (JSContext * cx, JSObject * obj, jsval id, jsval * vp) {JSBool ok; if (! JS_EnterLocalRootScope (x)) return JS_FALSE; ok = my_GetPropertyBody (cx, obj, id, vp); JS_LeaveLocalRootScope (cx); return ok; } // From the MDN see JS_EnterLocalRootScope
    • JS_LeaveLocalRootScope
    • JS_ForgetLocalRoot
    • JS_AddRoot
    • JS_RemoveRoot

    Macros

    ASome macros belonging to the functions start with JSFUN_. For example:

  • Argument

    • JS_ConvertArguments
    • JS_PushArguments jsval * JS_PushArguments (JSContext * cx, void ** markp, const char * format, ...); jsval * JS_PushArgumentsVA (JSContext * cx, void ** markp, const char * format, va_list ap); // format // b JSBool // c uint16 // i int32 ECMA // u uint32 ECMA // j int32 // d jsdouble // s char * (C String) // S JSString * // W jschar * // o JSObject * // f JSFunction * // * None all * are ignored
    • JS_PopArguments
    • JS_AddArgumentFormatter

    Arrays

    JSObject * array; / h2> // From the Cookbook // JavaScript var x = []; // JSAPI JSObject * x; if ((x = JS_NewArrayObject (cx, 0, NULL)) == NULL) {// error}

    A structure with callback functions for addProperty, delProperty, getProperty, a StrictPropertyOp for setProperty, a JSEnumerateOp for enumerate, and so on. When you create an object, a JSClass belongs to it. And you can influence their behavior here. So, although not cross-browser-wide, wonderful objects like a configured proxy and with different behavior can be created with the API.

    struct JSClass {char * name; uint32 flags; / * function pointers * / JSPropertyOp addProperty; JSPropertyOp delProperty; JSPropertyOp getProperty; JSStrictPropertyOp setProperty; JSEnumerateOp enumerate; JSResolveOp resolve; JSConvertOp convert; JSFinalizeOp finalize; / * members * / JSClassInternal reserved; JSCheckAccessOp checkAccess; JSNative class; JSNative construct; JSXDRObjectOp xdrObject; JSHasInstanceOp hasInstance; JSTraceOp trace; };

    The stubs from PropertyOp to FinalizeOp can be used wherever such functions are expected.

    // Default implementations of the required callbacks in JSClass. JSBool JS_PropertyStub (JSContext * cx, JSObject * obj, jsid id, jsval * vp); JSBool JS_EnumerateStub (JSContext * cx, JSObject * obj); JSBool JS_ResolveStub (JSContext * cx, JSObject * obj, jsid id); JSBool JS_ConvertStub (JSContext * cx, JSObject * obj, JSType type, jsval * vp); void JS_FinalizeStub (JSContext * cx, JSObject * obj); // Obsolete since JSAPI 15

    JSExtendedClass

    Obsolete by JavaScript 1.8.5 (means you shouldn't use it in new projects anymore).

    struct JSExtendedClass {JSClass base; JSEquality equality; JSObjectOp outerObject; JSObjectOp innerObject; JSInteratorOp iteratorObject; // Added in 1.8 JSObjectOp wrappedObject; // Added in 1.8 // ... and additional reserved fields. };

    Split_object was due and an architecture fix for the window object. It should be noted that it was used in Mozilla and should be avoided in other projects. It is then explained in detail why there are split objects and the and hook for ..

    JSPrincipals also have a different context, SpiderMonkey runs the scope chain up to the next JSPrincipals attached JSObject, about which (JSPrincipals) I still have to write.

    Object

    • JS_NewObject JSObject * obj; JSPropertySpac props [] = {{name};
    • JS_ConstructObject JSObject * obj; JSObject * objOnObj; uintN argc; jsval * argv; // JS_ConstructObject (context, JSClass * clasp, JSObject * proto, JSObject * parent) obj = JS_ConstructObject (cx, NULL, NULL, NULL); objOnObj = JS_ConstructObject (cx, NULL, NULL, obj); // JS_ConstructObject (context, clasp, proto, parent, argc, argv) obj = JS_ConstructObjectWithArguments (cx, NULL, NULL, NULL, argc, argv); objOnObj = JS_ConstructObjectWithArguments (cx, NULL, NULL, obj, argc, argv); // clasp == NULL creates ordinary JavaScript object // parent and proto can be JSObject or null // WithArguments passes the arguments to the constructor

    JS_GetFunctionObject

    JSObject * JS_GetFunctionObject (JSFunction * fun); // fun = pointer to a JSFunction

    There is such a parent function, it is better to find out what is possible.

    JSObject * parent = JS_GetParent (cx, obj); JSBool ok = JS_SetParent (cx, otherObj, parent);

    Standard library objects have the global object as their parent. This is the object on which the function was defined.

    All objects that were created with a constructor and new have the constructor as their parent. An object that is created by a script via implicit conversion ({a: 1, b: 2} or [1,2,3] or [[ToObject]]) has the global object as its parent. so it's important. follows rules.

    of a function depend on the scope. If no function includes the other function, then the global scope is the parent of the function, otherwise the function that envelops it. That's an important thing here: and

    JSObject * parent = JS_GetParent (obj);

    And takes the same three parameters. The context, the object, and its new parent object.

    JSBool ok = JS_SetParent (cx, otherObj, parent);

    Object property definition

    respectively

    // In JavaScript: // Define one Property on an object Object.defineProperty (obj, "foo", {value: "bar", writeable: false}); // Plural in JavaScript // Define multiple properties on one object Object.defineProperties (obj, {"foo": {value: "bar" writeable: false}, "bar": {value: "baz", enumerable: true} });

    This has always been possible in Spidermonkey, and Object.defineProperty seems more like an implementation of JS_DefineProperty to me.

    JSPropertySpec

    struct JSPropertySpec {const char * name; int8 tinyid; uint8 flags; JSPropertyOp getter; JSPropertyOp setter; };

    A property

    char * prop = "foo"; char * value = "Eddie"; JSPropertySpec foo = {"foo", // name 0, // tinyid (enum) if not used, then 0 JSPROP_READONLY, // flags NULL, // getter NULL // setter}; JS_DefineProperty (cx, obj, & foo);

    Multiple properties

    static JSPropertySec pspec [] = {{"foo", 0, JSPROP_READONY, NULL, NULL}, {"bar", 0, JSPROP_ENUMERATE, NULL, NULL}, {0, 0, 0, 0, 0} // terminating record }; JS_DefineProperties (cx, obj, & pspec);
    • JS_LookupProperty // This is copied from Mozilla and will be replaced with your own examples. JSBool JS_LookupProperty (JSContext * cx, JSObject * obj, const char * name, jsval * vp); JSBool JS_LookupUCProperty (JSContext * cx, JSObject * obj, const jschar * name, size_t namelen, jsval * vp); JSBool JS_LookupPropertyById (JSContext * cx, JSObject * obj, jsid id, jsval * vp); Added in SpiderMonkey 1.8.1 JSBool JS_LookupPropertyWithFlags (JSContext * cx, JSObject * obj, const char * name, uintN flags, jsval * vp); JSBool JS_LookupPropertyWithFlagsById (JSContext * cx, JSObject * obj, jsid id, uintN flags, JSObject ** objp, jsval * vp); Added in SpiderMonkey 1.8.1 Name Type Description cx JSContext * Pointer to a JS context from which to derive runtime information. Requires request. In a JS_THREADSAFE build, the caller must be in a request on this JSContext. obj JSObject * Object to search on for the property. name or id const char * Name of the property to look up. or const jschar * or jsid namelen size_t (only in JS_LookupUCProperty) The length of name in characters; or -1 to indicate that name is null-terminated. flags uintN (only in JS_LookupPropertyWithFlags) A combination of bits requesting special search behavior. See flags below. objp JSObject ** Out parameter. On success, * objp receives the object on which the property was found. This will be either obj or an element on obj's prototype chain. vp jsval * Out parameter. On success, * vp receives the stored value of the property, if any.

      var bool = ({a: 1}) ("a"); if (bool) {/ * ... * /}

    • JS_AlreadyHasOwnProperty // The interfaces JSBool JS_AlreadyHasOwnProperty (JSContext * cx, JSObject * obj, const char * name, JSBool * foundp); JSBool JS_AlreadyHasOwnUCProperty (JSContext * cx, JSObject * obj, const char * name, JSBool * foundp); JSBool JS_AlreadyHasOwnPropertyById (JSContext * cx, JSObject * obj, jsid id, JSBool * foundp); // Added in 1.8.1 JSBool JS_AlreadyHasOwnElement (JSContext * cx, JSObject * obj, jsint index, JSBool * foundp);

    Getters and Setters

    var obj = {get info () {return "information"; }, set dark (v) {this._dark = v; }}; var obj2 = Object.create (Object.prototype, {info: {value: "information", writeable: false, // JSPROP_READONLY configurable: false // JSPROP_PERMANENT (? still practice)}});

    and are functions with which you can set / read the magic JSPROP_ * (uint attrs).

    JSBool JS_SetPropertyAttributes (JSContext * cx, JSObject * obj, const char * name, uintN attrs, JSBool * foundp); JSBool JS_SetUCPropertyAttributes (JSContext * cx, JSObject * obj, const jschar * name, size_t namelen, uintN attrs, JSBool * foundp);
    Flag Sense and purpose
    JSPROP_ENUMERATE Property is visible in for..in loops (enumerable: true)
    JSPROP_READONLY Property is only readable (writeable: false)
    JSPROP_PERMANENT Property cannot be deleted
    JSPROP_EXPORTED Property can be imported from other objects
    JSPROP_INDEX Property is an index into an array of properties, and is cast into a const char *

    DefineFunctions

    static JSFunctionSpec system_functions [] = {{"log", log, LOG_MINARGS, 0}, {0,0,0,0}};

    JSString

    char *, Handle , JSString *, std :: string

    I have to do conversion tests.

    // Source code conversion test JSString * jstr; char * cstr; std :: string * ccstr = new std :: string ("Hello"); // Then let's cast and coercen ...

    In addition to JS_malloc, there is what allocates a copy of the zero-terminated string and returns a pointer for the copy.

    char * JS_strdup (JSContext * cx, const char * s);

    I looked for the functions to be able to work with JSString and (const char *) "strings".

    • JS_EncodeString (cx, jstr)
    • JS_GetStringLength const JSString * str = "abcdef"; size_t len; len = JS_GetStringLength (jstr);
    • JS_GetStringChars
    • JS_CompareStrings // JSBool JS_CompareStrings (JSContext * cx, JSString * str1, JSString * str2, int32_t * result); int result; if (JS_CompareStrings (cx, str1, str2, & result) {// JS_TRUE if (result == 0) {// The strings are the same} else if (result <0) {// str1 0) {// str> str2}} else {// JS_FALSE JS_ReportError (cx, "Can't compare the strings.");}

    My second own example

    Now I should call functions from the shell ... namely C functions that I write myself. Then the basis for an interpreter has already been tried out. Then you have to learn the libs you are using, as well as this SpiderMonkey library. First of all, I think of libuv to talk to the network, and because of the asynchronous design, of those. This is then the core library from the node.js project.

    libuv.html even already existed in my directory. But nothing has happened yet, it was just an idea.

    Ok, here is my improved REPL. In my first example I read up to CTRL-D, if I remember correctly, a new prompt was written line by line, but evaluation was only carried out at the end of the code. Here every line is evaluated. And the good thing is, the JSContext object, I think, keeps everything from step to step accordingly.

    // My second example: Spiderman with log function // Is already a REPL with a function "log" // log: The one or more parameters separated as strings with space and outputs a newline. #include #include #include static JSClass global_class = { "global" JSCLASS_GLOBAL_FLAGS, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub, JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub, JSCLASS_NO_OPTIONAL_MEMBERS}; void reportError (JSContext * cs, const char * message, JSErrorReport * report) {// prefer to use cerr? If I create files with >> I will notice whether I want to read them. std :: cout << (report-> filename? ");} // I now test whether the function is also returned. The answer is: YES. if (JS_SetErrorReporter (cx, reportError) == reportError) {say ("The previous Error Reporter is correctly returned.");} JS_SetOptions (cx, JSOPTION_VAROBJFIX | JSOPTION_JIT | JSOPTION_METHODJIT); JS_SetVersion (cx, JSVERSION_LATEST); // Set the GLOBAL OBJECT global = JSVERSION_LATEST, NewCompartment, & NewCompartment, & globalCompartment (global == NULL) {return say ("Error creating global object with new compartment.");} // Now initialize String, Object, Array, Date // Attention: There is no Console.say interface. I can write that , etc. pp. if (! JS_InitStandardClasses (cx, global)) {return say ("Can not initialize standard JS Classes");} else {say ("success JS_InitStandardClasses");} // This is where my Application code comes up, says Brendan // Here's mine REPL. Thanks for the great language. std :: string s; jsval rval; JSString * str; JSBool ok; const char * filename = "Spiderman-REPL"; uintN lineno = 0; say ("Defining my personal C Functions like log (s, ... r)"); ok = JS_DefineFunctions (cx, global, system_functions); // ok = JS_DefineFunction (cx, global, "log", log, LOG_MINARGS, 0); if (! ok) {say ("Failed defining my funcitons"); } else {say ("Defined my functions"); } // Now you should be able to log something in the shell with log (string) say ("#### Give me some SpiderMonkey JavaScript ..."); char c; bool exit = false; prompt(); // The Read Loop (R) while (! Exit) {c = std :: cin.get (); if (! std :: cin.eof ()) s + = c; else exit = true; if (c == '\ n') {++ lineno; // In node this is done for each line. // input evalen (E) ok = JS_EvaluateScript (cx, global, s.c_str (), s.length (), filename, lineno, & rval); // last return value if (rval == NULL | rval == JS_FALSE) {say ("Error executing input: jsval rval is NULL or JS_FALSE"); } // Sometimes the result is undefined if you evaluate "" ... // or throw back the undefined function.str = JS_ValueToString (cx, rval); say (JS_EncodeString (cx, str)); // So I can improve that. s = ""; // Empty my "Input Buffer" prompt (); }} // The loop was exited with CTRL-D or the file redirected with sm2nd.cpp - the source code as a file.

    And this is the result. As you can see, I now have my own REPL. The original REPL as I knew it can be admired at node.js, but that too has it all. In particular, it has things that V8 doesn't have, such as the generator functions.

    Created JSRuntime Created JSContent No previous Error Reporter has been set. The previous Error Reporter is correctly returned. success JS_InitStandardClasses Defining my personal C Functions like log (s, ... r) Defined my functions #### Give me some SpiderMonkey JavaScript ... Spiderman> undefined Spiderman> log function log () {[native code]} Spiderman> log ("Yeah"); Yeah undefined Spiderman>

    Find reference

    Simply write the name you are looking for after the JSAPI_Reference directory, and an article will usually appear or you will be redirected to the "mozilla Persona login", which indicates that the page does not exist ...

    So, as it is clear, you can use http://developer.mozilla.org/en-US/docs/SpiderMonkey/JSAPI_Reference/* (i.e. the directory followed by e.g. JSRuntime or JS_InitStandardClasses) to access practically any data type (JS * ) or any function (JS_ *) or any macro (which is CAPITAL). When I linked the basic terms, I noticed the structure.

    libuv and SpiderMonkey

    After I named the REPL Spiderman, it still outputs the jsval return code, even several times, it occurred to me that I could use libuv for the first native functions, because it stores the asynchronous event operations for node.js.

    As I already noticed, it doesn't seem difficult at all to use libuv.

    I already thought of a working variant. If you follow the libuv doc, you read that I first tried listings from the uvbook, and have to note that the getaddrinfo slide from the belder did not want to compile, which can also be my fault, but it can also be the slide, even with Crock I found Type-O's, then I tried out whether I could just let the loop run while the program started the REPL straight ahead.

    uv_loop_t * loop = uv_default_loop (); uv_run (loop); while (true) {// My Spidermonkey REPL} // At least it works that the REPL is running // Now I just have to add a few UV functions // to try out whether it works at all.

    My third example

    Example: TTY function tty () in Spiderman REPL

    The first attempt to work with libuv.

    Here I have incorporated a uv_tty_ function, which I made from the book earlier, into the listing. When you start the shell, you can enter tty () and the red Hello TTY from the uvbook will appear.

    #include #include #include #include #include #include #include #include // vars libuv: uv_loop_t * loop; uv_tty_t tty; // decl spidermonkey: // me for the repl bool constructor (); void myREPL (); void destructor (); // calibrate jsval rval; JSString * str, * oldstr; JSBool ok; const char * filename = "stdin"; uintN lineno = 0; // Spidermonkey JSRuntime * rt; JSContext * cx; JSObject * global; static JSClass global_class = {"global", JSCLASS_GLOBAL_FLAGS, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub, JS_EnumerateStub, JS_ResolveStub, JS_ResolveStub, JS_Convert_FinalStub, JS_Convert_Finalize}; void reportError (JSContext * cs, const char * message, JSErrorReport * report) {// prefer to use cerr? If I create files with >> I will notice whether I want to read them. std :: cout << (report-> filename? report-> filename: "") << ":" << (unsigned int) report-> lineno << ":" << (char *) message << std :: endl; } bool say (const char * str, bool ok = false) {std :: cout << str << std :: endl; return ok; } void prompt () {// my REPL is now called spiderman std :: cout << "Spiderman>"; } #define LOG_MINARGS 1 static JSBool log (JSContext * cx, unsigned argc, jsval * vp) {jsval * argv = JS_ARGV (cx, vp); for (int i = 0; i 0) std :: cout << ""; std :: cout << JS_EncodeString (cx, JS_ValueToString (cx, argv [i])); } std :: cout << std :: endl; JS_SET_RVAL (cx, vp, JSVAL_VOID); } #define REQUEST_MINARGS 3 static JSBool request (JSContext * cx, unsigned argc, jsval * vp) {jsval * argv = JS_ARGV (cx, vp); // This is where LIBUV comes into play and not only here. JS_SET_RVAL (cx, vp, JSVAL_VOID); } static JSBool print_tty (JSContext * cx, unsigned argc, jsval * vp) {jsval * argv = JS_ARGV (cx, vp); // I don't need (no args) uv_tty_init (loop, & tty, 1, 0); uv_tty_set_mode (& tty, 0); if (uv_guess_handle (1) == UV_TTY) {uv_write_t req; uv_buf_t buf; buf.base = (char *) "\ 033 [41; 37m"; buf.len = strlen (buf.base); uv_write (& req, (uv_stream_t *) & tty, & buf, 1, NULL); } uv_write_t req; uv_buf_t buf; buf.base = (char *) "Hello TTY! \ n"; buf.len = strlen (buf.base); uv_write (& req, (uv_stream_t *) & tty, & buf, 1, NULL); if (uv_guess_handle (1) == UV_TTY) {uv_write_t req; uv_buf_t buf; buf.base = (char *) "\ 033 [20; 12m"; buf.len = strlen (buf.base); uv_write (& req, (uv_stream_t *) & tty, & buf, 1, NULL); } uv_tty_reset_mode (); // uv_tty_stop (loop, & tty); // doesn’t exist // That doesn’t work yet that I am restoring the color here now ???? ");} JS_SetOptions (cx, JSOPTION_VAROBJFIX | JSOPTION_JIT | JSOPTION_METHODJIT); JS_SetVersion (cx, JSVERSION_LATEST); // Set the GLOBAL OBJECT global = JS_NewCompartment_NewCompartment_NewCompartment_AndGlobalObULLject (if "Error creating global object with new compartment.");} If (! JS_InitStandardClasses (cx, global)) {return say ("Can not initialize standard JS Classes");} else {say ("success JS_InitStandardClasses");} say ("Defining my personal C Functions like log (s, ... r), tty (), request is coming .."); ok = JS_DefineFunctions (cx, global, system_functions); if (! Ok) {say ("Failed defining my funcitons ");} else {say (" Defined my functions ");} say (" #### Give me some SpiderMonkey JavaScript ... "); return true;} void myREPL () {char c; std :: string s; bool stop = false; prompt (); while (! stop) {// just above global variable c = std :: cin.get (); if (! std :: cin.eof ()) s + = c; else stop = true; if (c == '\ n') {++ lineno; ok = JS_EvaluateScript (cx, global, s.c_str (), s.length (), filename, lineno, & rval); // Do I still have to find out what he meant by if (rval == NULL | rval == JS_FALSE) {say ("Error executing input: jsval rval is NULL (in C) or JS_FALSE"); } str = JS_ValueToString (cx, rval); // don't print all of them; if (str! = oldstr) {say (JS_EncodeString (cx, str)); oldstr = str; // WILL THAT segmentation fault at some point? Or whether the old string is garbage collected and the oldstr pointer (formerly str, the old str pointer) is no longer correct? } s = ""; prompt(); }}} void destructor () {JS_DestroyContext (cx); JS_DestroyRuntime (rt); JS_ShutDown (); } int main (int argc, char ** argv) {// libuv loop = uv_default_loop (); uv_run (loop); if (constructor ()) {myREPL (); destructor (); }}

    It's nice when you call, Hello TTY! output in color (it is a colored JS function), but the color is only reset when I know the commands by heart and can read the current value.

    I also added a function that ends the Spiderman REPL. :-)

    The "refactoring" (extract methods) with "constructor" and "desctructor" and "meinREPL" is of course bad, but I'm just getting started. Names are smoke and mirrors in this case.

    Sometimes my comments are weird too.

    User Guide

    It is also a good idea to read the User Guide.

    Here: http://developer.mozilla.org/en-US/docs/SpiderMonkey/JSAPI_User_Guide

    You can still learn a lot more than I've tried so far. Such as http://developer.mozilla.org/en-US/docs/SpiderMonkey/JSAPI_Reference/JS_CallFunctionName

    It continues tomorrow. I slept a little earlier but woke up again. So I experimented with the JSAPI for a few minutes.

    More reference

    The global object and JSClass

    A JSClass is used to create the global object. This is a struct that has a few fields that, when initialized, has some strange fields at the beginning. The keys will be open.

    static JSClass global_class = {"global", JSCLASS_GLOBAL_FLAGS, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub, JS_EnumerateStub, JS_ResolveStub, JS_ResolveStub, JS_Convert_FINALIZE, JS_ConvertBERSize, JS_Convert_Finalize};

    To set up a global object with the default objects, you need the following commands in addition to JSRuntime and JSContext.

    // The JSClass for the global object is given as memory for the information // of the environment variable and the other global object functionality. / * The class of the global object. * / static JSClass global_class = {"global", JSCLASS_GLOBAL_FLAGS, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub, JS_EnumerateStub, JS_ResolveStub, JS_ResolveStub, JS_ResolveStub, JS_Convert_FOPTION} // In the function in which the context is created / * * Create the global object in a new compartment. * You always need a global object per context. * / JSObject * global; global = JS_NewCompartmentAndGlobalObject (cx, & global_class, NULL); if (global == NULL) return 1; // The function creates the JavaScript objects like Math, Date, RegExp, Object, Array, Function, Boolean, String, Number if (! JS_InitStandardClasses (cx, global)) {return log ("Can not initialize standard JS Classes"); } else {log ("Created all Default JavaScript Objects like Math, RegExp, Proxy."); }
    • JSClass

      So JSClass is a special structure, which is not a class, but serves as a structure for stubs, which I have to get behind first ...

      static JSClass iframe_global = {"iframe", JSCLASS_GLOBAL_FLAGS, JS_PropertyStub, ... ... (find out) ....};
    • JSClass.flags
      Flagimportance
      JSCLASS_HAS_PRIVATEJS_GetPrivate and JS_SetPrivate, whether the class uses private data. The field private data can be set with Get and SetPrivate.
      JSCLASS_NEW_ENUMERATEThe EnumerateHook is JSNewEnumerateOp, not JSEnumerateOp
      JSCLASS_NEW_RESOLVEMozilla Extension. XPCOM. nsISupports. XPConnect and JSCLASS_HAS_PRIVATE must be set.
      JSCLASS_PRIVATE_IS_NSISUPPORTS
      JSCLASS_SHARE_ALL_PROPERTIESObsolete since JSAPI 1.8.5 Give all props of the objects of this class the JSPROP_SHARED attribute
      JSCLASS_NEW_RESOLVE_GETS_STARTObsolete since JSAPI 16
      JSLASS_CONSTRUCT_PROTOTYPEJS_InitClass intrudes the constructor to invoken when the class prototype is created.
      JSCLASS_HAS_RESERVED_SLOTS (n)Checks whether the instances of class n [0..255] have reserved slots. The slots usually contain unspecified jsval values. You can reach them with JS_GetReservedSlot and JS_SetReservedSlot. The JSClass.reserveSlots hook also allocates reserved slots to objects.
      JSCLASS_IS_EXTENDEDIs this JSClass really a JSExtendedClass?
      JSObsolete since JSAPI 5. Indicates that the mark hook implements the new JSTraceOp instead of the old JSMarkOp signature. It is recommended for all new code that really needs its own marking.
      JSCLASS_GLOBAL_FLAGSOnly relevant for the JSClass of an object that is used as a global object. The global object is also in Spidermonkey the last object in the scope chain, which can be another object at other times, at the end of the scope chain. JS_ExecuteScript and the other APIS set the global object for their script.
    • JSPropertyOp
    • JS_PropertyStub