| OLD | NEW |
| 1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
| 6 | 6 |
| 7 #include "fpdfsdk/jsapi/include/fxjs_v8.h" | 7 #include "fpdfsdk/jsapi/include/fxjs_v8.h" |
| 8 | 8 |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| 11 #include "core/fxcrt/include/fx_basic.h" | 11 #include "core/fxcrt/include/fx_basic.h" |
| 12 | 12 |
| 13 const wchar_t kFXJSValueNameString[] = L"string"; | 13 const wchar_t kFXJSValueNameString[] = L"string"; |
| 14 const wchar_t kFXJSValueNameNumber[] = L"number"; | 14 const wchar_t kFXJSValueNameNumber[] = L"number"; |
| 15 const wchar_t kFXJSValueNameBoolean[] = L"boolean"; | 15 const wchar_t kFXJSValueNameBoolean[] = L"boolean"; |
| 16 const wchar_t kFXJSValueNameDate[] = L"date"; | 16 const wchar_t kFXJSValueNameDate[] = L"date"; |
| 17 const wchar_t kFXJSValueNameObject[] = L"object"; | 17 const wchar_t kFXJSValueNameObject[] = L"object"; |
| 18 const wchar_t kFXJSValueNameFxobj[] = L"fxobj"; | 18 const wchar_t kFXJSValueNameFxobj[] = L"fxobj"; |
| 19 const wchar_t kFXJSValueNameNull[] = L"null"; | 19 const wchar_t kFXJSValueNameNull[] = L"null"; |
| 20 const wchar_t kFXJSValueNameUndefined[] = L"undefined"; | 20 const wchar_t kFXJSValueNameUndefined[] = L"undefined"; |
| 21 | 21 |
| 22 // Keep this consistent with the values defined in gin/public/context_holder.h | 22 // Keep this consistent with the values defined in gin/public/context_holder.h |
| 23 // (without actually requiring a dependency on gin itself for the standalone | 23 // (without actually requiring a dependency on gin itself for the standalone |
| 24 // embedders of PDFIum). The value we want to use is: | 24 // embedders of PDFIum). The value we want to use is: |
| 25 // kPerContextDataStartIndex + kEmbedderPDFium, which is 3. | 25 // kPerContextDataStartIndex + kEmbedderPDFium, which is 3. |
| 26 static const unsigned int kPerContextDataIndex = 3u; | 26 static const unsigned int kPerContextDataIndex = 3u; |
| 27 static unsigned int g_embedderDataSlot = 1u; | |
| 28 static v8::Isolate* g_isolate = nullptr; | 27 static v8::Isolate* g_isolate = nullptr; |
| 29 static size_t g_isolate_ref_count = 0; | 28 static size_t g_isolate_ref_count = 0; |
| 30 static FXJS_ArrayBufferAllocator* g_arrayBufferAllocator = nullptr; | 29 static FXJS_ArrayBufferAllocator* g_arrayBufferAllocator = nullptr; |
| 31 static v8::Global<v8::ObjectTemplate>* g_DefaultGlobalObjectTemplate = nullptr; | 30 static v8::Global<v8::ObjectTemplate>* g_DefaultGlobalObjectTemplate = nullptr; |
| 32 | 31 |
| 33 class CFXJS_PerObjectData { | 32 class CFXJS_PerObjectData { |
| 34 public: | 33 public: |
| 35 explicit CFXJS_PerObjectData(int nObjDefID) | 34 explicit CFXJS_PerObjectData(int nObjDefID) |
| 36 : m_ObjDefID(nObjDefID), m_pPrivate(nullptr) {} | 35 : m_ObjDefID(nObjDefID), m_pPrivate(nullptr) {} |
| 37 | 36 |
| 38 const int m_ObjDefID; | 37 const int m_ObjDefID; |
| 39 void* m_pPrivate; | 38 void* m_pPrivate; |
| 40 }; | 39 }; |
| 41 | 40 |
| 42 class CFXJS_ObjDefinition { | |
| 43 public: | |
| 44 static int MaxID(v8::Isolate* pIsolate) { | |
| 45 return FXJS_PerIsolateData::Get(pIsolate)->m_ObjectDefnArray.size(); | |
| 46 } | |
| 47 | |
| 48 static CFXJS_ObjDefinition* ForID(v8::Isolate* pIsolate, int id) { | |
| 49 // Note: GetAt() halts if out-of-range even in release builds. | |
| 50 return FXJS_PerIsolateData::Get(pIsolate)->m_ObjectDefnArray[id]; | |
| 51 } | |
| 52 | |
| 53 CFXJS_ObjDefinition(v8::Isolate* isolate, | |
| 54 const wchar_t* sObjName, | |
| 55 FXJSOBJTYPE eObjType, | |
| 56 FXJS_CONSTRUCTOR pConstructor, | |
| 57 FXJS_DESTRUCTOR pDestructor) | |
| 58 : m_ObjName(sObjName), | |
| 59 m_ObjType(eObjType), | |
| 60 m_pConstructor(pConstructor), | |
| 61 m_pDestructor(pDestructor), | |
| 62 m_pIsolate(isolate) { | |
| 63 v8::Isolate::Scope isolate_scope(isolate); | |
| 64 v8::HandleScope handle_scope(isolate); | |
| 65 | |
| 66 v8::Local<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(isolate); | |
| 67 fun->InstanceTemplate()->SetInternalFieldCount(2); | |
| 68 m_FunctionTemplate.Reset(isolate, fun); | |
| 69 | |
| 70 v8::Local<v8::Signature> sig = v8::Signature::New(isolate, fun); | |
| 71 m_Signature.Reset(isolate, sig); | |
| 72 } | |
| 73 | |
| 74 int AssignID() { | |
| 75 FXJS_PerIsolateData* pData = FXJS_PerIsolateData::Get(m_pIsolate); | |
| 76 pData->m_ObjectDefnArray.push_back(this); | |
| 77 return pData->m_ObjectDefnArray.size() - 1; | |
| 78 } | |
| 79 | |
| 80 v8::Local<v8::ObjectTemplate> GetInstanceTemplate() { | |
| 81 v8::EscapableHandleScope scope(m_pIsolate); | |
| 82 v8::Local<v8::FunctionTemplate> function = | |
| 83 m_FunctionTemplate.Get(m_pIsolate); | |
| 84 return scope.Escape(function->InstanceTemplate()); | |
| 85 } | |
| 86 | |
| 87 v8::Local<v8::Signature> GetSignature() { | |
| 88 v8::EscapableHandleScope scope(m_pIsolate); | |
| 89 return scope.Escape(m_Signature.Get(m_pIsolate)); | |
| 90 } | |
| 91 | |
| 92 const wchar_t* const m_ObjName; | |
| 93 const FXJSOBJTYPE m_ObjType; | |
| 94 const FXJS_CONSTRUCTOR m_pConstructor; | |
| 95 const FXJS_DESTRUCTOR m_pDestructor; | |
| 96 | |
| 97 v8::Isolate* m_pIsolate; | |
| 98 v8::Global<v8::FunctionTemplate> m_FunctionTemplate; | |
| 99 v8::Global<v8::Signature> m_Signature; | |
| 100 }; | |
| 101 | |
| 102 static v8::Local<v8::ObjectTemplate> GetGlobalObjectTemplate( | 41 static v8::Local<v8::ObjectTemplate> GetGlobalObjectTemplate( |
| 103 v8::Isolate* pIsolate) { | 42 v8::Isolate* pIsolate) { |
| 104 int maxID = CFXJS_ObjDefinition::MaxID(pIsolate); | 43 int maxID = CFXJS_ObjDefinition::MaxID(pIsolate); |
| 105 for (int i = 0; i < maxID; ++i) { | 44 for (int i = 0; i < maxID; ++i) { |
| 106 CFXJS_ObjDefinition* pObjDef = CFXJS_ObjDefinition::ForID(pIsolate, i); | 45 CFXJS_ObjDefinition* pObjDef = CFXJS_ObjDefinition::ForID(pIsolate, i); |
| 107 if (pObjDef->m_ObjType == FXJSOBJTYPE_GLOBAL) | 46 if (pObjDef->m_ObjType == FXJSOBJTYPE_GLOBAL) |
| 108 return pObjDef->GetInstanceTemplate(); | 47 return pObjDef->GetInstanceTemplate(); |
| 109 } | 48 } |
| 110 if (!g_DefaultGlobalObjectTemplate) { | 49 if (!g_DefaultGlobalObjectTemplate) { |
| 111 g_DefaultGlobalObjectTemplate = new v8::Global<v8::ObjectTemplate>; | 50 g_DefaultGlobalObjectTemplate = new v8::Global<v8::ObjectTemplate>; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 | 86 |
| 148 V8TemplateMapTraits::MapType* V8TemplateMapTraits::MapFromWeakCallbackInfo( | 87 V8TemplateMapTraits::MapType* V8TemplateMapTraits::MapFromWeakCallbackInfo( |
| 149 const v8::WeakCallbackInfo<WeakCallbackDataType>& data) { | 88 const v8::WeakCallbackInfo<WeakCallbackDataType>& data) { |
| 150 V8TemplateMap* pMap = | 89 V8TemplateMap* pMap = |
| 151 (FXJS_PerIsolateData::Get(data.GetIsolate()))->m_pDynamicObjsMap; | 90 (FXJS_PerIsolateData::Get(data.GetIsolate()))->m_pDynamicObjsMap; |
| 152 return pMap ? &pMap->m_map : nullptr; | 91 return pMap ? &pMap->m_map : nullptr; |
| 153 } | 92 } |
| 154 | 93 |
| 155 void FXJS_Initialize(unsigned int embedderDataSlot, v8::Isolate* pIsolate) { | 94 void FXJS_Initialize(unsigned int embedderDataSlot, v8::Isolate* pIsolate) { |
| 156 if (g_isolate) { | 95 if (g_isolate) { |
| 157 ASSERT(g_embedderDataSlot == embedderDataSlot); | 96 ASSERT(FXJS_PerIsolateData::EmbedderDataSlot() == embedderDataSlot); |
| 158 ASSERT(g_isolate == pIsolate); | 97 ASSERT(g_isolate == pIsolate); |
| 159 return; | 98 return; |
| 160 } | 99 } |
| 161 g_embedderDataSlot = embedderDataSlot; | 100 FXJS_PerIsolateData::SetEmbedderDataSlot(embedderDataSlot); |
| 162 g_isolate = pIsolate; | 101 g_isolate = pIsolate; |
| 163 } | 102 } |
| 164 | 103 |
| 165 void FXJS_Release() { | 104 void FXJS_Release() { |
| 166 ASSERT(!g_isolate || g_isolate_ref_count == 0); | 105 ASSERT(!g_isolate || g_isolate_ref_count == 0); |
| 167 delete g_DefaultGlobalObjectTemplate; | 106 delete g_DefaultGlobalObjectTemplate; |
| 168 g_DefaultGlobalObjectTemplate = nullptr; | 107 g_DefaultGlobalObjectTemplate = nullptr; |
| 169 g_isolate = nullptr; | 108 g_isolate = nullptr; |
| 170 | 109 |
| 171 delete g_arrayBufferAllocator; | 110 delete g_arrayBufferAllocator; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 183 v8::Isolate::CreateParams params; | 122 v8::Isolate::CreateParams params; |
| 184 params.array_buffer_allocator = g_arrayBufferAllocator; | 123 params.array_buffer_allocator = g_arrayBufferAllocator; |
| 185 *pResultIsolate = v8::Isolate::New(params); | 124 *pResultIsolate = v8::Isolate::New(params); |
| 186 return true; | 125 return true; |
| 187 } | 126 } |
| 188 | 127 |
| 189 size_t FXJS_GlobalIsolateRefCount() { | 128 size_t FXJS_GlobalIsolateRefCount() { |
| 190 return g_isolate_ref_count; | 129 return g_isolate_ref_count; |
| 191 } | 130 } |
| 192 | 131 |
| 193 // static | |
| 194 void FXJS_PerIsolateData::SetUp(v8::Isolate* pIsolate) { | |
| 195 if (!pIsolate->GetData(g_embedderDataSlot)) | |
| 196 pIsolate->SetData(g_embedderDataSlot, new FXJS_PerIsolateData()); | |
| 197 } | |
| 198 | |
| 199 // static | |
| 200 FXJS_PerIsolateData* FXJS_PerIsolateData::Get(v8::Isolate* pIsolate) { | |
| 201 return static_cast<FXJS_PerIsolateData*>( | |
| 202 pIsolate->GetData(g_embedderDataSlot)); | |
| 203 } | |
| 204 | |
| 205 int FXJS_DefineObj(v8::Isolate* pIsolate, | 132 int FXJS_DefineObj(v8::Isolate* pIsolate, |
| 206 const wchar_t* sObjName, | 133 const wchar_t* sObjName, |
| 207 FXJSOBJTYPE eObjType, | 134 FXJSOBJTYPE eObjType, |
| 208 FXJS_CONSTRUCTOR pConstructor, | 135 FXJS_CONSTRUCTOR pConstructor, |
| 209 FXJS_DESTRUCTOR pDestructor) { | 136 FXJS_DESTRUCTOR pDestructor) { |
| 210 v8::Isolate::Scope isolate_scope(pIsolate); | 137 v8::Isolate::Scope isolate_scope(pIsolate); |
| 211 v8::HandleScope handle_scope(pIsolate); | 138 v8::HandleScope handle_scope(pIsolate); |
| 212 | 139 |
| 213 FXJS_PerIsolateData::SetUp(pIsolate); | 140 FXJS_PerIsolateData::SetUp(pIsolate); |
| 214 CFXJS_ObjDefinition* pObjDef = new CFXJS_ObjDefinition( | 141 CFXJS_ObjDefinition* pObjDef = new CFXJS_ObjDefinition( |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 389 } | 316 } |
| 390 } | 317 } |
| 391 | 318 |
| 392 if (pIsolate == g_isolate && --g_isolate_ref_count > 0) | 319 if (pIsolate == g_isolate && --g_isolate_ref_count > 0) |
| 393 return; | 320 return; |
| 394 | 321 |
| 395 pData->ReleaseDynamicObjsMap(); | 322 pData->ReleaseDynamicObjsMap(); |
| 396 for (int i = 0; i < maxID; ++i) | 323 for (int i = 0; i < maxID; ++i) |
| 397 delete CFXJS_ObjDefinition::ForID(pIsolate, i); | 324 delete CFXJS_ObjDefinition::ForID(pIsolate, i); |
| 398 | 325 |
| 399 pIsolate->SetData(g_embedderDataSlot, nullptr); | 326 pIsolate->SetData(FXJS_PerIsolateData::EmbedderDataSlot(), nullptr); |
| 400 delete pData; | 327 delete pData; |
| 401 } | 328 } |
| 402 | 329 |
| 403 IJS_Runtime* FXJS_GetRuntimeFromIsolate(v8::Isolate* pIsolate) { | 330 IJS_Runtime* FXJS_GetRuntimeFromIsolate(v8::Isolate* pIsolate) { |
| 404 v8::Local<v8::Context> context = pIsolate->GetCurrentContext(); | 331 v8::Local<v8::Context> context = pIsolate->GetCurrentContext(); |
| 405 return static_cast<IJS_Runtime*>( | 332 return static_cast<IJS_Runtime*>( |
| 406 context->GetAlignedPointerFromEmbedderData(kPerContextDataIndex)); | 333 context->GetAlignedPointerFromEmbedderData(kPerContextDataIndex)); |
| 407 } | 334 } |
| 408 | 335 |
| 409 #ifdef PDF_ENABLE_XFA | 336 #ifdef PDF_ENABLE_XFA |
| (...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 807 v8::Local<v8::Value> pValue) { | 734 v8::Local<v8::Value> pValue) { |
| 808 if (pValue.IsEmpty()) | 735 if (pValue.IsEmpty()) |
| 809 return v8::Local<v8::Array>(); | 736 return v8::Local<v8::Array>(); |
| 810 v8::Local<v8::Context> context = pIsolate->GetCurrentContext(); | 737 v8::Local<v8::Context> context = pIsolate->GetCurrentContext(); |
| 811 return v8::Local<v8::Array>::Cast(pValue->ToObject(context).ToLocalChecked()); | 738 return v8::Local<v8::Array>::Cast(pValue->ToObject(context).ToLocalChecked()); |
| 812 } | 739 } |
| 813 | 740 |
| 814 void FXJS_ValueCopy(v8::Local<v8::Value>& pTo, v8::Local<v8::Value> pFrom) { | 741 void FXJS_ValueCopy(v8::Local<v8::Value>& pTo, v8::Local<v8::Value> pFrom) { |
| 815 pTo = pFrom; | 742 pTo = pFrom; |
| 816 } | 743 } |
| OLD | NEW |