| 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" | 7 #include "../../include/jsapi/fxjs_v8.h" |
| 8 | 8 |
| 9 #include "../../../core/include/fxcrt/fx_basic.h" | 9 #include "../../../core/include/fxcrt/fx_basic.h" |
| 10 | 10 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 // (without actually requiring a dependency on gin itself for the standalone | 21 // (without actually requiring a dependency on gin itself for the standalone |
| 22 // embedders of PDFIum). The value we want to use is: | 22 // embedders of PDFIum). The value we want to use is: |
| 23 // kPerContextDataStartIndex + kEmbedderPDFium, which is 3. | 23 // kPerContextDataStartIndex + kEmbedderPDFium, which is 3. |
| 24 static const unsigned int kPerContextDataIndex = 3u; | 24 static const unsigned int kPerContextDataIndex = 3u; |
| 25 static unsigned int g_embedderDataSlot = 1u; | 25 static unsigned int g_embedderDataSlot = 1u; |
| 26 static v8::Isolate* g_isolate = nullptr; | 26 static v8::Isolate* g_isolate = nullptr; |
| 27 static size_t g_isolate_ref_count = 0; | 27 static size_t g_isolate_ref_count = 0; |
| 28 static FXJS_ArrayBufferAllocator* g_arrayBufferAllocator = nullptr; | 28 static FXJS_ArrayBufferAllocator* g_arrayBufferAllocator = nullptr; |
| 29 static v8::Global<v8::ObjectTemplate>* g_DefaultGlobalObjectTemplate = nullptr; | 29 static v8::Global<v8::ObjectTemplate>* g_DefaultGlobalObjectTemplate = nullptr; |
| 30 | 30 |
| 31 class CFXJS_PrivateData { | 31 class CFXJS_PerObjectData { |
| 32 public: | 32 public: |
| 33 CFXJS_PrivateData(int nObjDefID) : ObjDefID(nObjDefID), pPrivate(NULL) {} | 33 CFXJS_PerObjectData(int nObjDefID) |
| 34 : m_ObjDefID(nObjDefID), m_pPrivate(nullptr) {} |
| 34 | 35 |
| 35 int ObjDefID; | 36 int m_ObjDefID; |
| 36 void* pPrivate; | 37 void* m_pPrivate; |
| 37 }; | 38 }; |
| 38 | 39 |
| 39 class CFXJS_ObjDefinition { | 40 class CFXJS_ObjDefinition { |
| 40 public: | 41 public: |
| 41 static int MaxID(v8::Isolate* pIsolate) { | 42 static int MaxID(v8::Isolate* pIsolate) { |
| 42 return static_cast<int>( | 43 return static_cast<int>( |
| 43 FXJS_PerIsolateData::Get(pIsolate)->m_ObjectDefnArray.GetSize()); | 44 FXJS_PerIsolateData::Get(pIsolate)->m_ObjectDefnArray.GetSize()); |
| 44 } | 45 } |
| 45 static CFXJS_ObjDefinition* ForID(v8::Isolate* pIsolate, int id) { | 46 static CFXJS_ObjDefinition* ForID(v8::Isolate* pIsolate, int id) { |
| 46 // Note: GetAt() halts if out-of-range even in release builds. | 47 // Note: GetAt() halts if out-of-range even in release builds. |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 v8::Local<v8::String> m_ObjName = | 295 v8::Local<v8::String> m_ObjName = |
| 295 v8::String::NewFromUtf8(pIsolate, bs.c_str(), | 296 v8::String::NewFromUtf8(pIsolate, bs.c_str(), |
| 296 v8::NewStringType::kNormal, | 297 v8::NewStringType::kNormal, |
| 297 bs.GetLength()).ToLocalChecked(); | 298 bs.GetLength()).ToLocalChecked(); |
| 298 | 299 |
| 299 if (pObjDef->m_ObjType == FXJSOBJTYPE_GLOBAL) { | 300 if (pObjDef->m_ObjType == FXJSOBJTYPE_GLOBAL) { |
| 300 v8Context->Global() | 301 v8Context->Global() |
| 301 ->GetPrototype() | 302 ->GetPrototype() |
| 302 ->ToObject(v8Context) | 303 ->ToObject(v8Context) |
| 303 .ToLocalChecked() | 304 .ToLocalChecked() |
| 304 ->SetAlignedPointerInInternalField(0, new CFXJS_PrivateData(i)); | 305 ->SetAlignedPointerInInternalField(0, new CFXJS_PerObjectData(i)); |
| 305 | 306 |
| 306 if (pObjDef->m_pConstructor) | 307 if (pObjDef->m_pConstructor) |
| 307 pObjDef->m_pConstructor(pIRuntime, v8Context->Global() | 308 pObjDef->m_pConstructor(pIRuntime, v8Context->Global() |
| 308 ->GetPrototype() | 309 ->GetPrototype() |
| 309 ->ToObject(v8Context) | 310 ->ToObject(v8Context) |
| 310 .ToLocalChecked()); | 311 .ToLocalChecked()); |
| 311 } else if (pObjDef->m_ObjType == FXJSOBJTYPE_STATIC) { | 312 } else if (pObjDef->m_ObjType == FXJSOBJTYPE_STATIC) { |
| 312 v8::Local<v8::Object> obj = FXJS_NewFxDynamicObj(pIsolate, pIRuntime, i); | 313 v8::Local<v8::Object> obj = FXJS_NewFxDynamicObj(pIsolate, pIRuntime, i); |
| 313 v8Context->Global()->Set(v8Context, m_ObjName, obj).FromJust(); | 314 v8Context->Global()->Set(v8Context, m_ObjName, obj).FromJust(); |
| 314 pObjDef->m_StaticObj.Reset(pIsolate, obj); | 315 pObjDef->m_StaticObj.Reset(pIsolate, obj); |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 408 | 409 |
| 409 if (nObjDefnID < 0 || nObjDefnID >= CFXJS_ObjDefinition::MaxID(pIsolate)) | 410 if (nObjDefnID < 0 || nObjDefnID >= CFXJS_ObjDefinition::MaxID(pIsolate)) |
| 410 return v8::Local<v8::Object>(); | 411 return v8::Local<v8::Object>(); |
| 411 | 412 |
| 412 CFXJS_ObjDefinition* pObjDef = | 413 CFXJS_ObjDefinition* pObjDef = |
| 413 CFXJS_ObjDefinition::ForID(pIsolate, nObjDefnID); | 414 CFXJS_ObjDefinition::ForID(pIsolate, nObjDefnID); |
| 414 v8::Local<v8::Object> obj; | 415 v8::Local<v8::Object> obj; |
| 415 if (!pObjDef->GetInstanceTemplate()->NewInstance(context).ToLocal(&obj)) | 416 if (!pObjDef->GetInstanceTemplate()->NewInstance(context).ToLocal(&obj)) |
| 416 return v8::Local<v8::Object>(); | 417 return v8::Local<v8::Object>(); |
| 417 | 418 |
| 418 obj->SetAlignedPointerInInternalField(0, new CFXJS_PrivateData(nObjDefnID)); | 419 obj->SetAlignedPointerInInternalField(0, new CFXJS_PerObjectData(nObjDefnID)); |
| 419 if (pObjDef->m_pConstructor) | 420 if (pObjDef->m_pConstructor) |
| 420 pObjDef->m_pConstructor(pIRuntime, obj); | 421 pObjDef->m_pConstructor(pIRuntime, obj); |
| 421 | 422 |
| 422 return obj; | 423 return obj; |
| 423 } | 424 } |
| 424 | 425 |
| 425 v8::Local<v8::Object> FXJS_GetThisObj(v8::Isolate* pIsolate) { | 426 v8::Local<v8::Object> FXJS_GetThisObj(v8::Isolate* pIsolate) { |
| 426 v8::Isolate::Scope isolate_scope(pIsolate); | 427 v8::Isolate::Scope isolate_scope(pIsolate); |
| 427 if (!FXJS_PerIsolateData::Get(pIsolate)) | 428 if (!FXJS_PerIsolateData::Get(pIsolate)) |
| 428 return v8::Local<v8::Object>(); | 429 return v8::Local<v8::Object>(); |
| 429 | 430 |
| 430 // Return the global object. | 431 // Return the global object. |
| 431 v8::Local<v8::Context> context = pIsolate->GetCurrentContext(); | 432 v8::Local<v8::Context> context = pIsolate->GetCurrentContext(); |
| 432 return context->Global()->GetPrototype()->ToObject(context).ToLocalChecked(); | 433 return context->Global()->GetPrototype()->ToObject(context).ToLocalChecked(); |
| 433 } | 434 } |
| 434 | 435 |
| 435 int FXJS_GetObjDefnID(v8::Local<v8::Object> pObj) { | 436 int FXJS_GetObjDefnID(v8::Local<v8::Object> pObj) { |
| 436 if (pObj.IsEmpty() || !pObj->InternalFieldCount()) | 437 if (pObj.IsEmpty() || !pObj->InternalFieldCount()) |
| 437 return -1; | 438 return -1; |
| 438 CFXJS_PrivateData* pPrivateData = | 439 CFXJS_PerObjectData* pPerObjectData = static_cast<CFXJS_PerObjectData*>( |
| 439 (CFXJS_PrivateData*)pObj->GetAlignedPointerFromInternalField(0); | 440 pObj->GetAlignedPointerFromInternalField(0)); |
| 440 if (pPrivateData) | 441 if (pPerObjectData) |
| 441 return pPrivateData->ObjDefID; | 442 return pPerObjectData->m_ObjDefID; |
| 442 return -1; | 443 return -1; |
| 443 } | 444 } |
| 444 | 445 |
| 445 void FXJS_Error(v8::Isolate* pIsolate, const CFX_WideString& message) { | 446 void FXJS_Error(v8::Isolate* pIsolate, const CFX_WideString& message) { |
| 446 // Conversion from pdfium's wchar_t wide-strings to v8's uint16_t | 447 // Conversion from pdfium's wchar_t wide-strings to v8's uint16_t |
| 447 // wide-strings isn't handled by v8, so use UTF8 as a common | 448 // wide-strings isn't handled by v8, so use UTF8 as a common |
| 448 // intermediate format. | 449 // intermediate format. |
| 449 CFX_ByteString utf8_message = message.UTF8Encode(); | 450 CFX_ByteString utf8_message = message.UTF8Encode(); |
| 450 pIsolate->ThrowException( | 451 pIsolate->ThrowException( |
| 451 v8::String::NewFromUtf8(pIsolate, utf8_message.c_str(), | 452 v8::String::NewFromUtf8(pIsolate, utf8_message.c_str(), |
| (...skipping 18 matching lines...) Expand all Loading... |
| 470 if (pObj->IsUndefined()) | 471 if (pObj->IsUndefined()) |
| 471 return kFXJSValueNameUndefined; | 472 return kFXJSValueNameUndefined; |
| 472 return NULL; | 473 return NULL; |
| 473 } | 474 } |
| 474 | 475 |
| 475 void FXJS_SetPrivate(v8::Isolate* pIsolate, | 476 void FXJS_SetPrivate(v8::Isolate* pIsolate, |
| 476 v8::Local<v8::Object> pObj, | 477 v8::Local<v8::Object> pObj, |
| 477 void* p) { | 478 void* p) { |
| 478 if (pObj.IsEmpty() || !pObj->InternalFieldCount()) | 479 if (pObj.IsEmpty() || !pObj->InternalFieldCount()) |
| 479 return; | 480 return; |
| 480 CFXJS_PrivateData* pPrivateData = | 481 CFXJS_PerObjectData* pPerObjectData = static_cast<CFXJS_PerObjectData*>( |
| 481 (CFXJS_PrivateData*)pObj->GetAlignedPointerFromInternalField(0); | 482 pObj->GetAlignedPointerFromInternalField(0)); |
| 482 if (!pPrivateData) | 483 if (!pPerObjectData) |
| 483 return; | 484 return; |
| 484 pPrivateData->pPrivate = p; | 485 pPerObjectData->m_pPrivate = p; |
| 485 } | 486 } |
| 486 | 487 |
| 487 void* FXJS_GetPrivate(v8::Isolate* pIsolate, v8::Local<v8::Object> pObj) { | 488 void* FXJS_GetPrivate(v8::Isolate* pIsolate, v8::Local<v8::Object> pObj) { |
| 488 if (pObj.IsEmpty()) | 489 if (pObj.IsEmpty()) |
| 489 return nullptr; | 490 return nullptr; |
| 490 CFXJS_PrivateData* pPrivateData = nullptr; | 491 CFXJS_PerObjectData* pPerObjectData = nullptr; |
| 491 if (pObj->InternalFieldCount()) { | 492 if (pObj->InternalFieldCount()) { |
| 492 pPrivateData = | 493 pPerObjectData = static_cast<CFXJS_PerObjectData*>( |
| 493 (CFXJS_PrivateData*)pObj->GetAlignedPointerFromInternalField(0); | 494 pObj->GetAlignedPointerFromInternalField(0)); |
| 494 } else { | 495 } else { |
| 495 // It could be a global proxy object. | 496 // It could be a global proxy object. |
| 496 v8::Local<v8::Value> v = pObj->GetPrototype(); | 497 v8::Local<v8::Value> v = pObj->GetPrototype(); |
| 497 v8::Local<v8::Context> context = pIsolate->GetCurrentContext(); | 498 v8::Local<v8::Context> context = pIsolate->GetCurrentContext(); |
| 498 if (v->IsObject()) { | 499 if (v->IsObject()) { |
| 499 pPrivateData = (CFXJS_PrivateData*)v->ToObject(context) | 500 pPerObjectData = static_cast<CFXJS_PerObjectData*>( |
| 500 .ToLocalChecked() | 501 v->ToObject(context) |
| 501 ->GetAlignedPointerFromInternalField(0); | 502 .ToLocalChecked() |
| 503 ->GetAlignedPointerFromInternalField(0)); |
| 502 } | 504 } |
| 503 } | 505 } |
| 504 return pPrivateData ? pPrivateData->pPrivate : nullptr; | 506 return pPerObjectData ? pPerObjectData->m_pPrivate : nullptr; |
| 505 } | 507 } |
| 506 | 508 |
| 507 void FXJS_FreePrivate(void* pPrivateData) { | 509 void FXJS_FreePrivate(void* pPerObjectData) { |
| 508 delete (CFXJS_PrivateData*)pPrivateData; | 510 delete static_cast<CFXJS_PerObjectData*>(pPerObjectData); |
| 509 } | 511 } |
| 510 | 512 |
| 511 void FXJS_FreePrivate(v8::Local<v8::Object> pObj) { | 513 void FXJS_FreePrivate(v8::Local<v8::Object> pObj) { |
| 512 if (pObj.IsEmpty() || !pObj->InternalFieldCount()) | 514 if (pObj.IsEmpty() || !pObj->InternalFieldCount()) |
| 513 return; | 515 return; |
| 514 FXJS_FreePrivate(pObj->GetAlignedPointerFromInternalField(0)); | 516 FXJS_FreePrivate(pObj->GetAlignedPointerFromInternalField(0)); |
| 515 pObj->SetAlignedPointerInInternalField(0, NULL); | 517 pObj->SetAlignedPointerInInternalField(0, NULL); |
| 516 } | 518 } |
| 517 | 519 |
| 518 v8::Local<v8::String> FXJS_WSToJSString(v8::Isolate* pIsolate, | 520 v8::Local<v8::String> FXJS_WSToJSString(v8::Isolate* pIsolate, |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 743 return v8::Local<v8::Array>(); | 745 return v8::Local<v8::Array>(); |
| 744 v8::Local<v8::Context> context = pIsolate->GetCurrentContext(); | 746 v8::Local<v8::Context> context = pIsolate->GetCurrentContext(); |
| 745 return v8::Local<v8::Array>::Cast(pValue->ToObject(context).ToLocalChecked()); | 747 return v8::Local<v8::Array>::Cast(pValue->ToObject(context).ToLocalChecked()); |
| 746 } | 748 } |
| 747 | 749 |
| 748 void FXJS_ValueCopy(v8::Local<v8::Value>& pTo, v8::Local<v8::Value> pFrom) { | 750 void FXJS_ValueCopy(v8::Local<v8::Value>& pTo, v8::Local<v8::Value> pFrom) { |
| 749 pTo = pFrom; | 751 pTo = pFrom; |
| 750 } | 752 } |
| 751 | 753 |
| 752 | 754 |
| OLD | NEW |