Remove some JS_Define macros

Attempt at clarity.

Change-Id: Ie37890888e1ec6e07cd10c68066b90f854fe6038
Reviewed-on: https://pdfium-review.googlesource.com/2719
Commit-Queue: dsinclair <dsinclair@chromium.org>
Reviewed-by: dsinclair <dsinclair@chromium.org>
diff --git a/fpdfsdk/javascript/Annot.cpp b/fpdfsdk/javascript/Annot.cpp
index dbb2cb2..74af4b4 100644
--- a/fpdfsdk/javascript/Annot.cpp
+++ b/fpdfsdk/javascript/Annot.cpp
@@ -19,17 +19,15 @@
 
 }  // namespace
 
-BEGIN_JS_STATIC_CONST(CJS_Annot)
-END_JS_STATIC_CONST()
+JSConstSpec CJS_Annot::ConstSpecs[] = {{0, JSConstSpec::Number, 0, 0}};
 
-BEGIN_JS_STATIC_PROP(CJS_Annot)
-JS_STATIC_PROP_ENTRY(hidden)
-JS_STATIC_PROP_ENTRY(name)
-JS_STATIC_PROP_ENTRY(type)
-END_JS_STATIC_PROP()
+JSPropertySpec CJS_Annot::PropertySpecs[] = {
+    {L"hidden", get_hidden_static, set_hidden_static},
+    {L"name", get_name_static, set_name_static},
+    {L"type", get_type_static, set_type_static},
+    {0, 0, 0}};
 
-BEGIN_JS_STATIC_METHOD(CJS_Annot)
-END_JS_STATIC_METHOD()
+JSMethodSpec CJS_Annot::MethodSpecs[] = {{0, 0}};
 
 IMPLEMENT_JS_CLASS(CJS_Annot, Annot)
 
diff --git a/fpdfsdk/javascript/Consts.cpp b/fpdfsdk/javascript/Consts.cpp
index c224ad0..a9fe01d 100644
--- a/fpdfsdk/javascript/Consts.cpp
+++ b/fpdfsdk/javascript/Consts.cpp
@@ -10,93 +10,93 @@
 #include "fpdfsdk/javascript/JS_Object.h"
 #include "fpdfsdk/javascript/JS_Value.h"
 
-BEGIN_JS_STATIC_CONST(CJS_Border)
-JS_STATIC_CONST_ENTRY_STRING(L"s", L"solid")
-JS_STATIC_CONST_ENTRY_STRING(L"b", L"beveled")
-JS_STATIC_CONST_ENTRY_STRING(L"d", L"dashed")
-JS_STATIC_CONST_ENTRY_STRING(L"i", L"inset")
-JS_STATIC_CONST_ENTRY_STRING(L"u", L"underline")
-END_JS_STATIC_CONST()
+JSConstSpec CJS_Border::ConstSpecs[] = {
+    {L"s", JSConstSpec::String, 0, L"solid"},
+    {L"b", JSConstSpec::String, 0, L"beveled"},
+    {L"d", JSConstSpec::String, 0, L"dashed"},
+    {L"i", JSConstSpec::String, 0, L"inset"},
+    {L"u", JSConstSpec::String, 0, L"underline"},
+    {0, JSConstSpec::Number, 0, 0}};
 IMPLEMENT_JS_CLASS_CONST(CJS_Border, border)
 
-BEGIN_JS_STATIC_CONST(CJS_Display)
-JS_STATIC_CONST_ENTRY_NUMBER(L"visible", 0)
-JS_STATIC_CONST_ENTRY_NUMBER(L"hidden", 1)
-JS_STATIC_CONST_ENTRY_NUMBER(L"noPrint", 2)
-JS_STATIC_CONST_ENTRY_NUMBER(L"noView", 3)
-END_JS_STATIC_CONST()
+JSConstSpec CJS_Display::ConstSpecs[] = {
+    {L"visible", JSConstSpec::Number, 0, 0},
+    {L"hidden", JSConstSpec::Number, 1, 0},
+    {L"noPrint", JSConstSpec::Number, 2, 0},
+    {L"noView", JSConstSpec::Number, 3, 0},
+    {0, JSConstSpec::Number, 0, 0}};
 IMPLEMENT_JS_CLASS_CONST(CJS_Display, display)
 
-BEGIN_JS_STATIC_CONST(CJS_Font)
-JS_STATIC_CONST_ENTRY_STRING(L"Times", L"Times-Roman")
-JS_STATIC_CONST_ENTRY_STRING(L"TimesB", L"Times-Bold")
-JS_STATIC_CONST_ENTRY_STRING(L"TimesI", L"Times-Italic")
-JS_STATIC_CONST_ENTRY_STRING(L"TimesBI", L"Times-BoldItalic")
-JS_STATIC_CONST_ENTRY_STRING(L"Helv", L"Helvetica")
-JS_STATIC_CONST_ENTRY_STRING(L"HelvB", L"Helvetica-Bold")
-JS_STATIC_CONST_ENTRY_STRING(L"HelvI", L"Helvetica-Oblique")
-JS_STATIC_CONST_ENTRY_STRING(L"HelvBI", L"Helvetica-BoldOblique")
-JS_STATIC_CONST_ENTRY_STRING(L"Cour", L"Courier")
-JS_STATIC_CONST_ENTRY_STRING(L"CourB", L"Courier-Bold")
-JS_STATIC_CONST_ENTRY_STRING(L"CourI", L"Courier-Oblique")
-JS_STATIC_CONST_ENTRY_STRING(L"CourBI", L"Courier-BoldOblique")
-JS_STATIC_CONST_ENTRY_STRING(L"Symbol", L"Symbol")
-JS_STATIC_CONST_ENTRY_STRING(L"ZapfD", L"ZapfDingbats")
-END_JS_STATIC_CONST()
+JSConstSpec CJS_Font::ConstSpecs[] = {
+    {L"Times", JSConstSpec::String, 0, L"Times-Roman"},
+    {L"TimesB", JSConstSpec::String, 0, L"Times-Bold"},
+    {L"TimesI", JSConstSpec::String, 0, L"Times-Italic"},
+    {L"TimesBI", JSConstSpec::String, 0, L"Times-BoldItalic"},
+    {L"Helv", JSConstSpec::String, 0, L"Helvetica"},
+    {L"HelvB", JSConstSpec::String, 0, L"Helvetica-Bold"},
+    {L"HelvI", JSConstSpec::String, 0, L"Helvetica-Oblique"},
+    {L"HelvBI", JSConstSpec::String, 0, L"Helvetica-BoldOblique"},
+    {L"Cour", JSConstSpec::String, 0, L"Courier"},
+    {L"CourB", JSConstSpec::String, 0, L"Courier-Bold"},
+    {L"CourI", JSConstSpec::String, 0, L"Courier-Oblique"},
+    {L"CourBI", JSConstSpec::String, 0, L"Courier-BoldOblique"},
+    {L"Symbol", JSConstSpec::String, 0, L"Symbol"},
+    {L"ZapfD", JSConstSpec::String, 0, L"ZapfDingbats"},
+    {0, JSConstSpec::Number, 0, 0}};
 IMPLEMENT_JS_CLASS_CONST(CJS_Font, font)
 
-BEGIN_JS_STATIC_CONST(CJS_Highlight)
-JS_STATIC_CONST_ENTRY_STRING(L"n", L"none")
-JS_STATIC_CONST_ENTRY_STRING(L"i", L"invert")
-JS_STATIC_CONST_ENTRY_STRING(L"p", L"push")
-JS_STATIC_CONST_ENTRY_STRING(L"o", L"outline")
-END_JS_STATIC_CONST()
+JSConstSpec CJS_Highlight::ConstSpecs[] = {
+    {L"n", JSConstSpec::String, 0, L"none"},
+    {L"i", JSConstSpec::String, 0, L"invert"},
+    {L"p", JSConstSpec::String, 0, L"push"},
+    {L"o", JSConstSpec::String, 0, L"outline"},
+    {0, JSConstSpec::Number, 0, 0}};
 IMPLEMENT_JS_CLASS_CONST(CJS_Highlight, highlight)
 
