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 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |