Chromium Code Reviews| Index: fpdfsdk/src/jsapi/fxjs_v8.cpp |
| diff --git a/fpdfsdk/src/jsapi/fxjs_v8.cpp b/fpdfsdk/src/jsapi/fxjs_v8.cpp |
| index 69ea2cb48bbe96ae886220f4cde9f5249219d61a..cf93e95842567f9573ed185712fb50954700a06e 100644 |
| --- a/fpdfsdk/src/jsapi/fxjs_v8.cpp |
| +++ b/fpdfsdk/src/jsapi/fxjs_v8.cpp |
| @@ -18,6 +18,7 @@ const wchar_t kFXJSValueNameNull[] = L"null"; |
| const wchar_t kFXJSValueNameUndefined[] = L"undefined"; |
| static unsigned int g_embedderDataSlot = 0u; |
| +static v8::Global<v8::ObjectTemplate> g_DefaultGloabalObjectTemplate; |
|
jochen (gone - plz use gerrit)
2015/09/25 11:30:19
spelling of Global
Tom Sepez
2015/09/28 18:13:38
Done.
|
| class CFXJS_PrivateData { |
| public: |
| @@ -26,47 +27,97 @@ class CFXJS_PrivateData { |
| void* pPrivate; |
| }; |
| -class CFXJS_ObjDefintion { |
| +class CFXJS_ObjDefinition { |
| public: |
| - CFXJS_ObjDefintion(v8::Isolate* isolate, |
| - const wchar_t* sObjName, |
| - FXJSOBJTYPE eObjType, |
| - FXJS_CONSTRUCTOR pConstructor, |
| - FXJS_DESTRUCTOR pDestructor) |
| + CFXJS_ObjDefinition(v8::Isolate* isolate, |
| + const wchar_t* sObjName, |
| + FXJSOBJTYPE eObjType, |
| + FXJS_CONSTRUCTOR pConstructor, |
| + FXJS_DESTRUCTOR pDestructor) |
| : objName(sObjName), |
| objType(eObjType), |
| m_pConstructor(pConstructor), |
| m_pDestructor(pDestructor), |
| - m_bSetAsGlobalObject(FALSE) { |
| + m_bSetAsGlobalObject(FALSE), |
| + m_pIsolate(isolate) { |
| v8::Isolate::Scope isolate_scope(isolate); |
| v8::HandleScope handle_scope(isolate); |
| - v8::Local<v8::ObjectTemplate> objTemplate = |
| - v8::ObjectTemplate::New(isolate); |
| - objTemplate->SetInternalFieldCount(2); |
| - m_objTemplate.Reset(isolate, objTemplate); |
| + v8::Local<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(isolate); |
| + v8::Local<v8::Signature> sig = v8::Signature::New(isolate, fun); |
| + |
| + fun->InstanceTemplate()->SetInternalFieldCount(2); |
| + fun->PrototypeTemplate()->SetInternalFieldCount(2); |
| + |
| + m_Signature.Reset(isolate, sig); |
| + m_FunctionTemplate.Reset(isolate, fun); |
| // Document as the global object. |
| if (FXSYS_wcscmp(sObjName, L"Document") == 0) { |
| m_bSetAsGlobalObject = TRUE; |
| } |
| } |
| - ~CFXJS_ObjDefintion() { |
| - m_objTemplate.Reset(); |
| - m_StaticObj.Reset(); |
| + |
| + static CFXJS_ObjDefinition* FromID(v8::Isolate* pIsolate, int nObjDefnID) { |
| + CFX_PtrArray* pArray = (CFX_PtrArray*)pIsolate->GetData(g_embedderDataSlot); |
| + // Note: GetAt() halts if out-of-range even in release builds. |
| + return (CFXJS_ObjDefinition*)pArray->GetAt(nObjDefnID); |
| + } |
| + |
| + int AssignID() { |
| + CFX_PtrArray* pArray = |
| + (CFX_PtrArray*)m_pIsolate->GetData(g_embedderDataSlot); |
| + pArray->Add(this); |
| + return pArray->GetSize() - 1; |
| + } |
| + |
| + v8::Local<v8::ObjectTemplate> GetPrototypeTemplate() { |
| + v8::EscapableHandleScope scope(m_pIsolate); |
| + v8::Local<v8::FunctionTemplate> function = |
| + m_FunctionTemplate.Get(m_pIsolate); |
| + return scope.Escape(function->PrototypeTemplate()); |
| + } |
| + |
| + v8::Local<v8::ObjectTemplate> GetInstanceTemplate() { |
| + v8::EscapableHandleScope scope(m_pIsolate); |
| + v8::Local<v8::FunctionTemplate> function = |
| + m_FunctionTemplate.Get(m_pIsolate); |
| + return scope.Escape(function->InstanceTemplate()); |
| + } |
| + |
| + v8::Local<v8::Signature> GetSignature() { |
| + v8::EscapableHandleScope scope(m_pIsolate); |
| + return scope.Escape(m_Signature.Get(m_pIsolate)); |
| } |
| - public: |
| const wchar_t* objName; |
| - FXJSOBJTYPE objType; |
| - FXJS_CONSTRUCTOR m_pConstructor; |
| - FXJS_DESTRUCTOR m_pDestructor; |
| + const FXJSOBJTYPE objType; |
| + const FXJS_CONSTRUCTOR m_pConstructor; |
| + const FXJS_DESTRUCTOR m_pDestructor; |
| FX_BOOL m_bSetAsGlobalObject; |
| - v8::Global<v8::ObjectTemplate> m_objTemplate; |
| + v8::Isolate* m_pIsolate; |
| + v8::Global<v8::FunctionTemplate> m_FunctionTemplate; |
| + v8::Global<v8::Signature> m_Signature; |
| v8::Global<v8::Object> m_StaticObj; |
| }; |
| +static v8::Local<v8::ObjectTemplate> GetGlobalObjectTemplate( |
| + v8::Isolate* pIsolate) { |
| + CFX_PtrArray* pArray = (CFX_PtrArray*)pIsolate->GetData(g_embedderDataSlot); |
| + for (int i = 0; i < pArray->GetSize(); ++i) { |
| + CFXJS_ObjDefinition* pObjDef = (CFXJS_ObjDefinition*)pArray->GetAt(i); |
| + if (pObjDef->m_bSetAsGlobalObject) |
| + return pObjDef->GetPrototypeTemplate(); |
| + } |
| + |
| + if (g_DefaultGloabalObjectTemplate.IsEmpty()) |
| + g_DefaultGloabalObjectTemplate.Reset(pIsolate, |
| + v8::ObjectTemplate::New(pIsolate)); |
| + |
| + return g_DefaultGloabalObjectTemplate.Get(pIsolate); |
| +} |
| + |
| void* FXJS_ArrayBufferAllocator::Allocate(size_t length) { |
| return calloc(1, length); |
| } |
| @@ -91,13 +142,10 @@ int FXJS_DefineObj(v8::Isolate* pIsolate, |
| FXJS_DESTRUCTOR pDestructor) { |
| v8::Isolate::Scope isolate_scope(pIsolate); |
| v8::HandleScope handle_scope(pIsolate); |
| - |
| FXJS_PrepareIsolate(pIsolate); |
| - CFX_PtrArray* pArray = (CFX_PtrArray*)pIsolate->GetData(g_embedderDataSlot); |
| - CFXJS_ObjDefintion* pObjDef = new CFXJS_ObjDefintion( |
| + CFXJS_ObjDefinition* pObjDef = new CFXJS_ObjDefinition( |
| pIsolate, sObjName, eObjType, pConstructor, pDestructor); |
| - pArray->Add(pObjDef); |
| - return pArray->GetSize() - 1; |
| + return pObjDef->AssignID(); |
| } |
| void FXJS_DefineObjMethod(v8::Isolate* pIsolate, |
| @@ -106,20 +154,15 @@ void FXJS_DefineObjMethod(v8::Isolate* pIsolate, |
| v8::FunctionCallback pMethodCall) { |
| v8::Isolate::Scope isolate_scope(pIsolate); |
| v8::HandleScope handle_scope(pIsolate); |
| - |
| - CFX_WideString ws = CFX_WideString(sMethodName); |
| - CFX_ByteString bsMethodName = ws.UTF8Encode(); |
| - CFX_PtrArray* pArray = (CFX_PtrArray*)pIsolate->GetData(g_embedderDataSlot); |
| - |
| - // Note: GetAt() halts if out-of-range even in release builds. |
| - CFXJS_ObjDefintion* pObjDef = (CFXJS_ObjDefintion*)pArray->GetAt(nObjDefnID); |
| - v8::Local<v8::ObjectTemplate> objTemp = |
| - v8::Local<v8::ObjectTemplate>::New(pIsolate, pObjDef->m_objTemplate); |
| - objTemp->Set( |
| + CFX_ByteString bsMethodName = CFX_WideString(sMethodName).UTF8Encode(); |
| + CFXJS_ObjDefinition* pObjDef = |
| + CFXJS_ObjDefinition::FromID(pIsolate, nObjDefnID); |
| + pObjDef->GetPrototypeTemplate()->Set( |
| v8::String::NewFromUtf8(pIsolate, bsMethodName.c_str(), |
| v8::NewStringType::kNormal).ToLocalChecked(), |
| - v8::FunctionTemplate::New(pIsolate, pMethodCall), v8::ReadOnly); |
| - pObjDef->m_objTemplate.Reset(pIsolate, objTemp); |
| + v8::FunctionTemplate::New(pIsolate, pMethodCall, v8::Local<v8::Value>(), |
| + pObjDef->GetSignature()), |
| + v8::ReadOnly); |
| } |
| void FXJS_DefineObjProperty(v8::Isolate* pIsolate, |
| @@ -129,20 +172,13 @@ void FXJS_DefineObjProperty(v8::Isolate* pIsolate, |
| v8::AccessorSetterCallback pPropPut) { |
| v8::Isolate::Scope isolate_scope(pIsolate); |
| v8::HandleScope handle_scope(pIsolate); |
| - |
| - CFX_WideString ws = CFX_WideString(sPropName); |
| - CFX_ByteString bsPropertyName = ws.UTF8Encode(); |
| - CFX_PtrArray* pArray = (CFX_PtrArray*)pIsolate->GetData(g_embedderDataSlot); |
| - |
| - // Note: GetAt() halts if out-of-range even in release builds. |
| - CFXJS_ObjDefintion* pObjDef = (CFXJS_ObjDefintion*)pArray->GetAt(nObjDefnID); |
| - v8::Local<v8::ObjectTemplate> objTemp = |
| - v8::Local<v8::ObjectTemplate>::New(pIsolate, pObjDef->m_objTemplate); |
| - objTemp->SetAccessor( |
| + CFX_ByteString bsPropertyName = CFX_WideString(sPropName).UTF8Encode(); |
| + CFXJS_ObjDefinition* pObjDef = |
| + CFXJS_ObjDefinition::FromID(pIsolate, nObjDefnID); |
| + pObjDef->GetPrototypeTemplate()->SetAccessor( |
| v8::String::NewFromUtf8(pIsolate, bsPropertyName.c_str(), |
| v8::NewStringType::kNormal).ToLocalChecked(), |
| pPropGet, pPropPut); |
| - pObjDef->m_objTemplate.Reset(pIsolate, objTemp); |
| } |
| void FXJS_DefineObjAllProperties(v8::Isolate* pIsolate, |
| @@ -153,14 +189,10 @@ void FXJS_DefineObjAllProperties(v8::Isolate* pIsolate, |
| v8::NamedPropertyDeleterCallback pPropDel) { |
| v8::Isolate::Scope isolate_scope(pIsolate); |
| v8::HandleScope handle_scope(pIsolate); |
| - CFX_PtrArray* pArray = (CFX_PtrArray*)pIsolate->GetData(g_embedderDataSlot); |
| - |
| - // Note: GetAt() halts if out-of-range even in release builds. |
| - CFXJS_ObjDefintion* pObjDef = (CFXJS_ObjDefintion*)pArray->GetAt(nObjDefnID); |
| - v8::Local<v8::ObjectTemplate> objTemp = |
| - v8::Local<v8::ObjectTemplate>::New(pIsolate, pObjDef->m_objTemplate); |
| - objTemp->SetNamedPropertyHandler(pPropGet, pPropPut, pPropQurey, pPropDel); |
| - pObjDef->m_objTemplate.Reset(pIsolate, objTemp); |
| + CFXJS_ObjDefinition* pObjDef = |
| + CFXJS_ObjDefinition::FromID(pIsolate, nObjDefnID); |
| + pObjDef->GetPrototypeTemplate()->SetNamedPropertyHandler( |
| + pPropGet, pPropPut, pPropQurey, pPropDel); |
| } |
| void FXJS_DefineObjConst(v8::Isolate* pIsolate, |
| @@ -169,33 +201,10 @@ void FXJS_DefineObjConst(v8::Isolate* pIsolate, |
| v8::Local<v8::Value> pDefault) { |
| v8::Isolate::Scope isolate_scope(pIsolate); |
| v8::HandleScope handle_scope(pIsolate); |
| - |
| - CFX_WideString ws = CFX_WideString(sConstName); |
| - CFX_ByteString bsConstName = ws.UTF8Encode(); |
| - CFX_PtrArray* pArray = (CFX_PtrArray*)pIsolate->GetData(g_embedderDataSlot); |
| - |
| - // Note: GetAt() halts if out-of-range even in release builds. |
| - CFXJS_ObjDefintion* pObjDef = (CFXJS_ObjDefintion*)pArray->GetAt(nObjDefnID); |
| - v8::Local<v8::ObjectTemplate> objTemp = |
| - v8::Local<v8::ObjectTemplate>::New(pIsolate, pObjDef->m_objTemplate); |
| - objTemp->Set(pIsolate, bsConstName.c_str(), pDefault); |
| - pObjDef->m_objTemplate.Reset(pIsolate, objTemp); |
| -} |
| - |
| -static v8::Global<v8::ObjectTemplate>& _getGlobalObjectTemplate( |
| - v8::Isolate* pIsolate) { |
| - v8::Isolate::Scope isolate_scope(pIsolate); |
| - v8::HandleScope handle_scope(pIsolate); |
| - |
| - CFX_PtrArray* pArray = (CFX_PtrArray*)pIsolate->GetData(g_embedderDataSlot); |
| - ASSERT(pArray != NULL); |
| - for (int i = 0; i < pArray->GetSize(); i++) { |
| - CFXJS_ObjDefintion* pObjDef = (CFXJS_ObjDefintion*)pArray->GetAt(i); |
| - if (pObjDef->m_bSetAsGlobalObject) |
| - return pObjDef->m_objTemplate; |
| - } |
| - static v8::Global<v8::ObjectTemplate> gloabalObjectTemplate; |
| - return gloabalObjectTemplate; |
| + CFX_ByteString bsConstName = CFX_WideString(sConstName).UTF8Encode(); |
| + CFXJS_ObjDefinition* pObjDef = |
| + CFXJS_ObjDefinition::FromID(pIsolate, nObjDefnID); |
| + pObjDef->GetPrototypeTemplate()->Set(pIsolate, bsConstName.c_str(), pDefault); |
| } |
| void FXJS_DefineGlobalMethod(v8::Isolate* pIsolate, |
| @@ -203,26 +212,11 @@ void FXJS_DefineGlobalMethod(v8::Isolate* pIsolate, |
| v8::FunctionCallback pMethodCall) { |
| v8::Isolate::Scope isolate_scope(pIsolate); |
| v8::HandleScope handle_scope(pIsolate); |
| - |
| - CFX_WideString ws = CFX_WideString(sMethodName); |
| - CFX_ByteString bsMethodName = ws.UTF8Encode(); |
| - |
| - v8::Local<v8::FunctionTemplate> funTempl = |
| - v8::FunctionTemplate::New(pIsolate, pMethodCall); |
| - v8::Local<v8::ObjectTemplate> objTemp; |
| - |
| - v8::Global<v8::ObjectTemplate>& globalObjTemp = |
| - _getGlobalObjectTemplate(pIsolate); |
| - if (globalObjTemp.IsEmpty()) |
| - objTemp = v8::ObjectTemplate::New(pIsolate); |
| - else |
| - objTemp = v8::Local<v8::ObjectTemplate>::New(pIsolate, globalObjTemp); |
| - objTemp->Set( |
| + CFX_ByteString bsMethodName = CFX_WideString(sMethodName).UTF8Encode(); |
| + GetGlobalObjectTemplate(pIsolate)->Set( |
| v8::String::NewFromUtf8(pIsolate, bsMethodName.c_str(), |
| v8::NewStringType::kNormal).ToLocalChecked(), |
| - funTempl, v8::ReadOnly); |
| - |
| - globalObjTemp.Reset(pIsolate, objTemp); |
| + v8::FunctionTemplate::New(pIsolate, pMethodCall), v8::ReadOnly); |
| } |
| void FXJS_DefineGlobalConst(v8::Isolate* pIsolate, |
| @@ -230,24 +224,11 @@ void FXJS_DefineGlobalConst(v8::Isolate* pIsolate, |
| v8::Local<v8::Value> pDefault) { |
| v8::Isolate::Scope isolate_scope(pIsolate); |
| v8::HandleScope handle_scope(pIsolate); |
| - |
| - CFX_WideString ws = CFX_WideString(sConstName); |
| - CFX_ByteString bsConst = ws.UTF8Encode(); |
| - |
| - v8::Local<v8::ObjectTemplate> objTemp; |
| - |
| - v8::Global<v8::ObjectTemplate>& globalObjTemp = |
| - _getGlobalObjectTemplate(pIsolate); |
| - if (globalObjTemp.IsEmpty()) |
| - objTemp = v8::ObjectTemplate::New(pIsolate); |
| - else |
| - objTemp = v8::Local<v8::ObjectTemplate>::New(pIsolate, globalObjTemp); |
| - objTemp->Set( |
| + CFX_ByteString bsConst = CFX_WideString(sConstName).UTF8Encode(); |
| + GetGlobalObjectTemplate(pIsolate)->Set( |
| v8::String::NewFromUtf8(pIsolate, bsConst.c_str(), |
| v8::NewStringType::kNormal).ToLocalChecked(), |
| pDefault, v8::ReadOnly); |
| - |
| - globalObjTemp.Reset(pIsolate, objTemp); |
| } |
| void FXJS_InitializeRuntime(v8::Isolate* pIsolate, |
| @@ -256,12 +237,8 @@ void FXJS_InitializeRuntime(v8::Isolate* pIsolate, |
| v8::Global<v8::Context>& v8PersistentContext) { |
| v8::Isolate::Scope isolate_scope(pIsolate); |
| v8::HandleScope handle_scope(pIsolate); |
| - |
| - v8::Global<v8::ObjectTemplate>& globalObjTemp = |
| - _getGlobalObjectTemplate(pIsolate); |
| - v8::Local<v8::Context> v8Context = v8::Context::New( |
| - pIsolate, NULL, |
| - v8::Local<v8::ObjectTemplate>::New(pIsolate, globalObjTemp)); |
| + v8::Local<v8::Context> v8Context = |
| + v8::Context::New(pIsolate, NULL, GetGlobalObjectTemplate(pIsolate)); |
| v8::Context::Scope context_scope(v8Context); |
| v8::Local<v8::External> ptr = v8::External::New(pIsolate, pFXRuntime); |
| @@ -272,7 +249,7 @@ void FXJS_InitializeRuntime(v8::Isolate* pIsolate, |
| return; |
| for (int i = 0; i < pArray->GetSize(); i++) { |
| - CFXJS_ObjDefintion* pObjDef = (CFXJS_ObjDefintion*)pArray->GetAt(i); |
| + CFXJS_ObjDefinition* pObjDef = (CFXJS_ObjDefinition*)pArray->GetAt(i); |
| CFX_WideString ws = CFX_WideString(pObjDef->objName); |
| CFX_ByteString bs = ws.UTF8Encode(); |
| v8::Local<v8::String> objName = |
| @@ -324,7 +301,7 @@ void FXJS_ReleaseRuntime(v8::Isolate* pIsolate, |
| return; |
| for (int i = 0; i < pArray->GetSize(); i++) { |
| - CFXJS_ObjDefintion* pObjDef = (CFXJS_ObjDefintion*)pArray->GetAt(i); |
| + CFXJS_ObjDefinition* pObjDef = (CFXJS_ObjDefinition*)pArray->GetAt(i); |
| if (!pObjDef->m_StaticObj.IsEmpty()) { |
| v8::Local<v8::Object> pObj = |
| v8::Local<v8::Object>::New(pIsolate, pObjDef->m_StaticObj); |
| @@ -352,10 +329,7 @@ int FXJS_Execute(v8::Isolate* pIsolate, |
| FXJSErr* pError) { |
| v8::Isolate::Scope isolate_scope(pIsolate); |
| v8::TryCatch try_catch(pIsolate); |
| - |
| - CFX_WideString wsScript(script); |
| - CFX_ByteString bsScript = wsScript.UTF8Encode(); |
| - |
| + CFX_ByteString bsScript = CFX_WideString(script).UTF8Encode(); |
| v8::Local<v8::Context> context = pIsolate->GetCurrentContext(); |
| v8::Local<v8::Script> compiled_script; |
| if (!v8::Script::Compile( |
| @@ -385,23 +359,18 @@ v8::Local<v8::Object> FXJS_NewFxDynamicObj(v8::Isolate* pIsolate, |
| if (-1 == nObjDefnID) { |
| v8::Local<v8::ObjectTemplate> objTempl = v8::ObjectTemplate::New(pIsolate); |
| v8::Local<v8::Object> obj; |
| - if (objTempl->NewInstance(context).ToLocal(&obj)) |
| - return obj; |
| - return v8::Local<v8::Object>(); |
| + if (!objTempl->NewInstance(context).ToLocal(&obj)) |
| + return v8::Local<v8::Object>(); |
| + return obj; |
| } |
| - CFX_PtrArray* pArray = (CFX_PtrArray*)pIsolate->GetData(g_embedderDataSlot); |
| - if (!pArray) |
| - return v8::Local<v8::Object>(); |
| - |
| - if (nObjDefnID < 0 || nObjDefnID >= pArray->GetSize()) |
| + if (!pIsolate->GetData(g_embedderDataSlot)) |
| return v8::Local<v8::Object>(); |
| - CFXJS_ObjDefintion* pObjDef = (CFXJS_ObjDefintion*)pArray->GetAt(nObjDefnID); |
| - v8::Local<v8::ObjectTemplate> objTemp = |
| - v8::Local<v8::ObjectTemplate>::New(pIsolate, pObjDef->m_objTemplate); |
| + CFXJS_ObjDefinition* pObjDef = |
| + CFXJS_ObjDefinition::FromID(pIsolate, nObjDefnID); |
| v8::Local<v8::Object> obj; |
| - if (!objTemp->NewInstance(context).ToLocal(&obj)) |
| + if (!pObjDef->GetInstanceTemplate()->NewInstance(context).ToLocal(&obj)) |
| return v8::Local<v8::Object>(); |
| CFXJS_PrivateData* pPrivateData = new CFXJS_PrivateData; |
| @@ -453,7 +422,7 @@ int FXJS_GetObjDefnID(v8::Isolate* pIsolate, const wchar_t* pObjName) { |
| return -1; |
| for (int i = 0; i < pArray->GetSize(); i++) { |
| - CFXJS_ObjDefintion* pObjDef = (CFXJS_ObjDefintion*)pArray->GetAt(i); |
| + CFXJS_ObjDefinition* pObjDef = (CFXJS_ObjDefinition*)pArray->GetAt(i); |
| if (FXSYS_wcscmp(pObjDef->objName, pObjName) == 0) |
| return i; |
| } |