-BEGIN_JS_STATIC_CONST(CJS_Position)
-JS_STATIC_CONST_ENTRY_NUMBER(L"textOnly", 0)
-JS_STATIC_CONST_ENTRY_NUMBER(L"iconOnly", 1)
-JS_STATIC_CONST_ENTRY_NUMBER(L"iconTextV", 2)
-JS_STATIC_CONST_ENTRY_NUMBER(L"textIconV", 3)
-JS_STATIC_CONST_ENTRY_NUMBER(L"iconTextH", 4)
-JS_STATIC_CONST_ENTRY_NUMBER(L"textIconH", 5)
-JS_STATIC_CONST_ENTRY_NUMBER(L"overlay", 6)
-END_JS_STATIC_CONST()
+JSConstSpec CJS_Position::ConstSpecs[] = {
+    {L"textOnly", JSConstSpec::Number, 0, 0},
+    {L"iconOnly", JSConstSpec::Number, 1, 0},
+    {L"iconTextV", JSConstSpec::Number, 2, 0},
+    {L"textIconV", JSConstSpec::Number, 3, 0},
+    {L"iconTextH", JSConstSpec::Number, 4, 0},
+    {L"textIconH", JSConstSpec::Number, 5, 0},
+    {L"overlay", JSConstSpec::Number, 6, 0},
+    {0, JSConstSpec::Number, 0, 0}};
 IMPLEMENT_JS_CLASS_CONST(CJS_Position, position)
 
-BEGIN_JS_STATIC_CONST(CJS_ScaleHow)
-JS_STATIC_CONST_ENTRY_NUMBER(L"proportional", 0)
-JS_STATIC_CONST_ENTRY_NUMBER(L"anamorphic", 1)
-END_JS_STATIC_CONST()
+JSConstSpec CJS_ScaleHow::ConstSpecs[] = {
+    {L"proportional", JSConstSpec::Number, 0, 0},
+    {L"anamorphic", JSConstSpec::Number, 1, 0},
+    {0, JSConstSpec::Number, 0, 0}};
 IMPLEMENT_JS_CLASS_CONST(CJS_ScaleHow, scaleHow)
 
-BEGIN_JS_STATIC_CONST(CJS_ScaleWhen)
-JS_STATIC_CONST_ENTRY_NUMBER(L"always", 0)
-JS_STATIC_CONST_ENTRY_NUMBER(L"never", 1)
-JS_STATIC_CONST_ENTRY_NUMBER(L"tooBig", 2)
-JS_STATIC_CONST_ENTRY_NUMBER(L"tooSmall", 3)
-END_JS_STATIC_CONST()
+JSConstSpec CJS_ScaleWhen::ConstSpecs[] = {
+    {L"always", JSConstSpec::Number, 0, 0},
+    {L"never", JSConstSpec::Number, 1, 0},
+    {L"tooBig", JSConstSpec::Number, 2, 0},
+    {L"tooSmall", JSConstSpec::Number, 3, 0},
+    {0, JSConstSpec::Number, 0, 0}};
 IMPLEMENT_JS_CLASS_CONST(CJS_ScaleWhen, scaleWhen)
 
-BEGIN_JS_STATIC_CONST(CJS_Style)
-JS_STATIC_CONST_ENTRY_STRING(L"ch", L"check")
-JS_STATIC_CONST_ENTRY_STRING(L"cr", L"cross")
-JS_STATIC_CONST_ENTRY_STRING(L"di", L"diamond")
-JS_STATIC_CONST_ENTRY_STRING(L"ci", L"circle")
-JS_STATIC_CONST_ENTRY_STRING(L"st", L"star")
-JS_STATIC_CONST_ENTRY_STRING(L"sq", L"square")
-END_JS_STATIC_CONST()
+JSConstSpec CJS_Style::ConstSpecs[] = {
+    {L"ch", JSConstSpec::String, 0, L"check"},
+    {L"cr", JSConstSpec::String, 0, L"cross"},
+    {L"di", JSConstSpec::String, 0, L"diamond"},
+    {L"ci", JSConstSpec::String, 0, L"circle"},
+    {L"st", JSConstSpec::String, 0, L"star"},
+    {L"sq", JSConstSpec::String, 0, L"square"},
+    {0, JSConstSpec::Number, 0, 0}};
 IMPLEMENT_JS_CLASS_CONST(CJS_Style, style)
 
-BEGIN_JS_STATIC_CONST(CJS_Zoomtype)
-JS_STATIC_CONST_ENTRY_STRING(L"none", L"NoVary")
-JS_STATIC_CONST_ENTRY_STRING(L"fitP", L"FitPage")
-JS_STATIC_CONST_ENTRY_STRING(L"fitW", L"FitWidth")
-JS_STATIC_CONST_ENTRY_STRING(L"fitH", L"FitHeight")
-JS_STATIC_CONST_ENTRY_STRING(L"fitV", L"FitVisibleWidth")
-JS_STATIC_CONST_ENTRY_STRING(L"pref", L"Preferred")
-JS_STATIC_CONST_ENTRY_STRING(L"refW", L"ReflowWidth")
-END_JS_STATIC_CONST()
+JSConstSpec CJS_Zoomtype::ConstSpecs[] = {
+    {L"none", JSConstSpec::String, 0, L"NoVary"},
+    {L"fitP", JSConstSpec::String, 0, L"FitPage"},
+    {L"fitW", JSConstSpec::String, 0, L"FitWidth"},
+    {L"fitH", JSConstSpec::String, 0, L"FitHeight"},
+    {L"fitV", JSConstSpec::String, 0, L"FitVisibleWidth"},
+    {L"pref", JSConstSpec::String, 0, L"Preferred"},
+    {L"refW", JSConstSpec::String, 0, L"ReflowWidth"},
+    {0, JSConstSpec::Number, 0, 0}};
 IMPLEMENT_JS_CLASS_CONST(CJS_Zoomtype, zoomtype)
 
 #define GLOBAL_STRING(rt, name, value)                                \
diff --git a/fpdfsdk/javascript/Document.cpp b/fpdfsdk/javascript/Document.cpp
index 133e1b3..adc831d 100644
--- a/fpdfsdk/javascript/Document.cpp
+++ b/fpdfsdk/javascript/Document.cpp
@@ -36,14 +36,11 @@
 #include "third_party/base/numerics/safe_math.h"
 #include "third_party/base/ptr_util.h"
 
-BEGIN_JS_STATIC_CONST(CJS_PrintParamsObj)
-END_JS_STATIC_CONST()
+JSConstSpec CJS_PrintParamsObj::ConstSpecs[] = {{0, JSConstSpec::Number, 0, 0}};
 
-BEGIN_JS_STATIC_PROP(CJS_PrintParamsObj)
-END_JS_STATIC_PROP()
+JSPropertySpec CJS_PrintParamsObj::PropertySpecs[] = {{0, 0, 0}};
 
-BEGIN_JS_STATIC_METHOD(CJS_PrintParamsObj)
-END_JS_STATIC_METHOD()
+JSMethodSpec CJS_PrintParamsObj::MethodSpecs[] = {{0, 0}};
 
 IMPLEMENT_JS_CLASS(CJS_PrintParamsObj, PrintParamsObj)
 
@@ -62,88 +59,88 @@
 #define MINWIDTH 5.0f
 #define MINHEIGHT 5.0f
 
-BEGIN_JS_STATIC_CONST(CJS_Document)
-END_JS_STATIC_CONST()
+JSConstSpec CJS_Document::ConstSpecs[] = {{0, JSConstSpec::Number, 0, 0}};
 
-BEGIN_JS_STATIC_PROP(CJS_Document)
-JS_STATIC_PROP_ENTRY(ADBE)
-JS_STATIC_PROP_ENTRY(author)
-JS_STATIC_PROP_ENTRY(baseURL)
-JS_STATIC_PROP_ENTRY(bookmarkRoot)
-JS_STATIC_PROP_ENTRY(calculate)
-JS_STATIC_PROP_ENTRY(Collab)
-JS_STATIC_PROP_ENTRY(creationDate)
-JS_STATIC_PROP_ENTRY(creator)
-JS_STATIC_PROP_ENTRY(delay)
-JS_STATIC_PROP_ENTRY(dirty)
-JS_STATIC_PROP_ENTRY(documentFileName)
-JS_STATIC_PROP_ENTRY(external)
-JS_STATIC_PROP_ENTRY(filesize)
-JS_STATIC_PROP_ENTRY(icons)
-JS_STATIC_PROP_ENTRY(info)
-JS_STATIC_PROP_ENTRY(keywords)
-JS_STATIC_PROP_ENTRY(layout)
-JS_STATIC_PROP_ENTRY(media)
-JS_STATIC_PROP_ENTRY(modDate)
-JS_STATIC_PROP_ENTRY(mouseX)
-JS_STATIC_PROP_ENTRY(mouseY)
-JS_STATIC_PROP_ENTRY(numFields)
-JS_STATIC_PROP_ENTRY(numPages)
-JS_STATIC_PROP_ENTRY(pageNum)
-JS_STATIC_PROP_ENTRY(pageWindowRect)
-JS_STATIC_PROP_ENTRY(path)
-JS_STATIC_PROP_ENTRY(producer)
-JS_STATIC_PROP_ENTRY(subject)
-JS_STATIC_PROP_ENTRY(title)
-JS_STATIC_PROP_ENTRY(URL)
-JS_STATIC_PROP_ENTRY(zoom)
-JS_STATIC_PROP_ENTRY(zoomType)
-END_JS_STATIC_PROP()
+JSPropertySpec CJS_Document::PropertySpecs[] = {
+    {L"ADBE", get_ADBE_static, set_ADBE_static},
+    {L"author", get_author_static, set_author_static},
+    {L"baseURL", get_baseURL_static, set_baseURL_static},
+    {L"bookmarkRoot", get_bookmarkRoot_static, set_bookmarkRoot_static},
+    {L"calculate", get_calculate_static, set_calculate_static},
+    {L"Collab", get_Collab_static, set_Collab_static},
+    {L"creationDate", get_creationDate_static, set_creationDate_static},
+    {L"creator", get_creator_static, set_creator_static},
+    {L"delay", get_delay_static, set_delay_static},
+    {L"dirty", get_dirty_static, set_dirty_static},
+    {L"documentFileName", get_documentFileName_static,
+     set_documentFileName_static},
+    {L"external", get_external_static, set_external_static},
+    {L"filesize", get_filesize_static, set_filesize_static},
+    {L"icons", get_icons_static, set_icons_static},
+    {L"info", get_info_static, set_info_static},
+    {L"keywords", get_keywords_static, set_keywords_static},
+    {L"layout", get_layout_static, set_layout_static},
+    {L"media", get_media_static, set_media_static},
+    {L"modDate", get_modDate_static, set_modDate_static},
+    {L"mouseX", get_mouseX_static, set_mouseX_static},
+    {L"mouseY", get_mouseY_static, set_mouseY_static},
+    {L"numFields", get_numFields_static, set_numFields_static},
+    {L"numPages", get_numPages_static, set_numPages_static},
+    {L"pageNum", get_pageNum_static, set_pageNum_static},
+    {L"pageWindowRect", get_pageWindowRect_static, set_pageWindowRect_static},
+    {L"path", get_path_static, set_path_static},
+    {L"producer", get_producer_static, set_producer_static},
+    {L"subject", get_subject_static, set_subject_static},
+    {L"title", get_title_static, set_title_static},
+    {L"URL", get_URL_static, set_URL_static},
+    {L"zoom", get_zoom_static, set_zoom_static},
+    {L"zoomType", get_zoomType_static, set_zoomType_static},
+    {0, 0, 0}};
 
-BEGIN_JS_STATIC_METHOD(CJS_Document)
-JS_STATIC_METHOD_ENTRY(addAnnot)
-JS_STATIC_METHOD_ENTRY(addField)
-JS_STATIC_METHOD_ENTRY(addLink)
-JS_STATIC_METHOD_ENTRY(addIcon)
-JS_STATIC_METHOD_ENTRY(calculateNow)
-JS_STATIC_METHOD_ENTRY(closeDoc)
-JS_STATIC_METHOD_ENTRY(createDataObject)
-JS_STATIC_METHOD_ENTRY(deletePages)
-JS_STATIC_METHOD_ENTRY(exportAsText)
-JS_STATIC_METHOD_ENTRY(exportAsFDF)
-JS_STATIC_METHOD_ENTRY(exportAsXFDF)
-JS_STATIC_METHOD_ENTRY(extractPages)
-JS_STATIC_METHOD_ENTRY(getAnnot)
-JS_STATIC_METHOD_ENTRY(getAnnots)
-JS_STATIC_METHOD_ENTRY(getAnnot3D)
-JS_STATIC_METHOD_ENTRY(getAnnots3D)
-JS_STATIC_METHOD_ENTRY(getField)
-JS_STATIC_METHOD_ENTRY(getIcon)
-JS_STATIC_METHOD_ENTRY(getLinks)
-JS_STATIC_METHOD_ENTRY(getNthFieldName)
-JS_STATIC_METHOD_ENTRY(getOCGs)
-JS_STATIC_METHOD_ENTRY(getPageBox)
-JS_STATIC_METHOD_ENTRY(getPageNthWord)
-JS_STATIC_METHOD_ENTRY(getPageNthWordQuads)
-JS_STATIC_METHOD_ENTRY(getPageNumWords)
-JS_STATIC_METHOD_ENTRY(getPrintParams)
-JS_STATIC_METHOD_ENTRY(getURL)
-JS_STATIC_METHOD_ENTRY(gotoNamedDest)
-JS_STATIC_METHOD_ENTRY(importAnFDF)
-JS_STATIC_METHOD_ENTRY(importAnXFDF)
-JS_STATIC_METHOD_ENTRY(importTextData)
-JS_STATIC_METHOD_ENTRY(insertPages)
-JS_STATIC_METHOD_ENTRY(mailForm)
-JS_STATIC_METHOD_ENTRY(print)
-JS_STATIC_METHOD_ENTRY(removeField)
-JS_STATIC_METHOD_ENTRY(replacePages)
-JS_STATIC_METHOD_ENTRY(resetForm)
-JS_STATIC_METHOD_ENTRY(removeIcon)
-JS_STATIC_METHOD_ENTRY(saveAs)
-JS_STATIC_METHOD_ENTRY(submitForm)
-JS_STATIC_METHOD_ENTRY(syncAnnotScan)
-JS_STATIC_METHOD_ENTRY(mailDoc)
-END_JS_STATIC_METHOD()
+JSMethodSpec CJS_Document::MethodSpecs[] = {
+    {L"addAnnot", addAnnot_static},
+    {L"addField", addField_static},
+    {L"addLink", addLink_static},
+    {L"addIcon", addIcon_static},
+    {L"calculateNow", calculateNow_static},
+    {L"closeDoc", closeDoc_static},
+    {L"createDataObject", createDataObject_static},
+    {L"deletePages", deletePages_static},
+    {L"exportAsText", exportAsText_static},
+    {L"exportAsFDF", exportAsFDF_static},
+    {L"exportAsXFDF", exportAsXFDF_static},
+    {L"extractPages", extractPages_static},
+    {L"getAnnot", getAnnot_static},
+    {L"getAnnots", getAnnots_static},
+    {L"getAnnot3D", getAnnot3D_static},
+    {L"getAnnots3D", getAnnots3D_static},
+    {L"getField", getField_static},
+    {L"getIcon", getIcon_static},
+    {L"getLinks", getLinks_static},
+    {L"getNthFieldName", getNthFieldName_static},
+    {L"getOCGs", getOCGs_static},
+    {L"getPageBox", getPageBox_static},
+    {L"getPageNthWord", getPageNthWord_static},
+    {L"getPageNthWordQuads", getPageNthWordQuads_static},
+    {L"getPageNumWords", getPageNumWords_static},
+    {L"getPrintParams", getPrintParams_static},
+    {L"getURL", getURL_static},
+    {L"gotoNamedDest", gotoNamedDest_static},
+    {L"importAnFDF", importAnFDF_static},
+    {L"importAnXFDF", importAnXFDF_static},
+    {L"importTextData", importTextData_static},
+    {L"insertPages", insertPages_static},
+    {L"mailForm", mailForm_static},
+    {L"print", print_static},
+    {L"removeField", removeField_static},
+    {L"replacePages", replacePages_static},
+    {L"resetForm", resetForm_static},
+    {L"removeIcon", removeIcon_static},
+    {L"saveAs", saveAs_static},
+    {L"submitForm", submitForm_static},
+    {L"syncAnnotScan", syncAnnotScan_static},
+    {L"mailDoc", mailDoc_static},
+    {0, 0}};
 
 IMPLEMENT_JS_CLASS(CJS_Document, Document)
 
diff --git a/fpdfsdk/javascript/Field.cpp b/fpdfsdk/javascript/Field.cpp
index 263e3a7..c580a21 100644
--- a/fpdfsdk/javascript/Field.cpp
+++ b/fpdfsdk/javascript/Field.cpp
@@ -72,92 +72,97 @@
 
 }  // namespace
 
-BEGIN_JS_STATIC_CONST(CJS_Field)
-END_JS_STATIC_CONST()
+JSConstSpec CJS_Field::ConstSpecs[] = {{0, JSConstSpec::Number, 0, 0}};
 
