非常に古いバージョンのビルド済みの V8 があり、JNI を介して Android NDK に統合されてうまく動作しましたが、すべて問題ありませんでした。
私は V8 をより新しいコード (4.1.0.22) にアップグレードし、Ubuntu で独自の ARM アーカイブ ファイルを構築し、独自のアーキテクチャを同じに保ち、V8 コードベースの変更で明らかに必要とされるようにコードをリファクタリングしました。
ただし、クラッシュします。
これを構築したい方法は、おそらくいくつかの単純な例と比較すると異常ですが、永続化された V8 インスタンスを使用して、一度初期化し、後で複数の呼び出しを行うことができるようにすることです。各呼び出しは、Javascript コードの内容とメソッド名 (通常は「main」) を提供します。
したがって、これは実質的に私の初期化コードであり、一度実行します。
Persistent<Context> exec_context;
Isolate* isolateRef;
Platform* platformRef;
V8Resources(void (&initialiseTemplate)(Isolate* isolate, Handle<ObjectTemplate>))
{
// Initialize V8.
V8::InitializeICU();
platformRef = platform::CreateDefaultPlatform();
V8::InitializePlatform(platformRef);
V8::Initialize();
isolateRef = Isolate::New();
{
// Create a stack-allocated handle scope.
HandleScope handle_scope(isolateRef);
//Register for callbacks
Handle<ObjectTemplate> global_templ = ObjectTemplate::New(isolateRef);
initialiseTemplate(isolateRef, global_templ);
Local<Context> local_context = Context::New(isolateRef, NULL, global_templ);
exec_context.Reset(isolateRef, local_context);
Context::Scope context_scope(local_context);
}
}
上記の私のV8Resources
オブジェクトは、ぶらぶらしているものです。私が知る限り、このコードは問題なく動作します。
次に、しばらくして呼び出される「スクリプトの実行」メソッドで、次のようにします。
Isolate* isolate = v8instance->getIsolate();
Locker v8Locker(isolate);
const char *source_str= //...
const char *function_name_str = //...
HandleScope handle_scope(isolate);
Local<Context> context = Context::New(isolate);
Context::Scope context_scope(context);
Local<Object> global = context->Global();
TryCatch trycatch(isolate);
Handle<String> js_source = String::NewFromUtf8(isolate, source_str);
Handle<Script> js_compiled = Script::Compile(js_source);
if (js_compiled.IsEmpty())
{
throwNativeException("Error: compiled script is empty!");
return 0;
}
js_compiled->Run(context);
Handle<String> js_function_name = String::NewFromUtf8(isolate, function_name_str);
Handle<Value> js_function_val = global->Get(js_function_name);
Handle<Function> js_func = Handle<Function>::Cast(js_function_val);
Handle<Value> argm[0];
Handle<Value> js_result;
{
js_result = js_func->Call(global, 0, argm);
if (js_result.IsEmpty())
{
//...
}
else
{
//...
}
}
ロギングを介して決定すると、これは で SIGSEGV で爆発し、js_func->Call
有用なものがある限り、次のスタック トレースを提供します。
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 000045d0
Stack frame 03-17 15:42:52.168: I/DEBUG(28556): #00 pc 002b24a0 /data/app-lib/com.myapp.app-43/libv8jsevaluator.so (v8::TryCatch::TryCatch()+52)
Stack frame 03-17 15:42:52.168: I/DEBUG(28556): #01 pc 0033cfd8 /data/app-lib/com.myapp.app-43/libv8jsevaluator.so (v8::internal::Execution::TryCall(v8::internal::Handle<v8::internal::JSFunction>, v8::internal::Handle<v8::internal::Object>, int, v8::internal::Handle<v8::internal::Object>*, v8::internal::MaybeHandle<v8::internal::Object>*)+64)
Stack frame 03-17 15:42:52.168: I/DEBUG(28556): #02 pc 0034abfc /data/app-lib/com.myapp.app-43/libv8jsevaluator.so (v8::internal::Factory::NewError(char const*, char const*, v8::internal::Handle<v8::internal::JSArray>)+384)
Stack frame 03-17 15:42:52.168: I/DEBUG(28556): #03 pc 00349da4 /data/app-lib/com.myapp.app-43/libv8jsevaluator.so (v8::internal::Factory::NewError(char const*, char const*, v8::internal::Vector<v8::internal::Handle<v8::internal::Object> >)+372)
Stack frame 03-17 15:42:52.168: I/DEBUG(28556): #04 pc 00349e90 /data/app-lib/com.myapp.app-43/libv8jsevaluator.so (v8::internal::Factory::NewReferenceError(char const*, v8::internal::Vector<v8::internal::Handle<v8::internal::Object> >)+40)
Stack frame 03-17 15:42:52.168: I/DEBUG(28556): #05 pc 00429d74 /data/app-lib/com.myapp.app-43/libv8jsevaluator.so (v8::internal::IC::ReferenceError(char const*, v8::internal::Handle<v8::internal::Name>)+76)
Stack frame 03-17 15:42:52.168: I/DEBUG(28556): #06 pc 0042ce44 /data/app-lib/com.myapp.app-43/libv8jsevaluator.so (v8::internal::LoadIC::Load(v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Name>)+1048)
Stack frame 03-17 15:42:52.168: I/DEBUG(28556): #07 pc 0042d8a0 /data/app-lib/com.myapp.app-43/libv8jsevaluator.so (v8::internal::LoadIC_Miss(int, v8::internal::Object**, v8::internal::Isolate*)+396)
Stack frame 03-17 15:42:52.178: I/DEBUG(28556): #08 pc 00000090 <unknown>
さまざまなTryCatchパターンを含め、これをかなりいじりましたが、どこにも行けず、実際にV8を適切に使用していると確信していません.
この説明に明らかに間違っている点はありますか?