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 |