V8 engine, needless to say, is famous, so far the fastest JS engine.
Such a good thing, if used in the browser, too wasteful, but also want to use other places, such as some client development.
Gossip less, this begins
Download Source
Go to official website: https://code.google.com/p/v8/
I like to use git, so download from here
git clone git://github.com/v8/v8.git V8 && CD V8
compiling
I've been compiling for the Android platform for a long time, documenting some of the highlights. You have to look at this first: Http://code.google.com/p/v8/wiki/BuildingWithGYP
But the point is,
Make dependencies
This will take a long time (er, no way, the domestic speed does not give force, I downloaded several times) ...
Then, build on Android (other platforms.) So easy, look at the document, you can first look at the D8onandroid (Android platform is a JS command line, unknown to the compiler, but no use.)
My own compilation method, is to use the cross compiled
cross-compiling
Similar to building and clang, you can also use a cross-compiler. Just Export your toolchain (Cxx/link environment variables-should) and enough. For example:
Export cxx=/path/to/cross-compile-g++
export link=/path/to/cross-compile-g++ make
arm.release
(Compile wait ...)
When you're done, you can use it.
use on Android
First, create a project (how to create it.) This one... Find it yourself), an activity project on the line, and then create a JNI directory under the engineering directory.
Concrete how to use NDK, I don't say, find it yourself, I said the focus: 1. copy header and library files
For convenience, I put my head files and library files under the Include and Lib under Jni. Header files can be copied directly from the V8/include folder, the library file is more cumbersome, you must copy these:
libicudata.a libicui18n.a libicuuc.a libv8.a libv8_snapshot.a You can search from the V8/out directory (find it, anyway, you can't remember exactly where it is) Less compile-time will be reported to find the wrong error (said more than the tears AH)
2. Note the android.mk
When writing a android.mk, you must note:
1. Library Reference order is very important, the order is wrong, the same cannot find the symbol
2. To use STL,
Android.mk and APPLICATION.MK (STL required) code as follows, for everyone and reference, save detours
ANDROID.MK:
Local_path: = $ (call My-dir)
include $ (clear_vars)
local_cflags + =-i$ (local_path)/include local_ldflags
+ + =
$ (local_path)/lib/libv8.a \
$ (local_path)/lib/libv8_snapshot.a \
$ (local_path)/LIB/LIBICUI18N.A \
$ (local_path)/LIB/LIBICUUC.A \
$ (local_path)/lib/libicudata.a \
/<path>/android-ndk-r9d// SOURCES/CXX-STL/STLPORT/LIBS/ARMEABI/LIBSTLPORT_STATIC.A
Local_module: = Jswrapper
LOCAL_LDLIBS: =-llog
local_src_files: = \
registers.cpp \
JavaScriptContextWrap.cpp \
javautils.cpp
\ JsJavaClassProxy.cpp \
javawrap.cpp
#sample. cpp sample-jni.cpp \
Local_allow_undefined_symbols: = True
local_whole_static_libraries + = Android_support
include $ (build_shared_library)
$ (call Import-module, Android/support)
(I am very stupid ah, STL not full path links can not find, er, God once again like me, to give me temper it ...)
Remember Lib's order and STL Oh ...
Application.mk
App_cflags + +-fexceptions
app_cflags + =-frtti
app_stl: = stlport_static
#gnustl_static
It's good to compile with ndk-build.
Code Writing
As for the JNI part of the code, I do not write, do not understand Baidu and Google, you understand.
Header file. It would be nice to use a "v8.h".
1. Initialize
V8::v8::initializeicu ();
Finished Yes, it's that simple . 2. Create isolate and context
Isolate_ = V8::isolate::new ();
Isolate_->enter ();
V8::handlescope Handle_scope (Isolate_);
v8::handle<v8::objecttemplate> global = v8::objecttemplate::new (Isolate_); //create log Object v8::handle<v8::objecttemplate> log
= V8::objecttemplate::new (Isolate_); Log->set (V8::string::newfromutf8 (Isolate_, "E"),
v8::functiontemplate::new (Isolate_, js_func_log_e)); Log->set (V8::string::newfromutf8 (Isolate_, "I"),
v8::functiontemplate::new (Isolate_, js_func_log_i)); Log->set (V8::string::newfromutf8 (Isolate_, "V"),
v8::functiontemplate::new (Isolate_, Js_func_log_v)); Log->set (V8::string::newfromutf8 (Isolate_,"D"), v8::functiontemplate::new (Isolate_, Js_
Func_log_d));
Global->set (V8::string::newfromutf8 (Isolate_, "Log"), log); //todo Others global->set (V8::string::newfromutf8 isolate_, "Import_java_ Class "), v8::functiontemplate::new (Isolate_,
Js_func_import_java_class)); Context_.
Reset (Isolate_, V8::context::new (Isolate_, NULL, Global));
Content a little Doha. Don't worry, listen to me slowly.
First, create a v8::isolate, with V8::isolate::new (). What isolate is. Well, I'm not really sure, like a virtual machine, all the JavaScript objects are on this isolate, not too isolate ways.
Then you need to call Isolate_->enter (), and of course when you want to destroy, call Isolate_->leave ().
By the way, V8 is C + +, and the member method initials are all uppercase.
Second, we can create a objecttemplate. Objecttemplate words too literally, is the object of the template, how to say, corresponding to C + + and Java inside, you can think of static class, there are a bunch of static methods.
Please read the last sentence first: v8::context::new (Isolate_, NULL, Global). This phrase registers a global template, that is, if I register a print function in global, I can write it directly in JS:
Print ("Hi, I\ ' m from native");
In our example, we registered a Log of the Objecttempl,log and contains E, I, V, D several methods, in fact, the corresponding android.util.log.e, I, V, D.
The registration method is to call the Set,c++ function pointer with the
V8::functiontemplate::new
To wrap. That's all you need to know (I don't really understand)
It is also important to note that the above code is actually part of a class with two member variables:
V8::P ersistent<v8::context> context_;
V8::isolate* Isolate_;
isolate uses pointers directly, and the context must be persistent, a pointer that can persist objects (to prevent V8 from being garbage collected), using Rest:
Context_. Reset (Isolate_, V8::context::new (Isolate_, NULL, Global));
3. Define a function
Look at the code first: (I use js_func_log_x to implement the common parts of functions such as js_func_log_i)
void js_func_log_x (int level, const v8::functioncallbackinfo<v8::value>& args) {
if (args). Length () = = 0) {return
;
}
Get tag
char sztag[1024] = "";
{
v8::handlescope handle_scope (args). Getisolate ());
V8::string::utf8value str (args[0]);
Const char* CSTR = tocstring (str);
strcpy (Sztag, CStr);
Char szlog[1024*8] = "";
bool A = true;
int len = 0;
for (int i = 1; i < args. Length (); i++)
{
v8::handlescope handle_scope (args. Getisolate ());
if (i) {i
= false;
} else {
len + = sprintf (Szlog + len, "");
}
V8::string::utf8value str (args[i]);
Const char* CSTR = tocstring (str);
Len + + sprintf (szlog + len, "%s", CStr);
}
__android_log_print (level, Sztag, "%s", Szlog);
}
The args contains parameters and runtime. When parameters are processed for each parameter, you must call the
V8::handlescope Handle_scope (args. Getisolate ());
(Why. I don ' t known .... )
To take a string from value, you need to use tocstring, and he's simple:
static const char* tocstring (const v8::string::utf8value& value) {return
*value? *value: <string Conversi On failed> ";
}
Seriously, the function for V8 is this:
void js_func_log_i (const v8::functioncallbackinfo<v8::value>& args) {
js_func_log_x (android_log_info , args);
}
void Js_func_log_v (const v8::functioncallbackinfo<v8::value>& args) {
js_func_log_x (android_log_ VERBOSE, args);
void Js_func_log_d (const v8::functioncallbackinfo<v8::value>& args) {
js_func_log_x (android_log_ DEBUG, args);
}
void js_func_log_e (const v8::functioncallbackinfo<v8::value>& args) {
js_func_log_x (android_log_ ERROR, args);
}
All right, this is the end of the first experience.
some important points of knowledge 1. Associate an object to the isolate
Isolate can have multiple, and if an object is associated with isolate, how do you find the object from isolate?
using the isolate Getdata/setdata
Like what
javawrapper* javawrapper::fromisolate (isolate* isolate) {
if (isolate = null) {return
null;
}
void *data = Isolate->getdata (isolate_slot_java_wrapper);
javawrapper* javawrap = reinterpret_cast<javawrapper*> (data);
return javawrap && Javawrap->isolate_ = = isolate? javawrap:null;
}
Javawrapper::javawrapper (isolate* Isolate)
: Isolate_ (Isolate)
{
Isolate_->setdata (isolate_slot_ Java_wrapper, (void*) this);
}
2. How to get other types of parameters from V8::value
V8::value is a composite object, and we can do this:
for (int i = 0; i < count; i++) {Handlescope handle_scope (args.
Getisolate ());
Local<value> v = args[i];
if (v->isundefined () | | | v->isnull ()) {Types[i] = Jsjavaclassproxy::nullclass ();
Values[i] = Jsjavaclassproxy::nullobject ();
LOGV ("Arg (%d) is null\n", i);
else if (v->istrue () | | V->isfalse ()) {Types[i] = Jsjavaclassproxy::booleanclass ();
Jboolean JV = (Jboolean) (V->istrue ()? true:false);
Values[i] = jreflect::valueof (env, JV);
LOGV ("Arg (%d) is boolean:%d", I, JV);
else if (v->isstring ()) {Types[i] = Jsjavaclassproxy::stringclass ();
String::utf8value str (v);
Const char* CSTR = tocstring (str);
Values[i] = Env->newstringutf (CStr);
LOGV ("Arg (%d) is string:%s", I, CStr); else if (V->isboolean ()) {Types[i] = Jsjavaclassproxy::booleanclAss ();
Jboolean JV = V->toboolean ()->value ();
Values[i] = jreflect::valueof (env, JV);
LOGV ("Arg (%d) is boolean:%d", I, JV);
else if (V->isint32 () | | V->isuint32 ()) {Types[i] = Jsjavaclassproxy::intclass ();
Jint JV = V->toint32 ()->value ();
Values[i] = jreflect::valueof (env, JV);
LOGV ("Arg (%d) is int:%d", I, JV);
else if (V->isnumber ()) {Types[i] = Jsjavaclassproxy::D oubleclass ();
Jdouble JV = V->tonumber ()->value ();
Values[i] = jreflect::valueof (env, JV);
LOGV ("Arg (%d) is double:%f", I, JV);
}/** TODO more **/else {LOGE ("Invalidate Arg type!");
ASSERT (FALSE); }
}
More, from the v8.h to see it.
OK, let's get here first.