diff options
author | Tom Sepez <tsepez@chromium.org> | 2015-09-22 08:36:17 -0700 |
---|---|---|
committer | Tom Sepez <tsepez@chromium.org> | 2015-09-22 08:36:17 -0700 |
commit | ed7b2b50aa1744e0bc5a60bef12c61fa91d863b7 (patch) | |
tree | 8661329f66b823af324441fb6accec98a8753cb8 | |
parent | 854a7f65b70d40225a53890a68a57f5c13cf268c (diff) | |
download | pdfium-ed7b2b50aa1744e0bc5a60bef12c61fa91d863b7.tar.xz |
XFA: contention between FXJSE and FXJS over isolate data slots
This probably broke at 06b60021e when the FXJS slot moved to 0
from 1 unless explicitly overriden by the embedder, which conflicted
with the FXJSE_ usage of slot 0.
Also simplify some logic used to track global intialization of the
underling JS.
TEST=run_javascript_tests.py on XFA branch doesn't segv.
R=jochen@chromium.org
Review URL: https://codereview.chromium.org/1351173002 .
-rw-r--r-- | fpdfsdk/include/fpdfxfa/fpdfxfa_app.h | 11 | ||||
-rw-r--r-- | fpdfsdk/include/javascript/JS_Define.h | 28 | ||||
-rw-r--r-- | fpdfsdk/include/jsapi/fxjs_v8.h | 29 | ||||
-rw-r--r-- | fpdfsdk/src/fpdfxfa/fpdfxfa_app.cpp | 18 | ||||
-rw-r--r-- | fpdfsdk/src/fsdk_mgr.cpp | 6 | ||||
-rw-r--r-- | fpdfsdk/src/javascript/JS_Runtime.cpp | 3 | ||||
-rw-r--r-- | fpdfsdk/src/jsapi/fxjs_v8.cpp | 165 | ||||
-rw-r--r-- | fpdfsdk/src/jsapi/fxjs_v8_embeddertest.cpp | 2 | ||||
-rw-r--r-- | xfa/src/fxjse/src/runtime.cpp | 23 |
9 files changed, 139 insertions, 146 deletions
diff --git a/fpdfsdk/include/fpdfxfa/fpdfxfa_app.h b/fpdfsdk/include/fpdfxfa/fpdfxfa_app.h index 49825c3f7f..f5052e3adf 100644 --- a/fpdfsdk/include/fpdfxfa/fpdfxfa_app.h +++ b/fpdfsdk/include/fpdfxfa/fpdfxfa_app.h @@ -23,9 +23,12 @@ class CPDFXFA_App : public IXFA_AppProvider { FX_BOOL AddFormFillEnv(CPDFDoc_Environment* pEnv);
FX_BOOL RemoveFormFillEnv(CPDFDoc_Environment* pEnv);
- FXJSE_HRUNTIME GetJSERuntime() { return m_hJSERuntime; }
- void ReleaseRuntime();
- FX_BOOL InitRuntime(FX_BOOL bReset = FALSE);
+ FX_BOOL IsJavaScriptInitialized() const { return m_bJavaScriptInitialized; }
+ void SetJavaScriptInitialized(FX_BOOL bInitialized) {
+ m_bJavaScriptInitialized = bInitialized;
+ }
+
+ FXJSE_HRUNTIME GetJSERuntime() const { return m_hJSERuntime; }
// IFXA_AppProvider:
void GetAppType(CFX_WideString& wsAppType) override;
@@ -81,7 +84,7 @@ class CPDFXFA_App : public IXFA_AppProvider { protected:
static CPDFXFA_App* g_pApp;
- FX_BOOL m_bInitRuntime;
+ FX_BOOL m_bJavaScriptInitialized;
IXFA_App* m_pXFAApp;
IXFA_FontMgr* m_pFontMgr;
FXJSE_HRUNTIME m_hJSERuntime;
diff --git a/fpdfsdk/include/javascript/JS_Define.h b/fpdfsdk/include/javascript/JS_Define.h index 1addca5cec..3b5798ef5c 100644 --- a/fpdfsdk/include/javascript/JS_Define.h +++ b/fpdfsdk/include/javascript/JS_Define.h @@ -79,8 +79,8 @@ void JSPropGetter(const char* prop_name_string, v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value>& info) { v8::Isolate* isolate = info.GetIsolate(); - IFXJS_Runtime* pRuntime = (IFXJS_Runtime*)isolate->GetData(2); - IFXJS_Context* pRuntimeContext = pRuntime->GetCurrentContext(); + FXJS_PerIsolateData* pData = FXJS_PerIsolateData::Get(isolate); + IFXJS_Context* pRuntimeContext = pData->m_pFXJSRuntime->GetCurrentContext(); CJS_PropValue value(isolate); value.StartGetting(); CJS_Object* pJSObj = (CJS_Object*)FXJS_GetPrivate(isolate, info.Holder()); @@ -102,8 +102,8 @@ void JSPropSetter(const char* prop_name_string, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& info) { v8::Isolate* isolate = info.GetIsolate(); - IFXJS_Runtime* pRuntime = (IFXJS_Runtime*)isolate->GetData(2); - IFXJS_Context* pRuntimeContext = pRuntime->GetCurrentContext(); + FXJS_PerIsolateData* pData = FXJS_PerIsolateData::Get(isolate); + IFXJS_Context* pRuntimeContext = pData->m_pFXJSRuntime->GetCurrentContext(); CJS_PropValue propValue(CJS_Value(isolate, value, CJS_Value::VT_unknown)); propValue.StartSetting(); CJS_Object* pJSObj = (CJS_Object*)FXJS_GetPrivate(isolate, info.Holder()); @@ -141,8 +141,8 @@ void JSMethod(const char* method_name_string, const char* class_name_string, const v8::FunctionCallbackInfo<v8::Value>& info) { v8::Isolate* isolate = info.GetIsolate(); - IFXJS_Runtime* pRuntime = (IFXJS_Runtime*)isolate->GetData(2); - IFXJS_Context* pRuntimeContext = pRuntime->GetCurrentContext(); + FXJS_PerIsolateData* pData = FXJS_PerIsolateData::Get(isolate); + IFXJS_Context* pRuntimeContext = pData->m_pFXJSRuntime->GetCurrentContext(); CJS_Parameters parameters; for (unsigned int i = 0; i < (unsigned int)info.Length(); i++) { parameters.push_back(CJS_Value(isolate, info[i], CJS_Value::VT_unknown)); @@ -268,8 +268,8 @@ void JSSpecialPropGet(const char* class_name, const v8::PropertyCallbackInfo<v8::Value>& info) { v8::Isolate* isolate = info.GetIsolate(); v8::Local<v8::Context> context = isolate->GetCurrentContext(); - IFXJS_Runtime* pRuntime = (IFXJS_Runtime*)isolate->GetData(2); - IFXJS_Context* pRuntimeContext = pRuntime->GetCurrentContext(); + FXJS_PerIsolateData* pData = FXJS_PerIsolateData::Get(isolate); + IFXJS_Context* pRuntimeContext = pData->m_pFXJSRuntime->GetCurrentContext(); CJS_Object* pJSObj = reinterpret_cast<CJS_Object*>(FXJS_GetPrivate(isolate, info.Holder())); Alt* pObj = reinterpret_cast<Alt*>(pJSObj->GetEmbedObject()); @@ -293,8 +293,8 @@ void JSSpecialPropPut(const char* class_name, const v8::PropertyCallbackInfo<v8::Value>& info) { v8::Isolate* isolate = info.GetIsolate(); v8::Local<v8::Context> context = isolate->GetCurrentContext(); - IFXJS_Runtime* pRuntime = (IFXJS_Runtime*)isolate->GetData(2); - IFXJS_Context* pRuntimeContext = pRuntime->GetCurrentContext(); + FXJS_PerIsolateData* pData = FXJS_PerIsolateData::Get(isolate); + IFXJS_Context* pRuntimeContext = pData->m_pFXJSRuntime->GetCurrentContext(); CJS_Object* pJSObj = reinterpret_cast<CJS_Object*>(FXJS_GetPrivate(isolate, info.Holder())); Alt* pObj = reinterpret_cast<Alt*>(pJSObj->GetEmbedObject()); @@ -315,8 +315,8 @@ void JSSpecialPropDel(const char* class_name, const v8::PropertyCallbackInfo<v8::Boolean>& info) { v8::Isolate* isolate = info.GetIsolate(); v8::Local<v8::Context> context = isolate->GetCurrentContext(); - IFXJS_Runtime* pRuntime = (IFXJS_Runtime*)isolate->GetData(2); - IFXJS_Context* pRuntimeContext = pRuntime->GetCurrentContext(); + FXJS_PerIsolateData* pData = FXJS_PerIsolateData::Get(isolate); + IFXJS_Context* pRuntimeContext = pData->m_pFXJSRuntime->GetCurrentContext(); CJS_Object* pJSObj = reinterpret_cast<CJS_Object*>(FXJS_GetPrivate(isolate, info.Holder())); Alt* pObj = reinterpret_cast<Alt*>(pJSObj->GetEmbedObject()); @@ -421,8 +421,8 @@ template <FX_BOOL ( void JSGlobalFunc(const char* func_name_string, const v8::FunctionCallbackInfo<v8::Value>& info) { v8::Isolate* isolate = info.GetIsolate(); - IFXJS_Runtime* pRuntime = (IFXJS_Runtime*)isolate->GetData(2); - IFXJS_Context* pRuntimeContext = pRuntime->GetCurrentContext(); + FXJS_PerIsolateData* pData = FXJS_PerIsolateData::Get(isolate); + IFXJS_Context* pRuntimeContext = pData->m_pFXJSRuntime->GetCurrentContext(); CJS_Parameters parameters; for (unsigned int i = 0; i < (unsigned int)info.Length(); i++) { parameters.push_back(CJS_Value(isolate, info[i], CJS_Value::VT_unknown)); diff --git a/fpdfsdk/include/jsapi/fxjs_v8.h b/fpdfsdk/include/jsapi/fxjs_v8.h index a1541593a1..a1e3e59797 100644 --- a/fpdfsdk/include/jsapi/fxjs_v8.h +++ b/fpdfsdk/include/jsapi/fxjs_v8.h @@ -11,7 +11,16 @@ #define FPDFSDK_INCLUDE_JSAPI_FXJS_V8_H_ #include <v8.h> -#include "../../../core/include/fxcrt/fx_string.h" // For CFX_WideString +#include "../../../core/include/fxcrt/fx_basic.h" + +// FXJS_V8 places no interpretation on these two classes; it merely +// passes them on to the caller-provided FXJS_CONSTRUCTORs. +class IFXJS_Context; +class IFXJS_Runtime; + +// FXJS_V8 places no interpreation on this calass; it merely passes it +// along to XFA. +class CFXJSE_RuntimeData; enum FXJSOBJTYPE { FXJS_DYNAMIC = 0, @@ -24,6 +33,20 @@ struct FXJSErr { unsigned linnum; }; +class FXJS_PerIsolateData { + public: + static void SetUp(v8::Isolate* pIsolate); + static FXJS_PerIsolateData* Get(v8::Isolate* pIsolate); + + CFX_PtrArray m_ObjectDefnArray; + IFXJS_Runtime* m_pFXJSRuntime; + CFXJSE_RuntimeData* m_pFXJSERuntimeData; + + protected: + FXJS_PerIsolateData() + : m_pFXJSRuntime(nullptr), m_pFXJSERuntimeData(nullptr) {} +}; + extern const wchar_t kFXJSValueNameString[]; extern const wchar_t kFXJSValueNameNumber[]; extern const wchar_t kFXJSValueNameBoolean[]; @@ -33,10 +56,6 @@ extern const wchar_t kFXJSValueNameFxobj[]; extern const wchar_t kFXJSValueNameNull[]; extern const wchar_t kFXJSValueNameUndefined[]; -// FXJS_V8 places no interpretation on these two classes; it merely -// passes them on to the caller-provided FXJS_CONSTRUCTORs. -class IFXJS_Context; -class IFXJS_Runtime; class FXJS_ArrayBufferAllocator : public v8::ArrayBuffer::Allocator { void* Allocate(size_t length) override; diff --git a/fpdfsdk/src/fpdfxfa/fpdfxfa_app.cpp b/fpdfsdk/src/fpdfxfa/fpdfxfa_app.cpp index dc5d0686fc..255d2bb024 100644 --- a/fpdfsdk/src/fpdfxfa/fpdfxfa_app.cpp +++ b/fpdfsdk/src/fpdfxfa/fpdfxfa_app.cpp @@ -28,7 +28,7 @@ void CPDFXFA_App::ReleaseInstance() { }
CPDFXFA_App::CPDFXFA_App()
- : m_bInitRuntime(FALSE),
+ : m_bJavaScriptInitialized(FALSE),
m_pXFAApp(NULL),
m_pFontMgr(NULL),
m_hJSERuntime(NULL),
@@ -70,18 +70,6 @@ FX_BOOL CPDFXFA_App::Initialize() { return TRUE;
}
-FX_BOOL CPDFXFA_App::InitRuntime(FX_BOOL bReset) {
- if (bReset) {
- m_bInitRuntime = FALSE;
- return TRUE;
- }
- if (m_bInitRuntime) {
- return TRUE;
- }
- m_bInitRuntime = TRUE;
- return FALSE;
-}
-
FX_BOOL CPDFXFA_App::AddFormFillEnv(CPDFDoc_Environment* pEnv) {
if (!pEnv)
return FALSE;
@@ -102,10 +90,6 @@ FX_BOOL CPDFXFA_App::RemoveFormFillEnv(CPDFDoc_Environment* pEnv) { return FALSE;
}
-void CPDFXFA_App::ReleaseRuntime() {
- v8::Global<v8::Context> context;
- FXJS_ReleaseRuntime((v8::Isolate*)m_hJSERuntime, context);
-}
void CPDFXFA_App::GetAppType(CFX_WideString& wsAppType) {
wsAppType = m_csAppType;
diff --git a/fpdfsdk/src/fsdk_mgr.cpp b/fpdfsdk/src/fsdk_mgr.cpp index a3e77e4514..346dacce59 100644 --- a/fpdfsdk/src/fsdk_mgr.cpp +++ b/fpdfsdk/src/fsdk_mgr.cpp @@ -222,10 +222,8 @@ CPDFDoc_Environment::~CPDFDoc_Environment() { m_pIFormFiller = NULL; CPDFXFA_App* pProvider = CPDFXFA_App::GetInstance(); - if (pProvider->m_pEnvList.GetSize() == 0) { - pProvider->ReleaseRuntime(); - pProvider->InitRuntime(TRUE); - } + if (pProvider->m_pEnvList.GetSize() == 0) + pProvider->SetJavaScriptInitialized(FALSE); delete m_pSysHandler; m_pSysHandler = NULL; diff --git a/fpdfsdk/src/javascript/JS_Runtime.cpp b/fpdfsdk/src/javascript/JS_Runtime.cpp index e8e48b0c07..9996653215 100644 --- a/fpdfsdk/src/javascript/JS_Runtime.cpp +++ b/fpdfsdk/src/javascript/JS_Runtime.cpp @@ -59,7 +59,7 @@ CJS_Runtime::CJS_Runtime(CPDFDoc_Environment* pApp) v8::Isolate::Scope isolate_scope(isolate); v8::Locker locker(isolate); v8::HandleScope handle_scope(isolate); - if (CPDFXFA_App::GetInstance()->InitRuntime(FALSE)) { + if (CPDFXFA_App::GetInstance()->IsJavaScriptInitialized()) { CJS_Context* pContext = (CJS_Context*)NewContext(); FXJS_InitializeRuntime(GetIsolate(), this, pContext, m_context); ReleaseContext(pContext); @@ -71,6 +71,7 @@ CJS_Runtime::CJS_Runtime(CPDFDoc_Environment* pApp) embedderDataSlot = pApp->GetFormFillInfo()->m_pJsPlatform->m_v8EmbedderSlot; FXJS_Initialize(embedderDataSlot); DefineJSObjects(); + CPDFXFA_App::GetInstance()->SetJavaScriptInitialized(TRUE); CJS_Context* pContext = (CJS_Context*)NewContext(); FXJS_InitializeRuntime(GetIsolate(), this, pContext, m_context); diff --git a/fpdfsdk/src/jsapi/fxjs_v8.cpp b/fpdfsdk/src/jsapi/fxjs_v8.cpp index 6349ca3a6f..1c9bb87883 100644 --- a/fpdfsdk/src/jsapi/fxjs_v8.cpp +++ b/fpdfsdk/src/jsapi/fxjs_v8.cpp @@ -17,22 +17,32 @@ const wchar_t kFXJSValueNameFxobj[] = L"fxobj"; const wchar_t kFXJSValueNameNull[] = L"null"; const wchar_t kFXJSValueNameUndefined[] = L"undefined"; -static unsigned int g_embedderDataSlot = 0u; +static unsigned int g_embedderDataSlot = 1u; class CFXJS_PrivateData { public: - CFXJS_PrivateData() : ObjDefID(-1), pPrivate(NULL) {} + CFXJS_PrivateData(int nObjDefID) : ObjDefID(nObjDefID), pPrivate(NULL) {} + int ObjDefID; void* pPrivate; }; -class CFXJS_ObjDefintion { +class CFXJS_ObjDefinition { public: - CFXJS_ObjDefintion(v8::Isolate* isolate, - const wchar_t* sObjName, - FXJSOBJTYPE eObjType, - FXJS_CONSTRUCTOR pConstructor, - FXJS_DESTRUCTOR pDestructor) + static int MaxID(v8::Isolate* pIsolate) { + return static_cast<int>( + FXJS_PerIsolateData::Get(pIsolate)->m_ObjectDefnArray.GetSize()); + } + static CFXJS_ObjDefinition* ForID(v8::Isolate* pIsolate, int id) { + // Note: GetAt() halts if out-of-range even in release builds. + return static_cast<CFXJS_ObjDefinition*>( + FXJS_PerIsolateData::Get(pIsolate)->m_ObjectDefnArray.GetAt(id)); + } + CFXJS_ObjDefinition(v8::Isolate* isolate, + const wchar_t* sObjName, + FXJSOBJTYPE eObjType, + FXJS_CONSTRUCTOR pConstructor, + FXJS_DESTRUCTOR pDestructor) : objName(sObjName), objType(eObjType), m_pConstructor(pConstructor), @@ -51,12 +61,11 @@ class CFXJS_ObjDefintion { m_bSetAsGlobalObject = TRUE; } } - ~CFXJS_ObjDefintion() { + ~CFXJS_ObjDefinition() { m_objTemplate.Reset(); m_StaticObj.Reset(); } - public: const wchar_t* objName; FXJSOBJTYPE objType; FXJS_CONSTRUCTOR m_pConstructor; @@ -79,9 +88,16 @@ void FXJS_ArrayBufferAllocator::Free(void* data, size_t length) { free(data); } -void FXJS_PrepareIsolate(v8::Isolate* pIsolate) { +// static +void FXJS_PerIsolateData::SetUp(v8::Isolate* pIsolate) { if (!pIsolate->GetData(g_embedderDataSlot)) - pIsolate->SetData(g_embedderDataSlot, new CFX_PtrArray()); + pIsolate->SetData(g_embedderDataSlot, new FXJS_PerIsolateData()); +} + +// static +FXJS_PerIsolateData* FXJS_PerIsolateData::Get(v8::Isolate* pIsolate) { + return static_cast<FXJS_PerIsolateData*>( + pIsolate->GetData(g_embedderDataSlot)); } int FXJS_DefineObj(v8::Isolate* pIsolate, @@ -92,12 +108,11 @@ int FXJS_DefineObj(v8::Isolate* pIsolate, v8::Isolate::Scope isolate_scope(pIsolate); v8::HandleScope handle_scope(pIsolate); - FXJS_PrepareIsolate(pIsolate); - CFX_PtrArray* pArray = (CFX_PtrArray*)pIsolate->GetData(g_embedderDataSlot); - CFXJS_ObjDefintion* pObjDef = new CFXJS_ObjDefintion( - pIsolate, sObjName, eObjType, pConstructor, pDestructor); - pArray->Add(pObjDef); - return pArray->GetSize() - 1; + FXJS_PerIsolateData::SetUp(pIsolate); + FXJS_PerIsolateData* pData = FXJS_PerIsolateData::Get(pIsolate); + pData->m_ObjectDefnArray.Add(new CFXJS_ObjDefinition( + pIsolate, sObjName, eObjType, pConstructor, pDestructor)); + return pData->m_ObjectDefnArray.GetSize() - 1; } void FXJS_DefineObjMethod(v8::Isolate* pIsolate, @@ -107,14 +122,12 @@ void FXJS_DefineObjMethod(v8::Isolate* pIsolate, v8::Isolate::Scope isolate_scope(pIsolate); v8::HandleScope handle_scope(pIsolate); - CFX_WideString ws = CFX_WideString(sMethodName); - CFX_ByteString bsMethodName = ws.UTF8Encode(); - CFX_PtrArray* pArray = (CFX_PtrArray*)pIsolate->GetData(g_embedderDataSlot); - - // Note: GetAt() halts if out-of-range even in release builds. - CFXJS_ObjDefintion* pObjDef = (CFXJS_ObjDefintion*)pArray->GetAt(nObjDefnID); + CFX_ByteString bsMethodName = CFX_WideString(sMethodName).UTF8Encode(); + CFXJS_ObjDefinition* pObjDef = + CFXJS_ObjDefinition::ForID(pIsolate, nObjDefnID); v8::Local<v8::ObjectTemplate> objTemp = v8::Local<v8::ObjectTemplate>::New(pIsolate, pObjDef->m_objTemplate); + objTemp->Set( v8::String::NewFromUtf8(pIsolate, bsMethodName.c_str(), v8::NewStringType::kNormal).ToLocalChecked(), @@ -130,12 +143,9 @@ void FXJS_DefineObjProperty(v8::Isolate* pIsolate, v8::Isolate::Scope isolate_scope(pIsolate); v8::HandleScope handle_scope(pIsolate); - CFX_WideString ws = CFX_WideString(sPropName); - CFX_ByteString bsPropertyName = ws.UTF8Encode(); - CFX_PtrArray* pArray = (CFX_PtrArray*)pIsolate->GetData(g_embedderDataSlot); - - // Note: GetAt() halts if out-of-range even in release builds. - CFXJS_ObjDefintion* pObjDef = (CFXJS_ObjDefintion*)pArray->GetAt(nObjDefnID); + CFX_ByteString bsPropertyName = CFX_WideString(sPropName).UTF8Encode(); + CFXJS_ObjDefinition* pObjDef = + CFXJS_ObjDefinition::ForID(pIsolate, nObjDefnID); v8::Local<v8::ObjectTemplate> objTemp = v8::Local<v8::ObjectTemplate>::New(pIsolate, pObjDef->m_objTemplate); objTemp->SetAccessor( @@ -153,10 +163,9 @@ void FXJS_DefineObjAllProperties(v8::Isolate* pIsolate, v8::NamedPropertyDeleterCallback pPropDel) { v8::Isolate::Scope isolate_scope(pIsolate); v8::HandleScope handle_scope(pIsolate); - CFX_PtrArray* pArray = (CFX_PtrArray*)pIsolate->GetData(g_embedderDataSlot); - // Note: GetAt() halts if out-of-range even in release builds. - CFXJS_ObjDefintion* pObjDef = (CFXJS_ObjDefintion*)pArray->GetAt(nObjDefnID); + CFXJS_ObjDefinition* pObjDef = + CFXJS_ObjDefinition::ForID(pIsolate, nObjDefnID); v8::Local<v8::ObjectTemplate> objTemp = v8::Local<v8::ObjectTemplate>::New(pIsolate, pObjDef->m_objTemplate); objTemp->SetNamedPropertyHandler(pPropGet, pPropPut, pPropQurey, pPropDel); @@ -170,12 +179,9 @@ void FXJS_DefineObjConst(v8::Isolate* pIsolate, v8::Isolate::Scope isolate_scope(pIsolate); v8::HandleScope handle_scope(pIsolate); - CFX_WideString ws = CFX_WideString(sConstName); - CFX_ByteString bsConstName = ws.UTF8Encode(); - CFX_PtrArray* pArray = (CFX_PtrArray*)pIsolate->GetData(g_embedderDataSlot); - - // Note: GetAt() halts if out-of-range even in release builds. - CFXJS_ObjDefintion* pObjDef = (CFXJS_ObjDefintion*)pArray->GetAt(nObjDefnID); + CFX_ByteString bsConstName = CFX_WideString(sConstName).UTF8Encode(); + CFXJS_ObjDefinition* pObjDef = + CFXJS_ObjDefinition::ForID(pIsolate, nObjDefnID); v8::Local<v8::ObjectTemplate> objTemp = v8::Local<v8::ObjectTemplate>::New(pIsolate, pObjDef->m_objTemplate); objTemp->Set(pIsolate, bsConstName.c_str(), pDefault); @@ -187,10 +193,9 @@ static v8::Global<v8::ObjectTemplate>& _getGlobalObjectTemplate( v8::Isolate::Scope isolate_scope(pIsolate); v8::HandleScope handle_scope(pIsolate); - CFX_PtrArray* pArray = (CFX_PtrArray*)pIsolate->GetData(g_embedderDataSlot); - ASSERT(pArray != NULL); - for (int i = 0; i < pArray->GetSize(); i++) { - CFXJS_ObjDefintion* pObjDef = (CFXJS_ObjDefintion*)pArray->GetAt(i); + int maxID = CFXJS_ObjDefinition::MaxID(pIsolate); + for (int i = 0; i < maxID; ++i) { + CFXJS_ObjDefinition* pObjDef = CFXJS_ObjDefinition::ForID(pIsolate, i); if (pObjDef->m_bSetAsGlobalObject) return pObjDef->m_objTemplate; } @@ -204,9 +209,7 @@ void FXJS_DefineGlobalMethod(v8::Isolate* pIsolate, v8::Isolate::Scope isolate_scope(pIsolate); v8::HandleScope handle_scope(pIsolate); - CFX_WideString ws = CFX_WideString(sMethodName); - CFX_ByteString bsMethodName = ws.UTF8Encode(); - + CFX_ByteString bsMethodName = CFX_WideString(sMethodName).UTF8Encode(); v8::Local<v8::FunctionTemplate> funTempl = v8::FunctionTemplate::New(pIsolate, pMethodCall); v8::Local<v8::ObjectTemplate> objTemp; @@ -265,17 +268,13 @@ void FXJS_InitializeRuntime(v8::Isolate* pIsolate, v8::Local<v8::ObjectTemplate>::New(pIsolate, globalObjTemp)); v8::Context::Scope context_scope(v8Context); - // v8::Local<External> ptr = External::New(isolate, pFXRuntime); - // v8Context->SetEmbedderData(1, ptr); - // TODO(tsepez): Don't use more than one embedder data slot. - pIsolate->SetData(2, pFXRuntime); + FXJS_PerIsolateData::SetUp(pIsolate); + FXJS_PerIsolateData* pData = FXJS_PerIsolateData::Get(pIsolate); + pData->m_pFXJSRuntime = pFXRuntime; - CFX_PtrArray* pArray = (CFX_PtrArray*)pIsolate->GetData(g_embedderDataSlot); - if (!pArray) - return; - - for (int i = 0; i < pArray->GetSize(); i++) { - CFXJS_ObjDefintion* pObjDef = (CFXJS_ObjDefintion*)pArray->GetAt(i); + int maxID = CFXJS_ObjDefinition::MaxID(pIsolate); + for (int i = 0; i < maxID; ++i) { + CFXJS_ObjDefinition* pObjDef = CFXJS_ObjDefinition::ForID(pIsolate, i); CFX_WideString ws = CFX_WideString(pObjDef->objName); CFX_ByteString bs = ws.UTF8Encode(); v8::Local<v8::String> objName = @@ -286,14 +285,11 @@ void FXJS_InitializeRuntime(v8::Isolate* pIsolate, if (pObjDef->objType == FXJS_DYNAMIC) { // Document is set as global object, need to construct it first. if (ws.Equal(L"Document")) { - CFXJS_PrivateData* pPrivateData = new CFXJS_PrivateData; - pPrivateData->ObjDefID = i; - v8Context->Global() ->GetPrototype() ->ToObject(v8Context) .ToLocalChecked() - ->SetAlignedPointerInInternalField(0, pPrivateData); + ->SetAlignedPointerInInternalField(0, new CFXJS_PrivateData(i)); if (pObjDef->m_pConstructor) pObjDef->m_pConstructor(context, v8Context->Global() @@ -323,12 +319,16 @@ void FXJS_ReleaseRuntime(v8::Isolate* pIsolate, v8::Local<v8::Context>::New(pIsolate, v8PersistentContext); v8::Context::Scope context_scope(context); - CFX_PtrArray* pArray = (CFX_PtrArray*)pIsolate->GetData(g_embedderDataSlot); - if (!pArray) + FXJS_PerIsolateData* pData = FXJS_PerIsolateData::Get(pIsolate); + if (!pData) return; - for (int i = 0; i < pArray->GetSize(); i++) { - CFXJS_ObjDefintion* pObjDef = (CFXJS_ObjDefintion*)pArray->GetAt(i); + // XFA, if present, should have already cleaned itself up. + FXSYS_assert(!pData->m_pFXJSERuntimeData); + + int maxID = CFXJS_ObjDefinition::MaxID(pIsolate); + for (int i = 0; i < maxID; ++i) { + CFXJS_ObjDefinition* pObjDef = CFXJS_ObjDefinition::ForID(pIsolate, i); if (!pObjDef->m_StaticObj.IsEmpty()) { v8::Local<v8::Object> pObj = v8::Local<v8::Object>::New(pIsolate, pObjDef->m_StaticObj); @@ -338,12 +338,9 @@ void FXJS_ReleaseRuntime(v8::Isolate* pIsolate, } delete pObjDef; } - delete pArray; - pIsolate->SetData(1, NULL); - pIsolate->SetData(g_embedderDataSlot, NULL); - // TODO(tsepez): Don't use more than one embedder data slot. - pIsolate->SetData(2, NULL); + pIsolate->SetData(g_embedderDataSlot, nullptr); + delete pData; } void FXJS_Initialize(unsigned int embedderDataSlot) { @@ -390,7 +387,7 @@ v8::Local<v8::Object> FXJS_NewFxDynamicObj(v8::Isolate* pIsolate, int nObjDefnID) { v8::Isolate::Scope isolate_scope(pIsolate); v8::Local<v8::Context> context = pIsolate->GetCurrentContext(); - if (-1 == nObjDefnID) { + if (nObjDefnID == -1) { v8::Local<v8::ObjectTemplate> objTempl = v8::ObjectTemplate::New(pIsolate); v8::Local<v8::Object> obj; if (objTempl->NewInstance(context).ToLocal(&obj)) @@ -398,13 +395,15 @@ v8::Local<v8::Object> FXJS_NewFxDynamicObj(v8::Isolate* pIsolate, return v8::Local<v8::Object>(); } - CFX_PtrArray* pArray = (CFX_PtrArray*)pIsolate->GetData(g_embedderDataSlot); - if (!pArray) + FXJS_PerIsolateData* pData = FXJS_PerIsolateData::Get(pIsolate); + if (!pData) return v8::Local<v8::Object>(); - if (nObjDefnID < 0 || nObjDefnID >= pArray->GetSize()) + if (nObjDefnID < 0 || nObjDefnID >= CFXJS_ObjDefinition::MaxID(pIsolate)) return v8::Local<v8::Object>(); - CFXJS_ObjDefintion* pObjDef = (CFXJS_ObjDefintion*)pArray->GetAt(nObjDefnID); + + CFXJS_ObjDefinition* pObjDef = + CFXJS_ObjDefinition::ForID(pIsolate, nObjDefnID); v8::Local<v8::ObjectTemplate> objTemp = v8::Local<v8::ObjectTemplate>::New(pIsolate, pObjDef->m_objTemplate); @@ -412,10 +411,7 @@ v8::Local<v8::Object> FXJS_NewFxDynamicObj(v8::Isolate* pIsolate, if (!objTemp->NewInstance(context).ToLocal(&obj)) return v8::Local<v8::Object>(); - CFXJS_PrivateData* pPrivateData = new CFXJS_PrivateData; - pPrivateData->ObjDefID = nObjDefnID; - - obj->SetAlignedPointerInInternalField(0, pPrivateData); + obj->SetAlignedPointerInInternalField(0, new CFXJS_PrivateData(nObjDefnID)); if (pObjDef->m_pConstructor) pObjDef->m_pConstructor( pJSContext, obj, @@ -425,12 +421,11 @@ v8::Local<v8::Object> FXJS_NewFxDynamicObj(v8::Isolate* pIsolate, } v8::Local<v8::Object> FXJS_GetThisObj(v8::Isolate* pIsolate) { - // Return the global object. v8::Isolate::Scope isolate_scope(pIsolate); - CFX_PtrArray* pArray = (CFX_PtrArray*)pIsolate->GetData(g_embedderDataSlot); - if (!pArray) + if (!FXJS_PerIsolateData::Get(pIsolate)) return v8::Local<v8::Object>(); + // Return the global object. v8::Local<v8::Context> context = pIsolate->GetCurrentContext(); return context->Global()->GetPrototype()->ToObject(context).ToLocalChecked(); } @@ -456,12 +451,12 @@ v8::Isolate* FXJS_GetRuntime(v8::Local<v8::Object> pObj) { int FXJS_GetObjDefnID(v8::Isolate* pIsolate, const wchar_t* pObjName) { v8::Isolate::Scope isolate_scope(pIsolate); - CFX_PtrArray* pArray = (CFX_PtrArray*)pIsolate->GetData(g_embedderDataSlot); - if (!pArray) + if (!FXJS_PerIsolateData::Get(pIsolate)) return -1; - for (int i = 0; i < pArray->GetSize(); i++) { - CFXJS_ObjDefintion* pObjDef = (CFXJS_ObjDefintion*)pArray->GetAt(i); + int maxID = CFXJS_ObjDefinition::MaxID(pIsolate); + for (int i = 0; i < maxID; ++i) { + CFXJS_ObjDefinition* pObjDef = CFXJS_ObjDefinition::ForID(pIsolate, i); if (FXSYS_wcscmp(pObjDef->objName, pObjName) == 0) return i; } diff --git a/fpdfsdk/src/jsapi/fxjs_v8_embeddertest.cpp b/fpdfsdk/src/jsapi/fxjs_v8_embeddertest.cpp index 827e96365a..7f65badd9d 100644 --- a/fpdfsdk/src/jsapi/fxjs_v8_embeddertest.cpp +++ b/fpdfsdk/src/jsapi/fxjs_v8_embeddertest.cpp @@ -32,7 +32,7 @@ class FXJSV8Embeddertest : public EmbedderTest { v8::Locker locker(m_pIsolate); v8::HandleScope handle_scope(m_pIsolate); FXJS_Initialize(0); - FXJS_PrepareIsolate(m_pIsolate); + FXJS_PerIsolateData::SetUp(m_pIsolate); FXJS_InitializeRuntime(m_pIsolate, nullptr, nullptr, m_pPersistentContext); } diff --git a/xfa/src/fxjse/src/runtime.cpp b/xfa/src/fxjse/src/runtime.cpp index a7ee67bc2a..4a77b4f165 100644 --- a/xfa/src/fxjse/src/runtime.cpp +++ b/xfa/src/fxjse/src/runtime.cpp @@ -4,6 +4,7 @@ // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+#include "../../../../fpdfsdk/include/jsapi/fxjs_v8.h" // For per-isolate data.
#include "../../foxitlib.h"
#include "fxv8.h"
#include "runtime.h"
@@ -38,11 +39,9 @@ void FXJSE_Initialize() { static void FXJSE_Runtime_DisposeCallback(v8::Isolate* pIsolate) {
{
v8::Locker locker(pIsolate);
- CFXJSE_RuntimeData* pRuntimeData =
- reinterpret_cast<CFXJSE_RuntimeData*>(pIsolate->GetData(0));
- if (pRuntimeData) {
- pIsolate->SetData(0, NULL);
- delete pRuntimeData;
+ if (FXJS_PerIsolateData* pData = FXJS_PerIsolateData::Get(pIsolate)) {
+ delete pData->m_pFXJSERuntimeData;
+ pData->m_pFXJSERuntimeData = nullptr;
}
}
pIsolate->Dispose();
@@ -73,7 +72,6 @@ void FXJSE_Runtime_Release(FXJSE_HRUNTIME hRuntime) { }
CFXJSE_RuntimeData* CFXJSE_RuntimeData::Create(v8::Isolate* pIsolate) {
CFXJSE_RuntimeData* pRuntimeData = new CFXJSE_RuntimeData(pIsolate);
- ASSERT(pRuntimeData);
CFXJSE_ScopeUtil_IsolateHandle scope(pIsolate);
v8::Local<v8::FunctionTemplate> hFuncTemplate =
v8::FunctionTemplate::New(pIsolate);
@@ -85,15 +83,10 @@ CFXJSE_RuntimeData* CFXJSE_RuntimeData::Create(v8::Isolate* pIsolate) { return pRuntimeData;
}
CFXJSE_RuntimeData* CFXJSE_RuntimeData::Get(v8::Isolate* pIsolate) {
- ASSERT(pIsolate);
- CFXJSE_RuntimeData* pRuntimeData =
- static_cast<CFXJSE_RuntimeData*>(pIsolate->GetData(0));
- if (!pRuntimeData) {
- pRuntimeData = CFXJSE_RuntimeData::Create(pIsolate);
- ASSERT(pRuntimeData);
- pIsolate->SetData(0, pRuntimeData);
- }
- return pRuntimeData;
+ FXJS_PerIsolateData* pData = FXJS_PerIsolateData::Get(pIsolate);
+ if (!pData->m_pFXJSERuntimeData)
+ pData->m_pFXJSERuntimeData = CFXJSE_RuntimeData::Create(pIsolate);
+ return pData->m_pFXJSERuntimeData;
}
CFXJSE_RuntimeList* CFXJSE_RuntimeData::g_RuntimeList = NULL;
void CFXJSE_RuntimeList::AppendRuntime(v8::Isolate* pIsolate) {
|