-BEGIN_JS_STATIC_PROP(CJS_Field)
-JS_STATIC_PROP_ENTRY(alignment)
-JS_STATIC_PROP_ENTRY(borderStyle)
-JS_STATIC_PROP_ENTRY(buttonAlignX)
-JS_STATIC_PROP_ENTRY(buttonAlignY)
-JS_STATIC_PROP_ENTRY(buttonFitBounds)
-JS_STATIC_PROP_ENTRY(buttonPosition)
-JS_STATIC_PROP_ENTRY(buttonScaleHow)
-JS_STATIC_PROP_ENTRY(buttonScaleWhen)
-JS_STATIC_PROP_ENTRY(calcOrderIndex)
-JS_STATIC_PROP_ENTRY(charLimit)
-JS_STATIC_PROP_ENTRY(comb)
-JS_STATIC_PROP_ENTRY(commitOnSelChange)
-JS_STATIC_PROP_ENTRY(currentValueIndices)
-JS_STATIC_PROP_ENTRY(defaultStyle)
-JS_STATIC_PROP_ENTRY(defaultValue)
-JS_STATIC_PROP_ENTRY(doNotScroll)
-JS_STATIC_PROP_ENTRY(doNotSpellCheck)
-JS_STATIC_PROP_ENTRY(delay)
-JS_STATIC_PROP_ENTRY(display)
-JS_STATIC_PROP_ENTRY(doc)
-JS_STATIC_PROP_ENTRY(editable)
-JS_STATIC_PROP_ENTRY(exportValues)
-JS_STATIC_PROP_ENTRY(hidden)
-JS_STATIC_PROP_ENTRY(fileSelect)
-JS_STATIC_PROP_ENTRY(fillColor)
-JS_STATIC_PROP_ENTRY(lineWidth)
-JS_STATIC_PROP_ENTRY(highlight)
-JS_STATIC_PROP_ENTRY(multiline)
-JS_STATIC_PROP_ENTRY(multipleSelection)
-JS_STATIC_PROP_ENTRY(name)
-JS_STATIC_PROP_ENTRY(numItems)
-JS_STATIC_PROP_ENTRY(page)
-JS_STATIC_PROP_ENTRY(password)
-JS_STATIC_PROP_ENTRY(print)
-JS_STATIC_PROP_ENTRY(radiosInUnison)
-JS_STATIC_PROP_ENTRY(readonly)
-JS_STATIC_PROP_ENTRY(rect)
-JS_STATIC_PROP_ENTRY(required)
-JS_STATIC_PROP_ENTRY(richText)
-JS_STATIC_PROP_ENTRY(richValue)
-JS_STATIC_PROP_ENTRY(rotation)
-JS_STATIC_PROP_ENTRY(strokeColor)
-JS_STATIC_PROP_ENTRY(style)
-JS_STATIC_PROP_ENTRY(submitName)
-JS_STATIC_PROP_ENTRY(textColor)
-JS_STATIC_PROP_ENTRY(textFont)
-JS_STATIC_PROP_ENTRY(textSize)
-JS_STATIC_PROP_ENTRY(type)
-JS_STATIC_PROP_ENTRY(userName)
-JS_STATIC_PROP_ENTRY(value)
-JS_STATIC_PROP_ENTRY(valueAsString)
-JS_STATIC_PROP_ENTRY(source)
-END_JS_STATIC_PROP()
+JSPropertySpec CJS_Field::PropertySpecs[] = {
+    {L"alignment", get_alignment_static, set_alignment_static},
+    {L"borderStyle", get_borderStyle_static, set_borderStyle_static},
+    {L"buttonAlignX", get_buttonAlignX_static, set_buttonAlignX_static},
+    {L"buttonAlignY", get_buttonAlignY_static, set_buttonAlignY_static},
+    {L"buttonFitBounds", get_buttonFitBounds_static,
+     set_buttonFitBounds_static},
+    {L"buttonPosition", get_buttonPosition_static, set_buttonPosition_static},
+    {L"buttonScaleHow", get_buttonScaleHow_static, set_buttonScaleHow_static},
+    {L"buttonScaleWhen", get_buttonScaleWhen_static,
+     set_buttonScaleWhen_static},
+    {L"calcOrderIndex", get_calcOrderIndex_static, set_calcOrderIndex_static},
+    {L"charLimit", get_charLimit_static, set_charLimit_static},
+    {L"comb", get_comb_static, set_comb_static},
+    {L"commitOnSelChange", get_commitOnSelChange_static,
+     set_commitOnSelChange_static},
+    {L"currentValueIndices", get_currentValueIndices_static,
+     set_currentValueIndices_static},
+    {L"defaultStyle", get_defaultStyle_static, set_defaultStyle_static},
+    {L"defaultValue", get_defaultValue_static, set_defaultValue_static},
+    {L"doNotScroll", get_doNotScroll_static, set_doNotScroll_static},
+    {L"doNotSpellCheck", get_doNotSpellCheck_static,
+     set_doNotSpellCheck_static},
+    {L"delay", get_delay_static, set_delay_static},
+    {L"display", get_display_static, set_display_static},
+    {L"doc", get_doc_static, set_doc_static},
+    {L"editable", get_editable_static, set_editable_static},
+    {L"exportValues", get_exportValues_static, set_exportValues_static},
+    {L"hidden", get_hidden_static, set_hidden_static},
+    {L"fileSelect", get_fileSelect_static, set_fileSelect_static},
+    {L"fillColor", get_fillColor_static, set_fillColor_static},
+    {L"lineWidth", get_lineWidth_static, set_lineWidth_static},
+    {L"highlight", get_highlight_static, set_highlight_static},
+    {L"multiline", get_multiline_static, set_multiline_static},
+    {L"multipleSelection", get_multipleSelection_static,
+     set_multipleSelection_static},
+    {L"name", get_name_static, set_name_static},
+    {L"numItems", get_numItems_static, set_numItems_static},
+    {L"page", get_page_static, set_page_static},
+    {L"password", get_password_static, set_password_static},
+    {L"print", get_print_static, set_print_static},
+    {L"radiosInUnison", get_radiosInUnison_static, set_radiosInUnison_static},
+    {L"readonly", get_readonly_static, set_readonly_static},
+    {L"rect", get_rect_static, set_rect_static},
+    {L"required", get_required_static, set_required_static},
+    {L"richText", get_richText_static, set_richText_static},
+    {L"richValue", get_richValue_static, set_richValue_static},
+    {L"rotation", get_rotation_static, set_rotation_static},
+    {L"strokeColor", get_strokeColor_static, set_strokeColor_static},
+    {L"style", get_style_static, set_style_static},
+    {L"submitName", get_submitName_static, set_submitName_static},
+    {L"textColor", get_textColor_static, set_textColor_static},
+    {L"textFont", get_textFont_static, set_textFont_static},
+    {L"textSize", get_textSize_static, set_textSize_static},
+    {L"type", get_type_static, set_type_static},
+    {L"userName", get_userName_static, set_userName_static},
+    {L"value", get_value_static, set_value_static},
+    {L"valueAsString", get_valueAsString_static, set_valueAsString_static},
+    {L"source", get_source_static, set_source_static},
+    {0, 0, 0}};
 
-BEGIN_JS_STATIC_METHOD(CJS_Field)
-JS_STATIC_METHOD_ENTRY(browseForFileToSubmit)
-JS_STATIC_METHOD_ENTRY(buttonGetCaption)
-JS_STATIC_METHOD_ENTRY(buttonGetIcon)
-JS_STATIC_METHOD_ENTRY(buttonImportIcon)
-JS_STATIC_METHOD_ENTRY(buttonSetCaption)
-JS_STATIC_METHOD_ENTRY(buttonSetIcon)
-JS_STATIC_METHOD_ENTRY(checkThisBox)
-JS_STATIC_METHOD_ENTRY(clearItems)
-JS_STATIC_METHOD_ENTRY(defaultIsChecked)
-JS_STATIC_METHOD_ENTRY(deleteItemAt)
-JS_STATIC_METHOD_ENTRY(getArray)
-JS_STATIC_METHOD_ENTRY(getItemAt)
-JS_STATIC_METHOD_ENTRY(getLock)
-JS_STATIC_METHOD_ENTRY(insertItemAt)
-JS_STATIC_METHOD_ENTRY(isBoxChecked)
-JS_STATIC_METHOD_ENTRY(isDefaultChecked)
-JS_STATIC_METHOD_ENTRY(setAction)
-JS_STATIC_METHOD_ENTRY(setFocus)
-JS_STATIC_METHOD_ENTRY(setItems)
-JS_STATIC_METHOD_ENTRY(setLock)
-JS_STATIC_METHOD_ENTRY(signatureGetModifications)
-JS_STATIC_METHOD_ENTRY(signatureGetSeedValue)
-JS_STATIC_METHOD_ENTRY(signatureInfo)
-JS_STATIC_METHOD_ENTRY(signatureSetSeedValue)
-JS_STATIC_METHOD_ENTRY(signatureSign)
-JS_STATIC_METHOD_ENTRY(signatureValidate)
-END_JS_STATIC_METHOD()
+JSMethodSpec CJS_Field::MethodSpecs[] = {
+    {L"browseForFileToSubmit", browseForFileToSubmit_static},
+    {L"buttonGetCaption", buttonGetCaption_static},
+    {L"buttonGetIcon", buttonGetIcon_static},
+    {L"buttonImportIcon", buttonImportIcon_static},
+    {L"buttonSetCaption", buttonSetCaption_static},
+    {L"buttonSetIcon", buttonSetIcon_static},
+    {L"checkThisBox", checkThisBox_static},
+    {L"clearItems", clearItems_static},
+    {L"defaultIsChecked", defaultIsChecked_static},
+    {L"deleteItemAt", deleteItemAt_static},
+    {L"getArray", getArray_static},
+    {L"getItemAt", getItemAt_static},
+    {L"getLock", getLock_static},
+    {L"insertItemAt", insertItemAt_static},
+    {L"isBoxChecked", isBoxChecked_static},
+    {L"isDefaultChecked", isDefaultChecked_static},
+    {L"setAction", setAction_static},
+    {L"setFocus", setFocus_static},
+    {L"setItems", setItems_static},
+    {L"setLock", setLock_static},
+    {L"signatureGetModifications", signatureGetModifications_static},
+    {L"signatureGetSeedValue", signatureGetSeedValue_static},
+    {L"signatureInfo", signatureInfo_static},
+    {L"signatureSetSeedValue", signatureSetSeedValue_static},
+    {L"signatureSign", signatureSign_static},
+    {L"signatureValidate", signatureValidate_static},
+    {0, 0}};
 
 IMPLEMENT_JS_CLASS(CJS_Field, Field)
 
