void js_error_reporter( JSContext *cx, const char *message, JSErrorReport *err )
{
bug( "JS Error: [%s:%d] %s", err->filename, err->lineno, message );
}
JSBool js_bug( JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval )
{
if ( argc < 1 )
{
/* No arguments, do nothing */
*rval = INT_TO_JSVAL(0);
return JS_TRUE;
}
string out;
/* a handy cheat - allows us to concat arguments, ie:
bug( "Hi ", name, ". How are you?" );
*/
for ( uintN i = 0; i < argc; i++ )
{
JSString *val = JS_ValueToString( cx, argv[i] );
out += JS_GetStringBytes(val);
}
bug( "%s", out.c_str() );
/* return the length of the string posted to bug() */
*rval = INT_TO_JSVAL( out.length() );
return JS_TRUE;
}
if ( JS_DefineFunction( cx, global, "bug", js_bug, 1, 0 ) == JS_FALSE )
{
ch_printf( ch, "Error defining bug function.\r\n" );
goto end;
}
#include <smjs/jsapi.h>
#include <string>
#include "mud.h"
using namespace std;
void js_error_reporter( JSContext *cx, const char *message, JSErrorReport *err )
{
bug( "JS Error: [%s:%d] %s", err->filename, err->lineno, message );
}
JSBool js_bug( JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval )
{
if ( argc < 1 )
{
/* No arguments, do nothing */
*rval = INT_TO_JSVAL(0);
return JS_TRUE;
}
string out;
/* a handy cheat - allows us to concat arguments, ie:
bug( "Hi ", name, ". How are you?" );
*/
for ( uintN i = 0; i < argc; i++ )
{
JSString *val = JS_ValueToString( cx, argv[i] );
out += JS_GetStringBytes(val);
}
bug( "%s", out.c_str() );
*rval = INT_TO_JSVAL( out.length() );
return JS_TRUE;
}
CMDF do_testjs( Character *ch, char *argument )
{
JSRuntime *rt;
JSContext *cx;
JSObject *global;
JSClass global_class = {
"global",0,
JS_PropertyStub,JS_PropertyStub,JS_PropertyStub,JS_PropertyStub,
JS_EnumerateStub,JS_ResolveStub,JS_ConvertStub,JS_FinalizeStub
};
const char *script = argument[0] == '\0' ? "bug( \"undefined argument to testjs\" );" : argument;
jsval rval;
JSString *str;
JSBool ok;
/*
* You always need:
* a runtime per process,
* a context per thread,
* a global object per context,
* standard classes (e.g. Date).
*/
rt = JS_NewRuntime(0x100000);
cx = JS_NewContext(rt, 0x1000);
global = JS_NewObject(cx, &global_class, NULL, NULL);
JS_InitStandardClasses(cx, global);
if ( JS_DefineFunction( cx, global, "bug", js_bug, 1, 0 ) == JS_FALSE )
{
ch_printf( ch, "Error defining bug function.\r\n" );
goto end;
}
JS_SetErrorReporter( cx, &js_error_reporter );
/*
* Now suppose script contains some JS to evaluate, say "22/7" as a
* bad approximation for Math.PI, or something longer, such as this:
* "(function fact(n){if (n <= 1) return 1; return n * fact(n-1)})(5)"
* to compute 5!
*/
if ( ( ok = JS_EvaluateScript(cx, global, script, strlen(script), "Drazon", 0, &rval) ) == JS_FALSE )
ch_printf( ch, "There was an error\r\n" );
else
{
str = JS_ValueToString(cx, rval);
ch_printf( ch, "script result: %s\n", JS_GetStringBytes(str));
}
JS_ClearScope( cx, global);
JS_GC( cx );
end:
JS_DestroyContext( cx );
JS_DestroyRuntime( rt );
}
#include <smjs/jsapi.h>
#include <string>
#include "mud.h"
using namespace std;
void js_error_reporter( JSContext *cx, const char *message, JSErrorReport *err )
{
bug( "JS Error: [%s:%d] %s", err->filename, err->lineno, message );
}
JSBool js_bug( JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval )
{
if ( argc < 1 )
{
/* No arguments, do nothing */
*rval = INT_TO_JSVAL(0);
return JS_TRUE;
}
string out;
/* a handy cheat - allows us to concat arguments, ie:
bug( "Hi ", name, ". How are you?" );
*/
for ( uintN i = 0; i < argc; i++ )
{
JSString *val = JS_ValueToString( cx, argv[i] );
out += JS_GetStringBytes(val);
}
bug( "%s", out.c_str() );
*rval = INT_TO_JSVAL( out.length() );
return JS_TRUE;
}
class JSRoom
{
public:
Room *room;
JSRoom() : room(NULL)
{
};
~JSRoom()
{
if ( room )
delete room;
room = NULL;
}
enum
{
vnum_prop,
name_prop
};
static JSPropertySpec room_properties[];
static JSFunctionSpec room_methods[];
static JSObject *JSInit( JSContext *cx, JSObject *obj, JSObject *proto )
{
return JS_InitClass( cx, obj, proto, &roomClass,
JSRoom::JSConstructor, 0,
JSRoom::room_properties, JSRoom::room_methods, NULL, NULL);
};
static JSBool JSConstructor( JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval )
{
int vnum = -1;
Area *area;
if ( argc < 2 )
return JS_FALSE;
if ( JS_ValueToInt32( cx, argv[0], &vnum ) == JS_FALSE )
return JS_FALSE;
if ( get_room_index( vnum ) )
return JS_FALSE;
area = get_area( JS_GetStringBytes( JS_ValueToString( cx, argv[1] ) ) );
JSRoom *r = new JSRoom();
r->room = new Room( vnum, area );
r->room->name = STRALLOC( "Floating in a void" );
r->room->description = STRALLOC( "" );
if ( !JS_SetPrivate( cx, obj, r ) )
return JS_FALSE;
*rval = OBJECT_TO_JSVAL( obj );
return JS_TRUE;
};
static JSBool JSGetProperty( JSContext *cx, JSObject *obj, jsval id, jsval *vp )
{
if ( JSVAL_IS_INT(id) )
{
JSRoom *r = (JSRoom *)JS_GetPrivate( cx, obj );
switch ( JSVAL_TO_INT(id) )
{
case vnum_prop: *vp = INT_TO_JSVAL( r->room->vnum ); break;
case name_prop: break;
}
}
return JS_TRUE;
};
static JSBool JSSetProperty( JSContext *cx, JSObject *obj, jsval id, jsval *vp )
{
if ( JSVAL_IS_INT(id) )
{
JSRoom *r = (JSRoom *)JS_GetPrivate( cx, obj );
switch( JSVAL_TO_INT(id) )
{
case vnum_prop: break;
case name_prop:
STRFREE( r->room->name );
r->room->name = STRALLOC( JS_GetStringBytes( JS_ValueToString( cx, *vp ) ) );
break;
}
}
return JS_TRUE;
};
static void JSDestructor( JSContext *cx, JSObject *obj )
{
JSRoom *r = (JSRoom *)JS_GetPrivate( cx, obj );
delete r;
r = NULL;
};
static JSClass roomClass;
};
JSClass JSRoom::roomClass = {
"Room", JSCLASS_HAS_PRIVATE,
JS_PropertyStub, JS_PropertyStub,
JSRoom::JSGetProperty, JSRoom::JSSetProperty,
JS_EnumerateStub, JS_ResolveStub,
JS_ConvertStub, JSRoom::JSDestructor
};
JSPropertySpec JSRoom::room_properties[] =
{
{ "vnum", vnum_prop, JSPROP_ENUMERATE | JSPROP_READONLY },
{ "name", name_prop, JSPROP_ENUMERATE },
{ NULL }
};
JSFunctionSpec JSRoom::room_methods[] =
{
{ NULL }
};
CMDF do_testjs( Character *ch, char *argument )
{
JSRuntime *rt;
JSContext *cx;
JSObject *global;
JSClass global_class = {
"global",0,
JS_PropertyStub,JS_PropertyStub,JS_PropertyStub,JS_PropertyStub,
JS_EnumerateStub,JS_ResolveStub,JS_ConvertStub,JS_FinalizeStub
};
const char *script = argument[0] == '\0' ? "bug( \"undefined argument to testjs\" );" : argument;
jsval rval;
JSString *str;
JSBool ok;
/*
* You always need:
* a runtime per process,
* a context per thread,
* a global object per context,
* standard classes (e.g. Date).
*/
rt = JS_NewRuntime(0x100000);
cx = JS_NewContext(rt, 0x1000);
global = JS_NewObject(cx, &global_class, NULL, NULL);
JS_InitStandardClasses(cx, global);
JSRoom::JSInit( cx, global, NULL );
if ( JS_DefineFunction( cx, global, "bug", js_bug, 1, 0 ) == JS_FALSE )
{
ch_printf( ch, "Error defining bug function.\r\n" );
goto end;
}
JS_SetErrorReporter( cx, &js_error_reporter );
/*
* Now suppose script contains some JS to evaluate, say "22/7" as a
* bad approximation for Math.PI, or something longer, such as this:
* "(function fact(n){if (n <= 1) return 1; return n * fact(n-1)})(5)"
* to compute 5!
*/
if ( ( ok = JS_EvaluateScript(cx, global, script, strlen(script), "Drazon", 0, &rval) ) == JS_FALSE )
ch_printf( ch, "There was an error\r\n" );
else
{
str = JS_ValueToString(cx, rval);
ch_printf( ch, "script result: %s\n", JS_GetStringBytes(str));
}
JS_ClearScope( cx, global);
JS_GC( cx );
end:
JS_DestroyContext( cx );
JS_DestroyRuntime( rt );
}
#define JS_STRALLOC_STRING( str, cx, vp ) \
if ( (str) ) \
STRFREE( (str) ); \
(str) = STRALLOC( JS_GetStringBytes( JS_ValueToString( (cx), (vp) ) ) );
#define JS_CSTR_TO_JSVAL( str, cx ) \
STRING_TO_JSVAL( JS_NewStringCopyN( (cx), (str), strlen((str)) ) );
JSObject *game = NULL;
if ( ( game = JS_DefineObject( cx, global, "game", &JSGame::gameClass, NULL, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE ) ) == NULL )
{
ch_printf( ch, "Error defining game object.\r\n" );
goto end;
}
static JSBool getCharacter( JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval )
{
if ( argc != 1 || ! JSVAL_IS_STRING(argv[0]) )
return JS_FALSE;
char *name = JS_JVAL_TO_CSTR( argv[0] );
JSRoom *r = (JSRoom *)JS_GetPrivate( cx, obj );
for ( Character *ch = r->room->first_person; ch; ch = ch->next_in_room )
if ( !str_cmp( ch->name, name ) )
{
JSCharacter *character = new JSCharacter;
JSObject *chobj = JS_NewObject( cx, &JSCharacter::characterClass, NULL, NULL );
character->character = ch;
if ( !JS_SetPrivate( cx, chobj, character ) )
return JS_FALSE;
*rval = OBJECT_TO_JSVAL( chobj );
return JS_TRUE;
}
return JS_FALSE;
}
#define JS_SET_DBL_VAL(cx, ret, a) \
{ \
jsdouble dbl = (jsdouble)a; \
*ret = DOUBLE_TO_JSVAL(JS_NewDouble(cx, dbl)); \
}
template<typename JSContainer, class ValueType>
JSObject *makeJSObject( JSContext *cx, ValueType value )
{
if ( !value )
return JSVAL_NULL;
JSContainer *cont = new JSContainer;
JSObject *jsobj = JS_NewObject( cx, &JSContainer::objectDefs, NULL, NULL );
cont->object = value;
if ( !JS_SetPrivate( cx, jsobj, cont ) )
{
delete cont;
return NULL;
}
return jsobj;
}
JSObject *obj = makeJSObject<JSCharacter>( cx, ch );
http://www.mozilla.org/js/spidermonkey/a...
http://www.mozilla.org/js/spidermonkey/a...
http://www.mozilla.org/js/spidermonkey/t...
http://users.skynet.be/saw/SpiderMonkey....
I am playing with embedding the spidermonkey javascript engine thingy. Just starting simple.
To get it to compile I have done:
<debian>apt-get install libsmjs-dev libsmjs1</debian>
added -lsmjs to L_FLAGS in Makefile
added -DXP_UNIX to C_FLAGS in Makefile
My js.cpp file looks like:
Will be posting more as I go :)