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 "../../include/jsapi/fxjs_v8.h" |
| 8 |
7 #include "../../../core/include/fxcrt/fx_basic.h" | 9 #include "../../../core/include/fxcrt/fx_basic.h" |
8 #include "../../include/jsapi/fxjs_v8.h" | |
9 | 10 |
10 const wchar_t kFXJSValueNameString[] = L"string"; | 11 const wchar_t kFXJSValueNameString[] = L"string"; |
11 const wchar_t kFXJSValueNameNumber[] = L"number"; | 12 const wchar_t kFXJSValueNameNumber[] = L"number"; |
12 const wchar_t kFXJSValueNameBoolean[] = L"boolean"; | 13 const wchar_t kFXJSValueNameBoolean[] = L"boolean"; |
13 const wchar_t kFXJSValueNameDate[] = L"date"; | 14 const wchar_t kFXJSValueNameDate[] = L"date"; |
14 const wchar_t kFXJSValueNameObject[] = L"object"; | 15 const wchar_t kFXJSValueNameObject[] = L"object"; |
15 const wchar_t kFXJSValueNameFxobj[] = L"fxobj"; | 16 const wchar_t kFXJSValueNameFxobj[] = L"fxobj"; |
16 const wchar_t kFXJSValueNameNull[] = L"null"; | 17 const wchar_t kFXJSValueNameNull[] = L"null"; |
17 const wchar_t kFXJSValueNameUndefined[] = L"undefined"; | 18 const wchar_t kFXJSValueNameUndefined[] = L"undefined"; |
18 | 19 |
19 // Keep this consistent with the values defined in gin/public/context_holder.h | 20 // Keep this consistent with the values defined in gin/public/context_holder.h |
20 // (without actually requiring a dependency on gin itself for the standalone | 21 // (without actually requiring a dependency on gin itself for the standalone |
21 // embedders of PDFIum). The value we want to use is: | 22 // embedders of PDFIum). The value we want to use is: |
22 // kPerContextDataStartIndex + kEmbedderPDFium, which is 3. | 23 // kPerContextDataStartIndex + kEmbedderPDFium, which is 3. |
23 static const unsigned int kPerContextDataIndex = 3u; | 24 static const unsigned int kPerContextDataIndex = 3u; |
24 static unsigned int g_embedderDataSlot = 1u; | 25 static unsigned int g_embedderDataSlot = 1u; |
25 static v8::Isolate* g_isolate = nullptr; | 26 static v8::Isolate* g_isolate = nullptr; |
| 27 static size_t g_isolate_ref_count = 0; |
26 static FXJS_ArrayBufferAllocator* g_arrayBufferAllocator = nullptr; | 28 static FXJS_ArrayBufferAllocator* g_arrayBufferAllocator = nullptr; |
27 static v8::Global<v8::ObjectTemplate>* g_DefaultGlobalObjectTemplate = nullptr; | 29 static v8::Global<v8::ObjectTemplate>* g_DefaultGlobalObjectTemplate = nullptr; |
28 | 30 |
29 class CFXJS_PrivateData { | 31 class CFXJS_PrivateData { |
30 public: | 32 public: |
31 CFXJS_PrivateData(int nObjDefID) : ObjDefID(nObjDefID), pPrivate(NULL) {} | 33 CFXJS_PrivateData(int nObjDefID) : ObjDefID(nObjDefID), pPrivate(NULL) {} |
32 | 34 |
33 int ObjDefID; | 35 int ObjDefID; |
34 void* pPrivate; | 36 void* pPrivate; |
35 }; | 37 }; |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 | 119 |
118 void* FXJS_ArrayBufferAllocator::AllocateUninitialized(size_t length) { | 120 void* FXJS_ArrayBufferAllocator::AllocateUninitialized(size_t length) { |
119 return malloc(length); | 121 return malloc(length); |
120 } | 122 } |
121 | 123 |
122 void FXJS_ArrayBufferAllocator::Free(void* data, size_t length) { | 124 void FXJS_ArrayBufferAllocator::Free(void* data, size_t length) { |
123 free(data); | 125 free(data); |
124 } | 126 } |
125 | 127 |
126 void FXJS_Initialize(unsigned int embedderDataSlot, v8::Isolate* pIsolate) { | 128 void FXJS_Initialize(unsigned int embedderDataSlot, v8::Isolate* pIsolate) { |
| 129 if (g_isolate) { |
| 130 ASSERT(g_embedderDataSlot == embedderDataSlot); |
| 131 ASSERT(g_isolate == pIsolate); |
| 132 return; |
| 133 } |
127 g_embedderDataSlot = embedderDataSlot; | 134 g_embedderDataSlot = embedderDataSlot; |
128 g_isolate = pIsolate; | 135 g_isolate = pIsolate; |
129 } | 136 } |
130 | 137 |
131 void FXJS_Release() { | 138 void FXJS_Release() { |
| 139 ASSERT(!g_isolate || g_isolate_ref_count == 0); |
132 g_DefaultGlobalObjectTemplate = nullptr; | 140 g_DefaultGlobalObjectTemplate = nullptr; |
133 g_isolate = nullptr; | 141 g_isolate = nullptr; |
134 | 142 |
135 delete g_arrayBufferAllocator; | 143 delete g_arrayBufferAllocator; |
136 g_arrayBufferAllocator = nullptr; | 144 g_arrayBufferAllocator = nullptr; |
137 } | 145 } |
138 | 146 |
139 bool FXJS_GetIsolate(v8::Isolate** pResultIsolate) { | 147 bool FXJS_GetIsolate(v8::Isolate** pResultIsolate) { |
140 if (g_isolate) { | 148 if (g_isolate) { |
141 *pResultIsolate = g_isolate; | 149 *pResultIsolate = g_isolate; |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
256 GetGlobalObjectTemplate(pIsolate)->Set( | 264 GetGlobalObjectTemplate(pIsolate)->Set( |
257 v8::String::NewFromUtf8(pIsolate, bsConst.c_str(), | 265 v8::String::NewFromUtf8(pIsolate, bsConst.c_str(), |
258 v8::NewStringType::kNormal).ToLocalChecked(), | 266 v8::NewStringType::kNormal).ToLocalChecked(), |
259 pDefault, v8::ReadOnly); | 267 pDefault, v8::ReadOnly); |
260 } | 268 } |
261 | 269 |
262 void FXJS_InitializeRuntime(v8::Isolate* pIsolate, | 270 void FXJS_InitializeRuntime(v8::Isolate* pIsolate, |
263 IFXJS_Runtime* pFXRuntime, | 271 IFXJS_Runtime* pFXRuntime, |
264 IFXJS_Context* context, | 272 IFXJS_Context* context, |
265 v8::Global<v8::Context>& v8PersistentContext) { | 273 v8::Global<v8::Context>& v8PersistentContext) { |
| 274 if (pIsolate == g_isolate) |
| 275 ++g_isolate_ref_count; |
| 276 |
266 v8::Isolate::Scope isolate_scope(pIsolate); | 277 v8::Isolate::Scope isolate_scope(pIsolate); |
267 v8::Locker locker(pIsolate); | 278 v8::Locker locker(pIsolate); |
268 v8::HandleScope handle_scope(pIsolate); | 279 v8::HandleScope handle_scope(pIsolate); |
269 v8::Local<v8::Context> v8Context = | 280 v8::Local<v8::Context> v8Context = |
270 v8::Context::New(pIsolate, NULL, GetGlobalObjectTemplate(pIsolate)); | 281 v8::Context::New(pIsolate, NULL, GetGlobalObjectTemplate(pIsolate)); |
271 v8::Context::Scope context_scope(v8Context); | 282 v8::Context::Scope context_scope(v8Context); |
272 | 283 |
273 FXJS_PerIsolateData::SetUp(pIsolate); | 284 FXJS_PerIsolateData::SetUp(pIsolate); |
274 v8Context->SetAlignedPointerInEmbedderData(kPerContextDataIndex, pFXRuntime); | 285 v8Context->SetAlignedPointerInEmbedderData(kPerContextDataIndex, pFXRuntime); |
275 | 286 |
276 int maxID = CFXJS_ObjDefinition::MaxID(pIsolate); | 287 int maxID = CFXJS_ObjDefinition::MaxID(pIsolate); |
277 for (int i = 0; i < maxID; ++i) { | 288 for (int i = 0; i < maxID; ++i) { |
278 CFXJS_ObjDefinition* pObjDef = CFXJS_ObjDefinition::ForID(pIsolate, i); | 289 CFXJS_ObjDefinition* pObjDef = CFXJS_ObjDefinition::ForID(pIsolate, i); |
279 CFX_ByteString bs = CFX_WideString(pObjDef->m_ObjName).UTF8Encode(); | 290 CFX_ByteString bs = CFX_WideString(pObjDef->m_ObjName).UTF8Encode(); |
280 v8::Local<v8::String> m_ObjName = | 291 v8::Local<v8::String> m_ObjName = |
281 v8::String::NewFromUtf8(pIsolate, bs.c_str(), | 292 v8::String::NewFromUtf8(pIsolate, bs.c_str(), |
282 v8::NewStringType::kNormal, | 293 v8::NewStringType::kNormal, |
283 bs.GetLength()).ToLocalChecked(); | 294 bs.GetLength()).ToLocalChecked(); |
284 | 295 |
285 if (pObjDef->m_ObjType == FXJSOBJTYPE_GLOBAL) { | 296 if (pObjDef->m_ObjType == FXJSOBJTYPE_GLOBAL) { |
286 v8Context->Global() | 297 v8Context->Global() |
287 ->GetPrototype() | 298 ->GetPrototype() |
288 ->ToObject(v8Context) | 299 ->ToObject(v8Context) |
289 .ToLocalChecked() | 300 .ToLocalChecked() |
290 ->SetAlignedPointerInInternalField(0, new CFXJS_PrivateData(i)); | 301 ->SetAlignedPointerInInternalField(0, new CFXJS_PrivateData(i)); |
291 | 302 |
292 if (pObjDef->m_pConstructor) | 303 if (pObjDef->m_pConstructor) { |
293 pObjDef->m_pConstructor(context, v8Context->Global() | 304 pObjDef->m_pConstructor(context, v8Context->Global() |
294 ->GetPrototype() | 305 ->GetPrototype() |
295 ->ToObject(v8Context) | 306 ->ToObject(v8Context) |
296 .ToLocalChecked()); | 307 .ToLocalChecked()); |
| 308 } |
297 } else if (pObjDef->m_ObjType == FXJSOBJTYPE_STATIC) { | 309 } else if (pObjDef->m_ObjType == FXJSOBJTYPE_STATIC) { |
298 v8::Local<v8::Object> obj = FXJS_NewFxDynamicObj(pIsolate, context, i); | 310 v8::Local<v8::Object> obj = FXJS_NewFxDynamicObj(pIsolate, context, i); |
299 v8Context->Global()->Set(v8Context, m_ObjName, obj).FromJust(); | 311 v8Context->Global()->Set(v8Context, m_ObjName, obj).FromJust(); |
300 pObjDef->m_StaticObj.Reset(pIsolate, obj); | 312 pObjDef->m_StaticObj.Reset(pIsolate, obj); |
301 } | 313 } |
302 } | 314 } |
303 v8PersistentContext.Reset(pIsolate, v8Context); | 315 v8PersistentContext.Reset(pIsolate, v8Context); |
304 } | 316 } |
305 | 317 |
306 void FXJS_ReleaseRuntime(v8::Isolate* pIsolate, | 318 void FXJS_ReleaseRuntime(v8::Isolate* pIsolate, |
307 v8::Global<v8::Context>& v8PersistentContext) { | 319 v8::Global<v8::Context>& v8PersistentContext) { |
| 320 if (pIsolate == g_isolate && --g_isolate_ref_count > 0) |
| 321 return; |
| 322 |
308 v8::Isolate::Scope isolate_scope(pIsolate); | 323 v8::Isolate::Scope isolate_scope(pIsolate); |
309 v8::Locker locker(pIsolate); | 324 v8::Locker locker(pIsolate); |
310 v8::HandleScope handle_scope(pIsolate); | 325 v8::HandleScope handle_scope(pIsolate); |
311 v8::Local<v8::Context> context = | 326 v8::Local<v8::Context> context = |
312 v8::Local<v8::Context>::New(pIsolate, v8PersistentContext); | 327 v8::Local<v8::Context>::New(pIsolate, v8PersistentContext); |
313 v8::Context::Scope context_scope(context); | 328 v8::Context::Scope context_scope(context); |
314 | 329 |
315 FXJS_PerIsolateData* pData = FXJS_PerIsolateData::Get(pIsolate); | 330 FXJS_PerIsolateData* pData = FXJS_PerIsolateData::Get(pIsolate); |
316 if (!pData) | 331 if (!pData) |
317 return; | 332 return; |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
479 if (pObj.IsEmpty()) | 494 if (pObj.IsEmpty()) |
480 return nullptr; | 495 return nullptr; |
481 CFXJS_PrivateData* pPrivateData = nullptr; | 496 CFXJS_PrivateData* pPrivateData = nullptr; |
482 if (pObj->InternalFieldCount()) { | 497 if (pObj->InternalFieldCount()) { |
483 pPrivateData = | 498 pPrivateData = |
484 (CFXJS_PrivateData*)pObj->GetAlignedPointerFromInternalField(0); | 499 (CFXJS_PrivateData*)pObj->GetAlignedPointerFromInternalField(0); |
485 } else { | 500 } else { |
486 // It could be a global proxy object. | 501 // It could be a global proxy object. |
487 v8::Local<v8::Value> v = pObj->GetPrototype(); | 502 v8::Local<v8::Value> v = pObj->GetPrototype(); |
488 v8::Local<v8::Context> context = pIsolate->GetCurrentContext(); | 503 v8::Local<v8::Context> context = pIsolate->GetCurrentContext(); |
489 if (v->IsObject()) | 504 if (v->IsObject()) { |
490 pPrivateData = (CFXJS_PrivateData*)v->ToObject(context) | 505 pPrivateData = (CFXJS_PrivateData*)v->ToObject(context) |
491 .ToLocalChecked() | 506 .ToLocalChecked() |
492 ->GetAlignedPointerFromInternalField(0); | 507 ->GetAlignedPointerFromInternalField(0); |
| 508 } |
493 } | 509 } |
494 return pPrivateData ? pPrivateData->pPrivate : nullptr; | 510 return pPrivateData ? pPrivateData->pPrivate : nullptr; |
495 } | 511 } |
496 | 512 |
497 void FXJS_FreePrivate(void* pPrivateData) { | 513 void FXJS_FreePrivate(void* pPrivateData) { |
498 delete (CFXJS_PrivateData*)pPrivateData; | 514 delete (CFXJS_PrivateData*)pPrivateData; |
499 } | 515 } |
500 | 516 |
501 void FXJS_FreePrivate(v8::Local<v8::Object> pObj) { | 517 void FXJS_FreePrivate(v8::Local<v8::Object> pObj) { |
502 if (pObj.IsEmpty() || !pObj->InternalFieldCount()) | 518 if (pObj.IsEmpty() || !pObj->InternalFieldCount()) |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
733 return v8::Local<v8::Array>(); | 749 return v8::Local<v8::Array>(); |
734 v8::Local<v8::Context> context = pIsolate->GetCurrentContext(); | 750 v8::Local<v8::Context> context = pIsolate->GetCurrentContext(); |
735 return v8::Local<v8::Array>::Cast(pValue->ToObject(context).ToLocalChecked()); | 751 return v8::Local<v8::Array>::Cast(pValue->ToObject(context).ToLocalChecked()); |
736 } | 752 } |
737 | 753 |
738 void FXJS_ValueCopy(v8::Local<v8::Value>& pTo, v8::Local<v8::Value> pFrom) { | 754 void FXJS_ValueCopy(v8::Local<v8::Value>& pTo, v8::Local<v8::Value> pFrom) { |
739 pTo = pFrom; | 755 pTo = pFrom; |
740 } | 756 } |
741 | 757 |
742 | 758 |
OLD | NEW |