[Webkit-unassigned] [Bug 48485] Crash in Function.prototype.call.apply

bugzilla-daemon at webkit.org bugzilla-daemon at webkit.org
Fri Oct 29 09:33:25 PDT 2010


https://bugs.webkit.org/show_bug.cgi?id=48485





--- Comment #4 from Zoltan Herczeg <zherczeg at webkit.org>  2010-10-29 09:33:24 PST ---
Hi guys,

actually I am little confused with this bug as I don't exactly remember how JS call system should work, and I need a little help.

This is a simplified example:

function g() {
    Function.prototype.call.apply(g, arguments);
}

g(0, 0, 0)

The byte-code of function g():

[   0] enter
[   1] init_lazy_reg     r1
[   3] init_lazy_reg     r0
[   5] resolve_global    r2, Function(@id0)
[  10] get_by_id         r2, r2, prototype(@id1)
[  18] get_by_id         r2, r2, call(@id2)
[  26] get_by_id         r3, r2, apply(@id3)
[  34] jneq_ptr          r3, r-1220017856, 22(->56)
[  38] mov               r4, r2
[  41] get_global_var    r6, -6
[  44] mov               r7, r1
[  47] load_varargs              r5, r7
[  50] call_varargs      r4, r5, 12
[  54] jmp               17(->71)
[  56] mov               r4, r2
[  59] get_global_var    r5, -6
[  62] create_arguments  r1
[  64] mov               r6, r1
[  67] call              r3, 3, 13
[  71] ret               undefined(@k0)

Before the "enter", the RegisterFile is extended, since the 'g' expects 0 parameter and got 3. Thus op_call_arityCheck() set the registerFile->m_end to 0x..100 (memory returned by mmap is always page aligned, thus the last 3 digit is always the same). As far as I remember, this should be the end of the memory used by the JS functon, shouldn't it?

The emit_op_load_varargs does not call the helper-stub function, it just extend %edi (call frame ptr) to 0x...118, which is 3 registers beyond the end of the registerFile, and should be never written by JIT code, shoudn't it?

call_varargs pass %edi as the call frame, and in Interpreter::executeCall oldEnd still points to 0x..100, and the callFrame to 0x...118. (I think an assert would be useful here).

    for (ArgList::const_iterator it = args.begin(); it != end; ++it)
        newCallFrame->r(++dst) = *it;

The 'for' above overwrites callFrame members (still in Interpreter::executeCall).

As far as I remember, registerFile->m_end points after the last available register, and no writes should happen after it. Thus I would blame emit_op_load_varargs at the moment, but I would be curious about your opinion.

-- 
Configure bugmail: https://bugs.webkit.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug.



More information about the webkit-unassigned mailing list