diff --git a/fpdfsdk/javascript/Icon.cpp b/fpdfsdk/javascript/Icon.cpp
index 778c1ed..05be259 100644
--- a/fpdfsdk/javascript/Icon.cpp
+++ b/fpdfsdk/javascript/Icon.cpp
@@ -10,15 +10,13 @@
 #include "fpdfsdk/javascript/JS_Object.h"
 #include "fpdfsdk/javascript/JS_Value.h"
 
-BEGIN_JS_STATIC_CONST(CJS_Icon)
-END_JS_STATIC_CONST()
+JSConstSpec CJS_Icon::ConstSpecs[] = {{0, JSConstSpec::Number, 0, 0}};
 
-BEGIN_JS_STATIC_PROP(CJS_Icon)
-JS_STATIC_PROP_ENTRY(name)
-END_JS_STATIC_PROP()
+JSPropertySpec CJS_Icon::PropertySpecs[] = {
+    {L"name", get_name_static, set_name_static},
+    {0, 0, 0}};
 
-BEGIN_JS_STATIC_METHOD(CJS_Icon)
-END_JS_STATIC_METHOD()
+JSMethodSpec CJS_Icon::MethodSpecs[] = {{0, 0}};
 
 IMPLEMENT_JS_CLASS(CJS_Icon, Icon)
 
diff --git a/fpdfsdk/javascript/JS_Define.h b/fpdfsdk/javascript/JS_Define.h
index 718442c..6ad0063 100644
--- a/fpdfsdk/javascript/JS_Define.h
+++ b/fpdfsdk/javascript/JS_Define.h
@@ -15,10 +15,12 @@
 #include "fxjs/fxjs_v8.h"
 
 struct JSConstSpec {
+  enum Type { Number = 0, String = 1 };
+
   const wchar_t* pName;
+  Type eType;
   double number;
-  const wchar_t* str;
-  uint8_t t;              // 0:double 1:str
+  const wchar_t* pStr;
 };
 
 struct JSPropertySpec {
@@ -33,42 +35,6 @@
 };
 
 #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 }              \
