diff options
-rw-r--r-- | fpdfsdk/include/jsapi/fxjs_v8.h | 3 | ||||
-rw-r--r-- | fpdfsdk/src/jsapi/fxjs_v8.cpp | 74 | ||||
-rw-r--r-- | fpdfsdk/src/jsapi/fxjs_v8_embeddertest.cpp | 74 |
3 files changed, 111 insertions, 40 deletions
diff --git a/fpdfsdk/include/jsapi/fxjs_v8.h b/fpdfsdk/include/jsapi/fxjs_v8.h index 76373ac4bc..4ec1c331e5 100644 --- a/fpdfsdk/include/jsapi/fxjs_v8.h +++ b/fpdfsdk/include/jsapi/fxjs_v8.h @@ -97,7 +97,8 @@ class FXJS_PerIsolateData { static void SetUp(v8::Isolate* pIsolate); static FXJS_PerIsolateData* Get(v8::Isolate* pIsolate); void CreateDynamicObjsMap(v8::Isolate* pIsolate) { - m_pDynamicObjsMap = new V8TemplateMap(pIsolate); + if (!m_pDynamicObjsMap) + m_pDynamicObjsMap = new V8TemplateMap(pIsolate); } void ReleaseDynamicObjsMap() { delete m_pDynamicObjsMap; diff --git a/fpdfsdk/src/jsapi/fxjs_v8.cpp b/fpdfsdk/src/jsapi/fxjs_v8.cpp index f015f87136..4e139ca37b 100644 --- a/fpdfsdk/src/jsapi/fxjs_v8.cpp +++ b/fpdfsdk/src/jsapi/fxjs_v8.cpp @@ -6,6 +6,8 @@ #include "fpdfsdk/include/jsapi/fxjs_v8.h" +#include <vector> + #include "core/include/fxcrt/fx_basic.h" const wchar_t kFXJSValueNameString[] = L"string"; @@ -225,7 +227,8 @@ void FXJS_DefineObjMethod(v8::Isolate* pIsolate, CFXJS_ObjDefinition::ForID(pIsolate, nObjDefnID); pObjDef->GetInstanceTemplate()->Set( v8::String::NewFromUtf8(pIsolate, bsMethodName.c_str(), - v8::NewStringType::kNormal).ToLocalChecked(), + v8::NewStringType::kNormal) + .ToLocalChecked(), v8::FunctionTemplate::New(pIsolate, pMethodCall, v8::Local<v8::Value>(), pObjDef->GetSignature()), v8::ReadOnly); @@ -243,7 +246,8 @@ void FXJS_DefineObjProperty(v8::Isolate* pIsolate, CFXJS_ObjDefinition::ForID(pIsolate, nObjDefnID); pObjDef->GetInstanceTemplate()->SetAccessor( v8::String::NewFromUtf8(pIsolate, bsPropertyName.c_str(), - v8::NewStringType::kNormal).ToLocalChecked(), + v8::NewStringType::kNormal) + .ToLocalChecked(), pPropGet, pPropPut); } @@ -279,10 +283,11 @@ void FXJS_DefineGlobalMethod(v8::Isolate* pIsolate, v8::Isolate::Scope isolate_scope(pIsolate); v8::HandleScope handle_scope(pIsolate); CFX_ByteString bsMethodName = CFX_WideString(sMethodName).UTF8Encode(); - GetGlobalObjectTemplate(pIsolate)->Set( - v8::String::NewFromUtf8(pIsolate, bsMethodName.c_str(), - v8::NewStringType::kNormal).ToLocalChecked(), - v8::FunctionTemplate::New(pIsolate, pMethodCall), v8::ReadOnly); + GetGlobalObjectTemplate(pIsolate) + ->Set(v8::String::NewFromUtf8(pIsolate, bsMethodName.c_str(), + v8::NewStringType::kNormal) + .ToLocalChecked(), + v8::FunctionTemplate::New(pIsolate, pMethodCall), v8::ReadOnly); } void FXJS_DefineGlobalConst(v8::Isolate* pIsolate, @@ -341,8 +346,8 @@ void FXJS_InitializeRuntime( CFX_ByteString bs = CFX_WideString(pObjDef->m_ObjName).UTF8Encode(); v8::Local<v8::String> m_ObjName = v8::String::NewFromUtf8(pIsolate, bs.c_str(), - v8::NewStringType::kNormal, - bs.GetLength()).ToLocalChecked(); + v8::NewStringType::kNormal, bs.GetLength()) + .ToLocalChecked(); v8::Local<v8::Object> obj = FXJS_NewFxDynamicObj(pIsolate, pIRuntime, i, true); @@ -368,7 +373,6 @@ void FXJS_ReleaseRuntime(v8::Isolate* pIsolate, FXJS_PerIsolateData* pData = FXJS_PerIsolateData::Get(pIsolate); if (!pData) return; - pData->ReleaseDynamicObjsMap(); int maxID = CFXJS_ObjDefinition::MaxID(pIsolate); for (int i = 0; i < maxID; ++i) { @@ -393,6 +397,7 @@ void FXJS_ReleaseRuntime(v8::Isolate* pIsolate, if (pIsolate == g_isolate && --g_isolate_ref_count > 0) return; + pData->ReleaseDynamicObjsMap(); for (int i = 0; i < maxID; ++i) delete CFXJS_ObjDefinition::ForID(pIsolate, i); @@ -422,10 +427,11 @@ int FXJS_Execute(v8::Isolate* pIsolate, CFX_ByteString bsScript = CFX_WideString(script).UTF8Encode(); v8::Local<v8::Context> context = pIsolate->GetCurrentContext(); v8::Local<v8::Script> compiled_script; - if (!v8::Script::Compile( - context, v8::String::NewFromUtf8( - pIsolate, bsScript.c_str(), v8::NewStringType::kNormal, - bsScript.GetLength()).ToLocalChecked()) + if (!v8::Script::Compile(context, + v8::String::NewFromUtf8(pIsolate, bsScript.c_str(), + v8::NewStringType::kNormal, + bsScript.GetLength()) + .ToLocalChecked()) .ToLocal(&compiled_script)) { v8::String::Utf8Value error(try_catch.Exception()); // TODO(tsepez): return error via pError->message. @@ -505,9 +511,10 @@ void FXJS_Error(v8::Isolate* pIsolate, const CFX_WideString& message) { // wide-strings isn't handled by v8, so use UTF8 as a common // intermediate format. CFX_ByteString utf8_message = message.UTF8Encode(); - pIsolate->ThrowException( - v8::String::NewFromUtf8(pIsolate, utf8_message.c_str(), - v8::NewStringType::kNormal).ToLocalChecked()); + pIsolate->ThrowException(v8::String::NewFromUtf8(pIsolate, + utf8_message.c_str(), + v8::NewStringType::kNormal) + .ToLocalChecked()); } const wchar_t* FXJS_GetTypeof(v8::Local<v8::Value> pObj) { @@ -582,7 +589,8 @@ v8::Local<v8::String> FXJS_WSToJSString(v8::Isolate* pIsolate, if (!pIsolate) pIsolate = v8::Isolate::GetCurrent(); return v8::String::NewFromUtf8(pIsolate, bs.c_str(), - v8::NewStringType::kNormal).ToLocalChecked(); + v8::NewStringType::kNormal) + .ToLocalChecked(); } v8::Local<v8::Value> FXJS_GetObjectElement(v8::Isolate* pIsolate, @@ -592,7 +600,8 @@ v8::Local<v8::Value> FXJS_GetObjectElement(v8::Isolate* pIsolate, return v8::Local<v8::Value>(); v8::Local<v8::Value> val; if (!pObj->Get(pIsolate->GetCurrentContext(), - FXJS_WSToJSString(pIsolate, PropertyName)).ToLocal(&val)) + FXJS_WSToJSString(pIsolate, PropertyName)) + .ToLocal(&val)) return v8::Local<v8::Value>(); return val; } @@ -615,7 +624,8 @@ void FXJS_PutObjectString(v8::Isolate* pIsolate, return; pObj->Set(pIsolate->GetCurrentContext(), FXJS_WSToJSString(pIsolate, PropertyName), - FXJS_WSToJSString(pIsolate, sValue)).FromJust(); + FXJS_WSToJSString(pIsolate, sValue)) + .FromJust(); } void FXJS_PutObjectNumber(v8::Isolate* pIsolate, @@ -626,7 +636,8 @@ void FXJS_PutObjectNumber(v8::Isolate* pIsolate, return; pObj->Set(pIsolate->GetCurrentContext(), FXJS_WSToJSString(pIsolate, PropertyName), - v8::Int32::New(pIsolate, nValue)).FromJust(); + v8::Int32::New(pIsolate, nValue)) + .FromJust(); } void FXJS_PutObjectNumber(v8::Isolate* pIsolate, @@ -637,7 +648,8 @@ void FXJS_PutObjectNumber(v8::Isolate* pIsolate, return; pObj->Set(pIsolate->GetCurrentContext(), FXJS_WSToJSString(pIsolate, PropertyName), - v8::Number::New(pIsolate, (double)fValue)).FromJust(); + v8::Number::New(pIsolate, (double)fValue)) + .FromJust(); } void FXJS_PutObjectNumber(v8::Isolate* pIsolate, @@ -648,7 +660,8 @@ void FXJS_PutObjectNumber(v8::Isolate* pIsolate, return; pObj->Set(pIsolate->GetCurrentContext(), FXJS_WSToJSString(pIsolate, PropertyName), - v8::Number::New(pIsolate, (double)dValue)).FromJust(); + v8::Number::New(pIsolate, (double)dValue)) + .FromJust(); } void FXJS_PutObjectBoolean(v8::Isolate* pIsolate, @@ -659,7 +672,8 @@ void FXJS_PutObjectBoolean(v8::Isolate* pIsolate, return; pObj->Set(pIsolate->GetCurrentContext(), FXJS_WSToJSString(pIsolate, PropertyName), - v8::Boolean::New(pIsolate, bValue)).FromJust(); + v8::Boolean::New(pIsolate, bValue)) + .FromJust(); } void FXJS_PutObjectObject(v8::Isolate* pIsolate, @@ -669,7 +683,8 @@ void FXJS_PutObjectObject(v8::Isolate* pIsolate, if (pObj.IsEmpty()) return; pObj->Set(pIsolate->GetCurrentContext(), - FXJS_WSToJSString(pIsolate, PropertyName), pPut).FromJust(); + FXJS_WSToJSString(pIsolate, PropertyName), pPut) + .FromJust(); } void FXJS_PutObjectNull(v8::Isolate* pIsolate, @@ -678,8 +693,8 @@ void FXJS_PutObjectNull(v8::Isolate* pIsolate, if (pObj.IsEmpty()) return; pObj->Set(pIsolate->GetCurrentContext(), - FXJS_WSToJSString(pIsolate, PropertyName), - v8::Local<v8::Object>()).FromJust(); + FXJS_WSToJSString(pIsolate, PropertyName), v8::Local<v8::Object>()) + .FromJust(); } v8::Local<v8::Array> FXJS_NewArray(v8::Isolate* pIsolate) { @@ -744,9 +759,8 @@ v8::Local<v8::Value> FXJS_NewObject2(v8::Isolate* pIsolate, return pObj->Clone(); } -v8::Local<v8::Value> FXJS_NewString(v8::Isolate* pIsolate, - const wchar_t* string) { - return FXJS_WSToJSString(pIsolate, string); +v8::Local<v8::Value> FXJS_NewString(v8::Isolate* pIsolate, const wchar_t* str) { + return FXJS_WSToJSString(pIsolate, str); } v8::Local<v8::Value> FXJS_NewNull() { @@ -806,5 +820,3 @@ v8::Local<v8::Array> FXJS_ToArray(v8::Isolate* pIsolate, void FXJS_ValueCopy(v8::Local<v8::Value>& pTo, v8::Local<v8::Value> pFrom) { pTo = pFrom; } - - diff --git a/fpdfsdk/src/jsapi/fxjs_v8_embeddertest.cpp b/fpdfsdk/src/jsapi/fxjs_v8_embeddertest.cpp index b7700c8b60..e89bb28113 100644 --- a/fpdfsdk/src/jsapi/fxjs_v8_embeddertest.cpp +++ b/fpdfsdk/src/jsapi/fxjs_v8_embeddertest.cpp @@ -7,11 +7,32 @@ namespace { -const wchar_t kScript[] = L"fred = 7"; +const double kExpected0 = 6.0; +const double kExpected1 = 7.0; +const double kExpected2 = 8.0; + +const wchar_t kScript0[] = L"fred = 6"; +const wchar_t kScript1[] = L"fred = 7"; +const wchar_t kScript2[] = L"fred = 8"; } // namespace -class FXJSV8EmbedderTest : public JSEmbedderTest {}; +class FXJSV8EmbedderTest : public JSEmbedderTest { + public: + void ExecuteInCurrentContext(const wchar_t* script) { + FXJSErr error; + int sts = FXJS_Execute(isolate(), nullptr, script, &error); + EXPECT_EQ(0, sts); + } + void CheckAssignmentInCurrentContext(double expected) { + v8::Local<v8::Object> This = FXJS_GetThisObj(isolate()); + v8::Local<v8::Value> fred = FXJS_GetObjectElement(isolate(), This, L"fred"); + EXPECT_TRUE(fred->IsNumber()); + EXPECT_EQ(expected, fred->ToNumber(isolate()->GetCurrentContext()) + .ToLocalChecked() + ->Value()); + } +}; TEST_F(FXJSV8EmbedderTest, Getters) { v8::Isolate::Scope isolate_scope(isolate()); @@ -21,11 +42,48 @@ TEST_F(FXJSV8EmbedderTest, Getters) { v8::HandleScope handle_scope(isolate()); v8::Context::Scope context_scope(GetV8Context()); - FXJSErr error; - int sts = FXJS_Execute(isolate(), nullptr, kScript, &error); - EXPECT_EQ(0, sts); + ExecuteInCurrentContext(kScript1); + CheckAssignmentInCurrentContext(kExpected1); +} + +TEST_F(FXJSV8EmbedderTest, MultipleRutimes) { + v8::Isolate::Scope isolate_scope(isolate()); +#ifdef PDF_ENABLE_XFA + v8::Locker locker(isolate()); +#endif // PDF_ENABLE_XFA + v8::HandleScope handle_scope(isolate()); + + v8::Global<v8::Context> global_context1; + std::vector<v8::Global<v8::Object>*> static_objects1; + FXJS_InitializeRuntime(isolate(), nullptr, &global_context1, + &static_objects1); + + v8::Global<v8::Context> global_context2; + std::vector<v8::Global<v8::Object>*> static_objects2; + FXJS_InitializeRuntime(isolate(), nullptr, &global_context2, + &static_objects2); + + v8::Context::Scope context_scope(GetV8Context()); + ExecuteInCurrentContext(kScript0); + CheckAssignmentInCurrentContext(kExpected0); + + { + v8::Local<v8::Context> context1 = + v8::Local<v8::Context>::New(isolate(), global_context1); + v8::Context::Scope context_scope(context1); + ExecuteInCurrentContext(kScript1); + CheckAssignmentInCurrentContext(kExpected1); + } + FXJS_ReleaseRuntime(isolate(), &global_context1, &static_objects1); + + { + v8::Local<v8::Context> context2 = + v8::Local<v8::Context>::New(isolate(), global_context2); + v8::Context::Scope context_scope(context2); + ExecuteInCurrentContext(kScript2); + CheckAssignmentInCurrentContext(kExpected2); + } + FXJS_ReleaseRuntime(isolate(), &global_context2, &static_objects2); - v8::Local<v8::Object> This = FXJS_GetThisObj(isolate()); - v8::Local<v8::Value> fred = FXJS_GetObjectElement(isolate(), This, L"fred"); - EXPECT_TRUE(fred->IsNumber()); + CheckAssignmentInCurrentContext(kExpected0); } |