03.12.14

Working on the JS engine, Episode V

From a stack trace for a crash:

20:12:01     INFO -   2  libxul.so!bool js::DependentAddPtr<js::HashSet<js::ReadBarriered<js::UnownedBaseShape*>, js::StackBaseShape, js::SystemAllocPolicy> >::add<JS::RootedGeneric<js::StackBaseShape*>, js::UnownedBaseShape*>(js::ExclusiveContext const*, js::HashSet<js::ReadBarriered<js::UnownedBaseShape*>, js::StackBaseShape, js::SystemAllocPolicy>&, JS::RootedGeneric<js::StackBaseShape*> const&, js::UnownedBaseShape* const&) [HashTable.h:3ba384952a02 : 372 + 0x4]

If you can figure out where in that mess the actual method name is without staring at this for at least 15 seconds, I salute you. (Note that when I saw this originally, it wasn’t line-wrapped, making it even less readable.)

I’m not sure how this could be presented better, given the depth and breadth of template use in the class, in the template parameters to that class, in the method, and in the method arguments here.

03.02.11

Working on the JS engine, Episode IV

A testcase submitted to us today:

([][(![]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+[]]+(![]+[]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]]()+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][(![]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+[]]+(![]+[]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]]()+[])[!+[]+!+[]]

The result according to ES3, plus a common implementation-specific behavior, is the string "job".

The result according to ES5, plus a common implementation-specific behavior, is a thrown TypeError.

26.02.10

Working on the JS engine, Episode III: offered without comment

#define WORKAROUND(cx_, saver_)                                               \
    Workaround WORKAROUND_PASTE(w_, __LINE__)((cx_), (saver_))
#define WORKAROUND_PASTE(a_, b_) WORKAROUND_PASTE2(a_, b_)
#define WORKAROUND_PASTE2(a_, b_) a_ ## b_ /* having fun yet? */
#define SAVER(cx_, saver_)                                                    \
    AutoValueRooter saver_(cx_);                                              \
    WORKAROUND((cx_), (saver_));

16.10.09

Working on the JS engine, redux

In a continuation of a topic started by mrbkap, I present you this gem of a gdb command I needed to use today:

cond 8 \
  (*$9 && \
   ((*$9)->id&7) == 4 && \
   (*(jschar**)((uintptr_t) (*$9)->id + 4))[0] == 'o' && \
   (*(jschar**)((uintptr_t) (*$9)->id + 4))[1] == 'f' && \
   (*(jschar**)((uintptr_t) (*$9)->id + 4))[2] == 'f')

For minimal background, breakpoint 8 was the result of watch *$9, and of course $9 = (JSScopeProperty **) 0x7ffff2f08038.

By the way, did you know the gdb command line supports line continuations? I didn’t, before I had to think about how the above command would display without any. 🙂 This is the above command as I originally wrote it:

cond 8 (*$9 && ((*$9)->id&7) == 4 && (*(jschar**)((uintptr_t) (*$9)->id + 4))[0] == 'o' && (*(jschar**)((uintptr_t) (*$9)->id + 4))[1] == 'f' && (*(jschar**)((uintptr_t) (*$9)->id + 4))[2] == 'f')