@@ 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()