Beispiel #1
0
void Initialize()
{
	if (base::win::get_version() < base::win::VERSION_WIN7)
	{
		return ;
	}

	const wchar_t* currentAppID = 0;
	HRESULT hr = windows7::GetCurrentProcessExplicitAppUserModelID((wchar_t**)&currentAppID);
	if (FAILED(hr) || !currentAppID)
	{
		currentAppID = getCurrentAppID();
		windows7::SetCurrentProcessExplicitAppUserModelID(currentAppID);
	}

	JumpList jumpList;
	jumpList.SetAppID(currentAppID);
	if (jumpList.InitializeList())
	{
		fs::path ydweDirectory = base::path::get(base::path::DIR_MODULE).remove_filename().remove_filename();

		jumpList.AddTaskSeparator();

		jumpList.AddTask(L"YDWEÅäÖÃ", [&](CComPtr<IShellLinkW>& shellLinkPtr)
		{
			shellLinkPtr->SetPath((ydweDirectory / L"bin" / L"YDWEConfig.exe").c_str());
			shellLinkPtr->SetDescription(L"´ò¿ªYDWEÅäÖóÌÐò¡£");
			shellLinkPtr->SetIconLocation((ydweDirectory / L"bin" / L"logo.ico").c_str(), 0);
		});
	}
}
Beispiel #2
0
void Generator::terminateAlternative(JumpList& successes, JumpList& failures)
{
    successes.append(jump());
    
    failures.link(this);
    peek(index);
}
Beispiel #3
0
void JIT::compileLoadVarargs(Instruction* instruction)
{
    int thisValue = instruction[2].u.operand;
    int arguments = instruction[3].u.operand;
    int firstFreeRegister = instruction[4].u.operand;

    killLastResultRegister();

    JumpList slowCase;
    JumpList end;
    if (m_codeBlock->usesArguments() && arguments == m_codeBlock->argumentsRegister()) {
        emitGetVirtualRegister(arguments, regT0);
        slowCase.append(branchPtr(NotEqual, regT0, TrustedImmPtr(JSValue::encode(JSValue()))));

        emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT0);
        slowCase.append(branch32(Above, regT0, TrustedImm32(Arguments::MaxArguments + 1)));
        // regT0: argumentCountIncludingThis

        move(regT0, regT1);
        add32(TrustedImm32(firstFreeRegister + RegisterFile::CallFrameHeaderSize), regT1);
        lshift32(TrustedImm32(3), regT1);
        addPtr(callFrameRegister, regT1);
        // regT1: newCallFrame

        slowCase.append(branchPtr(Below, AbsoluteAddress(m_globalData->interpreter->registerFile().addressOfEnd()), regT1));

        // Initialize ArgumentCount.
        emitFastArithReTagImmediate(regT0, regT2);
        storePtr(regT2, Address(regT1, RegisterFile::ArgumentCount * static_cast<int>(sizeof(Register))));

        // Initialize 'this'.
        emitGetVirtualRegister(thisValue, regT2);
        storePtr(regT2, Address(regT1, CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register))));

        // Copy arguments.
        neg32(regT0);
        signExtend32ToPtr(regT0, regT0);
        end.append(branchAddPtr(Zero, Imm32(1), regT0));
        // regT0: -argumentCount

        Label copyLoop = label();
        loadPtr(BaseIndex(callFrameRegister, regT0, TimesEight, CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register))), regT2);
        storePtr(regT2, BaseIndex(regT1, regT0, TimesEight, CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register))));
        branchAddPtr(NonZero, Imm32(1), regT0).linkTo(copyLoop, this);

        end.append(jump());
    }

    if (m_codeBlock->usesArguments() && arguments == m_codeBlock->argumentsRegister())
        slowCase.link(this);

    JITStubCall stubCall(this, cti_op_load_varargs);
    stubCall.addArgument(thisValue, regT0);
    stubCall.addArgument(arguments, regT0);
    stubCall.addArgument(Imm32(firstFreeRegister));
    stubCall.call(regT1);

    if (m_codeBlock->usesArguments() && arguments == m_codeBlock->argumentsRegister())
        end.link(this);
}
Beispiel #4
0
void JIT::compileLoadVarargs(Instruction* instruction)
{
    int thisValue = instruction[3].u.operand;
    int arguments = instruction[4].u.operand;
    int firstFreeRegister = instruction[5].u.operand;

    JumpList slowCase;
    JumpList end;
    bool canOptimize = m_codeBlock->usesArguments()
        && arguments == m_codeBlock->argumentsRegister().offset()
        && !m_codeBlock->symbolTable()->slowArguments();

    if (canOptimize) {
        emitGetVirtualRegister(arguments, regT0);
        slowCase.append(branch64(NotEqual, regT0, TrustedImm64(JSValue::encode(JSValue()))));

        emitGetFromCallFrameHeader32(JSStack::ArgumentCount, regT0);
        slowCase.append(branch32(Above, regT0, TrustedImm32(Arguments::MaxArguments + 1)));
        // regT0: argumentCountIncludingThis

        move(regT0, regT1);
        neg64(regT1);
        add64(TrustedImm32(firstFreeRegister - JSStack::CallFrameHeaderSize), regT1);
        lshift64(TrustedImm32(3), regT1);
        addPtr(callFrameRegister, regT1);
        // regT1: newCallFrame

        slowCase.append(branchPtr(Above, AbsoluteAddress(m_vm->addressOfJSStackLimit()), regT1));

        // Initialize ArgumentCount.
        store32(regT0, Address(regT1, JSStack::ArgumentCount * static_cast<int>(sizeof(Register)) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)));

        // Initialize 'this'.
        emitGetVirtualRegister(thisValue, regT2);
        store64(regT2, Address(regT1, CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register))));

        // Copy arguments.
        signExtend32ToPtr(regT0, regT0);
        end.append(branchSub64(Zero, TrustedImm32(1), regT0));
        // regT0: argumentCount

        Label copyLoop = label();
        load64(BaseIndex(callFrameRegister, regT0, TimesEight, CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register))), regT2);
        store64(regT2, BaseIndex(regT1, regT0, TimesEight, CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register))));
        branchSub64(NonZero, TrustedImm32(1), regT0).linkTo(copyLoop, this);

        end.append(jump());
    }

    if (canOptimize)
        slowCase.link(this);

    emitGetVirtualRegister(thisValue, regT0);
    emitGetVirtualRegister(arguments, regT1);
    callOperation(operationLoadVarargs, regT0, regT1, firstFreeRegister);
    move(returnValueGPR, regT1);

    if (canOptimize)
        end.link(this);
}
Beispiel #5
0
void JIT::compileLoadVarargs(Instruction* instruction)
{
    int thisValue = instruction[2].u.operand;
    int arguments = instruction[3].u.operand;
    int firstFreeRegister = instruction[4].u.operand;

    JumpList slowCase;
    JumpList end;
    if (m_codeBlock->usesArguments() && arguments == m_codeBlock->argumentsRegister()) {
        emitLoadTag(arguments, regT1);
        slowCase.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::EmptyValueTag)));

        load32(payloadFor(RegisterFile::ArgumentCount), regT2);
        slowCase.append(branch32(Above, regT2, TrustedImm32(Arguments::MaxArguments + 1)));
        // regT2: argumentCountIncludingThis

        move(regT2, regT3);
        add32(TrustedImm32(firstFreeRegister + RegisterFile::CallFrameHeaderSize), regT3);
        lshift32(TrustedImm32(3), regT3);
        addPtr(callFrameRegister, regT3);
        // regT3: newCallFrame

        slowCase.append(branchPtr(Below, AbsoluteAddress(m_globalData->interpreter->registerFile().addressOfEnd()), regT3));

        // Initialize ArgumentCount.
        store32(regT2, payloadFor(RegisterFile::ArgumentCount, regT3));

        // Initialize 'this'.
        emitLoad(thisValue, regT1, regT0);
        store32(regT0, Address(regT3, OBJECT_OFFSETOF(JSValue, u.asBits.payload) + (CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register)))));
        store32(regT1, Address(regT3, OBJECT_OFFSETOF(JSValue, u.asBits.tag) + (CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register)))));

        // Copy arguments.
        neg32(regT2);
        end.append(branchAdd32(Zero, TrustedImm32(1), regT2));
        // regT2: -argumentCount;

        Label copyLoop = label();
        load32(BaseIndex(callFrameRegister, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload) +(CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register)))), regT0);
        load32(BaseIndex(callFrameRegister, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag) +(CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register)))), regT1);
        store32(regT0, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload) +(CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register)))));
        store32(regT1, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag) +(CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register)))));
        branchAdd32(NonZero, TrustedImm32(1), regT2).linkTo(copyLoop, this);

        end.append(jump());
    }

    if (m_codeBlock->usesArguments() && arguments == m_codeBlock->argumentsRegister())
        slowCase.link(this);

    JITStubCall stubCall(this, cti_op_load_varargs);
    stubCall.addArgument(thisValue);
    stubCall.addArgument(arguments);
    stubCall.addArgument(Imm32(firstFreeRegister));
    stubCall.call(regT3);

    if (m_codeBlock->usesArguments() && arguments == m_codeBlock->argumentsRegister())
        end.link(this);
}
Beispiel #6
0
void Generator::generateAssertionEOL(JumpList& failures)
{
    if (m_parser.multiline()) {
        JumpList nextIsNewline;

        generateLoadCharacter(nextIsNewline); // end of input == success
        generateCharacterClassInverted(nextIsNewline, CharacterClass::newline());
        failures.append(jump());
        nextIsNewline.link(this);
    } else {
        failures.append(jne32(length, index));
    }
}
Beispiel #7
0
void Generator::generateParenthesesInvertedAssertion(JumpList& failures)
{
    JumpList disjunctionFailed;

    push(index);
    m_parser.parseDisjunction(disjunctionFailed);

    // If the disjunction succeeded, the inverted assertion failed.
    pop(index);
    failures.append(jump());

    // If the disjunction failed, the inverted assertion succeeded.
    disjunctionFailed.link(this);
    pop(index);
}
Beispiel #8
0
void Generator::generateParenthesesAssertion(JumpList& failures)
{
    JumpList disjunctionFailed;

    push(index);
    m_parser.parseDisjunction(disjunctionFailed);
    Jump success = jump();

    disjunctionFailed.link(this);
    pop(index);
    failures.append(jump());

    success.link(this);
    pop(index);
}
Beispiel #9
0
void Generator::generateCharacterClass(JumpList& failures, const CharacterClass& charClass, bool invert)
{
    generateLoadCharacter(failures);

    if (invert)
        generateCharacterClassInverted(failures, charClass);
    else {
        JumpList successes;
        generateCharacterClassInverted(successes, charClass);
        failures.append(jump());
        successes.link(this);
    }
    
    add32(Imm32(1), index);
}
Beispiel #10
0
void Generator::generateAssertionWordBoundary(JumpList& failures, bool invert)
{
    JumpList wordBoundary;
    JumpList notWordBoundary;

    // (1) Check if the previous value was a word char

    // (1.1) check for begin of input
    Jump atBegin = je32(index, Imm32(0));
    // (1.2) load the last char, and chck if is word character
    load16(BaseIndex(input, index, TimesTwo, -2), character);
    JumpList previousIsWord;
    generateCharacterClassInverted(previousIsWord, CharacterClass::wordchar());
    // (1.3) if we get here, previous is not a word char
    atBegin.link(this);

    // (2) Handle situation where previous was NOT a \w

    generateLoadCharacter(notWordBoundary);
    generateCharacterClassInverted(wordBoundary, CharacterClass::wordchar());
    // (2.1) If we get here, neither chars are word chars
    notWordBoundary.append(jump());

    // (3) Handle situation where previous was a \w

    // (3.0) link success in first match to here
    previousIsWord.link(this);
    generateLoadCharacter(wordBoundary);
    generateCharacterClassInverted(notWordBoundary, CharacterClass::wordchar());
    // (3.1) If we get here, this is an end of a word, within the input.
    
    // (4) Link everything up
    
    if (invert) {
        // handle the fall through case
        wordBoundary.append(jump());
    
        // looking for non word boundaries, so link boundary fails to here.
        notWordBoundary.link(this);

        failures.append(wordBoundary);
    } else {
        // looking for word boundaries, so link successes here.
        wordBoundary.link(this);
        
        failures.append(notWordBoundary);
    }
}
Beispiel #11
0
//
//   FUNCTION: InitMainWindowInstance(HINSTANCE, int)
//
//   PURPOSE: Saves instance handle and creates main window
//
//   COMMENTS:
//
//        In this function, we save the instance handle in a global variable and
//        create and display the main program window.
//
HWND InitMainWindowInstance(
    HINSTANCE hInstance, 
    int nCmdShow, 
    PTCHAR szWindowClass, 
    PTCHAR szTitle) 
{
    hInst = hInstance;  // Store instance handle in our global variable

    beginMainWindowCreationTime.Now();

    //  Should make window size be data driven
    mainWindowHandle = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW | WS_EX_CLIENTEDGE,
                                    szWindowClass, szTitle,
                                    WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
                                    CW_USEDEFAULT, CW_USEDEFAULT,
                                    //        WS_POPUP, CW_USEDEFAULT, 0,
                                    DEFAULT_WIN_WIDTH, DEFAULT_WIN_HEIGHT,
                                    NULL, NULL,
                                    hInstance, NULL);

    if (mainWindowHandle)
    {
        if (!devMode)
        {
            jumpList.SetUpJumpList(hInst);
        }
    }

    return mainWindowHandle;
}
Beispiel #12
0
void Generator::generatePatternCharacter(JumpList& failures, int ch)
{
    generateLoadCharacter(failures);

    // used for unicode case insensitive
    bool hasUpper = false;
    Jump isUpper;
    
    // if case insensitive match
    if (m_parser.ignoreCase()) {
        UChar lower, upper;
        
        // check for ascii case sensitive characters
        if (isASCIIAlpha(ch)) {
            or32(Imm32(32), character);
            ch |= 32;
        } else if (!isASCII(ch) && ((lower = Unicode::toLower(ch)) != (upper = Unicode::toUpper(ch)))) {
            // handle unicode case sentitive characters - branch to success on upper
            isUpper = je32(character, Imm32(upper));
            hasUpper = true;
            ch = lower;
        }
    }
    
    // checks for ch, or lower case version of ch, if insensitive
    failures.append(jne32(character, Imm32((unsigned short)ch)));

    if (m_parser.ignoreCase() && hasUpper) {
        // for unicode case insensitive matches, branch here if upper matches.
        isUpper.link(this);
    }
    
    // on success consume the char
    add32(Imm32(1), index);
}
Beispiel #13
0
void Generator::generateCharacterClassInvertedRange(JumpList& failures, JumpList& matchDest, const CharacterRange* ranges, unsigned count, unsigned* matchIndex, const UChar* matches, unsigned matchCount)
{
    do {
        // pick which range we're going to generate
        int which = count >> 1;
        char lo = ranges[which].begin;
        char hi = ranges[which].end;
        
        // check if there are any ranges or matches below lo.  If not, just jl to failure -
        // if there is anything else to check, check that first, if it falls through jmp to failure.
        if ((*matchIndex < matchCount) && (matches[*matchIndex] < lo)) {
            Jump loOrAbove = jge32(character, Imm32((unsigned short)lo));
            
            // generate code for all ranges before this one
            if (which)
                generateCharacterClassInvertedRange(failures, matchDest, ranges, which, matchIndex, matches, matchCount);
            
            do {
                matchDest.append(je32(character, Imm32((unsigned short)matches[*matchIndex])));
                ++*matchIndex;
            } while ((*matchIndex < matchCount) && (matches[*matchIndex] < lo));
            failures.append(jump());

            loOrAbove.link(this);
        } else if (which) {
            Jump loOrAbove = jge32(character, Imm32((unsigned short)lo));

            generateCharacterClassInvertedRange(failures, matchDest, ranges, which, matchIndex, matches, matchCount);
            failures.append(jump());

            loOrAbove.link(this);
        } else
            failures.append(jl32(character, Imm32((unsigned short)lo)));

        while ((*matchIndex < matchCount) && (matches[*matchIndex] <= hi))
            ++*matchIndex;

        matchDest.append(jle32(character, Imm32((unsigned short)hi)));
        // fall through to here, the value is above hi.

        // shuffle along & loop around if there are any more matches to handle.
        unsigned next = which + 1;
        ranges += next;
        count -= next;
    } while (count);
}
Beispiel #14
0
bool Generator::generatePatternCharacterPair(JumpList& failures, int ch1, int ch2)
{
    if (m_parser.ignoreCase()) {
        // Non-trivial case folding requires more than one test, so we can't
        // test as a pair with an adjacent character.
        if (!isASCII(ch1) && Unicode::toLower(ch1) != Unicode::toUpper(ch1))
            return false;
        if (!isASCII(ch2) && Unicode::toLower(ch2) != Unicode::toUpper(ch2))
            return false;
    }

    // Optimistically consume 2 characters.
    add32(Imm32(2), index);
    failures.append(jg32(index, length));

    // Load the characters we just consumed, offset -2 characters from index.
    load32(BaseIndex(input, index, TimesTwo, -2 * 2), character);

    if (m_parser.ignoreCase()) {
        // Convert ASCII alphabet characters to upper case before testing for
        // equality. (ASCII non-alphabet characters don't require upper-casing
        // because they have no uppercase equivalents. Unicode characters don't
        // require upper-casing because we only handle Unicode characters whose
        // upper and lower cases are equal.)
        int ch1Mask = 0;
        if (isASCIIAlpha(ch1)) {
            ch1 |= 32;
            ch1Mask = 32;
        }

        int ch2Mask = 0;
        if (isASCIIAlpha(ch2)) {
            ch2 |= 32;
            ch2Mask = 32;
        }

        int mask = ch1Mask | (ch2Mask << 16);
        if (mask)
            or32(Imm32(mask), character);
    }
    int pair = ch1 | (ch2 << 16);

    failures.append(jne32(character, Imm32(pair)));
    return true;
}
Beispiel #15
0
void JIT::privateCompileClosureCall(CallLinkInfo* callLinkInfo, CodeBlock* calleeCodeBlock, Structure* expectedStructure, ExecutableBase* expectedExecutable, MacroAssemblerCodePtr codePtr)
{
    JumpList slowCases;

    slowCases.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag)));
    slowCases.append(branchPtr(NotEqual, Address(regT0, JSCell::structureOffset()), TrustedImmPtr(expectedStructure)));
    slowCases.append(branchPtr(NotEqual, Address(regT0, JSFunction::offsetOfExecutable()), TrustedImmPtr(expectedExecutable)));
    
    loadPtr(Address(regT0, JSFunction::offsetOfScopeChain()), regT1);
    emitPutCellToCallFrameHeader(regT1, JSStack::ScopeChain);
    
    Call call = nearCall();
    Jump done = jump();
    
    slowCases.link(this);
    move(TrustedImmPtr(callLinkInfo->callReturnLocation.executableAddress()), regT2);
    restoreReturnAddressBeforeReturn(regT2);
    Jump slow = jump();
    
    LinkBuffer patchBuffer(*m_vm, this, m_codeBlock);
    
    patchBuffer.link(call, FunctionPtr(codePtr.executableAddress()));
    patchBuffer.link(done, callLinkInfo->hotPathOther.labelAtOffset(0));
    patchBuffer.link(slow, CodeLocationLabel(m_vm->getCTIStub(virtualCallThunkGenerator).code()));
    
    RefPtr<ClosureCallStubRoutine> stubRoutine = adoptRef(new ClosureCallStubRoutine(
        FINALIZE_CODE(
            patchBuffer,
            ("Baseline closure call stub for %s, return point %p, target %p (%s)",
                toCString(*m_codeBlock).data(),
                callLinkInfo->hotPathOther.labelAtOffset(0).executableAddress(),
                codePtr.executableAddress(),
                toCString(pointerDump(calleeCodeBlock)).data())),
        *m_vm, m_codeBlock->ownerExecutable(), expectedStructure, expectedExecutable,
        callLinkInfo->codeOrigin));
    
    RepatchBuffer repatchBuffer(m_codeBlock);
    
    repatchBuffer.replaceWithJump(
        RepatchBuffer::startOfBranchPtrWithPatchOnRegister(callLinkInfo->hotPathBegin),
        CodeLocationLabel(stubRoutine->code().code()));
    repatchBuffer.relink(callLinkInfo->callReturnLocation, m_vm->getCTIStub(virtualCallThunkGenerator).code());
    
    callLinkInfo->stub = stubRoutine.release();
}
Beispiel #16
0
void Generator::generateAssertionBOL(JumpList& failures)
{
    if (m_parser.multiline()) {
        JumpList previousIsNewline;

        // begin of input == success
        previousIsNewline.append(je32(index, Imm32(0)));

        // now check prev char against newline characters.
        load16(BaseIndex(input, index, TimesTwo, -2), character);
        generateCharacterClassInverted(previousIsNewline, CharacterClass::newline());

        failures.append(jump());

        previousIsNewline.link(this);
    } else
        failures.append(jne32(index, Imm32(0)));
}
Beispiel #17
0
void Generator::generateNonGreedyQuantifier(JumpList& failures, GenerateAtomFunctor& functor, unsigned min, unsigned max)
{
    JumpList atomFailedList;
    JumpList alternativeFailedList;

    // (0) Setup: Save, then init repeatCount.
    push(repeatCount);
    move(Imm32(0), repeatCount);
    Jump start = jump();

    // (4) Quantifier failed: No more atom reading possible.
    Label quantifierFailed(this);
    pop(repeatCount);
    failures.append(jump()); 

    // (3) Alternative failed: If we can, read another atom, then fall through to (2) to try again.
    Label alternativeFailed(this);
    pop(index);
    if (max != Quantifier::Infinity)
        je32(repeatCount, Imm32(max), quantifierFailed);

    // (1) Read an atom.
    if (min)
        start.link(this);
    Label readAtom(this);
    functor.generateAtom(this, atomFailedList);
    atomFailedList.linkTo(quantifierFailed, this);
    add32(Imm32(1), repeatCount);
    
    // (2) Keep reading if we're under the minimum.
    if (min > 1)
        jl32(repeatCount, Imm32(min), readAtom);

    // (3) Test the rest of the alternative.
    if (!min)
        start.link(this);
    push(index);
    m_parser.parseAlternative(alternativeFailedList);
    alternativeFailedList.linkTo(alternativeFailed, this);

    pop();
    pop(repeatCount);
}
Beispiel #18
0
bool JumpListAddRecentTask(JumpList& jumpList, fs::path const& ydweDirectory, fs::path const& filePath)
{
	HRESULT hr = jumpList.AddTask(filePath.filename().c_str(), [&](CComPtr<IShellLinkW>& shellLinkPtr)
	{
		shellLinkPtr->SetPath((ydweDirectory / L"YDWE.exe").c_str());
		shellLinkPtr->SetArguments((L" -loadfile \"" + filePath.wstring() + L"\"").c_str());
		shellLinkPtr->SetDescription(filePath.c_str());
		shellLinkPtr->SetIconLocation((ydweDirectory / L"bin" / L"logo.ico").c_str(), 0);
	});

	return SUCCEEDED(hr);
}
Beispiel #19
0
Generator::Jump Generator::generateParenthesesResetTrampoline(JumpList& newFailures, unsigned subpatternIdBefore, unsigned subpatternIdAfter)
{
    Jump skip = jump();
    newFailures.link(this);
    for (unsigned i = subpatternIdBefore + 1; i <= subpatternIdAfter; ++i) {
        store32(Imm32(-1), Address(output, (2 * i) * sizeof(int)));
        store32(Imm32(-1), Address(output, (2 * i + 1) * sizeof(int)));
    }
    
    Jump newFailJump = jump();
    skip.link(this);
    
    return newFailJump;
}
Beispiel #20
0
void Generator::generateGreedyQuantifier(JumpList& failures, GenerateAtomFunctor& functor, unsigned min, unsigned max)
{
    if (!max)
        return;

    JumpList doneReadingAtomsList;
    JumpList alternativeFailedList;

    // (0) Setup: Save, then init repeatCount.
    push(repeatCount);
    move(Imm32(0), repeatCount);

    // (1) Greedily read as many copies of the atom as possible, then jump to (2).
    Label readAtom(this);
    functor.generateAtom(this, doneReadingAtomsList);
    add32(Imm32(1), repeatCount);
    if (max == Quantifier::Infinity)
        jump(readAtom);
    else if (max == 1)
        doneReadingAtomsList.append(jump());
    else {
        jne32(repeatCount, Imm32(max), readAtom);
        doneReadingAtomsList.append(jump());
    }

    // (5) Quantifier failed: No more backtracking possible.
    Label quantifierFailed(this);
    pop(repeatCount);
    failures.append(jump()); 

    // (4) Alternative failed: Backtrack, then fall through to (2) to try again.
    Label alternativeFailed(this);
    pop(index);
    functor.backtrack(this);
    sub32(Imm32(1), repeatCount);

    // (2) Verify that we have enough atoms.
    doneReadingAtomsList.link(this);
    jl32(repeatCount, Imm32(min), quantifierFailed);

    // (3) Test the rest of the alternative.
    push(index);
    m_parser.parseAlternative(alternativeFailedList);
    alternativeFailedList.linkTo(alternativeFailed, this);

    pop();
    pop(repeatCount);
}
Beispiel #21
0
void JIT::compileSetupVarargsFrame(Instruction* instruction, CallLinkInfo* info)
{
    int thisValue = instruction[3].u.operand;
    int arguments = instruction[4].u.operand;
    int firstFreeRegister = instruction[5].u.operand;
    int firstVarArgOffset = instruction[6].u.operand;

    JumpList slowCase;
    JumpList end;
    bool canOptimize = m_codeBlock->usesArguments()
        && arguments == m_codeBlock->argumentsRegister().offset()
        && !m_codeBlock->symbolTable()->slowArguments();

    if (canOptimize) {
        emitGetVirtualRegister(arguments, regT0);
        slowCase.append(branch64(NotEqual, regT0, TrustedImm64(JSValue::encode(JSValue()))));
        
        move(TrustedImm32(-firstFreeRegister), regT1);
        emitSetupVarargsFrameFastCase(*this, regT1, regT0, regT1, regT2, firstVarArgOffset, slowCase);
        end.append(jump());
        slowCase.link(this);
    }

    emitGetVirtualRegister(arguments, regT1);
    callOperation(operationSizeFrameForVarargs, regT1, -firstFreeRegister, firstVarArgOffset);
    move(TrustedImm32(-firstFreeRegister), regT1);
    emitSetVarargsFrame(*this, returnValueGPR, false, regT1, regT1);
    addPtr(TrustedImm32(-(sizeof(CallerFrameAndPC) + WTF::roundUpToMultipleOf(stackAlignmentBytes(), 5 * sizeof(void*)))), regT1, stackPointerRegister);
    emitGetVirtualRegister(arguments, regT2);
    callOperation(operationSetupVarargsFrame, regT1, regT2, firstVarArgOffset, regT0);
    move(returnValueGPR, regT1);

    if (canOptimize)
        end.link(this);
    
    // Profile the argument count.
    load32(Address(regT1, JSStack::ArgumentCount * static_cast<int>(sizeof(Register)) + PayloadOffset), regT2);
    load8(&info->maxNumArguments, regT0);
    Jump notBiggest = branch32(Above, regT0, regT2);
    Jump notSaturated = branch32(BelowOrEqual, regT2, TrustedImm32(255));
    move(TrustedImm32(255), regT2);
    notSaturated.link(this);
    store8(regT2, &info->maxNumArguments);
    notBiggest.link(this);
    
    // Initialize 'this'.
    emitGetVirtualRegister(thisValue, regT0);
    store64(regT0, Address(regT1, CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register))));

    addPtr(TrustedImm32(sizeof(CallerFrameAndPC)), regT1, stackPointerRegister);
}
Beispiel #22
0
void Generator::generateBackreference(JumpList& failures, unsigned subpatternId)
{
    push(index);
    push(repeatCount);

    // get the start pos of the backref into repeatCount (multipurpose!)
    load32(Address(output, (2 * subpatternId) * sizeof(int)), repeatCount);

    Jump skipIncrement = jump();
    Label topOfLoop(this);

    add32(Imm32(1), index);
    add32(Imm32(1), repeatCount);
    skipIncrement.link(this);

    // check if we're at the end of backref (if we are, success!)
    Jump endOfBackRef = je32(Address(output, ((2 * subpatternId) + 1) * sizeof(int)), repeatCount);

    load16(BaseIndex(input, repeatCount, MacroAssembler::TimesTwo), character);

    // check if we've run out of input (this would be a can o'fail)
    Jump endOfInput = je32(length, index);

    je16(character, BaseIndex(input, index, TimesTwo), topOfLoop);

    endOfInput.link(this);

    // Failure
    pop(repeatCount);
    pop(index);
    failures.append(jump());

    // Success
    endOfBackRef.link(this);
    pop(repeatCount);
    pop();
}
Beispiel #23
0
void Generator::generateLoadCharacter(JumpList& failures)
{
    failures.append(je32(length, index));
    load16(BaseIndex(input, index, TimesTwo), character);
}
Beispiel #24
0
void Generator::generateCharacterClassInverted(JumpList& matchDest, const CharacterClass& charClass)
{
    Jump unicodeFail;
    if (charClass.numMatchesUnicode || charClass.numRangesUnicode) {
        Jump isAscii = jle32(character, Imm32(0x7f));
    
        if (charClass.numMatchesUnicode) {
            for (unsigned i = 0; i < charClass.numMatchesUnicode; ++i) {
                UChar ch = charClass.matchesUnicode[i];
                matchDest.append(je32(character, Imm32(ch)));
            }
        }
        
        if (charClass.numRangesUnicode) {
            for (unsigned i = 0; i < charClass.numRangesUnicode; ++i) {
                UChar lo = charClass.rangesUnicode[i].begin;
                UChar hi = charClass.rangesUnicode[i].end;
                
                Jump below = jl32(character, Imm32(lo));
                matchDest.append(jle32(character, Imm32(hi)));
                below.link(this);
            }
        }

        unicodeFail = jump();
        isAscii.link(this);
    }

    if (charClass.numRanges) {
        unsigned matchIndex = 0;
        JumpList failures; 
        generateCharacterClassInvertedRange(failures, matchDest, charClass.ranges, charClass.numRanges, &matchIndex, charClass.matches, charClass.numMatches);
        while (matchIndex < charClass.numMatches)
            matchDest.append(je32(character, Imm32((unsigned short)charClass.matches[matchIndex++])));

        failures.link(this);
    } else if (charClass.numMatches) {
        // optimization: gather 'a','A' etc back together, can mask & test once.
        Vector<char> matchesAZaz;

        for (unsigned i = 0; i < charClass.numMatches; ++i) {
            char ch = charClass.matches[i];
            if (m_parser.ignoreCase()) {
                if (isASCIILower(ch)) {
                    matchesAZaz.append(ch);
                    continue;
                }
                if (isASCIIUpper(ch))
                    continue;
            }
            matchDest.append(je32(character, Imm32((unsigned short)ch)));
        }

        if (unsigned countAZaz = matchesAZaz.size()) {
            or32(Imm32(32), character);
            for (unsigned i = 0; i < countAZaz; ++i)
                matchDest.append(je32(character, Imm32(matchesAZaz[i])));
        }
    }

    if (charClass.numMatchesUnicode || charClass.numRangesUnicode)
        unicodeFail.link(this);
}
Beispiel #25
0
void JIT::compileLoadVarargs(Instruction* instruction)
{
    int thisValue = instruction[3].u.operand;
    int arguments = instruction[4].u.operand;
    int firstFreeRegister = instruction[5].u.operand;

    JumpList slowCase;
    JumpList end;
    bool canOptimize = m_codeBlock->usesArguments()
        && VirtualRegister(arguments) == m_codeBlock->argumentsRegister()
        && !m_codeBlock->symbolTable()->slowArguments();

    if (canOptimize) {
        emitLoadTag(arguments, regT1);
        slowCase.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::EmptyValueTag)));

        load32(payloadFor(JSStack::ArgumentCount), regT2);
        slowCase.append(branch32(Above, regT2, TrustedImm32(Arguments::MaxArguments + 1)));
        // regT2: argumentCountIncludingThis

        move(regT2, regT3);
        neg32(regT3);
        add32(TrustedImm32(firstFreeRegister - JSStack::CallFrameHeaderSize), regT3);
        lshift32(TrustedImm32(3), regT3);
        addPtr(callFrameRegister, regT3);
        // regT3: newCallFrame

        slowCase.append(branchPtr(Above, AbsoluteAddress(m_vm->interpreter->stack().addressOfEnd()), regT3));

        // Initialize ArgumentCount.
        store32(regT2, payloadFor(JSStack::ArgumentCount, regT3));

        // Initialize 'this'.
        emitLoad(thisValue, regT1, regT0);
        store32(regT0, Address(regT3, OBJECT_OFFSETOF(JSValue, u.asBits.payload) + (CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register)))));
        store32(regT1, Address(regT3, OBJECT_OFFSETOF(JSValue, u.asBits.tag) + (CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register)))));

        // Copy arguments.
        end.append(branchSub32(Zero, TrustedImm32(1), regT2));
        // regT2: argumentCount;

        Label copyLoop = label();
        load32(BaseIndex(callFrameRegister, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload) +(CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register)))), regT0);
        load32(BaseIndex(callFrameRegister, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag) +(CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register)))), regT1);
        store32(regT0, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload) +(CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register)))));
        store32(regT1, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag) +(CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register)))));
        branchSub32(NonZero, TrustedImm32(1), regT2).linkTo(copyLoop, this);

        end.append(jump());
    }

    if (canOptimize)
        slowCase.link(this);

    emitLoad(thisValue, regT1, regT0);
    emitLoad(arguments, regT3, regT2);
    callOperation(operationLoadVarargs, regT1, regT0, regT3, regT2, firstFreeRegister);
    move(returnValueRegister, regT3);

    if (canOptimize)
        end.link(this);
}
Beispiel #26
0
//
//  FUNCTION: MainWindowWndProc(HWND, UINT, WPARAM, LPARAM)
//
//  PURPOSE:  Processes messages for the main window.
//
LRESULT CALLBACK MainWindowWndProc(
    HWND hWnd, 
    UINT message, 
    WPARAM wParam,
    LPARAM lParam) 
{
    PAINTSTRUCT ps;
    HDC hdc;
    HMENU sysMenu;

    // Callback for the main window
    switch (message) 
    {
        case WM_CREATE: 
        {
            DWORD bufferSize = 65535;
            wstring buff;
            buff.resize(bufferSize);
            bufferSize = ::GetEnvironmentVariable(L"lala", &buff[0], bufferSize);

            if (bufferSize)
            {
                buff.resize(bufferSize);
                SetEnvironmentVariable(L"lala", NULL);
            }

            // Add exit option to system menu
            TCHAR szDescription[INFOTIPSIZE];
            StringManager.LoadString(IDS_EXIT_CAFFEINE, szDescription, INFOTIPSIZE);

            sysMenu = GetSystemMenu(hWnd, FALSE);
            InsertMenu(sysMenu, 2, MF_SEPARATOR, 0, L"-");
            AppendMenu(sysMenu, MF_STRING, IDS_EXIT_CAFFEINE, szDescription);

            WTSRegisterSessionNotification(hWnd, NOTIFY_FOR_THIS_SESSION);
            app->m_WindowHandler[mainUUID] = new CaffeineClientHandler();
            app->m_WindowHandler[mainUUID]->SetMainHwnd(hWnd);

            // Create the child windows used for navigation
            RECT rect;

            GetClientRect(hWnd, &rect);

            CefWindowInfo info;
            CefBrowserSettings browser_settings;
            browser_settings.universal_access_from_file_urls = STATE_ENABLED;
//            browser_settings.file_access_from_file_urls = STATE_ENABLED;
            browser_settings.web_security = STATE_DISABLED;
            browser_settings.local_storage = STATE_ENABLED;
            browser_settings.application_cache = STATE_DISABLED;
            browser_settings.javascript_open_windows = STATE_DISABLED;
//            browser_settings.accelerated_compositing = STATE_DISABLED;
            
            // Initialize window info to the defaults for a child window
            info.SetAsChild(hWnd, rect);

            // Create the new child browser window
            wstring URL(L"file:///stub.html?" + AppGetCommandLine()->GetSwitchValue("querystring").ToWString());
            if (AppGetCommandLine()->HasSwitch("yid"))
            {
                URL += L"&yid=" + ExtractYID(AppGetCommandLine()->GetSwitchValue("yid").ToWString());
            }
            //  TODO:  Can we just use the same window handler (assuming we get rid of the globals and add some sync)?
            CefRefPtr<CefBrowser> browser = CefBrowserHost::CreateBrowserSync(info, app->m_WindowHandler[mainUUID].get(), URL, browser_settings, NULL);
            app->m_WindowHandler[mainUUID]->m_MainBrowser = browser;
            mainWinBrowser = browser;

            app->hwndRender = hWnd; // setup current handle to use in Show/HideWindow
        
            CefRefPtr<CefProcessMessage> process_message = CefProcessMessage::Create("setHandle");
            process_message->GetArgumentList()->SetInt(0, reinterpret_cast<int>(hWnd));
            browser->SendProcessMessage(PID_RENDERER, process_message);

            // Send the main window creation start time to the renderer
            process_message = CefProcessMessage::Create("mainWindowCreationTime");
            CefRefPtr<CefBinaryValue> startTime = CefBinaryValue::Create(&beginMainWindowCreationTime, sizeof(CefTime));
            process_message->GetArgumentList()->SetBinary(0, startTime);
            browser->SendProcessMessage(PID_RENDERER, process_message);

            if (bufferSize)
            {
                process_message = CefProcessMessage::Create("lala");
                process_message->GetArgumentList()->SetString(0, buff);
                browser->SendProcessMessage(PID_RENDERER, process_message);
            }

            SetWindowLongPtr(hWnd, 0, reinterpret_cast<LONG_PTR>(new WindowExtras));

            SetTimer(hWnd, IDLETIMER, IdleTimerPollIntervalMS, NULL);
            SetTimer(hWnd, NETWORKTIMER, NetworkTimerPollIntervalMS, NULL);

            return 0;
        }

        case WM_MOVE:
            if (app->m_WindowHandler[mainUUID].get())
            {
                //  TODO:  Below is a hack to work around the fact that CEF isn't updating screenX and screenY.  Periodically,
                //  TODO:  check to see if they fix it.  
                //  TODO:  See issue https://code.google.com/p/chromiumembedded/issues/detail?id=1303&thanks=1303&ts=1402082749
                WINDOWINFO wi = {sizeof(WINDOWINFO), 0};
                GetWindowInfo(hWnd, &wi);
                RECT rClient = wi.rcWindow;

                CefString JS = "window.screenLeft = window.screenX = " + to_string(_Longlong(rClient.left)) + "; window.screenTop = window.screenY = " + 
                    to_string(_Longlong(rClient.top)) + ";";
                CefRefPtr<CefFrame> frame = app->m_WindowHandler[mainUUID]->GetBrowser()->GetMainFrame();
                frame->ExecuteJavaScript(JS, frame->GetURL(), 0);

                //  TODO:  Another workaround.  For whatever reason, the window positions get updated when the size changes,
                //  TODO:  but not when the window is moved.
                CefWindowHandle hwnd = app->m_WindowHandler[mainUUID]->GetBrowser()->GetHost()->GetWindowHandle();
                if (hwnd) 
                {
                    wi.cbSize = sizeof(WINDOWINFO);
                    GetWindowInfo(hwnd, &wi);
                    RECT rWindow = wi.rcWindow;

                    MoveWindow(hwnd, 0, 0, rWindow.right - rWindow.left, rWindow.bottom - rWindow.top + 1, FALSE);
                    MoveWindow(hwnd, 0, 0, rWindow.right - rWindow.left, rWindow.bottom - rWindow.top, FALSE);
                }

                app->m_WindowHandler[mainUUID]->CreateAndDispatchCustomEvent("move");
            }

            break;

        case WM_POWERBROADCAST:
            if (app->m_WindowHandler[mainUUID].get())
            {
                if (wParam == PBT_APMRESUMEAUTOMATIC || wParam == PBT_APMSUSPEND)
                {
                    app->m_WindowHandler[mainUUID]->CreateAndDispatchCustomEvent(wParam == PBT_APMSUSPEND? "suspend" : "resume");
                    //  Do we really need a return value?
                    return TRUE;
                }
            }
            break;

        case WM_WTSSESSION_CHANGE:
            if (app->m_WindowHandler[mainUUID].get())
            {
                string eventName;

                switch(wParam)
                {
                    //  Used
                    case WTS_SESSION_LOGON:
                        eventName = "os:logon";
                        break;
                    //  Used
                    case WTS_SESSION_LOGOFF:
                        eventName = "os:logoff";
                        break;
                    //  Used
                    case WTS_SESSION_LOCK:
                        eventName = "os:locked";
                        break;
                    //  Used
                    case WTS_SESSION_UNLOCK:
                        eventName = "os:unlocked";
                        break;
                }

                app->m_WindowHandler[mainUUID]->CreateAndDispatchCustomEvent(eventName);
            }
            break;

        case WM_PAINT:
            {
                //RECT cr = {0,};
                //::GetClientRect(hWnd, &cr);
                //::InvalidateRect(hWnd, &cr, FALSE);
                hdc = BeginPaint(hWnd, &ps);
                EndPaint(hWnd, &ps);
                return 0;
            }

        case WM_ACTIVATE:
            if (app->m_WindowHandler[mainUUID].get() && app->m_WindowHandler[mainUUID]->GetBrowser()) 
            {
                app->m_WindowHandler[mainUUID]->CreateAndDispatchCustomEvent((LOWORD(wParam)>0)? "activated" : "deactivated");
            }
            break;
        case WM_SETFOCUS:
            if (app->m_WindowHandler[mainUUID].get() && app->m_WindowHandler[mainUUID]->GetBrowser()) 
            {
                // Pass focus to the browser window
                CefWindowHandle hwnd = app->m_WindowHandler[mainUUID]->GetBrowser()->GetHost()->GetWindowHandle();
                if (hwnd) PostMessage(hwnd, message, wParam, lParam);
            }
            return 0;

        case WM_SIZE:
            // Minimizing resizes the window to 0x0 which causes our layout to go all
            // screwy, so we just ignore it.
            if (wParam != SIZE_MINIMIZED && app->m_WindowHandler[mainUUID].get() && 
                app->m_WindowHandler[mainUUID]->GetBrowser()) 
            {
                    CefWindowHandle hwnd = app->m_WindowHandler[mainUUID]->GetBrowser()->GetHost()->GetWindowHandle();
                    if (hwnd) 
                    {
                        //  This will send a WM_SIZE and WM_PAINT message to the render process
                        SetWindowPos(hwnd, NULL, 0, 0, LOWORD(lParam), HIWORD(lParam), SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER); 
                        return 0;
                    }
            }
            break;

        case WM_ERASEBKGND:
            if (app->m_WindowHandler[mainUUID].get() && app->m_WindowHandler[mainUUID]->GetBrowser()) {
                CefWindowHandle hwnd =
                    app->m_WindowHandler[mainUUID]->GetBrowser()->GetHost()->GetWindowHandle();
                if (hwnd) {
                    // Dont erase the background if the browser window has been loaded
                    // (this avoids flashing)
                    return 0;
                }
            }
            break;

        case WM_SYSCOMMAND:
            if (wParam == IDS_EXIT_CAFFEINE) {
                PostMessage(hWnd, WM_CLOSE, g_exitCode, 0);
                return 0;
            }
            break;

        case WM_COMMAND:
            // Currently only option from the context menu is to exit, hence the fall through to the WM_CLOSE
            wParam = g_exitCode;

        case WM_CLOSE:
        {
            if (devMode || enableClose)
            {
                wParam = g_exitCode;
            }

            CefRefPtr<CaffeineClientHandler> handler = app->m_WindowHandler[mainUUID].get();

            if (handler && !handler->IsClosing()) {
                if (wParam == g_exitCode) // Jump list exit
                {
                    for (map<string, CefRefPtr<CaffeineClientHandler> >::iterator it=app->m_WindowHandler.begin(); it!=app->m_WindowHandler.end(); ++it)
                    {
                        if(it->second.get()) 
                        {
                            CefRefPtr<CefBrowser> browser = it->second->GetBrowser();
                            browser->GetHost()->CloseBrowser(false);
                        }
                    }

					//CefRefPtr<CefBrowser> browser = handler->GetBrowser();
					//if (browser.get()) {
					//	browser->GetHost()->CloseBrowser(false);
					//}
				} else {
                    ShowWindow(hWnd, SW_MINIMIZE);
                }
                return 0;
            }

            break;
        }

        case WM_TIMER:
        {
            if(IDLETIMER == wParam)
            {
                //  TODO:  Check timer id
                LASTINPUTINFO lif = {sizeof(LASTINPUTINFO), 0};
                GetLastInputInfo(&lif);
                UINT IdleTimePassed = GetTickCount() - lif.dwTime;
                
                WindowExtras *pWE = reinterpret_cast<WindowExtras *>(::GetWindowLongPtr(hWnd, 0));
                bool CurrentlyIdle = (pWE->IdleTimeThreshold < IdleTimePassed);
                if(CurrentlyIdle != pWE->IsIdle)
                {
                    const CefString EventName = (CurrentlyIdle? "startIdle" : "stopIdle");
                    pWE->IsIdle = CurrentlyIdle;
                    app->m_WindowHandler[mainUUID]->CreateAndDispatchCustomEvent(EventName);
                }
            }
            //  TODO:  When we drop XP support, we can use COM and get network connectivity events.
            else if(NETWORKTIMER == wParam)
            {
                WindowExtras *pWE = reinterpret_cast<WindowExtras *>(::GetWindowLongPtr(hWnd, 0));
                bool CurrentlyConnected = pWE->NetworkAvailable();
                if(CurrentlyConnected != pWE->IsConnected)
                {
                    const CefString EventName = (CurrentlyConnected? "os:online" : "os:offline");
                    pWE->IsConnected = CurrentlyConnected;
                    app->m_WindowHandler[mainUUID]->CreateAndDispatchCustomEvent(EventName);
                }
            }
            break;
        }

        case WM_DESTROY:
        {
            WTSUnRegisterSessionNotification(hWnd);
            // The frame window has exited

            if (!devMode)
            {
                jumpList.RemoveAllTasks();
            }

            KillTimer(hWnd, IDLETIMER);
            KillTimer(hWnd, NETWORKTIMER);
            WindowExtras *pWE = reinterpret_cast<WindowExtras *>(::GetWindowLongPtr(hWnd, 0));
            delete pWE;
            SetWindowLongPtr(hWnd, 0, 0);
            SetShutdownFlag(true);
            PostQuitMessage(0);
            return 0;
        }

        case WM_GETMINMAXINFO:
        {
            LPMINMAXINFO minmaxInfoPtr = (LPMINMAXINFO) lParam;
            minmaxInfoPtr->ptMinTrackSize.x = MAIN_WINDOW_MIN_WIN_WIDTH;
            minmaxInfoPtr->ptMinTrackSize.y = MAIN_WINDOW_MIN_WIN_HEIGHT;

            // Keep the width the same
            RECT rect;
            GetWindowRect(hWnd, &rect);
            minmaxInfoPtr->ptMaxSize.x = (rect.right - rect.left);

            // Keep window at same position
            minmaxInfoPtr->ptMaxPosition.x = rect.left;
            minmaxInfoPtr->ptMaxPosition.y = 0;

            SystemParametersInfo( SPI_GETWORKAREA, 0, &rect, 0 );
            minmaxInfoPtr->ptMaxSize.y = (rect.bottom - rect.top);

            return 0;
        }

        case WM_COPYDATA:
        {
            BOOL retval = FALSE;
            PCOPYDATASTRUCT pCds = reinterpret_cast<PCOPYDATASTRUCT>(lParam);
            if (pCds->dwData == WM_PENDING_YID) 
            {
                if (app->m_WindowHandler[mainUUID].get() && app->m_WindowHandler[mainUUID]->GetBrowser()) 
                {
                    CefRefPtr<CefFrame> frame = app->m_WindowHandler[mainUUID]->GetBrowser()->GetMainFrame();
                    wstring code = L"Caffeine.pendingYIDs.push(\"";
                    //  TODO:  Escape this ... otherwise there's an XSS
                    code += static_cast<LPWSTR>(pCds->lpData);
                    code += L"\");";
                    frame->ExecuteJavaScript(code, frame->GetURL(), 0);
                }

                retval = TRUE;
            }
            return retval;
        }

        case CAFFEINE_SOCKETS_MSG:
            CefRefPtr<CefProcessMessage> process_message = CefProcessMessage::Create("invokeSocketMethod");
            process_message->GetArgumentList()->SetInt(0, wParam);
            if (WSAGETSELECTERROR(lParam))
            {
                process_message->GetArgumentList()->SetString(1, "error");
                process_message->GetArgumentList()->SetInt(2, WSAGETSELECTERROR(lParam));
            }
            else
            {
                //  No error
                switch(WSAGETSELECTEVENT(lParam))
                {
                    case FD_CONNECT:
                        process_message->GetArgumentList()->SetString(1, "connect");
                        break;
                    case FD_CLOSE:
                        process_message->GetArgumentList()->SetString(1, "close");
                        break;
                    case FD_READ:
                        process_message->GetArgumentList()->SetString(1, "read");
                        break;
                    case FD_WRITE:
                        process_message->GetArgumentList()->SetString(1, "write");
                        break;
                }
            }
            mainWinBrowser->SendProcessMessage(PID_RENDERER, process_message);
            break;
    }

    return DefWindowProc(hWnd, message, wParam, lParam);
}
Beispiel #27
0
void Generator::generateParenthesesNonGreedy(JumpList& failures, Label start, Jump success, Jump fail)
{
    jump(start);
    success.link(this);
    failures.append(fail);
}
Beispiel #28
0
void Generator::terminateDisjunction(JumpList& successes)
{
    successes.link(this);
}
void JIT::emitSlow_op_urshift(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
{
    unsigned dst = currentInstruction[1].u.operand;
    unsigned op1 = currentInstruction[2].u.operand;
    unsigned op2 = currentInstruction[3].u.operand;
    if (isOperandConstantImmediateInt(op2)) {
        int shift = getConstantOperand(op2).asInt32();
        // op1 = regT0
        linkSlowCase(iter); // int32 check
        if (supportsFloatingPointTruncate()) {
            JumpList failures;
            failures.append(emitJumpIfNotImmediateNumber(regT0)); // op1 is not a double
            addPtr(tagTypeNumberRegister, regT0);
            movePtrToDouble(regT0, fpRegT0);
            failures.append(branchTruncateDoubleToInt32(fpRegT0, regT0));
            if (shift)
                urshift32(Imm32(shift & 0x1f), regT0);
            if (shift < 0 || !(shift & 31))
                failures.append(branch32(LessThan, regT0, Imm32(0)));
            emitFastArithReTagImmediate(regT0, regT0);
            emitPutVirtualRegister(dst, regT0);
            emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_rshift));
            failures.link(this);
        }
        if (shift < 0 || !(shift & 31))
            linkSlowCase(iter); // failed to box in hot path
    } else {
        // op1 = regT0
        // op2 = regT1
        if (!isOperandConstantImmediateInt(op1)) {
            linkSlowCase(iter); // int32 check -- op1 is not an int
            if (supportsFloatingPointTruncate()) {
                JumpList failures;
                failures.append(emitJumpIfNotImmediateNumber(regT0)); // op1 is not a double
                addPtr(tagTypeNumberRegister, regT0);
                movePtrToDouble(regT0, fpRegT0);
                failures.append(branchTruncateDoubleToInt32(fpRegT0, regT0));
                failures.append(emitJumpIfNotImmediateInteger(regT1)); // op2 is not an int
                emitFastArithImmToInt(regT1);
                urshift32(regT1, regT0);
                failures.append(branch32(LessThan, regT0, Imm32(0)));
                emitFastArithReTagImmediate(regT0, regT0);
                emitPutVirtualRegister(dst, regT0);
                emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_rshift));
                failures.link(this);
            }
        }
        
        linkSlowCase(iter); // int32 check - op2 is not an int
        linkSlowCase(iter); // Can't represent unsigned result as an immediate
    }
    
    JITStubCall stubCall(this, cti_op_urshift);
    stubCall.addArgument(op1, regT0);
    stubCall.addArgument(op2, regT1);
    stubCall.call(dst);
}
Beispiel #30
0
void JIT::compileLoadVarargs(Instruction* instruction)
{
    int thisValue = instruction[3].u.operand;
    int arguments = instruction[4].u.operand;
    int firstFreeRegister = instruction[5].u.operand;
    int firstVarArgOffset = instruction[6].u.operand;

    JumpList slowCase;
    JumpList end;
    bool canOptimize = m_codeBlock->usesArguments()
        && arguments == m_codeBlock->argumentsRegister().offset()
        && !m_codeBlock->symbolTable()->slowArguments();

    if (canOptimize) {
        emitGetVirtualRegister(arguments, regT0);
        slowCase.append(branch64(NotEqual, regT0, TrustedImm64(JSValue::encode(JSValue()))));

        emitGetFromCallFrameHeader32(JSStack::ArgumentCount, regT0);
        if (firstVarArgOffset) {
            Jump sufficientArguments = branch32(GreaterThan, regT0, TrustedImm32(firstVarArgOffset + 1));
            move(TrustedImm32(1), regT0);
            Jump endVarArgs = jump();
            sufficientArguments.link(this);
            sub32(TrustedImm32(firstVarArgOffset), regT0);
            endVarArgs.link(this);
        }
        slowCase.append(branch32(Above, regT0, TrustedImm32(Arguments::MaxArguments + 1)));
        // regT0: argumentCountIncludingThis
        move(regT0, regT1);
        add64(TrustedImm32(-firstFreeRegister + JSStack::CallFrameHeaderSize), regT1);
        // regT1 now has the required frame size in Register units
        // Round regT1 to next multiple of stackAlignmentRegisters()
        add64(TrustedImm32(stackAlignmentRegisters() - 1), regT1);
        and64(TrustedImm32(~(stackAlignmentRegisters() - 1)), regT1);

        neg64(regT1);
        lshift64(TrustedImm32(3), regT1);
        addPtr(callFrameRegister, regT1);
        // regT1: newCallFrame

        slowCase.append(branchPtr(Above, AbsoluteAddress(m_vm->addressOfStackLimit()), regT1));

        // Initialize ArgumentCount.
        store32(regT0, Address(regT1, JSStack::ArgumentCount * static_cast<int>(sizeof(Register)) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)));

        // Initialize 'this'.
        emitGetVirtualRegister(thisValue, regT2);
        store64(regT2, Address(regT1, CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register))));

        // Copy arguments.
        signExtend32ToPtr(regT0, regT0);
        end.append(branchSub64(Zero, TrustedImm32(1), regT0));
        // regT0: argumentCount

        Label copyLoop = label();
        load64(BaseIndex(callFrameRegister, regT0, TimesEight, (CallFrame::thisArgumentOffset() + firstVarArgOffset) * static_cast<int>(sizeof(Register))), regT2);
        store64(regT2, BaseIndex(regT1, regT0, TimesEight, CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register))));
        branchSub64(NonZero, TrustedImm32(1), regT0).linkTo(copyLoop, this);

        end.append(jump());
    }

    if (canOptimize)
        slowCase.link(this);

    emitGetVirtualRegister(arguments, regT1);
    callOperation(operationSizeFrameForVarargs, regT1, firstFreeRegister, firstVarArgOffset);
    move(returnValueGPR, stackPointerRegister);
    emitGetVirtualRegister(thisValue, regT1);
    emitGetVirtualRegister(arguments, regT2);
    callOperation(operationLoadVarargs, returnValueGPR, regT1, regT2, firstVarArgOffset);
    move(returnValueGPR, regT1);

    if (canOptimize)
        end.link(this);
    
    addPtr(TrustedImm32(sizeof(CallerFrameAndPC)), regT1, stackPointerRegister);
}