How to use iMonkey in an iOS app
iMonkey looks like an interesting way of embedding a JS runtime in an iOS app, but I can't find any examples on how to actually run some JS code.
I can build/link the lib, include the jsapi.h header (from the src directory), but it trips over various linker errors ('undefined symbol for architecture...') when I try some example code from spider monkey (see below). To be clear, this is pretty much a copy-paste from a Mac related posting on another site, I am not at all sure if this is how it should be done. I am sure I have the right static library (universal) for my architecture (simulator).
Anyone knows how to do this?
#include "jsapi.h"
.....
JSR开发者_Python百科untime *rt;
JSContext *cx;
JSObject *global;
/* Create a JS runtime. */
rt = JS_NewRuntime(8L * 1024L * 1024L);
/* Create a context. */
cx = JS_NewContext(rt, 8192);
JS_SetOptions(cx, JSOPTION_VAROBJFIX);
/* Create the global object. */
global = JS_NewObject(cx, &global_class, NULL, NULL);
/* Populate the global object with the standard globals,
like Object and Array. */
if (!JS_InitStandardClasses(cx, global))
@throw [[NSException alloc]initWithName:@"JSerror" reason:@"jserrpr" userInfo:nil];
/* Cleanup. */
JS_DestroyContext(cx);
JS_DestroyRuntime(rt);
JS_ShutDown();
Here's an example loosely based off the examples found in the original spider monkey.
http://egachine.berlios.de/embedding-sm-best-practice/embedding-sm-best-practice.html
I modified so it works with multi threading (which is already enabled by iMonkey).
https://developer.mozilla.org/En/SpiderMonkey/Internals/Thread_Safety
//
// JSEngine.mm
// POC_JS
//
// Created by Quoc Le on 7/12/12.
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
#import "JSEngine.h"
/* get SpiderMonkey API declarations */
#include <jsapi.h>
/* EXIT_FAILURE and EXIT_SUCCESS */
#include <stdlib.h>
/* strlen */
#include <string.h>
@implementation JSEngine
+ (int) run
{
/* pointer to our runtime object */
JSRuntime *runtime=NULL;
/* pointer to our context */
JSContext *context=NULL;
/* pointer to our global JavaScript object */
JSObject *global=NULL;
/* script to run (should return 100) */
char *script="var x=10;x*x;";
/* JavaScript value to store the result of the script */
jsval rval;
/* create new runtime, new context, global object */
if ( (!(runtime = JS_NewRuntime (1024L*1024L)))
|| (!(context = JS_NewContext (runtime, 8192)))
) return EXIT_FAILURE;
JS_SetContextThread(context);
JS_BeginRequest(context);
// || (!(global = JS_NewObject (context, NULL, NULL, NULL)))
global = JS_NewObject (context, NULL, NULL, NULL);
/* set global object of context and initialize standard ECMAScript
objects (Math, Date, ...) within this global object scope */
if (!JS_InitStandardClasses(context, global)) return EXIT_FAILURE;
/* now we are ready to run our script */
if (!JS_EvaluateScript(context, global,script, strlen(script),
"script", 1, &rval))
return EXIT_FAILURE;
/* check if the result is really 100 */
NSLog(@"RSVAL %d", JSVAL_TO_INT(rval));
if (!(JSVAL_IS_INT(rval)&&(JSVAL_TO_INT(rval)==100)))
return EXIT_FAILURE;
JS_EndRequest(context);
JS_ClearContextThread(context);
/* clean up */
//JS_DestroyContext(context);
//JS_DestroyRuntime(runtime);
//JS_ShutDown();
return EXIT_SUCCESS;
}
@end
I had similar problem with linker. just add libstdc++6 to your project to avoid this problem
精彩评论