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 7b93a2ad268fa5f018d06405407714644c718d64..608d82a502f14cf0cca0990ec9d79420f45a7db6 100644 |
| --- a/fpdfsdk/src/jsapi/fxjs_v8.cpp |
| +++ b/fpdfsdk/src/jsapi/fxjs_v8.cpp |
| @@ -24,6 +24,8 @@ static unsigned int g_embedderDataSlot = 1u; |
| // kPerContextDataStartIndex + kEmbedderPDFium, which is 3. |
| static const unsigned int kPerContextDataIndex = 3u; |
| +static v8::Global<v8::ObjectTemplate> g_DefaultGlobalObjectTemplate; |
| + |
| class CFXJS_PrivateData { |
| public: |
| CFXJS_PrivateData(int nObjDefID) : ObjDefID(nObjDefID), pPrivate(NULL) {} |
| @@ -43,7 +45,7 @@ class CFXJS_ObjDefinition { |
| return static_cast<CFXJS_ObjDefinition*>( |
| FXJS_PerIsolateData::Get(pIsolate)->m_ObjectDefnArray.GetAt(id)); |
| } |
| - CFXJS_ObjDefinition(v8::Isolate* isolate, |
| + CFXJS_ObjDefinition(v8::Isolate* pIsolate, |
| const wchar_t* sObjName, |
| FXJSOBJTYPE eObjType, |
| FXJS_CONSTRUCTOR pConstructor, |
| @@ -52,35 +54,77 @@ class CFXJS_ObjDefinition { |
| objType(eObjType), |
| m_pConstructor(pConstructor), |
| m_pDestructor(pDestructor), |
| - m_bSetAsGlobalObject(FALSE) { |
| - v8::Isolate::Scope isolate_scope(isolate); |
| - v8::HandleScope handle_scope(isolate); |
| + m_bSetAsGlobalObject(FALSE), |
| + m_pIsolate(pIsolate) { |
| + v8::Isolate::Scope isolate_scope(pIsolate); |
| + v8::HandleScope handle_scope(pIsolate); |
| - 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(pIsolate); |
| + fun->InstanceTemplate()->SetInternalFieldCount(2); |
| + fun->PrototypeTemplate()->SetInternalFieldCount(2); |
|
jochen (gone - plz use gerrit)
2015/09/30 08:30:20
this shouldn't be required (setting it on the inst
|
| + m_FunctionTemplate.Reset(pIsolate, fun); |
| - // Document as the global object. |
| if (FXSYS_wcscmp(sObjName, L"Document") == 0) { |
| m_bSetAsGlobalObject = TRUE; |
| + } else { |
| + v8::Local<v8::Signature> sig = v8::Signature::New(pIsolate, fun); |
|
jochen (gone - plz use gerrit)
2015/09/29 07:30:47
you appear to put the functions on the prototype (
Tom Sepez
2015/09/29 15:50:34
Hmm. Signature ctor wants a function template, no
jochen (gone - plz use gerrit)
2015/09/30 08:30:20
my bad, ignore this comment
|
| + m_Signature.Reset(pIsolate, sig); |
| } |
| } |
| - ~CFXJS_ObjDefinition() { |
| - m_objTemplate.Reset(); |
| - m_StaticObj.Reset(); |
| + |
| + int AssignID() { |
| + FXJS_PerIsolateData* pData = FXJS_PerIsolateData::Get(m_pIsolate); |
| + pData->m_ObjectDefnArray.Add(this); |
| + return pData->m_ObjectDefnArray.GetSize() - 1; |
| + } |
| + |
| + v8::Local<v8::ObjectTemplate> GetPrototypeTemplate() { |
|
jochen (gone - plz use gerrit)
2015/09/30 08:30:20
this method should not be needed - replace all cal
|
| + 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)); |
| } |
| 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) { |
| + int maxID = CFXJS_ObjDefinition::MaxID(pIsolate); |
| + for (int i = 0; i < maxID; ++i) { |
| + CFXJS_ObjDefinition* pObjDef = CFXJS_ObjDefinition::ForID(pIsolate, i); |
| + if (pObjDef->m_bSetAsGlobalObject) |
| + return pObjDef->GetPrototypeTemplate(); |
| + } |
| + |
| + if (g_DefaultGlobalObjectTemplate.IsEmpty()) |
| + g_DefaultGlobalObjectTemplate.Reset(pIsolate, |
| + v8::ObjectTemplate::New(pIsolate)); |
| + |
| + return g_DefaultGlobalObjectTemplate.Get(pIsolate); |
| +} |
| + |
| void* FXJS_ArrayBufferAllocator::Allocate(size_t length) { |
| return calloc(1, length); |
| } |
| @@ -121,10 +165,9 @@ int FXJS_DefineObj(v8::Isolate* pIsolate, |
| v8::HandleScope handle_scope(pIsolate); |
| FXJS_PerIsolateData::SetUp(pIsolate); |
| - FXJS_PerIsolateData* pData = FXJS_PerIsolateData::Get(pIsolate); |
| - pData->m_ObjectDefnArray.Add(new CFXJS_ObjDefinition( |
| - pIsolate, sObjName, eObjType, pConstructor, pDestructor)); |
| - return pData->m_ObjectDefnArray.GetSize() - 1; |
| + CFXJS_ObjDefinition* pObjDef = new CFXJS_ObjDefinition( |
| + pIsolate, sObjName, eObjType, pConstructor, pDestructor); |
| + return pObjDef->AssignID(); |
| } |
| void FXJS_DefineObjMethod(v8::Isolate* pIsolate, |
| @@ -133,18 +176,15 @@ void FXJS_DefineObjMethod(v8::Isolate* pIsolate, |
| v8::FunctionCallback pMethodCall) { |
| v8::Isolate::Scope isolate_scope(pIsolate); |
| v8::HandleScope handle_scope(pIsolate); |
| - |
| CFX_ByteString bsMethodName = CFX_WideString(sMethodName).UTF8Encode(); |
| CFXJS_ObjDefinition* pObjDef = |
| CFXJS_ObjDefinition::ForID(pIsolate, nObjDefnID); |
| - v8::Local<v8::ObjectTemplate> objTemp = |
| - v8::Local<v8::ObjectTemplate>::New(pIsolate, pObjDef->m_objTemplate); |
| - |
| - objTemp->Set( |
| + 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()), |
|
jochen (gone - plz use gerrit)
2015/09/29 07:30:47
here ^^^
|
| + v8::ReadOnly); |
| } |
| void FXJS_DefineObjProperty(v8::Isolate* pIsolate, |
| @@ -154,17 +194,13 @@ void FXJS_DefineObjProperty(v8::Isolate* pIsolate, |
| v8::AccessorSetterCallback pPropPut) { |
| v8::Isolate::Scope isolate_scope(pIsolate); |
| v8::HandleScope handle_scope(pIsolate); |
| - |
| CFX_ByteString bsPropertyName = CFX_WideString(sPropName).UTF8Encode(); |
| CFXJS_ObjDefinition* pObjDef = |
| CFXJS_ObjDefinition::ForID(pIsolate, nObjDefnID); |
| - v8::Local<v8::ObjectTemplate> objTemp = |
| - v8::Local<v8::ObjectTemplate>::New(pIsolate, pObjDef->m_objTemplate); |
| - objTemp->SetAccessor( |
| + 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, |
| @@ -175,13 +211,10 @@ void FXJS_DefineObjAllProperties(v8::Isolate* pIsolate, |
| v8::NamedPropertyDeleterCallback pPropDel) { |
| v8::Isolate::Scope isolate_scope(pIsolate); |
| v8::HandleScope handle_scope(pIsolate); |
| - |
| CFXJS_ObjDefinition* pObjDef = |
| CFXJS_ObjDefinition::ForID(pIsolate, 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); |
| + pObjDef->GetPrototypeTemplate()->SetNamedPropertyHandler( |
| + pPropGet, pPropPut, pPropQurey, pPropDel); |
| } |
| void FXJS_DefineObjConst(v8::Isolate* pIsolate, |
| @@ -190,29 +223,10 @@ void FXJS_DefineObjConst(v8::Isolate* pIsolate, |
| v8::Local<v8::Value> pDefault) { |
| v8::Isolate::Scope isolate_scope(pIsolate); |
| v8::HandleScope handle_scope(pIsolate); |
| - |
| CFX_ByteString bsConstName = CFX_WideString(sConstName).UTF8Encode(); |
| CFXJS_ObjDefinition* pObjDef = |
| CFXJS_ObjDefinition::ForID(pIsolate, 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); |
| - |
| - int maxID = CFXJS_ObjDefinition::MaxID(pIsolate); |
| - for (int i = 0; i < maxID; ++i) { |
| - CFXJS_ObjDefinition* pObjDef = CFXJS_ObjDefinition::ForID(pIsolate, i); |
| - if (pObjDef->m_bSetAsGlobalObject) |
| - return pObjDef->m_objTemplate; |
| - } |
| - static v8::Global<v8::ObjectTemplate> gloabalObjectTemplate; |
| - return gloabalObjectTemplate; |
| + pObjDef->GetPrototypeTemplate()->Set(pIsolate, bsConstName.c_str(), pDefault); |
| } |
| void FXJS_DefineGlobalMethod(v8::Isolate* pIsolate, |
| @@ -220,24 +234,11 @@ void FXJS_DefineGlobalMethod(v8::Isolate* pIsolate, |
| v8::FunctionCallback pMethodCall) { |
| v8::Isolate::Scope isolate_scope(pIsolate); |
| v8::HandleScope handle_scope(pIsolate); |
| - |
| CFX_ByteString bsMethodName = CFX_WideString(sMethodName).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( |
| + 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, |
| @@ -245,24 +246,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, |
| @@ -271,12 +259,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); |
| FXJS_PerIsolateData::SetUp(pIsolate); |
| @@ -293,8 +277,7 @@ void FXJS_InitializeRuntime(v8::Isolate* pIsolate, |
| bs.GetLength()).ToLocalChecked(); |
| if (pObjDef->objType == FXJS_DYNAMIC) { |
| - // Document is set as global object, need to construct it first. |
| - if (ws.Equal(L"Document")) { |
| + if (pObjDef->m_bSetAsGlobalObject) { |
| v8Context->Global() |
| ->GetPrototype() |
| ->ToObject(v8Context) |
| @@ -362,10 +345,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( |
| @@ -395,9 +375,9 @@ v8::Local<v8::Object> FXJS_NewFxDynamicObj(v8::Isolate* pIsolate, |
| if (nObjDefnID == -1) { |
| 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; |
| } |
| FXJS_PerIsolateData* pData = FXJS_PerIsolateData::Get(pIsolate); |
| @@ -409,11 +389,8 @@ v8::Local<v8::Object> FXJS_NewFxDynamicObj(v8::Isolate* pIsolate, |
| CFXJS_ObjDefinition* pObjDef = |
| CFXJS_ObjDefinition::ForID(pIsolate, nObjDefnID); |
| - |
| - v8::Local<v8::ObjectTemplate> objTemp = |
| - v8::Local<v8::ObjectTemplate>::New(pIsolate, pObjDef->m_objTemplate); |
| v8::Local<v8::Object> obj; |
| - if (!objTemp->NewInstance(context).ToLocal(&obj)) |
| + if (!pObjDef->GetInstanceTemplate()->NewInstance(context).ToLocal(&obj)) |
| return v8::Local<v8::Object>(); |
| obj->SetAlignedPointerInInternalField(0, new CFXJS_PrivateData(nObjDefnID)); |