d7396adcdea7 — Steve Fink 5 years ago
[knowledge] Remove the hardcoded enum definitions, replace with parsing actual source. Note that adding a new Value type would not actually work automatically; there are hardcoded pieces too.
1 files changed, 41 insertions(+), 83 deletions(-)

M plugins/knowledge/__init__.py
M plugins/knowledge/__init__.py +41 -83
@@ 9,6 9,20 @@ from collections import defaultdict
 from twisted.internet.task import LoopingCall
 from twisted.python import log
 
+def get_text_range(line_iter, start_re, end_re):
+    start_pattern = re.compile(start_re)
+    end_pattern = re.compile(end_re)
+    text = None
+    for line in line_iter:
+        if text is None:
+            if start_pattern.match(line):
+                text = line
+        else:
+            text += line
+            if end_pattern.match(line):
+                return text
+    raise Exception("start and/or end pattern not seen")
+
 def parse_enum(s, handler):
     pending_comment = None
     enum_value = 0

          
@@ 27,6 41,14 @@ def parse_enum(s, handler):
                 handler(name, value, pending_comment)
                 pending_comment = None
 
+# Example:
+#
+#    typedef enum JSWhyMagic
+#    {
+#    /** a hole in a native object's elements */
+#    JS_ELEMENTS_HOLE,
+#    ...
+#
 def parse_magic(s):
     table = {}
 

          
@@ 36,67 58,12 @@ def parse_magic(s):
     parse_enum(s, handle)
     return table
 
-JSVAL_MAGIC = parse_magic('''
-typedef enum JSWhyMagic
-{
-    /** a hole in a native object's elements */
-    JS_ELEMENTS_HOLE,
-
-    /** there is not a pending iterator value */
-    JS_NO_ITER_VALUE,
-
-    /** exception value thrown when closing a generator */
-    JS_GENERATOR_CLOSING,
-
-    /** compiler sentinel value */
-    JS_NO_CONSTANT,
-
-    /** used in debug builds to catch tracing errors */
-    JS_THIS_POISON,
-
-    /** used in debug builds to catch tracing errors */
-    JS_ARG_POISON,
-
-    /** an empty subnode in the AST serializer */
-    JS_SERIALIZE_NO_NODE,
-
-    /** lazy arguments value on the stack */
-    JS_LAZY_ARGUMENTS,
-
-    /** optimized-away 'arguments' value */
-    JS_OPTIMIZED_ARGUMENTS,
-
-    /** magic value passed to natives to indicate construction */
-    JS_IS_CONSTRUCTING,
-
-    /** value of static block object slot */
-    JS_BLOCK_NEEDS_CLONE,
-
-    /** see class js::HashableValue */
-    JS_HASH_KEY_EMPTY,
-
-    /** error while running Ion code */
-    JS_ION_ERROR,
-
-    /** missing recover instruction result */
-    JS_ION_BAILOUT,
-
-    /** optimized out slot */
-    JS_OPTIMIZED_OUT,
-
-    /** uninitialized lexical bindings that produce ReferenceError on touch. */
-    JS_UNINITIALIZED_LEXICAL,
-
-    /** standard constructors are not created for off-thread parsing. */
-    JS_OFF_THREAD_CONSTRUCTOR,
-
-    /** for local use */
-    JS_GENERIC_MAGIC,
-
-    JS_WHY_MAGIC_COUNT
-} JSWhyMagic;
-''')
-
+# Example:
+#
+#  enum JSValueType : uint8_t {
+#  JSVAL_TYPE_DOUBLE = 0x00,
+#  JSVAL_TYPE_INT32 = 0x01,
+#  ...
 def parse_JSValueType(s):
     table = {}
 

          
@@ 106,26 73,8 @@ def parse_JSValueType(s):
     parse_enum(s, handle)
     return table
 
-tagToType = parse_JSValueType('''
-JS_ENUM_HEADER(JSValueType, uint8_t)
-{
-    JSVAL_TYPE_DOUBLE              = 0x00,
-    JSVAL_TYPE_INT32               = 0x01,
-    JSVAL_TYPE_BOOLEAN             = 0x02,
-    JSVAL_TYPE_UNDEFINED           = 0x03,
-    JSVAL_TYPE_NULL                = 0x04,
-    JSVAL_TYPE_MAGIC               = 0x05,
-    JSVAL_TYPE_STRING              = 0x06,
-    JSVAL_TYPE_SYMBOL              = 0x07,
-    JSVAL_TYPE_PRIVATE_GCTHING     = 0x08,
-    JSVAL_TYPE_BIGINT              = 0x09,
-    JSVAL_TYPE_OBJECT              = 0x0c,
-
-    /* These never appear in a jsval; they are only provided as an out-of-band value. */
-    JSVAL_TYPE_UNKNOWN             = 0x20,
-    JSVAL_TYPE_MISSING             = 0x21
-} JS_ENUM_FOOTER(JSValueType);
-''')
+JSVAL_MAGIC = None
+tagToType = None
 
 JSVAL_TAG_SHIFT = 47
 JSVAL_TAG_MAX_DOUBLE           = 0x1FFF0

          
@@ 454,7 403,7 @@ it is the symptom when you mark a Cell (
         self.poller = None
 
     def startup(self):
-        self.poller = LoopingCall(self.load_nsresults)
+        self.poller = LoopingCall(self.extract_from_source)
         self.handle_poll_error(None, self.poller)  # Actually start the looper
 
     # Handle errors by restarting the looping call

          
@@ 594,7 543,16 @@ it is the symptom when you mark a Cell (
         elif platform == 'fastcall':
             return "fastcall x86: f(ECX, EDX); push(argN)..push(arg2); push(retaddr); ret=EAX"
 
-    def load_nsresults(self):
+    def parse_jsapi_stuff(self):
+        with open(os.path.join(self.config['checkout-path'], "js/public/Value.h"), "r") as fh:
+            global JSVAL_MAGIC
+            JSVAL_MAGIC = parse_magic(get_text_range(fh, r'^enum JSWhyMagic', r'^\}'))
+        with open(os.path.join(self.config['checkout-path'], "js/public/Value.h"), "r") as fh:
+            global tagToType
+            tagToType = parse_JSValueType(get_text_range(fh, r'^enum JSValueType', r'^\}'))
+
+    def extract_from_source(self):
+        self.parse_jsapi_stuff()
         nsresult_code_to_number.clear()
         nsresult_number_to_codes.clear()
         nsresult_number_to_module.clear()