-  }                           \
-  ;  // NOLINT
-
-#define BEGIN_JS_STATIC_PROP(js_class_name) \
-  JSPropertySpec js_class_name::JS_Class_Properties[] = {
-#define JS_STATIC_PROP_ENTRY(prop_name)                \
-  {JS_WIDESTRING(prop_name), get_##prop_name##_static, \
-   set_##prop_name##_static},  // NOLINT
-
-#define END_JS_STATIC_PROP() \
-  { 0, 0, 0 }                \
-  }                          \
-  ;  // NOLINT
-
-#define BEGIN_JS_STATIC_METHOD(js_class_name) \
-  JSMethodSpec js_class_name::JS_Class_Methods[] = {
-#define JS_STATIC_METHOD_ENTRY(method_name)            \
-  { JS_WIDESTRING(method_name), method_name##_static } \
-  ,
-
-#define END_JS_STATIC_METHOD() \
-  { 0, 0 }                     \
-  }                            \
-  ;  // NOLINT
 
 template <class C, bool (C::*M)(CJS_Runtime*, CJS_PropValue&, CFX_WideString&)>
 void JSPropGetter(const char* prop_name_string,
@@ -199,19 +165,18 @@
     DefineConsts(pEngine);                                                   \
   }
 
-#define DECLARE_JS_CLASS_CONST_PART()   \
-  static JSConstSpec JS_Class_Consts[]; \
+#define DECLARE_JS_CLASS_CONST_PART() \
+  static JSConstSpec ConstSpecs[];    \
   static void DefineConsts(CFXJS_Engine* pEngine);
 
-#define IMPLEMENT_JS_CLASS_CONST_PART(js_class_name, class_name)     \
-  void js_class_name::DefineConsts(CFXJS_Engine* pEngine) {          \
-    for (size_t i = 0; i < FX_ArraySize(JS_Class_Consts) - 1; ++i) { \
-      pEngine->DefineObjConst(                                       \
-          g_nObjDefnID, JS_Class_Consts[i].pName,                    \
-          JS_Class_Consts[i].t == 0                                  \
-              ? pEngine->NewNumber(JS_Class_Consts[i].number)        \
-              : pEngine->NewString(JS_Class_Consts[i].str));         \
-    }                                                                \
+#define IMPLEMENT_JS_CLASS_CONST_PART(js_class_name, class_name)             \
+  void js_class_name::DefineConsts(CFXJS_Engine* pEngine) {                  \
+    for (size_t i = 0; i < FX_ArraySize(ConstSpecs) - 1; ++i) {              \
+      pEngine->DefineObjConst(g_nObjDefnID, ConstSpecs[i].pName,             \
+                              ConstSpecs[i].eType == JSConstSpec::Number     \
+                                  ? pEngine->NewNumber(ConstSpecs[i].number) \
+                                  : pEngine->NewString(ConstSpecs[i].pStr)); \
+    }                                                                        \
   }
 
 // Convenience macros for declaring classes without an alternate.
@@ -244,36 +209,36 @@
   static void JSDestructor(CFXJS_Engine* pEngine, v8::Local<v8::Object> obj);  \
   static void DefineProps(CFXJS_Engine* pEngine);                              \
   static void DefineMethods(CFXJS_Engine* pEngine);                            \
-  static JSPropertySpec JS_Class_Properties[];                                 \
-  static JSMethodSpec JS_Class_Methods[];
+  static JSPropertySpec PropertySpecs[];                                       \
+  static JSMethodSpec MethodSpecs[];
 
-#define IMPLEMENT_JS_CLASS_RICH_PART(js_class_name, class_alternate,         \
-                                     class_name)                             \
-  void js_class_name::JSConstructor(CFXJS_Engine* pEngine,                   \
-                                    v8::Local<v8::Object> obj) {             \
-    CJS_Object* pObj = new js_class_name(obj);                               \
-    pObj->SetEmbedObject(new class_alternate(pObj));                         \
-    pEngine->SetObjectPrivate(obj, (void*)pObj);                             \
-    pObj->InitInstance(static_cast<CJS_Runtime*>(pEngine));                  \
-  }                                                                          \
-  void js_class_name::JSDestructor(CFXJS_Engine* pEngine,                    \
-                                   v8::Local<v8::Object> obj) {              \
-    js_class_name* pObj =                                                    \
-        static_cast<js_class_name*>(pEngine->GetObjectPrivate(obj));         \
-    delete pObj;                                                             \
-  }                                                                          \
-  void js_class_name::DefineProps(CFXJS_Engine* pEngine) {                   \
-    for (size_t i = 0; i < FX_ArraySize(JS_Class_Properties) - 1; ++i) {     \
-      pEngine->DefineObjProperty(g_nObjDefnID, JS_Class_Properties[i].pName, \
-                                 JS_Class_Properties[i].pPropGet,            \
-                                 JS_Class_Properties[i].pPropPut);           \
-    }                                                                        \
-  }                                                                          \
-  void js_class_name::DefineMethods(CFXJS_Engine* pEngine) {                 \
-    for (size_t i = 0; i < FX_ArraySize(JS_Class_Methods) - 1; ++i) {        \
-      pEngine->DefineObjMethod(g_nObjDefnID, JS_Class_Methods[i].pName,      \
-                               JS_Class_Methods[i].pMethodCall);             \
-    }                                                                        \
+#define IMPLEMENT_JS_CLASS_RICH_PART(js_class_name, class_alternate,   \
+                                     class_name)                       \
+  void js_class_name::JSConstructor(CFXJS_Engine* pEngine,             \
+                                    v8::Local<v8::Object> obj) {       \
+    CJS_Object* pObj = new js_class_name(obj);                         \
+    pObj->SetEmbedObject(new class_alternate(pObj));                   \
+    pEngine->SetObjectPrivate(obj, (void*)pObj);                       \
+    pObj->InitInstance(static_cast<CJS_Runtime*>(pEngine));            \
+  }                                                                    \
+  void js_class_name::JSDestructor(CFXJS_Engine* pEngine,              \
+                                   v8::Local<v8::Object> obj) {        \
+    js_class_name* pObj =                                              \
+        static_cast<js_class_name*>(pEngine->GetObjectPrivate(obj));   \
+    delete pObj;                                                       \
+  }                                                                    \
+  void js_class_name::DefineProps(CFXJS_Engine* pEngine) {             \
+    for (size_t i = 0; i < FX_ArraySize(PropertySpecs) - 1; ++i) {     \
+      pEngine->DefineObjProperty(g_nObjDefnID, PropertySpecs[i].pName, \
+                                 PropertySpecs[i].pPropGet,            \
+                                 PropertySpecs[i].pPropPut);           \
+    }                                                                  \
+  }                                                                    \
+  void js_class_name::DefineMethods(CFXJS_Engine* pEngine) {           \
+    for (size_t i = 0; i < FX_ArraySize(MethodSpecs) - 1; ++i) {       \
+      pEngine->DefineObjMethod(g_nObjDefnID, MethodSpecs[i].pName,     \
+                               MethodSpecs[i].pMethodCall);            \
+    }                                                                  \
   }
 
 // Special JS classes implement methods, props, and queries, but not consts.
@@ -455,24 +420,17 @@
     JSGlobalFunc<fun_name>(#fun_name, info);             \
   }
 
-#define JS_STATIC_DECLARE_GLOBAL_FUN()  \
-  static JSMethodSpec global_methods[]; \
+#define JS_STATIC_DECLARE_GLOBAL_FUN()       \
+  static JSMethodSpec GlobalFunctionSpecs[]; \
   static void DefineJSObjects(CFXJS_Engine* pEngine)
 
-#define BEGIN_JS_STATIC_GLOBAL_FUN(js_class_name) \
-  JSMethodSpec js_class_name::global_methods[] = {
-#define JS_STATIC_GLOBAL_FUN_ENTRY(method_name) \
-  JS_STATIC_METHOD_ENTRY(method_name)
-
-#define END_JS_STATIC_GLOBAL_FUN() END_JS_STATIC_METHOD()
-
-#define IMPLEMENT_JS_STATIC_GLOBAL_FUN(js_class_name)               \
-  void js_class_name::DefineJSObjects(CFXJS_Engine* pEngine) {      \
-    for (size_t i = 0; i < FX_ArraySize(global_methods) - 1; ++i) { \
-      pEngine->DefineGlobalMethod(                                  \
-          js_class_name::global_methods[i].pName,                   \
-          js_class_name::global_methods[i].pMethodCall);            \
-    }                                                               \
+#define IMPLEMENT_JS_STATIC_GLOBAL_FUN(js_class_name)                    \
+  void js_class_name::DefineJSObjects(CFXJS_Engine* pEngine) {           \
+    for (size_t i = 0; i < FX_ArraySize(GlobalFunctionSpecs) - 1; ++i) { \
+      pEngine->DefineGlobalMethod(                                       \
+          js_class_name::GlobalFunctionSpecs[i].pName,                   \
+          js_class_name::GlobalFunctionSpecs[i].pMethodCall);            \
+    }                                                                    \
   }
 
 #endif  // FPDFSDK_JAVASCRIPT_JS_DEFINE_H_
diff --git a/fpdfsdk/javascript/PublicMethods.cpp b/fpdfsdk/javascript/PublicMethods.cpp
index 7eee979..42903c2 100644
--- a/fpdfsdk/javascript/PublicMethods.cpp
+++ b/fpdfsdk/javascript/PublicMethods.cpp
@@ -30,30 +30,30 @@
 
 #define DOUBLE_CORRECT 0.000000000000001
 
-BEGIN_JS_STATIC_GLOBAL_FUN(CJS_PublicMethods)
-JS_STATIC_GLOBAL_FUN_ENTRY(AFNumber_Format)
-JS_STATIC_GLOBAL_FUN_ENTRY(AFNumber_Keystroke)
-JS_STATIC_GLOBAL_FUN_ENTRY(AFPercent_Format)
-JS_STATIC_GLOBAL_FUN_ENTRY(AFPercent_Keystroke)
-JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_FormatEx)
-JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_KeystrokeEx)
-JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_Format)
-JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_Keystroke)
-JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_FormatEx)
-JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_KeystrokeEx)
-JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_Format)
-JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_Keystroke)
-JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_Format)
-JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_Keystroke)
-JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_KeystrokeEx)
-JS_STATIC_GLOBAL_FUN_ENTRY(AFSimple)
-JS_STATIC_GLOBAL_FUN_ENTRY(AFMakeNumber)
-JS_STATIC_GLOBAL_FUN_ENTRY(AFSimple_Calculate)
-JS_STATIC_GLOBAL_FUN_ENTRY(AFRange_Validate)
-JS_STATIC_GLOBAL_FUN_ENTRY(AFMergeChange)
-JS_STATIC_GLOBAL_FUN_ENTRY(AFParseDateEx)
-JS_STATIC_GLOBAL_FUN_ENTRY(AFExtractNums)
-END_JS_STATIC_GLOBAL_FUN()
+JSMethodSpec CJS_PublicMethods::GlobalFunctionSpecs[] = {
+    {L"AFNumber_Format", AFNumber_Format_static},
+    {L"AFNumber_Keystroke", AFNumber_Keystroke_static},
+    {L"AFPercent_Format", AFPercent_Format_static},
+    {L"AFPercent_Keystroke", AFPercent_Keystroke_static},
+    {L"AFDate_FormatEx", AFDate_FormatEx_static},
+    {L"AFDate_KeystrokeEx", AFDate_KeystrokeEx_static},
+    {L"AFDate_Format", AFDate_Format_static},
+    {L"AFDate_Keystroke", AFDate_Keystroke_static},
+    {L"AFTime_FormatEx", AFTime_FormatEx_static},
+    {L"AFTime_KeystrokeEx", AFTime_KeystrokeEx_static},
+    {L"AFTime_Format", AFTime_Format_static},
+    {L"AFTime_Keystroke", AFTime_Keystroke_static},
+    {L"AFSpecial_Format", AFSpecial_Format_static},
+    {L"AFSpecial_Keystroke", AFSpecial_Keystroke_static},
+    {L"AFSpecial_KeystrokeEx", AFSpecial_KeystrokeEx_static},
+    {L"AFSimple", AFSimple_static},
+    {L"AFMakeNumber", AFMakeNumber_static},
+    {L"AFSimple_Calculate", AFSimple_Calculate_static},
+    {L"AFRange_Validate", AFRange_Validate_static},
+    {L"AFMergeChange", AFMergeChange_static},
+    {L"AFParseDateEx", AFParseDateEx_static},
+    {L"AFExtractNums", AFExtractNums_static},
+    {0, 0}};
 
 IMPLEMENT_JS_STATIC_GLOBAL_FUN(CJS_PublicMethods)
 
diff --git a/fpdfsdk/javascript/app.cpp b/fpdfsdk/javascript/app.cpp
index dfd2cc1..d2bb7bd 100644
--- a/fpdfsdk/javascript/app.cpp
+++ b/fpdfsdk/javascript/app.cpp
@@ -131,14 +131,11 @@
   return s_TimerMap;
 }
 
-BEGIN_JS_STATIC_CONST(CJS_TimerObj)
-END_JS_STATIC_CONST()
+JSConstSpec CJS_TimerObj::ConstSpecs[] = {{0, JSConstSpec::Number, 0, 0}};
 
-BEGIN_JS_STATIC_PROP(CJS_TimerObj)
-END_JS_STATIC_PROP()
+JSPropertySpec CJS_TimerObj::PropertySpecs[] = {{0, 0, 0}};
 
