diff options
author | Tom Sepez <tsepez@chromium.org> | 2015-10-06 11:10:52 -0700 |
---|---|---|
committer | Tom Sepez <tsepez@chromium.org> | 2015-10-06 11:10:52 -0700 |
commit | f0a5b2803c09f3605dcd606e764ef604f0d2a8ea (patch) | |
tree | c70b0fd99702afbeb7474b7c168d13dc5d6831a3 /fpdfsdk/src/javascript/JS_Define.h | |
parent | 4ea721cb7954898a9722c389dae86c62957352d0 (diff) | |
download | pdfium-f0a5b2803c09f3605dcd606e764ef604f0d2a8ea.tar.xz |
Store object definition ID in each js_class.
Avoids doing a lookup via FXJS_V8 for something already
known in CJS layer.
Also:
Consolidate repeated code in JS macros.
Remove knowledge that Document is global from FXJS layer
R=thestig@chromium.org
Review URL: https://codereview.chromium.org/1382263002 .
Diffstat (limited to 'fpdfsdk/src/javascript/JS_Define.h')
-rw-r--r-- | fpdfsdk/src/javascript/JS_Define.h | 328 |
1 files changed, 167 insertions, 161 deletions
diff --git a/fpdfsdk/src/javascript/JS_Define.h b/fpdfsdk/src/javascript/JS_Define.h index 5e98b4f0ea..3881951ff8 100644 --- a/fpdfsdk/src/javascript/JS_Define.h +++ b/fpdfsdk/src/javascript/JS_Define.h @@ -30,18 +30,17 @@ struct JSMethodSpec { v8::FunctionCallback pMethodCall; }; -/* ====================================== PUBLIC DEFINE SPEC - * ============================================== */ #define JS_WIDESTRING(widestring) L## #widestring - #define BEGIN_JS_STATIC_CONST(js_class_name) \ JSConstSpec js_class_name::JS_Class_Consts[] = { #define JS_STATIC_CONST_ENTRY_NUMBER(const_name, pValue) \ { const_name, pValue, L"", 0 } \ , + #define JS_STATIC_CONST_ENTRY_STRING(const_name, pValue) \ { const_name, 0, pValue, 1 } \ , + #define END_JS_STATIC_CONST() \ { 0, 0, 0, 0 } \ } \ @@ -55,6 +54,7 @@ struct JSMethodSpec { set_##prop_name##_static \ } \ , + #define END_JS_STATIC_PROP() \ { 0, 0, 0 } \ } \ @@ -65,14 +65,12 @@ struct JSMethodSpec { #define JS_STATIC_METHOD_ENTRY(method_name) \ { JS_WIDESTRING(method_name), method_name##_static } \ , + #define END_JS_STATIC_METHOD() \ { 0, 0 } \ } \ ; -/* ======================================== PROP CALLBACK - * ============================================ */ - template <class C, FX_BOOL (C::*M)(IFXJS_Context* cc, CJS_PropValue& vp, @@ -138,9 +136,6 @@ void JSPropSetter(const char* prop_name_string, property, value, info); \ } -/* ========================================= METHOD CALLBACK - * =========================================== */ - template <class C, FX_BOOL (C::*M)(IFXJS_Context* cc, const CJS_Parameters& params, @@ -184,79 +179,175 @@ void JSMethod(const char* method_name_string, #method_name, #class_name, info); \ } -/* ===================================== JS CLASS - * =============================================== */ - -#define DECLARE_JS_CLASS(js_class_name) \ - static void JSConstructor(IFXJS_Context* cc, v8::Local<v8::Object> obj, \ - v8::Local<v8::Object> global); \ - static void JSDestructor(v8::Local<v8::Object> obj); \ - static void DefineJSObjects(v8::Isolate* pIsolate, FXJSOBJTYPE eObjType); \ - static JSConstSpec JS_Class_Consts[]; \ - static JSPropertySpec JS_Class_Properties[]; \ - static JSMethodSpec JS_Class_Methods[]; \ - static const wchar_t* m_pClassName - -#define IMPLEMENT_JS_CLASS_RICH(js_class_name, class_alternate, class_name) \ - const wchar_t* js_class_name::m_pClassName = JS_WIDESTRING(class_name); \ - void js_class_name::JSConstructor(IFXJS_Context* cc, \ - v8::Local<v8::Object> obj, \ - v8::Local<v8::Object> global) { \ - CJS_Object* pObj = new js_class_name(obj); \ - pObj->SetEmbedObject(new class_alternate(pObj)); \ - FXJS_SetPrivate(NULL, obj, (void*)pObj); \ - pObj->InitInstance(cc); \ - } \ - \ - void js_class_name::JSDestructor(v8::Local<v8::Object> obj) { \ - js_class_name* pObj = (js_class_name*)FXJS_GetPrivate(NULL, obj); \ - pObj->ExitInstance(); \ - delete pObj; \ - } \ - \ - void js_class_name::DefineJSObjects(v8::Isolate* pIsolate, \ - FXJSOBJTYPE eObjType) { \ - int nObjDefnID = FXJS_DefineObj(pIsolate, js_class_name::m_pClassName, \ - eObjType, JSConstructor, JSDestructor); \ - for (int i = 0; i < FX_ArraySize(JS_Class_Properties) - 1; ++i) { \ - FXJS_DefineObjProperty( \ - pIsolate, nObjDefnID, JS_Class_Properties[i].pName, \ - JS_Class_Properties[i].pPropGet, JS_Class_Properties[i].pPropPut); \ - } \ - for (int i = 0; i < FX_ArraySize(JS_Class_Methods) - 1; ++i) { \ - FXJS_DefineObjMethod(pIsolate, nObjDefnID, JS_Class_Methods[i].pName, \ - JS_Class_Methods[i].pMethodCall); \ - } \ +// All JS classes have a name, an object defintion ID, and the ability to +// register themselves with FXJS_V8. We never make a BASE class on its own +// because it can't really do anything. +#define DECLARE_JS_CLASS_BASE_PART() \ + static const wchar_t* g_pClassName; \ + static int g_nObjDefnID; \ + static void DefineJSObjects(v8::Isolate* pIsolate, FXJSOBJTYPE eObjType); + +#define IMPLEMENT_JS_CLASS_BASE_PART(js_class_name, class_name) \ + const wchar_t* js_class_name::g_pClassName = JS_WIDESTRING(class_name); \ + int js_class_name::g_nObjDefnID = -1; + +// CONST classes provide constants, but not constructors, methods, or props. +#define DECLARE_JS_CLASS_CONST() \ + DECLARE_JS_CLASS_BASE_PART() \ + DECLARE_JS_CLASS_CONST_PART() + +#define IMPLEMENT_JS_CLASS_CONST(js_class_name, class_name) \ + IMPLEMENT_JS_CLASS_BASE_PART(js_class_name, class_name) \ + IMPLEMENT_JS_CLASS_CONST_PART(js_class_name, class_name) \ + void js_class_name::DefineJSObjects(v8::Isolate* pIsolate, \ + FXJSOBJTYPE eObjType) { \ + g_nObjDefnID = FXJS_DefineObj(pIsolate, js_class_name::g_pClassName, \ + eObjType, nullptr, nullptr); \ + DefineConsts(pIsolate); \ } +#define DECLARE_JS_CLASS_CONST_PART() \ + static JSConstSpec JS_Class_Consts[]; \ + static void DefineConsts(v8::Isolate* pIsolate); + +#define IMPLEMENT_JS_CLASS_CONST_PART(js_class_name, class_name) \ + void js_class_name::DefineConsts(v8::Isolate* pIsolate) { \ + for (size_t i = 0; i < FX_ArraySize(JS_Class_Consts) - 1; ++i) { \ + FXJS_DefineObjConst( \ + pIsolate, g_nObjDefnID, JS_Class_Consts[i].pName, \ + JS_Class_Consts[i].t == 0 \ + ? FXJS_NewNumber(pIsolate, JS_Class_Consts[i].number) \ + : FXJS_NewString(pIsolate, JS_Class_Consts[i].string)); \ + } \ + } + +// Convenience macros for declaring classes without an alternate. +#define DECLARE_JS_CLASS() DECLARE_JS_CLASS_RICH() #define IMPLEMENT_JS_CLASS(js_class_name, class_name) \ IMPLEMENT_JS_CLASS_RICH(js_class_name, class_name, class_name) -/* ======================================== CONST CLASS - * ============================================ */ - -#define DECLARE_JS_CLASS_CONST() \ - static void DefineJSObjects(v8::Isolate* pIsolate, FXJSOBJTYPE eObjType); \ - static JSConstSpec JS_Class_Consts[]; \ - static const wchar_t* m_pClassName - -#define IMPLEMENT_JS_CLASS_CONST(js_class_name, class_name) \ - const wchar_t* js_class_name::m_pClassName = JS_WIDESTRING(class_name); \ - void js_class_name::DefineJSObjects(v8::Isolate* pIsolate, \ - FXJSOBJTYPE eObjType) { \ - int nObjDefnID = FXJS_DefineObj(pIsolate, js_class_name::m_pClassName, \ - eObjType, NULL, NULL); \ - for (int i = 0; i < FX_ArraySize(JS_Class_Consts) - 1; ++i) { \ - FXJS_DefineObjConst( \ - pIsolate, nObjDefnID, JS_Class_Consts[i].pName, \ - JS_Class_Consts[i].t == 0 \ - ? FXJS_NewNumber(pIsolate, JS_Class_Consts[i].number) \ - : FXJS_NewString(pIsolate, JS_Class_Consts[i].string)); \ - } \ +// Rich JS classes provide constants, methods, properties, and the ability +// to construct native object state. +#define DECLARE_JS_CLASS_RICH() \ + DECLARE_JS_CLASS_BASE_PART() \ + DECLARE_JS_CLASS_CONST_PART() \ + DECLARE_JS_CLASS_RICH_PART() + +#define IMPLEMENT_JS_CLASS_RICH(js_class_name, class_alternate, class_name) \ + IMPLEMENT_JS_CLASS_BASE_PART(js_class_name, class_name) \ + IMPLEMENT_JS_CLASS_CONST_PART(js_class_name, class_name) \ + IMPLEMENT_JS_CLASS_RICH_PART(js_class_name, class_alternate, class_name) \ + void js_class_name::DefineJSObjects(v8::Isolate* pIsolate, \ + FXJSOBJTYPE eObjType) { \ + g_nObjDefnID = FXJS_DefineObj(pIsolate, js_class_name::g_pClassName, \ + eObjType, JSConstructor, JSDestructor); \ + DefineConsts(pIsolate); \ + DefineProps(pIsolate); \ + DefineMethods(pIsolate); \ } -/* ===================================== SPECIAL JS CLASS - * =============================================== */ +#define DECLARE_JS_CLASS_RICH_PART() \ + static void JSConstructor(IFXJS_Context* cc, v8::Local<v8::Object> obj, \ + v8::Local<v8::Object> global); \ + static void JSDestructor(v8::Local<v8::Object> obj); \ + static void DefineProps(v8::Isolate* pIsoalte); \ + static void DefineMethods(v8::Isolate* pIsoalte); \ + static JSPropertySpec JS_Class_Properties[]; \ + static JSMethodSpec JS_Class_Methods[]; + +#define IMPLEMENT_JS_CLASS_RICH_PART(js_class_name, class_alternate, \ + class_name) \ + void js_class_name::JSConstructor(IFXJS_Context* cc, \ + v8::Local<v8::Object> obj, \ + v8::Local<v8::Object> global) { \ + CJS_Object* pObj = new js_class_name(obj); \ + pObj->SetEmbedObject(new class_alternate(pObj)); \ + FXJS_SetPrivate(nullptr, obj, (void*)pObj); \ + pObj->InitInstance(cc); \ + } \ + void js_class_name::JSDestructor(v8::Local<v8::Object> obj) { \ + js_class_name* pObj = (js_class_name*)FXJS_GetPrivate(nullptr, obj); \ + pObj->ExitInstance(); \ + delete pObj; \ + } \ + void js_class_name::DefineProps(v8::Isolate* pIsolate) { \ + for (size_t i = 0; i < FX_ArraySize(JS_Class_Properties) - 1; ++i) { \ + FXJS_DefineObjProperty( \ + pIsolate, g_nObjDefnID, JS_Class_Properties[i].pName, \ + JS_Class_Properties[i].pPropGet, JS_Class_Properties[i].pPropPut); \ + } \ + } \ + void js_class_name::DefineMethods(v8::Isolate* pIsolate) { \ + for (size_t i = 0; i < FX_ArraySize(JS_Class_Methods) - 1; ++i) { \ + FXJS_DefineObjMethod(pIsolate, g_nObjDefnID, JS_Class_Methods[i].pName, \ + JS_Class_Methods[i].pMethodCall); \ + } \ + } + +// Special JS classes implement methods, props, and queries, but not consts. +#define DECLARE_SPECIAL_JS_CLASS() \ + DECLARE_JS_CLASS_BASE_PART() \ + DECLARE_JS_CLASS_CONST_PART() \ + DECLARE_JS_CLASS_RICH_PART() \ + DECLARE_SPECIAL_JS_CLASS_PART() + +#define IMPLEMENT_SPECIAL_JS_CLASS(js_class_name, class_alternate, class_name) \ + IMPLEMENT_JS_CLASS_BASE_PART(js_class_name, class_name) \ + IMPLEMENT_JS_CLASS_CONST_PART(js_class_name, class_name) \ + IMPLEMENT_JS_CLASS_RICH_PART(js_class_name, class_alternate, class_name) \ + IMPLEMENT_SPECIAL_JS_CLASS_PART(js_class_name, class_alternate, class_name) \ + void js_class_name::DefineJSObjects(v8::Isolate* pIsolate, \ + FXJSOBJTYPE eObjType) { \ + g_nObjDefnID = FXJS_DefineObj(pIsolate, js_class_name::g_pClassName, \ + eObjType, JSConstructor, JSDestructor); \ + DefineConsts(pIsolate); \ + DefineProps(pIsolate); \ + DefineMethods(pIsolate); \ + DefineAllProperties(pIsolate); \ + } + +#define DECLARE_SPECIAL_JS_CLASS_PART() \ + static void queryprop_static( \ + v8::Local<v8::String> property, \ + const v8::PropertyCallbackInfo<v8::Integer>& info); \ + static void getprop_static(v8::Local<v8::String> property, \ + const v8::PropertyCallbackInfo<v8::Value>& info); \ + static void putprop_static(v8::Local<v8::String> property, \ + v8::Local<v8::Value> value, \ + const v8::PropertyCallbackInfo<v8::Value>& info); \ + static void delprop_static( \ + v8::Local<v8::String> property, \ + const v8::PropertyCallbackInfo<v8::Boolean>& info); \ + static void DefineAllProperties(v8::Isolate* pIsolate); + +#define IMPLEMENT_SPECIAL_JS_CLASS_PART(js_class_name, class_alternate, \ + class_name) \ + void js_class_name::queryprop_static( \ + v8::Local<v8::String> property, \ + const v8::PropertyCallbackInfo<v8::Integer>& info) { \ + JSSpecialPropQuery<class_alternate>(#class_name, property, info); \ + } \ + void js_class_name::getprop_static( \ + v8::Local<v8::String> property, \ + const v8::PropertyCallbackInfo<v8::Value>& info) { \ + JSSpecialPropGet<class_alternate>(#class_name, property, info); \ + } \ + void js_class_name::putprop_static( \ + v8::Local<v8::String> property, v8::Local<v8::Value> value, \ + const v8::PropertyCallbackInfo<v8::Value>& info) { \ + JSSpecialPropPut<class_alternate>(#class_name, property, value, info); \ + } \ + void js_class_name::delprop_static( \ + v8::Local<v8::String> property, \ + const v8::PropertyCallbackInfo<v8::Boolean>& info) { \ + JSSpecialPropDel<class_alternate>(#class_name, property, info); \ + } \ + void js_class_name::DefineAllProperties(v8::Isolate* pIsolate) { \ + FXJS_DefineObjAllProperties( \ + pIsolate, g_nObjDefnID, js_class_name::queryprop_static, \ + js_class_name::getprop_static, js_class_name::putprop_static, \ + js_class_name::delprop_static); \ + } template <class Alt> void JSSpecialPropQuery(const char*, @@ -345,91 +436,6 @@ void JSSpecialPropDel(const char* class_name, } } -#define DECLARE_SPECIAL_JS_CLASS(js_class_name) \ - static void JSConstructor(IFXJS_Context* cc, v8::Local<v8::Object> obj, \ - v8::Local<v8::Object> global); \ - static void JSDestructor(v8::Local<v8::Object> obj); \ - static JSConstSpec JS_Class_Consts[]; \ - static JSPropertySpec JS_Class_Properties[]; \ - static JSMethodSpec JS_Class_Methods[]; \ - static void DefineJSObjects(v8::Isolate* pIsolate, FXJSOBJTYPE eObjType); \ - static const wchar_t* m_pClassName; \ - static void queryprop_##js_class_name##_static( \ - v8::Local<v8::String> property, \ - const v8::PropertyCallbackInfo<v8::Integer>& info); \ - static void getprop_##js_class_name##_static( \ - v8::Local<v8::String> property, \ - const v8::PropertyCallbackInfo<v8::Value>& info); \ - static void putprop_##js_class_name##_static( \ - v8::Local<v8::String> property, v8::Local<v8::Value> value, \ - const v8::PropertyCallbackInfo<v8::Value>& info); \ - static void delprop_##js_class_name##_static( \ - v8::Local<v8::String> property, \ - const v8::PropertyCallbackInfo<v8::Boolean>& info) - -#define IMPLEMENT_SPECIAL_JS_CLASS(js_class_name, class_alternate, class_name) \ - const wchar_t* js_class_name::m_pClassName = JS_WIDESTRING(class_name); \ - void js_class_name::queryprop_##js_class_name##_static( \ - v8::Local<v8::String> property, \ - const v8::PropertyCallbackInfo<v8::Integer>& info) { \ - JSSpecialPropQuery<class_alternate>(#class_name, property, info); \ - } \ - void js_class_name::getprop_##js_class_name##_static( \ - v8::Local<v8::String> property, \ - const v8::PropertyCallbackInfo<v8::Value>& info) { \ - JSSpecialPropGet<class_alternate>(#class_name, property, info); \ - } \ - void js_class_name::putprop_##js_class_name##_static( \ - v8::Local<v8::String> property, v8::Local<v8::Value> value, \ - const v8::PropertyCallbackInfo<v8::Value>& info) { \ - JSSpecialPropPut<class_alternate>(#class_name, property, value, info); \ - } \ - void js_class_name::delprop_##js_class_name##_static( \ - v8::Local<v8::String> property, \ - const v8::PropertyCallbackInfo<v8::Boolean>& info) { \ - JSSpecialPropDel<class_alternate>(#class_name, property, info); \ - } \ - void js_class_name::JSConstructor(IFXJS_Context* cc, \ - v8::Local<v8::Object> obj, \ - v8::Local<v8::Object> global) { \ - CJS_Object* pObj = new js_class_name(obj); \ - pObj->SetEmbedObject(new class_alternate(pObj)); \ - FXJS_SetPrivate(NULL, obj, (void*)pObj); \ - pObj->InitInstance(cc); \ - } \ - \ - void js_class_name::JSDestructor(v8::Local<v8::Object> obj) { \ - js_class_name* pObj = (js_class_name*)FXJS_GetPrivate(NULL, obj); \ - ASSERT(pObj != NULL); \ - pObj->ExitInstance(); \ - delete pObj; \ - } \ - \ - void js_class_name::DefineJSObjects(v8::Isolate* pIsolate, \ - FXJSOBJTYPE eObjType) { \ - int nObjDefnID = FXJS_DefineObj(pIsolate, js_class_name::m_pClassName, \ - eObjType, JSConstructor, JSDestructor); \ - for (int i = 0; i < FX_ArraySize(JS_Class_Properties) - 1; ++i) { \ - FXJS_DefineObjProperty( \ - pIsolate, nObjDefnID, JS_Class_Properties[i].pName, \ - JS_Class_Properties[i].pPropGet, JS_Class_Properties[i].pPropPut); \ - } \ - \ - for (int i = 0; i < FX_ArraySize(JS_Class_Methods) - 1; ++i) { \ - FXJS_DefineObjMethod(pIsolate, nObjDefnID, JS_Class_Methods[i].pName, \ - JS_Class_Methods[i].pMethodCall); \ - } \ - FXJS_DefineObjAllProperties( \ - pIsolate, nObjDefnID, \ - js_class_name::queryprop_##js_class_name##_static, \ - js_class_name::getprop_##js_class_name##_static, \ - js_class_name::putprop_##js_class_name##_static, \ - js_class_name::delprop_##js_class_name##_static); \ - } - -/* ======================================== GLOBAL METHODS - * ============================================ */ - template <FX_BOOL (*F)(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, @@ -473,7 +479,7 @@ void JSGlobalFunc(const char* func_name_string, #define IMPLEMENT_JS_STATIC_GLOBAL_FUN(js_class_name) \ void js_class_name::DefineJSObjects(v8::Isolate* pIsolate) { \ - for (int i = 0; i < FX_ArraySize(global_methods) - 1; ++i) { \ + for (size_t i = 0; i < FX_ArraySize(global_methods) - 1; ++i) { \ FXJS_DefineGlobalMethod(pIsolate, \ js_class_name::global_methods[i].pName, \ js_class_name::global_methods[i].pMethodCall); \ |