| 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); | 
| 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 | 
|---|