-BEGIN_JS_STATIC_METHOD(CJS_TimerObj)
-END_JS_STATIC_METHOD()
+JSMethodSpec CJS_TimerObj::MethodSpecs[] = {{0, 0}};
 
 IMPLEMENT_JS_CLASS(CJS_TimerObj, TimerObj)
 
@@ -161,47 +158,47 @@
 #endif  // PDF_ENABLE_XFA
 #define JS_NUM_FORMSVERSION 7
 
-BEGIN_JS_STATIC_CONST(CJS_App)
-END_JS_STATIC_CONST()
+JSConstSpec CJS_App::ConstSpecs[] = {{0, JSConstSpec::Number, 0, 0}};
 
-BEGIN_JS_STATIC_PROP(CJS_App)
-JS_STATIC_PROP_ENTRY(activeDocs)
-JS_STATIC_PROP_ENTRY(calculate)
-JS_STATIC_PROP_ENTRY(formsVersion)
-JS_STATIC_PROP_ENTRY(fs)
-JS_STATIC_PROP_ENTRY(fullscreen)
-JS_STATIC_PROP_ENTRY(language)
-JS_STATIC_PROP_ENTRY(media)
-JS_STATIC_PROP_ENTRY(platform)
-JS_STATIC_PROP_ENTRY(runtimeHighlight)
-JS_STATIC_PROP_ENTRY(viewerType)
-JS_STATIC_PROP_ENTRY(viewerVariation)
-JS_STATIC_PROP_ENTRY(viewerVersion)
-END_JS_STATIC_PROP()
+JSPropertySpec CJS_App::PropertySpecs[] = {
+    {L"activeDocs", get_activeDocs_static, set_activeDocs_static},
+    {L"calculate", get_calculate_static, set_calculate_static},
+    {L"formsVersion", get_formsVersion_static, set_formsVersion_static},
+    {L"fs", get_fs_static, set_fs_static},
+    {L"fullscreen", get_fullscreen_static, set_fullscreen_static},
+    {L"language", get_language_static, set_language_static},
+    {L"media", get_media_static, set_media_static},
+    {L"platform", get_platform_static, set_platform_static},
+    {L"runtimeHighlight", get_runtimeHighlight_static,
+     set_runtimeHighlight_static},
+    {L"viewerType", get_viewerType_static, set_viewerType_static},
+    {L"viewerVariation", get_viewerVariation_static,
+     set_viewerVariation_static},
+    {L"viewerVersion", get_viewerVersion_static, set_viewerVersion_static},
+    {0, 0, 0}};
 
-BEGIN_JS_STATIC_METHOD(CJS_App)
-JS_STATIC_METHOD_ENTRY(alert)
-JS_STATIC_METHOD_ENTRY(beep)
-JS_STATIC_METHOD_ENTRY(browseForDoc)
-JS_STATIC_METHOD_ENTRY(clearInterval)
-JS_STATIC_METHOD_ENTRY(clearTimeOut)
-JS_STATIC_METHOD_ENTRY(execDialog)
-JS_STATIC_METHOD_ENTRY(execMenuItem)
-JS_STATIC_METHOD_ENTRY(findComponent)
-JS_STATIC_METHOD_ENTRY(goBack)
-JS_STATIC_METHOD_ENTRY(goForward)
-JS_STATIC_METHOD_ENTRY(launchURL)
-JS_STATIC_METHOD_ENTRY(mailMsg)
-JS_STATIC_METHOD_ENTRY(newFDF)
-JS_STATIC_METHOD_ENTRY(newDoc)
-JS_STATIC_METHOD_ENTRY(openDoc)
-JS_STATIC_METHOD_ENTRY(openFDF)
-JS_STATIC_METHOD_ENTRY(popUpMenuEx)
-JS_STATIC_METHOD_ENTRY(popUpMenu)
-JS_STATIC_METHOD_ENTRY(response)
-JS_STATIC_METHOD_ENTRY(setInterval)
-JS_STATIC_METHOD_ENTRY(setTimeOut)
-END_JS_STATIC_METHOD()
+JSMethodSpec CJS_App::MethodSpecs[] = {{L"alert", alert_static},
+                                       {L"beep", beep_static},
+                                       {L"browseForDoc", browseForDoc_static},
+                                       {L"clearInterval", clearInterval_static},
+                                       {L"clearTimeOut", clearTimeOut_static},
+                                       {L"execDialog", execDialog_static},
+                                       {L"execMenuItem", execMenuItem_static},
+                                       {L"findComponent", findComponent_static},
+                                       {L"goBack", goBack_static},
+                                       {L"goForward", goForward_static},
+                                       {L"launchURL", launchURL_static},
+                                       {L"mailMsg", mailMsg_static},
+                                       {L"newFDF", newFDF_static},
+                                       {L"newDoc", newDoc_static},
+                                       {L"openDoc", openDoc_static},
+                                       {L"openFDF", openFDF_static},
+                                       {L"popUpMenuEx", popUpMenuEx_static},
+                                       {L"popUpMenu", popUpMenu_static},
+                                       {L"response", response_static},
+                                       {L"setInterval", setInterval_static},
+                                       {L"setTimeOut", setTimeOut_static},
+                                       {0, 0}};
 
 IMPLEMENT_JS_CLASS(CJS_App, app)
 
diff --git a/fpdfsdk/javascript/color.cpp b/fpdfsdk/javascript/color.cpp
index 90a8495..4d8701b 100644
--- a/fpdfsdk/javascript/color.cpp
+++ b/fpdfsdk/javascript/color.cpp
@@ -15,28 +15,26 @@
 #include "fpdfsdk/javascript/cjs_event_context.h"
 #include "fpdfsdk/javascript/cjs_runtime.h"
 
-BEGIN_JS_STATIC_CONST(CJS_Color)
-END_JS_STATIC_CONST()
+JSConstSpec CJS_Color::ConstSpecs[] = {{0, JSConstSpec::Number, 0, 0}};
 
-BEGIN_JS_STATIC_PROP(CJS_Color)
-JS_STATIC_PROP_ENTRY(black)
-JS_STATIC_PROP_ENTRY(blue)
-JS_STATIC_PROP_ENTRY(cyan)
-JS_STATIC_PROP_ENTRY(dkGray)
-JS_STATIC_PROP_ENTRY(gray)
-JS_STATIC_PROP_ENTRY(green)
-JS_STATIC_PROP_ENTRY(ltGray)
-JS_STATIC_PROP_ENTRY(magenta)
-JS_STATIC_PROP_ENTRY(red)
-JS_STATIC_PROP_ENTRY(transparent)
-JS_STATIC_PROP_ENTRY(white)
-JS_STATIC_PROP_ENTRY(yellow)
-END_JS_STATIC_PROP()
+JSPropertySpec CJS_Color::PropertySpecs[] = {
+    {L"black", get_black_static, set_black_static},
+    {L"blue", get_blue_static, set_blue_static},
+    {L"cyan", get_cyan_static, set_cyan_static},
+    {L"dkGray", get_dkGray_static, set_dkGray_static},
+    {L"gray", get_gray_static, set_gray_static},
+    {L"green", get_green_static, set_green_static},
+    {L"ltGray", get_ltGray_static, set_ltGray_static},
+    {L"magenta", get_magenta_static, set_magenta_static},
+    {L"red", get_red_static, set_red_static},
+    {L"transparent", get_transparent_static, set_transparent_static},
+    {L"white", get_white_static, set_white_static},
+    {L"yellow", get_yellow_static, set_yellow_static},
+    {0, 0, 0}};
 
-BEGIN_JS_STATIC_METHOD(CJS_Color)
-JS_STATIC_METHOD_ENTRY(convert)
-JS_STATIC_METHOD_ENTRY(equal)
-END_JS_STATIC_METHOD()
+JSMethodSpec CJS_Color::MethodSpecs[] = {{L"convert", convert_static},
+                                         {L"equal", equal_static},
+                                         {0, 0}};
 
 IMPLEMENT_JS_CLASS(CJS_Color, color)
 
diff --git a/fpdfsdk/javascript/console.cpp b/fpdfsdk/javascript/console.cpp
index fdef98f..1b0d81d 100644
--- a/fpdfsdk/javascript/console.cpp
+++ b/fpdfsdk/javascript/console.cpp
@@ -14,18 +14,15 @@
 #include "fpdfsdk/javascript/JS_Value.h"
 #include "fpdfsdk/javascript/cjs_event_context.h"
 
-BEGIN_JS_STATIC_CONST(CJS_Console)
-END_JS_STATIC_CONST()
+JSConstSpec CJS_Console::ConstSpecs[] = {{0, JSConstSpec::Number, 0, 0}};
 
