V8 JavaScript engine initial experience __UI

Source: Internet
Author: User
Tags sprintf git clone

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.




Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.