Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(871)

Side by Side Diff: fpdfsdk/src/jsapi/fxjs_v8.cpp

Issue 1377463005: Refcount external V8 isolate initialization / release. (Closed) Base URL: https://pdfium.googlesource.com/pdfium@master
Patch Set: Add another sanity check Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 127
126 void* FXJS_ArrayBufferAllocator::AllocateUninitialized(size_t length) { 128 void* FXJS_ArrayBufferAllocator::AllocateUninitialized(size_t length) {
127 return malloc(length); 129 return malloc(length);
128 } 130 }
129 131
130 void FXJS_ArrayBufferAllocator::Free(void* data, size_t length) { 132 void FXJS_ArrayBufferAllocator::Free(void* data, size_t length) {
131 free(data); 133 free(data);
132 } 134 }
133 135
134 void FXJS_Initialize(unsigned int embedderDataSlot, v8::Isolate* pIsolate) { 136 void FXJS_Initialize(unsigned int embedderDataSlot, v8::Isolate* pIsolate) {
137 if (g_isolate) {
138 ASSERT(g_embedderDataSlot == embedderDataSlot);
139 ASSERT(g_isolate == pIsolate);
140 return;
141 }
135 g_embedderDataSlot = embedderDataSlot; 142 g_embedderDataSlot = embedderDataSlot;
136 g_isolate = pIsolate; 143 g_isolate = pIsolate;
137 } 144 }
138 145
139 void FXJS_Release() { 146 void FXJS_Release() {
147 ASSERT(!g_isolate || (g_isolate_ref_count == 0));
Tom Sepez 2015/10/03 16:45:40 nit: overparenthesized.
Lei Zhang 2015/10/03 16:54:27 Done.
140 g_DefaultGlobalObjectTemplate = nullptr; 148 g_DefaultGlobalObjectTemplate = nullptr;
141 g_isolate = nullptr; 149 g_isolate = nullptr;
142 150
143 delete g_arrayBufferAllocator; 151 delete g_arrayBufferAllocator;
144 g_arrayBufferAllocator = nullptr; 152 g_arrayBufferAllocator = nullptr;
145 } 153 }
146 154
147 bool FXJS_GetIsolate(v8::Isolate** pResultIsolate) { 155 bool FXJS_GetIsolate(v8::Isolate** pResultIsolate) {
148 if (g_isolate) { 156 if (g_isolate) {
149 *pResultIsolate = g_isolate; 157 *pResultIsolate = g_isolate;
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 GetGlobalObjectTemplate(pIsolate)->Set( 272 GetGlobalObjectTemplate(pIsolate)->Set(
265 v8::String::NewFromUtf8(pIsolate, bsConst.c_str(), 273 v8::String::NewFromUtf8(pIsolate, bsConst.c_str(),
266 v8::NewStringType::kNormal).ToLocalChecked(), 274 v8::NewStringType::kNormal).ToLocalChecked(),
267 pDefault, v8::ReadOnly); 275 pDefault, v8::ReadOnly);
268 } 276 }
269 277
270 void FXJS_InitializeRuntime(v8::Isolate* pIsolate, 278 void FXJS_InitializeRuntime(v8::Isolate* pIsolate,
271 IFXJS_Runtime* pFXRuntime, 279 IFXJS_Runtime* pFXRuntime,
272 IFXJS_Context* context, 280 IFXJS_Context* context,
273 v8::Global<v8::Context>& v8PersistentContext) { 281 v8::Global<v8::Context>& v8PersistentContext) {
282 if (pIsolate == g_isolate)
283 ++g_isolate_ref_count;
284
274 v8::Isolate::Scope isolate_scope(pIsolate); 285 v8::Isolate::Scope isolate_scope(pIsolate);
275 v8::HandleScope handle_scope(pIsolate); 286 v8::HandleScope handle_scope(pIsolate);
276 v8::Local<v8::Context> v8Context = 287 v8::Local<v8::Context> v8Context =
277 v8::Context::New(pIsolate, NULL, GetGlobalObjectTemplate(pIsolate)); 288 v8::Context::New(pIsolate, NULL, GetGlobalObjectTemplate(pIsolate));
278 v8::Context::Scope context_scope(v8Context); 289 v8::Context::Scope context_scope(v8Context);
279 290
280 FXJS_PerIsolateData::SetUp(pIsolate); 291 FXJS_PerIsolateData::SetUp(pIsolate);
281 v8Context->SetAlignedPointerInEmbedderData(kPerContextDataIndex, pFXRuntime); 292 v8Context->SetAlignedPointerInEmbedderData(kPerContextDataIndex, pFXRuntime);
282 293
283 int maxID = CFXJS_ObjDefinition::MaxID(pIsolate); 294 int maxID = CFXJS_ObjDefinition::MaxID(pIsolate);
284 for (int i = 0; i < maxID; ++i) { 295 for (int i = 0; i < maxID; ++i) {
285 CFXJS_ObjDefinition* pObjDef = CFXJS_ObjDefinition::ForID(pIsolate, i); 296 CFXJS_ObjDefinition* pObjDef = CFXJS_ObjDefinition::ForID(pIsolate, i);
286 CFX_WideString ws = CFX_WideString(pObjDef->objName); 297 CFX_WideString ws = CFX_WideString(pObjDef->objName);
287 CFX_ByteString bs = ws.UTF8Encode(); 298 CFX_ByteString bs = ws.UTF8Encode();
288 v8::Local<v8::String> objName = 299 v8::Local<v8::String> objName =
289 v8::String::NewFromUtf8(pIsolate, bs.c_str(), 300 v8::String::NewFromUtf8(pIsolate, bs.c_str(),
290 v8::NewStringType::kNormal, 301 v8::NewStringType::kNormal,
291 bs.GetLength()).ToLocalChecked(); 302 bs.GetLength()).ToLocalChecked();
292 303
293 if (pObjDef->objType == FXJS_DYNAMIC) { 304 if (pObjDef->objType == FXJS_DYNAMIC) {
294 // Document is set as global object, need to construct it first. 305 // Document is set as global object, need to construct it first.
295 if (ws.Equal(L"Document")) { 306 if (ws.Equal(L"Document")) {
296 v8Context->Global() 307 v8Context->Global()
297 ->GetPrototype() 308 ->GetPrototype()
298 ->ToObject(v8Context) 309 ->ToObject(v8Context)
299 .ToLocalChecked() 310 .ToLocalChecked()
300 ->SetAlignedPointerInInternalField(0, new CFXJS_PrivateData(i)); 311 ->SetAlignedPointerInInternalField(0, new CFXJS_PrivateData(i));
301 312
302 if (pObjDef->m_pConstructor) 313 if (pObjDef->m_pConstructor) {
303 pObjDef->m_pConstructor(context, v8Context->Global() 314 pObjDef->m_pConstructor(context, v8Context->Global()
304 ->GetPrototype() 315 ->GetPrototype()
305 ->ToObject(v8Context) 316 ->ToObject(v8Context)
306 .ToLocalChecked(), 317 .ToLocalChecked(),
307 v8Context->Global() 318 v8Context->Global()
308 ->GetPrototype() 319 ->GetPrototype()
309 ->ToObject(v8Context) 320 ->ToObject(v8Context)
310 .ToLocalChecked()); 321 .ToLocalChecked());
322 }
311 } 323 }
312 } else { 324 } else {
313 v8::Local<v8::Object> obj = FXJS_NewFxDynamicObj(pIsolate, context, i); 325 v8::Local<v8::Object> obj = FXJS_NewFxDynamicObj(pIsolate, context, i);
314 v8Context->Global()->Set(v8Context, objName, obj).FromJust(); 326 v8Context->Global()->Set(v8Context, objName, obj).FromJust();
315 pObjDef->m_StaticObj.Reset(pIsolate, obj); 327 pObjDef->m_StaticObj.Reset(pIsolate, obj);
316 } 328 }
317 } 329 }
318 v8PersistentContext.Reset(pIsolate, v8Context); 330 v8PersistentContext.Reset(pIsolate, v8Context);
319 } 331 }
320 332
321 void FXJS_ReleaseRuntime(v8::Isolate* pIsolate, 333 void FXJS_ReleaseRuntime(v8::Isolate* pIsolate,
322 v8::Global<v8::Context>& v8PersistentContext) { 334 v8::Global<v8::Context>& v8PersistentContext) {
335 if (pIsolate == g_isolate && --g_isolate_ref_count > 0)
336 return;
337
323 v8::Isolate::Scope isolate_scope(pIsolate); 338 v8::Isolate::Scope isolate_scope(pIsolate);
324 v8::HandleScope handle_scope(pIsolate); 339 v8::HandleScope handle_scope(pIsolate);
325 v8::Local<v8::Context> context = 340 v8::Local<v8::Context> context =
326 v8::Local<v8::Context>::New(pIsolate, v8PersistentContext); 341 v8::Local<v8::Context>::New(pIsolate, v8PersistentContext);
327 v8::Context::Scope context_scope(context); 342 v8::Context::Scope context_scope(context);
328 343
329 FXJS_PerIsolateData* pData = FXJS_PerIsolateData::Get(pIsolate); 344 FXJS_PerIsolateData* pData = FXJS_PerIsolateData::Get(pIsolate);
330 if (!pData) 345 if (!pData)
331 return; 346 return;
332 347
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 if (nObjDefnID < 0 || nObjDefnID >= CFXJS_ObjDefinition::MaxID(pIsolate)) 417 if (nObjDefnID < 0 || nObjDefnID >= CFXJS_ObjDefinition::MaxID(pIsolate))
403 return v8::Local<v8::Object>(); 418 return v8::Local<v8::Object>();
404 419
405 CFXJS_ObjDefinition* pObjDef = 420 CFXJS_ObjDefinition* pObjDef =
406 CFXJS_ObjDefinition::ForID(pIsolate, nObjDefnID); 421 CFXJS_ObjDefinition::ForID(pIsolate, nObjDefnID);
407 v8::Local<v8::Object> obj; 422 v8::Local<v8::Object> obj;
408 if (!pObjDef->GetInstanceTemplate()->NewInstance(context).ToLocal(&obj)) 423 if (!pObjDef->GetInstanceTemplate()->NewInstance(context).ToLocal(&obj))
409 return v8::Local<v8::Object>(); 424 return v8::Local<v8::Object>();
410 425
411 obj->SetAlignedPointerInInternalField(0, new CFXJS_PrivateData(nObjDefnID)); 426 obj->SetAlignedPointerInInternalField(0, new CFXJS_PrivateData(nObjDefnID));
412 if (pObjDef->m_pConstructor) 427 if (pObjDef->m_pConstructor) {
413 pObjDef->m_pConstructor( 428 pObjDef->m_pConstructor(
414 pJSContext, obj, 429 pJSContext, obj,
415 context->Global()->GetPrototype()->ToObject(context).ToLocalChecked()); 430 context->Global()->GetPrototype()->ToObject(context).ToLocalChecked());
431 }
416 432
417 return obj; 433 return obj;
418 } 434 }
419 435
420 v8::Local<v8::Object> FXJS_GetThisObj(v8::Isolate* pIsolate) { 436 v8::Local<v8::Object> FXJS_GetThisObj(v8::Isolate* pIsolate) {
421 v8::Isolate::Scope isolate_scope(pIsolate); 437 v8::Isolate::Scope isolate_scope(pIsolate);
422 if (!FXJS_PerIsolateData::Get(pIsolate)) 438 if (!FXJS_PerIsolateData::Get(pIsolate))
423 return v8::Local<v8::Object>(); 439 return v8::Local<v8::Object>();
424 440
425 // Return the global object. 441 // Return the global object.
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 if (pObj.IsEmpty()) 522 if (pObj.IsEmpty())
507 return nullptr; 523 return nullptr;
508 CFXJS_PrivateData* pPrivateData = nullptr; 524 CFXJS_PrivateData* pPrivateData = nullptr;
509 if (pObj->InternalFieldCount()) { 525 if (pObj->InternalFieldCount()) {
510 pPrivateData = 526 pPrivateData =
511 (CFXJS_PrivateData*)pObj->GetAlignedPointerFromInternalField(0); 527 (CFXJS_PrivateData*)pObj->GetAlignedPointerFromInternalField(0);
512 } else { 528 } else {
513 // It could be a global proxy object. 529 // It could be a global proxy object.
514 v8::Local<v8::Value> v = pObj->GetPrototype(); 530 v8::Local<v8::Value> v = pObj->GetPrototype();
515 v8::Local<v8::Context> context = pIsolate->GetCurrentContext(); 531 v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
516 if (v->IsObject()) 532 if (v->IsObject()) {
517 pPrivateData = (CFXJS_PrivateData*)v->ToObject(context) 533 pPrivateData = (CFXJS_PrivateData*)v->ToObject(context)
518 .ToLocalChecked() 534 .ToLocalChecked()
519 ->GetAlignedPointerFromInternalField(0); 535 ->GetAlignedPointerFromInternalField(0);
536 }
520 } 537 }
521 return pPrivateData ? pPrivateData->pPrivate : nullptr; 538 return pPrivateData ? pPrivateData->pPrivate : nullptr;
522 } 539 }
523 540
524 void FXJS_FreePrivate(void* pPrivateData) { 541 void FXJS_FreePrivate(void* pPrivateData) {
525 delete (CFXJS_PrivateData*)pPrivateData; 542 delete (CFXJS_PrivateData*)pPrivateData;
526 } 543 }
527 544
528 void FXJS_FreePrivate(v8::Local<v8::Object> pObj) { 545 void FXJS_FreePrivate(v8::Local<v8::Object> pObj) {
529 if (pObj.IsEmpty() || !pObj->InternalFieldCount()) 546 if (pObj.IsEmpty() || !pObj->InternalFieldCount())
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
760 return v8::Local<v8::Array>(); 777 return v8::Local<v8::Array>();
761 v8::Local<v8::Context> context = pIsolate->GetCurrentContext(); 778 v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
762 return v8::Local<v8::Array>::Cast(pValue->ToObject(context).ToLocalChecked()); 779 return v8::Local<v8::Array>::Cast(pValue->ToObject(context).ToLocalChecked());
763 } 780 }
764 781
765 void FXJS_ValueCopy(v8::Local<v8::Value>& pTo, v8::Local<v8::Value> pFrom) { 782 void FXJS_ValueCopy(v8::Local<v8::Value>& pTo, v8::Local<v8::Value> pFrom) {
766 pTo = pFrom; 783 pTo = pFrom;
767 } 784 }
768 785
769 786
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698