-BEGIN_JS_STATIC_PROP(CJS_Console)
-END_JS_STATIC_PROP()
+JSPropertySpec CJS_Console::PropertySpecs[] = {{0, 0, 0}};
 
-BEGIN_JS_STATIC_METHOD(CJS_Console)
-JS_STATIC_METHOD_ENTRY(clear)
-JS_STATIC_METHOD_ENTRY(hide)
-JS_STATIC_METHOD_ENTRY(println)
-JS_STATIC_METHOD_ENTRY(show)
-END_JS_STATIC_METHOD()
+JSMethodSpec CJS_Console::MethodSpecs[] = {{L"clear", clear_static},
+                                           {L"hide", hide_static},
+                                           {L"println", println_static},
+                                           {L"show", show_static},
+                                           {0, 0}};
 
 IMPLEMENT_JS_CLASS(CJS_Console, console)
 
diff --git a/fpdfsdk/javascript/event.cpp b/fpdfsdk/javascript/event.cpp
index 88dce4b..323e2dd 100644
--- a/fpdfsdk/javascript/event.cpp
+++ b/fpdfsdk/javascript/event.cpp
@@ -13,34 +13,32 @@
 #include "fpdfsdk/javascript/JS_Value.h"
 #include "fpdfsdk/javascript/cjs_event_context.h"
 
-BEGIN_JS_STATIC_CONST(CJS_Event)
-END_JS_STATIC_CONST()
+JSConstSpec CJS_Event::ConstSpecs[] = {{0, JSConstSpec::Number, 0, 0}};
 
-BEGIN_JS_STATIC_PROP(CJS_Event)
-JS_STATIC_PROP_ENTRY(change)
-JS_STATIC_PROP_ENTRY(changeEx)
-JS_STATIC_PROP_ENTRY(commitKey)
-JS_STATIC_PROP_ENTRY(fieldFull)
-JS_STATIC_PROP_ENTRY(keyDown)
-JS_STATIC_PROP_ENTRY(modifier)
-JS_STATIC_PROP_ENTRY(name)
-JS_STATIC_PROP_ENTRY(rc)
-JS_STATIC_PROP_ENTRY(richChange)
-JS_STATIC_PROP_ENTRY(richChangeEx)
-JS_STATIC_PROP_ENTRY(richValue)
-JS_STATIC_PROP_ENTRY(selEnd)
-JS_STATIC_PROP_ENTRY(selStart)
-JS_STATIC_PROP_ENTRY(shift)
-JS_STATIC_PROP_ENTRY(source)
-JS_STATIC_PROP_ENTRY(target)
-JS_STATIC_PROP_ENTRY(targetName)
-JS_STATIC_PROP_ENTRY(type)
-JS_STATIC_PROP_ENTRY(value)
-JS_STATIC_PROP_ENTRY(willCommit)
-END_JS_STATIC_PROP()
+JSPropertySpec CJS_Event::PropertySpecs[] = {
+    {L"change", get_change_static, set_change_static},
+    {L"changeEx", get_changeEx_static, set_changeEx_static},
+    {L"commitKey", get_commitKey_static, set_commitKey_static},
+    {L"fieldFull", get_fieldFull_static, set_fieldFull_static},
+    {L"keyDown", get_keyDown_static, set_keyDown_static},
+    {L"modifier", get_modifier_static, set_modifier_static},
+    {L"name", get_name_static, set_name_static},
+    {L"rc", get_rc_static, set_rc_static},
+    {L"richChange", get_richChange_static, set_richChange_static},
+    {L"richChangeEx", get_richChangeEx_static, set_richChangeEx_static},
+    {L"richValue", get_richValue_static, set_richValue_static},
+    {L"selEnd", get_selEnd_static, set_selEnd_static},
+    {L"selStart", get_selStart_static, set_selStart_static},
+    {L"shift", get_shift_static, set_shift_static},
+    {L"source", get_source_static, set_source_static},
+    {L"target", get_target_static, set_target_static},
+    {L"targetName", get_targetName_static, set_targetName_static},
+    {L"type", get_type_static, set_type_static},
+    {L"value", get_value_static, set_value_static},
+    {L"willCommit", get_willCommit_static, set_willCommit_static},
+    {0, 0, 0}};
 
-BEGIN_JS_STATIC_METHOD(CJS_Event)
-END_JS_STATIC_METHOD()
+JSMethodSpec CJS_Event::MethodSpecs[] = {{0, 0}};
 
 IMPLEMENT_JS_CLASS(CJS_Event, event)
 
diff --git a/fpdfsdk/javascript/global.cpp b/fpdfsdk/javascript/global.cpp
index 8f9ce1a..df379c9 100644
--- a/fpdfsdk/javascript/global.cpp
+++ b/fpdfsdk/javascript/global.cpp
@@ -17,15 +17,13 @@
 #include "fpdfsdk/javascript/cjs_event_context.h"
 #include "fpdfsdk/javascript/resource.h"
 
-BEGIN_JS_STATIC_CONST(CJS_Global)
-END_JS_STATIC_CONST()
+JSConstSpec CJS_Global::ConstSpecs[] = {{0, JSConstSpec::Number, 0, 0}};
 
-BEGIN_JS_STATIC_PROP(CJS_Global)
-END_JS_STATIC_PROP()
+JSPropertySpec CJS_Global::PropertySpecs[] = {{0, 0, 0}};
 
-BEGIN_JS_STATIC_METHOD(CJS_Global)
-JS_STATIC_METHOD_ENTRY(setPersistent)
-END_JS_STATIC_METHOD()
+JSMethodSpec CJS_Global::MethodSpecs[] = {
+    {L"setPersistent", setPersistent_static},
+    {0, 0}};
 
 IMPLEMENT_SPECIAL_JS_CLASS(CJS_Global, JSGlobalAlternate, global);
 
diff --git a/fpdfsdk/javascript/report.cpp b/fpdfsdk/javascript/report.cpp
index 2cb123a..6c98f12 100644
--- a/fpdfsdk/javascript/report.cpp
+++ b/fpdfsdk/javascript/report.cpp
@@ -12,16 +12,13 @@
 #include "fpdfsdk/javascript/JS_Object.h"
 #include "fpdfsdk/javascript/JS_Value.h"
 
-BEGIN_JS_STATIC_CONST(CJS_Report)
-END_JS_STATIC_CONST()
+JSConstSpec CJS_Report::ConstSpecs[] = {{0, JSConstSpec::Number, 0, 0}};
 
-BEGIN_JS_STATIC_PROP(CJS_Report)
-END_JS_STATIC_PROP()
+JSPropertySpec CJS_Report::PropertySpecs[] = {{0, 0, 0}};
 
-BEGIN_JS_STATIC_METHOD(CJS_Report)
-JS_STATIC_METHOD_ENTRY(save)
-JS_STATIC_METHOD_ENTRY(writeText)
-END_JS_STATIC_METHOD()
+JSMethodSpec CJS_Report::MethodSpecs[] = {{L"save", save_static},
+                                          {L"writeText", writeText_static},
+                                          {0, 0}};
 
 IMPLEMENT_JS_CLASS(CJS_Report, Report)
 
diff --git a/fpdfsdk/javascript/util.cpp b/fpdfsdk/javascript/util.cpp
index 8ae1773..b5423e3 100644
--- a/fpdfsdk/javascript/util.cpp
+++ b/fpdfsdk/javascript/util.cpp
@@ -26,19 +26,14 @@
 #include <ctype.h>
 #endif
 
-BEGIN_JS_STATIC_CONST(CJS_Util)
-END_JS_STATIC_CONST()
+JSConstSpec CJS_Util::ConstSpecs[] = {{0, JSConstSpec::Number, 0, 0}};
 
-BEGIN_JS_STATIC_PROP(CJS_Util)
-END_JS_STATIC_PROP()
+JSPropertySpec CJS_Util::PropertySpecs[] = {{0, 0, 0}};
 
-BEGIN_JS_STATIC_METHOD(CJS_Util)
-JS_STATIC_METHOD_ENTRY(printd)
-JS_STATIC_METHOD_ENTRY(printf)
-JS_STATIC_METHOD_ENTRY(printx)
-JS_STATIC_METHOD_ENTRY(scand)
-JS_STATIC_METHOD_ENTRY(byteToChar)
-END_JS_STATIC_METHOD()
+JSMethodSpec CJS_Util::MethodSpecs[] = {
+    {L"printd", printd_static},         {L"printf", printf_static},
+    {L"printx", printx_static},         {L"scand", scand_static},
+    {L"byteToChar", byteToChar_static}, {0, 0}};
 
 IMPLEMENT_JS_CLASS(CJS_Util, util)