Changeset 179538 in webkit


Ignore:
Timestamp:
Feb 2, 2015 9:20:59 PM (9 years ago)
Author:
fpizlo@apple.com
Message:

arguments[-1] should have well-defined behavior
https://bugs.webkit.org/show_bug.cgi?id=141183

Reviewed by Mark Lam.

According to JSC's internal argument numbering, 0 is "this" and 1 is the first argument.
In the "arguments[i]" expression, "this" is not accessible and i = 0 refers to the first
argument. Previously we handled the bounds check in "arguments[i]" - where "arguments" is
statically known to be the current function's arguments object - as follows:

add 1, i
branchAboveOrEqual i, callFrame.ArgumentCount, slowPath


The problem with this is that if i = -1, this passes the test, and we end up accessing
what would be the "this" argument slot. That's wrong, since we should really be bottoming
out in arguments-1?, which is usually undefined but could be anything. It's even worse
if the function is inlined or if we're in a constructor - in that case the "this" slot
could be garbage.

It turns out that we had this bug in all of our engines.

This fixes the issue by changing the algorithm to:

load32 callFrame.ArgumentCount, tmp
sub 1, tmp
branchAboveOrEqual i, tmp, slowPath


In some engines, we would have used the modified "i" (the one that had 1 added to it) for
the subsequent argument load; since we don't do this anymore I also had to change some of
the offsets on the BaseIndex arguments load.

This also includes tests that are written in such a way as to get coverage on LLInt and
Baseline JIT (get-my-argument-by-val-wrap-around-no-warm-up), DFG and FTL
(get-my-argument-by-val-wrap-around), and DFG when we're being paranoid about the user
overwriting the "arguments" variable (get-my-argument-by-val-safe-wrap-around). This also
includes off-by-1 out-of-bounds tests for each of these cases, since in the process of
writing the patch I broke the arguments[arguments.length] case in the DFG and didn't see
any test failures.

  • dfg/DFGSpeculativeJIT32_64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • ftl/FTLLowerDFGToLLVM.cpp:

(JSC::FTL::LowerDFGToLLVM::compileGetMyArgumentByVal):

  • jit/AssemblyHelpers.h:

(JSC::AssemblyHelpers::offsetOfArguments):
(JSC::AssemblyHelpers::offsetOfArgumentsIncludingThis): Deleted.

  • jit/JITOpcodes.cpp:

(JSC::JIT::emit_op_get_argument_by_val):

  • jit/JITOpcodes32_64.cpp:

(JSC::JIT::emit_op_get_argument_by_val):

  • llint/LowLevelInterpreter.asm:
  • llint/LowLevelInterpreter32_64.asm:
  • llint/LowLevelInterpreter64.asm:
  • tests/stress/get-my-argument-by-val-out-of-bounds-no-warm-up.js: Added.

(foo):

  • tests/stress/get-my-argument-by-val-out-of-bounds.js: Added.

(foo):

  • tests/stress/get-my-argument-by-val-safe-out-of-bounds.js: Added.

(foo):

  • tests/stress/get-my-argument-by-val-safe-wrap-around.js: Added.

(foo):

  • tests/stress/get-my-argument-by-val-wrap-around-no-warm-up.js: Added.

(foo):

  • tests/stress/get-my-argument-by-val-wrap-around.js: Added.

(foo):

Location:
trunk/Source/JavaScriptCore
Files:
6 added
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r179536 r179538  
     12015-02-02  Filip Pizlo  <fpizlo@apple.com>
     2
     3        arguments[-1] should have well-defined behavior
     4        https://bugs.webkit.org/show_bug.cgi?id=141183
     5
     6        Reviewed by Mark Lam.
     7       
     8        According to JSC's internal argument numbering, 0 is "this" and 1 is the first argument.
     9        In the "arguments[i]" expression, "this" is not accessible and i = 0 refers to the first
     10        argument. Previously we handled the bounds check in "arguments[i]" - where "arguments" is
     11        statically known to be the current function's arguments object - as follows:
     12       
     13            add 1, i
     14            branchAboveOrEqual i, callFrame.ArgumentCount, slowPath
     15       
     16        The problem with this is that if i = -1, this passes the test, and we end up accessing
     17        what would be the "this" argument slot. That's wrong, since we should really be bottoming
     18        out in arguments["-1"], which is usually undefined but could be anything. It's even worse
     19        if the function is inlined or if we're in a constructor - in that case the "this" slot
     20        could be garbage.
     21       
     22        It turns out that we had this bug in all of our engines.
     23       
     24        This fixes the issue by changing the algorithm to:
     25       
     26            load32 callFrame.ArgumentCount, tmp
     27            sub 1, tmp
     28            branchAboveOrEqual i, tmp, slowPath
     29       
     30        In some engines, we would have used the modified "i" (the one that had 1 added to it) for
     31        the subsequent argument load; since we don't do this anymore I also had to change some of
     32        the offsets on the BaseIndex arguments load.
     33       
     34        This also includes tests that are written in such a way as to get coverage on LLInt and
     35        Baseline JIT (get-my-argument-by-val-wrap-around-no-warm-up), DFG and FTL
     36        (get-my-argument-by-val-wrap-around), and DFG when we're being paranoid about the user
     37        overwriting the "arguments" variable (get-my-argument-by-val-safe-wrap-around). This also
     38        includes off-by-1 out-of-bounds tests for each of these cases, since in the process of
     39        writing the patch I broke the arguments[arguments.length] case in the DFG and didn't see
     40        any test failures.
     41
     42        * dfg/DFGSpeculativeJIT32_64.cpp:
     43        (JSC::DFG::SpeculativeJIT::compile):
     44        * dfg/DFGSpeculativeJIT64.cpp:
     45        (JSC::DFG::SpeculativeJIT::compile):
     46        * ftl/FTLLowerDFGToLLVM.cpp:
     47        (JSC::FTL::LowerDFGToLLVM::compileGetMyArgumentByVal):
     48        * jit/AssemblyHelpers.h:
     49        (JSC::AssemblyHelpers::offsetOfArguments):
     50        (JSC::AssemblyHelpers::offsetOfArgumentsIncludingThis): Deleted.
     51        * jit/JITOpcodes.cpp:
     52        (JSC::JIT::emit_op_get_argument_by_val):
     53        * jit/JITOpcodes32_64.cpp:
     54        (JSC::JIT::emit_op_get_argument_by_val):
     55        * llint/LowLevelInterpreter.asm:
     56        * llint/LowLevelInterpreter32_64.asm:
     57        * llint/LowLevelInterpreter64.asm:
     58        * tests/stress/get-my-argument-by-val-out-of-bounds-no-warm-up.js: Added.
     59        (foo):
     60        * tests/stress/get-my-argument-by-val-out-of-bounds.js: Added.
     61        (foo):
     62        * tests/stress/get-my-argument-by-val-safe-out-of-bounds.js: Added.
     63        (foo):
     64        * tests/stress/get-my-argument-by-val-safe-wrap-around.js: Added.
     65        (foo):
     66        * tests/stress/get-my-argument-by-val-wrap-around-no-warm-up.js: Added.
     67        (foo):
     68        * tests/stress/get-my-argument-by-val-wrap-around.js: Added.
     69        (foo):
     70
    1712015-02-02  Filip Pizlo  <fpizlo@apple.com>
    272
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

    r179478 r179538  
    43484348        }
    43494349           
    4350         m_jit.add32(TrustedImm32(1), indexGPR, resultPayloadGPR);
    4351            
    43524350        if (node->origin.semantic.inlineCallFrame) {
    43534351            speculationCheck(
     
    43554353                m_jit.branch32(
    43564354                    JITCompiler::AboveOrEqual,
    4357                     resultPayloadGPR,
    4358                     Imm32(node->origin.semantic.inlineCallFrame->arguments.size())));
     4355                    indexGPR,
     4356                    Imm32(node->origin.semantic.inlineCallFrame->arguments.size() - 1)));
    43594357        } else {
     4358            m_jit.load32(JITCompiler::payloadFor(JSStack::ArgumentCount), resultPayloadGPR);
     4359            m_jit.sub32(TrustedImm32(1), resultPayloadGPR);
    43604360            speculationCheck(
    43614361                Uncountable, JSValueRegs(), 0,
    4362                 m_jit.branch32(
    4363                     JITCompiler::AboveOrEqual,
    4364                     resultPayloadGPR,
    4365                     JITCompiler::payloadFor(JSStack::ArgumentCount)));
     4362                m_jit.branch32(JITCompiler::AboveOrEqual, indexGPR, resultPayloadGPR));
    43664363        }
    43674364       
     
    44004397        m_jit.load32(
    44014398            JITCompiler::BaseIndex(
    4402                 GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight,
    4403                 m_jit.offsetOfArgumentsIncludingThis(node->origin.semantic) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)),
     4399                GPRInfo::callFrameRegister, indexGPR, JITCompiler::TimesEight,
     4400                m_jit.offsetOfArguments(node->origin.semantic) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)),
    44044401            resultTagGPR);
    44054402        m_jit.load32(
    44064403            JITCompiler::BaseIndex(
    4407                 GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight,
    4408                 m_jit.offsetOfArgumentsIncludingThis(node->origin.semantic) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)),
     4404                GPRInfo::callFrameRegister, indexGPR, JITCompiler::TimesEight,
     4405                m_jit.offsetOfArguments(node->origin.semantic) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)),
    44094406            resultPayloadGPR);
    44104407           
     
    44284425                TrustedImm32(JSValue::EmptyValueTag)));
    44294426       
    4430         m_jit.add32(TrustedImm32(1), indexGPR, resultPayloadGPR);
    44314427        if (node->origin.semantic.inlineCallFrame) {
    44324428            slowPath.append(
    44334429                m_jit.branch32(
    44344430                    JITCompiler::AboveOrEqual,
    4435                     resultPayloadGPR,
    4436                     Imm32(node->origin.semantic.inlineCallFrame->arguments.size())));
     4431                    indexGPR,
     4432                    Imm32(node->origin.semantic.inlineCallFrame->arguments.size() - 1)));
    44374433        } else {
     4434            m_jit.load32(JITCompiler::payloadFor(JSStack::ArgumentCount), resultPayloadGPR);
     4435            m_jit.sub32(TrustedImm32(1), resultPayloadGPR);
    44384436            slowPath.append(
    4439                 m_jit.branch32(
    4440                     JITCompiler::AboveOrEqual,
    4441                     resultPayloadGPR,
    4442                     JITCompiler::payloadFor(JSStack::ArgumentCount)));
     4437                m_jit.branch32(JITCompiler::AboveOrEqual, indexGPR, resultPayloadGPR));
    44434438        }
    44444439       
     
    44764471        m_jit.load32(
    44774472            JITCompiler::BaseIndex(
    4478                 GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight,
    4479                 m_jit.offsetOfArgumentsIncludingThis(node->origin.semantic) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)),
     4473                GPRInfo::callFrameRegister, indexGPR, JITCompiler::TimesEight,
     4474                m_jit.offsetOfArguments(node->origin.semantic) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)),
    44804475            resultTagGPR);
    44814476        m_jit.load32(
    44824477            JITCompiler::BaseIndex(
    4483                 GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight,
    4484                 m_jit.offsetOfArgumentsIncludingThis(node->origin.semantic) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)),
     4478                GPRInfo::callFrameRegister, indexGPR, JITCompiler::TimesEight,
     4479                m_jit.offsetOfArguments(node->origin.semantic) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)),
    44854480            resultPayloadGPR);
    44864481       
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r179478 r179538  
    43954395        }
    43964396
    4397         m_jit.add32(TrustedImm32(1), indexGPR, resultGPR);
    43984397        if (node->origin.semantic.inlineCallFrame) {
    43994398            speculationCheck(
     
    44014400                m_jit.branch32(
    44024401                    JITCompiler::AboveOrEqual,
    4403                     resultGPR,
    4404                     Imm32(node->origin.semantic.inlineCallFrame->arguments.size())));
     4402                    indexGPR,
     4403                    Imm32(node->origin.semantic.inlineCallFrame->arguments.size() - 1)));
    44054404        } else {
     4405            m_jit.load32(JITCompiler::payloadFor(JSStack::ArgumentCount), resultGPR);
     4406            m_jit.sub32(TrustedImm32(1), resultGPR);
    44064407            speculationCheck(
    44074408                Uncountable, JSValueRegs(), 0,
    4408                 m_jit.branch32(
    4409                     JITCompiler::AboveOrEqual,
    4410                     resultGPR,
    4411                     JITCompiler::payloadFor(JSStack::ArgumentCount)));
     4409                m_jit.branch32(JITCompiler::AboveOrEqual, indexGPR, resultGPR));
    44124410        }
    44134411
     
    44394437        slowArgumentOutOfBounds.link(&m_jit);
    44404438
    4441         m_jit.signExtend32ToPtr(resultGPR, resultGPR);
    4442            
    44434439        m_jit.load64(
    44444440            JITCompiler::BaseIndex(
    4445                 GPRInfo::callFrameRegister, resultGPR, JITCompiler::TimesEight, m_jit.offsetOfArgumentsIncludingThis(node->origin.semantic)),
     4441                GPRInfo::callFrameRegister, indexGPR, JITCompiler::TimesEight, m_jit.offsetOfArguments(node->origin.semantic)),
    44464442            resultGPR);
    44474443
     
    44644460                    m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic))));
    44654461       
    4466         m_jit.add32(TrustedImm32(1), indexGPR, resultGPR);
    44674462        if (node->origin.semantic.inlineCallFrame) {
    44684463            slowPath.append(
     
    44704465                    JITCompiler::AboveOrEqual,
    44714466                    resultGPR,
    4472                     Imm32(node->origin.semantic.inlineCallFrame->arguments.size())));
     4467                    Imm32(node->origin.semantic.inlineCallFrame->arguments.size() - 1)));
    44734468        } else {
     4469            m_jit.load32(JITCompiler::payloadFor(JSStack::ArgumentCount), resultGPR);
     4470            m_jit.sub32(TrustedImm32(1), resultGPR);
    44744471            slowPath.append(
    4475                 m_jit.branch32(
    4476                     JITCompiler::AboveOrEqual,
    4477                     resultGPR,
    4478                     JITCompiler::payloadFor(JSStack::ArgumentCount)));
     4472                m_jit.branch32(JITCompiler::AboveOrEqual, indexGPR, resultGPR));
    44794473        }
    44804474       
     
    45064500        slowArgumentOutOfBounds.link(&m_jit);
    45074501
    4508         m_jit.signExtend32ToPtr(resultGPR, resultGPR);
    4509        
    45104502        m_jit.load64(
    45114503            JITCompiler::BaseIndex(
    4512                 GPRInfo::callFrameRegister, resultGPR, JITCompiler::TimesEight, m_jit.offsetOfArgumentsIncludingThis(node->origin.semantic)),
     4504                GPRInfo::callFrameRegister, indexGPR, JITCompiler::TimesEight, m_jit.offsetOfArguments(node->origin.semantic)),
    45134505            resultGPR);
    45144506       
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp

    r179515 r179538  
    11/*
    2  * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    19981998        CodeOrigin codeOrigin = m_node->origin.semantic;
    19991999       
    2000         LValue zeroBasedIndex = lowInt32(m_node->child1());
    2001         LValue oneBasedIndex = m_out.add(zeroBasedIndex, m_out.int32One);
     2000        LValue index = lowInt32(m_node->child1());
    20022001       
    20032002        LValue limit;
    20042003        if (codeOrigin.inlineCallFrame)
    2005             limit = m_out.constInt32(codeOrigin.inlineCallFrame->arguments.size());
     2004            limit = m_out.constInt32(codeOrigin.inlineCallFrame->arguments.size() - 1);
    20062005        else
    2007             limit = m_out.load32(payloadFor(JSStack::ArgumentCount));
    2008        
    2009         speculate(Uncountable, noValue(), 0, m_out.aboveOrEqual(oneBasedIndex, limit));
     2006            limit = m_out.sub(m_out.load32(payloadFor(JSStack::ArgumentCount)), m_out.int32One);
     2007       
     2008        speculate(Uncountable, noValue(), 0, m_out.aboveOrEqual(index, limit));
    20102009       
    20112010        SymbolTable* symbolTable = m_graph.baselineCodeBlockFor(codeOrigin)->symbolTable();
     
    20332032       
    20342033        LValue pointer = m_out.baseIndex(
    2035             base.value(), m_out.zeroExt(zeroBasedIndex, m_out.intPtr), ScaleEight);
     2034            base.value(), m_out.zeroExt(index, m_out.intPtr), ScaleEight);
    20362035        setJSValue(m_out.load64(TypedPointer(m_heaps.variables.atAnyIndex(), pointer)));
    20372036    }
  • trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h

    r175593 r179538  
    604604    }
    605605
    606     int offsetOfArgumentsIncludingThis(InlineCallFrame* inlineCallFrame)
     606    int offsetOfArguments(InlineCallFrame* inlineCallFrame)
    607607    {
    608608        if (!inlineCallFrame)
    609             return CallFrame::argumentOffsetIncludingThis(0) * sizeof(Register);
     609            return CallFrame::argumentOffset(0) * sizeof(Register);
    610610        if (inlineCallFrame->arguments.size() <= 1)
    611611            return 0;
    612612        ValueRecovery recovery = inlineCallFrame->arguments[1];
    613613        RELEASE_ASSERT(recovery.technique() == DisplacedInJSStack);
    614         return (recovery.virtualRegister().offset() - 1) * sizeof(Register);
    615     }
    616    
    617     int offsetOfArgumentsIncludingThis(const CodeOrigin& codeOrigin)
    618     {
    619         return offsetOfArgumentsIncludingThis(codeOrigin.inlineCallFrame);
    620     }
    621 
     614        return recovery.virtualRegister().offset() * sizeof(Register);
     615    }
     616   
     617    int offsetOfArguments(const CodeOrigin& codeOrigin)
     618    {
     619        return offsetOfArguments(codeOrigin.inlineCallFrame);
     620    }
     621   
    622622    void emitLoadStructure(RegisterID source, RegisterID dest, RegisterID scratch)
    623623    {
  • trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp

    r179372 r179538  
    921921    emitGetVirtualRegister(property, regT1);
    922922    addSlowCase(emitJumpIfNotImmediateInteger(regT1));
    923     add32(TrustedImm32(1), regT1);
    924     // regT1 now contains the integer index of the argument we want, including this
    925923    emitGetFromCallFrameHeader32(JSStack::ArgumentCount, regT2);
     924    sub32(TrustedImm32(1), regT2);
    926925    addSlowCase(branch32(AboveOrEqual, regT1, regT2));
    927926
    928927    signExtend32ToPtr(regT1, regT1);
    929     load64(BaseIndex(callFrameRegister, regT1, TimesEight, CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register))), regT0);
     928    load64(BaseIndex(callFrameRegister, regT1, TimesEight, CallFrame::argumentOffset(0) * static_cast<int>(sizeof(Register))), regT0);
    930929    emitValueProfilingSite();
    931930    emitPutVirtualRegister(dst, regT0);
  • trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp

    r178856 r179538  
    10451045    emitLoad(property, regT1, regT2);
    10461046    addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
    1047     add32(TrustedImm32(1), regT2);
    10481047    // regT2 now contains the integer index of the argument we want, including this
    10491048    load32(payloadFor(JSStack::ArgumentCount), regT3);
     1049    sub32(TrustedImm32(1), regT3);
    10501050    addSlowCase(branch32(AboveOrEqual, regT2, regT3));
    10511051   
    1052     loadPtr(BaseIndex(callFrameRegister, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload) + CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register))), regT0);
    1053     loadPtr(BaseIndex(callFrameRegister, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag) + CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register))), regT1);
     1052    loadPtr(BaseIndex(callFrameRegister, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload) + CallFrame::argumentOffset(0) * static_cast<int>(sizeof(Register))), regT0);
     1053    loadPtr(BaseIndex(callFrameRegister, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag) + CallFrame::argumentOffset(0) * static_cast<int>(sizeof(Register))), regT1);
    10541054    emitValueProfilingSite();
    10551055    emitStore(dst, regT1, regT0);
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm

    r179429 r179538  
    1 # Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
     1# Copyright (C) 2011-2015 Apple Inc. All rights reserved.
    22#
    33# Redistribution and use in source and binary forms, with or without
     
    5454const ArgumentCount = Callee + SlotSize
    5555const ThisArgumentOffset = ArgumentCount + SlotSize
     56const FirstArgumentOffset = ThisArgumentOffset + SlotSize
    5657const CallFrameHeaderSize = ThisArgumentOffset
    5758
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm

    r179372 r179538  
    1 # Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
     1# Copyright (C) 2011-2015 Apple Inc. All rights reserved.
    22#
    33# Redistribution and use in source and binary forms, with or without
     
    16141614    bineq TagOffset[cfr, t0, 8], EmptyValueTag, .opGetArgumentByValSlow
    16151615    loadConstantOrVariablePayload(t1, Int32Tag, t2, .opGetArgumentByValSlow)
    1616     addi 1, t2
    16171616    loadi ArgumentCount + PayloadOffset[cfr], t1
     1617    subi 1, t1
    16181618    biaeq t2, t1, .opGetArgumentByValSlow
    16191619    loadi 4[PC], t3
    1620     loadi ThisArgumentOffset + TagOffset[cfr, t2, 8], t0
    1621     loadi ThisArgumentOffset + PayloadOffset[cfr, t2, 8], t1
     1620    loadi FirstArgumentOffset + TagOffset[cfr, t2, 8], t0
     1621    loadi FirstArgumentOffset + PayloadOffset[cfr, t2, 8], t1
    16221622    storei t0, TagOffset[cfr, t3, 8]
    16231623    storei t1, PayloadOffset[cfr, t3, 8]
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm

    r179372 r179538  
    1 # Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
     1# Copyright (C) 2011-2015 Apple Inc. All rights reserved.
    22#
    33# Redistribution and use in source and binary forms, with or without
     
    14721472    btqnz [cfr, t0, 8], .opGetArgumentByValSlow
    14731473    loadConstantOrVariableInt32(t1, t2, .opGetArgumentByValSlow)
    1474     addi 1, t2
    14751474    loadi ArgumentCount + PayloadOffset[cfr], t1
     1475    sxi2q t2, t2
     1476    subi 1, t1
    14761477    biaeq t2, t1, .opGetArgumentByValSlow
    14771478    loadisFromInstruction(1, t3)
    14781479    loadpFromInstruction(6, t1)
    1479     loadq ThisArgumentOffset[cfr, t2, 8], t0
     1480    loadq FirstArgumentOffset[cfr, t2, 8], t0
    14801481    storeq t0, [cfr, t3, 8]
    14811482    valueProfile(t0, 6, t1)
Note: See TracChangeset for help on using the changeset viewer.