115613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 2a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Redistribution and use in source and binary forms, with or without 3a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// modification, are permitted provided that the following conditions are 4a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// met: 5a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// 6a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// * Redistributions of source code must retain the above copyright 7a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// notice, this list of conditions and the following disclaimer. 8a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// * Redistributions in binary form must reproduce the above 9a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// copyright notice, this list of conditions and the following 10a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// disclaimer in the documentation and/or other materials provided 11a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// with the distribution. 12a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// * Neither the name of Google Inc. nor the names of its 13a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// contributors may be used to endorse or promote products derived 14a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// from this software without specific prior written permission. 15a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// 16a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 28a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#include "v8.h" 299dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 3093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_IA32 319dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 32c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org#include "cpu-profiler.h" 338bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org#include "unicode.h" 34a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#include "log.h" 353291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org#include "regexp-stack.h" 36a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#include "macro-assembler.h" 37a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#include "regexp-macro-assembler.h" 383a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org#include "ia32/regexp-macro-assembler-ia32.h" 39a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 { 4171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal { 42a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 43c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org#ifndef V8_INTERPRETED_REGEXP 44a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org/* 45a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org * This assembler uses the following register assignment convention 4615613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * - edx : Current character. Must be loaded using LoadCurrentCharacter 4715613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * before using any of the dispatch methods. Temporarily stores the 4815613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * index of capture start after a matching pass for a global regexp. 4915613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * - edi : Current position in input, as negative offset from end of string. 50a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org * Please notice that this is the byte offset, not the character offset! 51a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org * - esi : end of input (points to byte after last character in input). 5215613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * - ebp : Frame pointer. Used to access arguments, local variables and 53bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org * RegExp registers. 5415613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * - esp : Points to tip of C stack. 5515613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * - ecx : Points to tip of backtrack stack 56a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org * 57dff694e8cc18aa9640e92962de2699b9d07a7690vegorov@chromium.org * The registers eax and ebx are free to use for computations. 58a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org * 59a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org * Each call to a public method should retain this convention. 60a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org * The stack will have the following structure: 6115613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * - Isolate* isolate (address of the current isolate) 620c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org * - direct_call (if 1, direct call from JavaScript code, if 0 630c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org * call through the runtime system) 6415613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * - stack_area_base (high end of the memory area to use as 650c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org * backtracking stack) 6615613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * - capture array size (may fit multiple sets of matches) 670c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org * - int* capture_array (int[num_saved_registers_], for output). 6815613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * - end of input (address of end of string) 6915613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * - start of input (address of first character in string) 700c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org * - start index (character index of start) 710c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org * - String* input_string (location of a handle containing the string) 72bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org * --- frame alignment (if applicable) --- 73a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org * - return address 74a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org * ebp-> - old ebp 753291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org * - backup of caller esi 763291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org * - backup of caller edi 773291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org * - backup of caller ebx 7815613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * - success counter (only for global regexps to count matches). 79bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org * - Offset of location before start of input (effectively character 80bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org * position -1). Used to initialize capture registers to a non-position. 8115613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * - register 0 ebp[-4] (only positions must be stored in the first 82a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org * - register 1 ebp[-8] num_saved_registers_ registers) 83a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org * - ... 84a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org * 85a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org * The first num_saved_registers_ registers are initialized to point to 86a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org * "character -1" in the string (i.e., char_size() bytes before the first 87a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org * character of the string). The remaining registers starts out as garbage. 88a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org * 89a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org * The data up to the return address must be placed there by the calling 90911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org * code, by calling the code entry as cast to a function with the signature: 91bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org * int (*match)(String* input_string, 920c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org * int start_index, 93bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org * Address start, 94bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org * Address end, 95bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org * int* capture_output_array, 96bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org * bool at_start, 970c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org * byte* stack_area_base, 980c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org * bool direct_call) 99a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org */ 100a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 10165dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#define __ ACCESS_MASM(masm_) 102a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 103a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgRegExpMacroAssemblerIA32::RegExpMacroAssemblerIA32( 104a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Mode mode, 1057028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org int registers_to_save, 1067028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Zone* zone) 1077028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org : NativeRegExpMacroAssembler(zone), 1081fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org masm_(new MacroAssembler(zone->isolate(), NULL, kRegExpCodeSize)), 109a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org mode_(mode), 110a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org num_registers_(registers_to_save), 111a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org num_saved_registers_(registers_to_save), 112a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org entry_label_(), 113a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org start_label_(), 114a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org success_label_(), 11537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com backtrack_label_(), 116061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org exit_label_() { 11718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org ASSERT_EQ(0, registers_to_save % 2); 118a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org __ jmp(&entry_label_); // We'll write the entry code later. 119a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org __ bind(&start_label_); // And then continue from here. 120a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 121a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 122a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 123a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgRegExpMacroAssemblerIA32::~RegExpMacroAssemblerIA32() { 124a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org delete masm_; 125a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Unuse labels in case we throw away the assembler without calling GetCode. 126a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org entry_label_.Unuse(); 127a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org start_label_.Unuse(); 128a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org success_label_.Unuse(); 12937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com backtrack_label_.Unuse(); 130a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org exit_label_.Unuse(); 13137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com check_preempt_label_.Unuse(); 1323291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org stack_overflow_label_.Unuse(); 1333291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org} 1343291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 1353291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 1363291210ab99f306b74430ebbc4b7d939629e699fager@chromium.orgint RegExpMacroAssemblerIA32::stack_limit_slack() { 1373291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org return RegExpStack::kStackLimitSlack; 138a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 139a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 140a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 141a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpMacroAssemblerIA32::AdvanceCurrentPosition(int by) { 1428bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org if (by != 0) { 143c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ add(edi, Immediate(by * char_size())); 1448bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org } 145a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 146a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 147a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 148a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpMacroAssemblerIA32::AdvanceRegister(int reg, int by) { 149a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ASSERT(reg >= 0); 150a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ASSERT(reg < num_registers_); 1513291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org if (by != 0) { 1523291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ add(register_location(reg), Immediate(by)); 1533291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org } 154a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 155a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 156a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 157a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpMacroAssemblerIA32::Backtrack() { 1583291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org CheckPreemption(); 1593291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Pop Code* offset from backtrack stack, add Code* and jump to location. 1603291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org Pop(ebx); 161c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ add(ebx, Immediate(masm_->CodeObject())); 162c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ jmp(ebx); 163a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 164a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 165a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 166a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpMacroAssemblerIA32::Bind(Label* label) { 167a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org __ bind(label); 168a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 169a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 1703291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 17137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.comvoid RegExpMacroAssemblerIA32::CheckCharacter(uint32_t c, Label* on_equal) { 172a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org __ cmp(current_character(), c); 173a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org BranchOrBacktrack(equal, on_equal); 174a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 175a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 176a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 177a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpMacroAssemblerIA32::CheckCharacterGT(uc16 limit, Label* on_greater) { 178a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org __ cmp(current_character(), limit); 179a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org BranchOrBacktrack(greater, on_greater); 180a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 181a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 182a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 183ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgvoid RegExpMacroAssemblerIA32::CheckAtStart(Label* on_at_start) { 184bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org Label not_at_start; 185ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org // Did we start the match at the start of the string at all? 186dff694e8cc18aa9640e92962de2699b9d07a7690vegorov@chromium.org __ cmp(Operand(ebp, kStartIndex), Immediate(0)); 187dff694e8cc18aa9640e92962de2699b9d07a7690vegorov@chromium.org BranchOrBacktrack(not_equal, ¬_at_start); 188ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org // If we did, are we still at the start of the input? 189bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org __ lea(eax, Operand(esi, edi, times_1, 0)); 190bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org __ cmp(eax, Operand(ebp, kInputStart)); 191ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org BranchOrBacktrack(equal, on_at_start); 192bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org __ bind(¬_at_start); 193ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org} 194ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org 195ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org 196a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpMacroAssemblerIA32::CheckNotAtStart(Label* on_not_at_start) { 1973291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Did we start the match at the start of the string at all? 198dff694e8cc18aa9640e92962de2699b9d07a7690vegorov@chromium.org __ cmp(Operand(ebp, kStartIndex), Immediate(0)); 199dff694e8cc18aa9640e92962de2699b9d07a7690vegorov@chromium.org BranchOrBacktrack(not_equal, on_not_at_start); 2003291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // If we did, are we still at the start of the input? 201bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org __ lea(eax, Operand(esi, edi, times_1, 0)); 202bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org __ cmp(eax, Operand(ebp, kInputStart)); 203a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org BranchOrBacktrack(not_equal, on_not_at_start); 204a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 205a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 206a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 207a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpMacroAssemblerIA32::CheckCharacterLT(uc16 limit, Label* on_less) { 208a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org __ cmp(current_character(), limit); 209a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org BranchOrBacktrack(less, on_less); 210a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 211a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 212a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 2138bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.orgvoid RegExpMacroAssemblerIA32::CheckGreedyLoop(Label* on_equal) { 2148bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org Label fallthrough; 2153291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ cmp(edi, Operand(backtrack_stackpointer(), 0)); 216bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ j(not_equal, &fallthrough); 217c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ add(backtrack_stackpointer(), Immediate(kPointerSize)); // Pop. 2188bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org BranchOrBacktrack(no_condition, on_equal); 2198bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org __ bind(&fallthrough); 220a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 221a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 222a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 223a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpMacroAssemblerIA32::CheckNotBackReferenceIgnoreCase( 2248bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org int start_reg, 2258bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org Label* on_no_match) { 226a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Label fallthrough; 2273291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ mov(edx, register_location(start_reg)); // Index of start of capture 2283291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ mov(ebx, register_location(start_reg + 1)); // Index of end of capture 229c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ sub(ebx, edx); // Length of capture. 2303291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 2313291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // The length of a capture should not be negative. This can only happen 2323291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // if the end of the capture is unrecorded, or at a point earlier than 2333291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // the start of the capture. 2347304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org BranchOrBacktrack(less, on_no_match); 2353291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 2363291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // If length is zero, either the capture is empty or it is completely 2373291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // uncaptured. In either case succeed immediately. 238a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org __ j(equal, &fallthrough); 239a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 2405a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // Check that there are sufficient characters left in the input. 2415a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org __ mov(eax, edi); 2425a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org __ add(eax, ebx); 2435a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org BranchOrBacktrack(greater, on_no_match); 2445a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 2458bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org if (mode_ == ASCII) { 2468bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org Label success; 2478bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org Label fail; 24837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com Label loop_increment; 2493291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Save register contents to make the registers available below. 2508bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org __ push(edi); 2513291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ push(backtrack_stackpointer()); 252245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org // After this, the eax, ecx, and edi registers are available. 2533291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 254c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ add(edx, esi); // Start of capture 255c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ add(edi, esi); // Start of text to match against capture. 256c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ add(ebx, edi); // End of text to match against capture. 25737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com 2588bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org Label loop; 2598bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org __ bind(&loop); 26037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com __ movzx_b(eax, Operand(edi, 0)); 26137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com __ cmpb_al(Operand(edx, 0)); 262bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ j(equal, &loop_increment); 26337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com 2643291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Mismatch, try case-insensitive match (converting letters to lower-case). 2653291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ or_(eax, 0x20); // Convert match character to lower-case. 2663291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ lea(ecx, Operand(eax, -'a')); 2673291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ cmp(ecx, static_cast<int32_t>('z' - 'a')); // Is eax a lowercase letter? 26859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org Label convert_capture; 26959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ j(below_equal, &convert_capture); // In range 'a'-'z'. 27059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org // Latin-1: Check for values in range [224,254] but not 247. 27159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ sub(ecx, Immediate(224 - 'a')); 27259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ cmp(ecx, Immediate(254 - 224)); 27359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ j(above, &fail); // Weren't Latin-1 letters. 27459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ cmp(ecx, Immediate(247 - 224)); // Check for 247. 27559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ j(equal, &fail); 27659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ bind(&convert_capture); 2773291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Also convert capture character. 2783291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ movzx_b(ecx, Operand(edx, 0)); 2793291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ or_(ecx, 0x20); 2803291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 281c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ cmp(eax, ecx); 282bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ j(not_equal, &fail); 28337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com 28437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com __ bind(&loop_increment); 2853291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Increment pointers into match and capture strings. 286c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ add(edx, Immediate(1)); 287c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ add(edi, Immediate(1)); 2883291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Compare to end of match, and loop if not done. 289c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ cmp(edi, ebx); 2907304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ j(below, &loop); 291bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ jmp(&success); 2928bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org 2938bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org __ bind(&fail); 2943291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Restore original values before failing. 2953291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ pop(backtrack_stackpointer()); 2968bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org __ pop(edi); 2978bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org BranchOrBacktrack(no_condition, on_no_match); 298a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 2998bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org __ bind(&success); 3003291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Restore original value before continuing. 3013291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ pop(backtrack_stackpointer()); 3023291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Drop original value of character position. 303c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ add(esp, Immediate(kPointerSize)); 3043291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Compute new value of character position after the matched part. 305c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ sub(edi, esi); 3068bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org } else { 30737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com ASSERT(mode_ == UC16); 3083291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Save registers before calling C function. 3098bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org __ push(esi); 3108bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org __ push(edi); 3113291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ push(backtrack_stackpointer()); 3123291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ push(ebx); 313bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 314c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org static const int argument_count = 4; 315ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org __ PrepareCallCFunction(argument_count, ecx); 316ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org // Put arguments into allocated stack area, last argument highest on stack. 317ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org // Parameters are 318bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org // Address byte_offset1 - Address captured substring's start. 319bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org // Address byte_offset2 - Address of current character position. 320ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org // size_t byte_length - length of capture in bytes(!) 321c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org // Isolate* isolate 322ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org 323c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org // Set isolate. 324c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org __ mov(Operand(esp, 3 * kPointerSize), 32532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Immediate(ExternalReference::isolate_address(isolate()))); 326ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org // Set byte_length. 327bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org __ mov(Operand(esp, 2 * kPointerSize), ebx); 328ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org // Set byte_offset2. 329ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org // Found by adding negative string-end offset of current position (edi) 330bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org // to end of string. 331c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ add(edi, esi); 332bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org __ mov(Operand(esp, 1 * kPointerSize), edi); 333ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org // Set byte_offset1. 334245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org // Start of capture, where edx already holds string-end negative offset. 335c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ add(edx, esi); 336bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org __ mov(Operand(esp, 0 * kPointerSize), edx); 337ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org 338c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com { 339c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com AllowExternalCallThatCantCauseGC scope(masm_); 340c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ExternalReference compare = 34132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org ExternalReference::re_case_insensitive_compare_uc16(isolate()); 342c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ CallCFunction(compare, argument_count); 343c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3443291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Pop original values before reacting on result value. 3453291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ pop(ebx); 3463291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ pop(backtrack_stackpointer()); 3478bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org __ pop(edi); 3488bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org __ pop(esi); 34937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com 3503291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Check if function returned non-zero for success or zero for failure. 351c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ or_(eax, eax); 3528bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org BranchOrBacktrack(zero, on_no_match); 3533291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // On success, increment position by length of capture. 354c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ add(edi, ebx); 3558bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org } 356a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org __ bind(&fallthrough); 357a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 358a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 359a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 360a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpMacroAssemblerIA32::CheckNotBackReference( 3618bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org int start_reg, 3628bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org Label* on_no_match) { 363a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Label fallthrough; 36437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com Label success; 36537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com Label fail; 3663291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 3673291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Find length of back-referenced capture. 36837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com __ mov(edx, register_location(start_reg)); 3693291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ mov(eax, register_location(start_reg + 1)); 370c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ sub(eax, edx); // Length to check. 3713291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Fail on partial or illegal capture (start of capture after end of capture). 372a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org BranchOrBacktrack(less, on_no_match); 3733291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Succeed on empty capture (including no capture) 374a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org __ j(equal, &fallthrough); 37537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com 3763291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Check that there are sufficient characters left in the input. 377a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org __ mov(ebx, edi); 378c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ add(ebx, eax); 379a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org BranchOrBacktrack(greater, on_no_match); 380a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 3813291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Save register to make it available below. 3823291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ push(backtrack_stackpointer()); 3833291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 3843291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Compute pointers to match string and capture string 3853291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ lea(ebx, Operand(esi, edi, times_1, 0)); // Start of match. 386c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ add(edx, esi); // Start of capture. 3873291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ lea(ecx, Operand(eax, ebx, times_1, 0)); // End of match 38837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com 38937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com Label loop; 39037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com __ bind(&loop); 39137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com if (mode_ == ASCII) { 39237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com __ movzx_b(eax, Operand(edx, 0)); 3933291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ cmpb_al(Operand(ebx, 0)); 39437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com } else { 39537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com ASSERT(mode_ == UC16); 39637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com __ movzx_w(eax, Operand(edx, 0)); 3973291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ cmpw_ax(Operand(ebx, 0)); 39837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com } 399bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ j(not_equal, &fail); 4003291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Increment pointers into capture and match string. 401c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ add(edx, Immediate(char_size())); 402c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ add(ebx, Immediate(char_size())); 4033291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Check if we have reached end of match area. 404c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ cmp(ebx, ecx); 40537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com __ j(below, &loop); 406bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ jmp(&success); 40737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com 40837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com __ bind(&fail); 4093291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Restore backtrack stackpointer. 4103291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ pop(backtrack_stackpointer()); 411a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org BranchOrBacktrack(no_condition, on_no_match); 412a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 413a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org __ bind(&success); 4143291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Move current character position to position after match. 4153291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ mov(edi, ecx); 416c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ sub(edi, esi); 4173291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Restore backtrack stackpointer. 4183291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ pop(backtrack_stackpointer()); 4193291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 420a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org __ bind(&fallthrough); 421a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 422a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 423a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 42437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.comvoid RegExpMacroAssemblerIA32::CheckNotCharacter(uint32_t c, 42537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com Label* on_not_equal) { 426a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org __ cmp(current_character(), c); 427a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org BranchOrBacktrack(not_equal, on_not_equal); 428a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 429a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 430a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 43137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.comvoid RegExpMacroAssemblerIA32::CheckCharacterAfterAnd(uint32_t c, 43237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com uint32_t mask, 43337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com Label* on_equal) { 4341456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org if (c == 0) { 4351456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org __ test(current_character(), Immediate(mask)); 4361456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org } else { 4377d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org __ mov(eax, mask); 4387d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org __ and_(eax, current_character()); 4391456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org __ cmp(eax, c); 4401456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org } 44137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com BranchOrBacktrack(equal, on_equal); 44237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com} 44337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com 44437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com 44537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.comvoid RegExpMacroAssemblerIA32::CheckNotCharacterAfterAnd(uint32_t c, 44637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com uint32_t mask, 44737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com Label* on_not_equal) { 4481456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org if (c == 0) { 4491456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org __ test(current_character(), Immediate(mask)); 4501456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org } else { 4517d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org __ mov(eax, mask); 4527d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org __ and_(eax, current_character()); 4531456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org __ cmp(eax, c); 4541456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org } 455a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org BranchOrBacktrack(not_equal, on_not_equal); 456a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 457a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 458a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 45937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.comvoid RegExpMacroAssemblerIA32::CheckNotCharacterAfterMinusAnd( 460a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uc16 c, 46137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com uc16 minus, 462a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org uc16 mask, 463a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Label* on_not_equal) { 464154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org ASSERT(minus < String::kMaxUtf16CodeUnit); 46537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com __ lea(eax, Operand(current_character(), -minus)); 4661456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org if (c == 0) { 4671456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org __ test(eax, Immediate(mask)); 4681456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org } else { 4691456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org __ and_(eax, mask); 4701456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org __ cmp(eax, c); 4711456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org } 472a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org BranchOrBacktrack(not_equal, on_not_equal); 473a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 474a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 4753291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 4761456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgvoid RegExpMacroAssemblerIA32::CheckCharacterInRange( 4771456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org uc16 from, 4781456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org uc16 to, 4791456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org Label* on_in_range) { 4801456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org __ lea(eax, Operand(current_character(), -from)); 4811456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org __ cmp(eax, to - from); 4821456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org BranchOrBacktrack(below_equal, on_in_range); 4831456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org} 4841456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 4851456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 4861456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgvoid RegExpMacroAssemblerIA32::CheckCharacterNotInRange( 4871456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org uc16 from, 4881456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org uc16 to, 4891456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org Label* on_not_in_range) { 4901456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org __ lea(eax, Operand(current_character(), -from)); 4911456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org __ cmp(eax, to - from); 4921456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org BranchOrBacktrack(above, on_not_in_range); 4931456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org} 4941456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 4951456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 4961456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgvoid RegExpMacroAssemblerIA32::CheckBitInTable( 4971456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org Handle<ByteArray> table, 4981456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org Label* on_bit_set) { 4991456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org __ mov(eax, Immediate(table)); 5001456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org Register index = current_character(); 50159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org if (mode_ != ASCII || kTableMask != String::kMaxOneByteCharCode) { 5027d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org __ mov(ebx, kTableSize - 1); 5037d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org __ and_(ebx, current_character()); 5041456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org index = ebx; 5051456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org } 5061456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org __ cmpb(FieldOperand(eax, index, times_1, ByteArray::kHeaderSize), 0); 5071456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org BranchOrBacktrack(not_equal, on_bit_set); 5081456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org} 5091456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 5101456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 51137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.combool RegExpMacroAssemblerIA32::CheckSpecialCharacterClass(uc16 type, 51237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com Label* on_no_match) { 51337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com // Range checks (c in min..max) are generally implemented by an unsigned 51437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com // (c - min) <= (max - min) check 51537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com switch (type) { 51637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com case 's': 51737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com // Match space-characters 51837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com if (mode_ == ASCII) { 5196e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org // One byte space characters are '\t'..'\r', ' ' and \u00a0. 52037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com Label success; 52137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com __ cmp(current_character(), ' '); 5226e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org __ j(equal, &success, Label::kNear); 52337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com // Check range 0x09..0x0d 5240c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org __ lea(eax, Operand(current_character(), -'\t')); 5250c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org __ cmp(eax, '\r' - '\t'); 5266e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org __ j(below_equal, &success, Label::kNear); 5276e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org // \u00a0 (NBSP). 5286e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org __ cmp(eax, 0x00a0 - '\t'); 5296e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org BranchOrBacktrack(not_equal, on_no_match); 53037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com __ bind(&success); 53137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com return true; 53237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com } 53337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com return false; 53437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com case 'S': 5356e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org // The emitted code for generic character classes is good enough. 53637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com return false; 53737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com case 'd': 53837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com // Match ASCII digits ('0'..'9') 5390c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org __ lea(eax, Operand(current_character(), -'0')); 5400c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org __ cmp(eax, '9' - '0'); 5413291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org BranchOrBacktrack(above, on_no_match); 54237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com return true; 54337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com case 'D': 54437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com // Match non ASCII-digits 5450c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org __ lea(eax, Operand(current_character(), -'0')); 5460c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org __ cmp(eax, '9' - '0'); 5473291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org BranchOrBacktrack(below_equal, on_no_match); 54837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com return true; 54937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com case '.': { 55037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com // Match non-newlines (not 0x0a('\n'), 0x0d('\r'), 0x2028 and 0x2029) 551c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ mov(eax, current_character()); 552c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ xor_(eax, Immediate(0x01)); 5533291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // See if current character is '\n'^1 or '\r'^1, i.e., 0x0b or 0x0c 554c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ sub(eax, Immediate(0x0b)); 5550c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org __ cmp(eax, 0x0c - 0x0b); 5563291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org BranchOrBacktrack(below_equal, on_no_match); 55737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com if (mode_ == UC16) { 55837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com // Compare original value to 0x2028 and 0x2029, using the already 5593291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // computed (current_char ^ 0x01 - 0x0b). I.e., check for 5603291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // 0x201d (0x2028 - 0x0b) or 0x201e. 561c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ sub(eax, Immediate(0x2028 - 0x0b)); 5620c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org __ cmp(eax, 0x2029 - 0x2028); 5633291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org BranchOrBacktrack(below_equal, on_no_match); 56437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com } 56537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com return true; 56637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com } 5670c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org case 'w': { 568b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (mode_ != ASCII) { 569b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Table is 128 entries, so all ASCII characters can be tested. 570c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ cmp(current_character(), Immediate('z')); 571b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org BranchOrBacktrack(above, on_no_match); 572b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 573b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ASSERT_EQ(0, word_character_map[0]); // Character '\0' is not a word char. 574b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ExternalReference word_map = ExternalReference::re_word_character_map(); 575b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ test_b(current_character(), 576b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Operand::StaticArray(current_character(), times_1, word_map)); 577b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org BranchOrBacktrack(zero, on_no_match); 5780c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org return true; 5790c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } 5800c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org case 'W': { 581b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Label done; 582b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (mode_ != ASCII) { 583b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Table is 128 entries, so all ASCII characters can be tested. 584c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ cmp(current_character(), Immediate('z')); 585bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ j(above, &done); 586b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 587b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ASSERT_EQ(0, word_character_map[0]); // Character '\0' is not a word char. 588b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ExternalReference word_map = ExternalReference::re_word_character_map(); 589b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ test_b(current_character(), 590b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Operand::StaticArray(current_character(), times_1, word_map)); 591b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org BranchOrBacktrack(not_zero, on_no_match); 592b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (mode_ != ASCII) { 593b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ bind(&done); 594b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 5950c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org return true; 5960c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } 5970c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // Non-standard classes (with no syntactic shorthand) used internally. 59837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com case '*': 59937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com // Match any character. 6000c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org return true; 6010c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org case 'n': { 6020c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // Match newlines (0x0a('\n'), 0x0d('\r'), 0x2028 or 0x2029). 6030c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // The opposite of '.'. 604c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ mov(eax, current_character()); 605c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ xor_(eax, Immediate(0x01)); 6060c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // See if current character is '\n'^1 or '\r'^1, i.e., 0x0b or 0x0c 607c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ sub(eax, Immediate(0x0b)); 6080c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org __ cmp(eax, 0x0c - 0x0b); 6090c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org if (mode_ == ASCII) { 6100c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org BranchOrBacktrack(above, on_no_match); 6110c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } else { 6120c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org Label done; 6130c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org BranchOrBacktrack(below_equal, &done); 6140c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org ASSERT_EQ(UC16, mode_); 6150c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // Compare original value to 0x2028 and 0x2029, using the already 6160c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // computed (current_char ^ 0x01 - 0x0b). I.e., check for 6170c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // 0x201d (0x2028 - 0x0b) or 0x201e. 618c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ sub(eax, Immediate(0x2028 - 0x0b)); 6190c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org __ cmp(eax, 1); 6200c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org BranchOrBacktrack(above, on_no_match); 6210c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org __ bind(&done); 62237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com } 62337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com return true; 6240c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } 6250c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // No custom implementation (yet): s(UC16), S(UC16). 62637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com default: 62737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com return false; 62837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com } 62937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com} 630a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 631a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 632a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpMacroAssemblerIA32::Fail() { 63315613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org STATIC_ASSERT(FAILURE == 0); // Return value for failure is zero. 63415613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org if (!global()) { 63515613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ Set(eax, Immediate(FAILURE)); 63615613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org } 637a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org __ jmp(&exit_label_); 638a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 639a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 640a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 64183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgHandle<HeapObject> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) { 64215613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org Label return_eax; 643a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Finalize code - write the entry point code now we know how many 644a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // registers we need. 645a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 646a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Entry code: 647a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org __ bind(&entry_label_); 648c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 649c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Tell the system that we have a stack frame. Because the type is MANUAL, no 650c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // code is generated. 651c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FrameScope scope(masm_, StackFrame::MANUAL); 652c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 653c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Actually emit code to start a new stack frame. 6543291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ push(ebp); 6553291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ mov(ebp, esp); 656bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org // Save callee-save registers. Order here should correspond to order of 657a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // kBackup_ebx etc. 658a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org __ push(esi); 659a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org __ push(edi); 660a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org __ push(ebx); // Callee-save on MacOS. 66115613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ push(Immediate(0)); // Number of successful matches in a global regexp. 662245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org __ push(Immediate(0)); // Make room for "input start - 1" constant. 6633291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 6643291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Check if we have space on the stack for registers. 6653291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org Label stack_limit_hit; 6663291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org Label stack_ok; 6673291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 668c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org ExternalReference stack_limit = 66932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org ExternalReference::address_of_stack_limit(isolate()); 6703291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ mov(ecx, esp); 671c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org __ sub(ecx, Operand::StaticVariable(stack_limit)); 6723291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Handle it if the stack pointer is already below the stack limit. 673bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ j(below_equal, &stack_limit_hit); 6743291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Check if there is room for the variable number of registers above 6753291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // the stack limit. 6763291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ cmp(ecx, num_registers_ * kPointerSize); 677bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ j(above_equal, &stack_ok); 678bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org // Exit with OutOfMemory exception. There is not enough space on the stack 679bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org // for our working registers. 6803291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ mov(eax, EXCEPTION); 68115613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ jmp(&return_eax); 6823291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 6833291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ bind(&stack_limit_hit); 684bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org CallCheckStackGuardState(ebx); 685c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ or_(eax, eax); 686bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org // If returned value is non-zero, we exit with the returned value as result. 68715613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ j(not_zero, &return_eax); 6883291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 6893291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ bind(&stack_ok); 690cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org // Load start index for later use. 691cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org __ mov(ebx, Operand(ebp, kStartIndex)); 6923291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 6933291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Allocate space on stack for registers. 694c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ sub(esp, Immediate(num_registers_ * kPointerSize)); 695a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Load string length. 696bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org __ mov(esi, Operand(ebp, kInputEnd)); 697a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Load input position. 698bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org __ mov(edi, Operand(ebp, kInputStart)); 699a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Set up edi to be negative offset from string end. 700c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ sub(edi, esi); 701cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org 702cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org // Set eax to address of char before start of the string. 703911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // (effectively string position -1). 704cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org __ neg(ebx); 705cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org if (mode_ == UC16) { 706cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org __ lea(eax, Operand(edi, ebx, times_2, -char_size())); 707cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org } else { 708cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org __ lea(eax, Operand(edi, ebx, times_1, -char_size())); 709cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org } 710911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Store this value in a local variable, for use when clearing 711911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // position registers. 712911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ mov(Operand(ebp, kInputStartMinusOne), eax); 713b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 71415613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org#ifdef WIN32 71515613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // Ensure that we write to each stack page, in order. Skipping a page 7163291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // on Windows can cause segmentation faults. Assuming page size is 4k. 7173291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org const int kPageSize = 4096; 7183291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org const int kRegistersPerPage = kPageSize / kPointerSize; 7193291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org for (int i = num_saved_registers_ + kRegistersPerPage - 1; 7203291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org i < num_registers_; 7213291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org i += kRegistersPerPage) { 7223291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ mov(register_location(i), eax); // One write every page. 723a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 72415613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org#endif // WIN32 72515613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org 72615613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org Label load_char_start_regexp, start_regexp; 72715613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // Load newline if index is at start, previous character otherwise. 72815613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ cmp(Operand(ebp, kStartIndex), Immediate(0)); 72915613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ j(not_equal, &load_char_start_regexp, Label::kNear); 73015613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ mov(current_character(), '\n'); 73115613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ jmp(&start_regexp, Label::kNear); 7323291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 73315613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // Global regexp restarts matching here. 73415613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ bind(&load_char_start_regexp); 73515613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // Load previous char as initial value of current character register. 73615613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org LoadCurrentCharacterUnchecked(-1, 1); 73715613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ bind(&start_regexp); 73815613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org 73915613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // Initialize on-stack registers. 74015613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org if (num_saved_registers_ > 0) { // Always is, if generated from a regexp. 74115613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // Fill saved registers with initial value = start offset - 1 74215613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // Fill in stack push order, to avoid accessing across an unwritten 74315613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // page (a problem on Windows). 74415613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org if (num_saved_registers_ > 8) { 74515613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ mov(ecx, kRegisterZero); 74615613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org Label init_loop; 74715613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ bind(&init_loop); 74815613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ mov(Operand(ebp, ecx, times_1, 0), eax); 74915613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ sub(ecx, Immediate(kPointerSize)); 75015613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ cmp(ecx, kRegisterZero - num_saved_registers_ * kPointerSize); 75115613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ j(greater, &init_loop); 75215613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org } else { // Unroll the loop. 75315613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org for (int i = 0; i < num_saved_registers_; i++) { 75415613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ mov(register_location(i), eax); 75515613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org } 75615613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org } 75715613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org } 7583291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 7593291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Initialize backtrack stack pointer. 7603291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ mov(backtrack_stackpointer(), Operand(ebp, kStackHighEnd)); 761a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 76215613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ jmp(&start_label_); 763a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 764a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Exit code: 76537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com if (success_label_.is_linked()) { 7663291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Save captures when successful. 76737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com __ bind(&success_label_); 76837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com if (num_saved_registers_ > 0) { 76937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com // copy captures to output 77037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com __ mov(ebx, Operand(ebp, kRegisterOutput)); 771bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org __ mov(ecx, Operand(ebp, kInputEnd)); 772cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org __ mov(edx, Operand(ebp, kStartIndex)); 773bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org __ sub(ecx, Operand(ebp, kInputStart)); 774cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org if (mode_ == UC16) { 775cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org __ lea(ecx, Operand(ecx, edx, times_2, 0)); 776cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org } else { 777c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ add(ecx, edx); 778cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org } 77937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com for (int i = 0; i < num_saved_registers_; i++) { 78037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com __ mov(eax, register_location(i)); 781400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org if (i == 0 && global_with_zero_length_check()) { 78215613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // Keep capture start in edx for the zero-length check later. 78315613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ mov(edx, eax); 78415613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org } 785cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org // Convert to index from start of string, not end. 786c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ add(eax, ecx); 78737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com if (mode_ == UC16) { 78837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com __ sar(eax, 1); // Convert byte index to character index. 78937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com } 79037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com __ mov(Operand(ebx, i * kPointerSize), eax); 791a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 792a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 79315613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org 79415613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org if (global()) { 79515613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // Restart matching if the regular expression is flagged as global. 79615613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // Increment success counter. 79715613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ inc(Operand(ebp, kSuccessfulCaptures)); 79815613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // Capture results have been stored, so the number of remaining global 79915613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // output registers is reduced by the number of stored captures. 80015613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ mov(ecx, Operand(ebp, kNumOutputRegisters)); 80115613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ sub(ecx, Immediate(num_saved_registers_)); 80215613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // Check whether we have enough room for another set of capture results. 80315613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ cmp(ecx, Immediate(num_saved_registers_)); 80415613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ j(less, &exit_label_); 80515613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org 80615613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ mov(Operand(ebp, kNumOutputRegisters), ecx); 80715613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // Advance the location for output. 80815613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ add(Operand(ebp, kRegisterOutput), 80915613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org Immediate(num_saved_registers_ * kPointerSize)); 81015613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org 81115613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // Prepare eax to initialize registers with its value in the next run. 81215613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ mov(eax, Operand(ebp, kInputStartMinusOne)); 81315613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org 814400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org if (global_with_zero_length_check()) { 815400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org // Special case for zero-length matches. 816400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org // edx: capture start index 817400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org __ cmp(edi, edx); 818400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org // Not a zero-length match, restart. 819400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org __ j(not_equal, &load_char_start_regexp); 820400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org // edi (offset from the end) is zero if we already reached the end. 821400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org __ test(edi, edi); 822400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org __ j(zero, &exit_label_, Label::kNear); 823400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org // Advance current position after a zero-length match. 824400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org if (mode_ == UC16) { 825400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org __ add(edi, Immediate(2)); 826400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org } else { 827400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org __ inc(edi); 828400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org } 82915613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org } 830400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org 83115613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ jmp(&load_char_start_regexp); 83215613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org } else { 83315613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ mov(eax, Immediate(SUCCESS)); 83415613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org } 835a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 83615613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org 837a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org __ bind(&exit_label_); 83815613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org if (global()) { 83915613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // Return the number of successful captures. 84015613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ mov(eax, Operand(ebp, kSuccessfulCaptures)); 84115613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org } 84215613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org 84315613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ bind(&return_eax); 8443291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Skip esp past regexp registers. 8453291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ lea(esp, Operand(ebp, kBackup_ebx)); 8463291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Restore callee-save registers. 847a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org __ pop(ebx); 848a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org __ pop(edi); 849a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org __ pop(esi); 8503291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Exit function frame, restore previous one. 8513291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ pop(ebp); 852a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org __ ret(0); 853a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 85437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com // Backtrack code (branch target for conditional backtracks). 85537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com if (backtrack_label_.is_linked()) { 85637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com __ bind(&backtrack_label_); 85737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com Backtrack(); 85837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com } 85937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com 8603291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org Label exit_with_exception; 8613291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 86237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com // Preempt-code 86337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com if (check_preempt_label_.is_linked()) { 8645a6af92a1549c81fb61855518f43b712e4c0e469christian.plesner.hansen@gmail.com SafeCallTarget(&check_preempt_label_); 8653291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 8663291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ push(backtrack_stackpointer()); 86737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com __ push(edi); 86837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com 869bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org CallCheckStackGuardState(ebx); 870c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ or_(eax, eax); 871bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org // If returning non-zero, we should end execution with the given 872bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org // result as return value. 87315613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ j(not_zero, &return_eax); 87437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com 87537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com __ pop(edi); 8763291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ pop(backtrack_stackpointer()); 877bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org // String might have moved: Reload esi from frame. 878bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org __ mov(esi, Operand(ebp, kInputEnd)); 8793291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org SafeReturn(); 8803291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org } 8813291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 8823291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Backtrack stack overflow code. 8833291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org if (stack_overflow_label_.is_linked()) { 8845a6af92a1549c81fb61855518f43b712e4c0e469christian.plesner.hansen@gmail.com SafeCallTarget(&stack_overflow_label_); 8853291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Reached if the backtrack-stack limit has been hit. 8863291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 8873291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org Label grow_failed; 8883291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Save registers before calling C function 8893291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ push(esi); 8903291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ push(edi); 8913291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 8923291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Call GrowStack(backtrack_stackpointer()) 893c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org static const int num_arguments = 3; 894ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org __ PrepareCallCFunction(num_arguments, ebx); 895c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org __ mov(Operand(esp, 2 * kPointerSize), 89632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Immediate(ExternalReference::isolate_address(isolate()))); 8976f10e41fef1524c70846d970268de222e41c594cager@chromium.org __ lea(eax, Operand(ebp, kStackHighEnd)); 8986f10e41fef1524c70846d970268de222e41c594cager@chromium.org __ mov(Operand(esp, 1 * kPointerSize), eax); 8996f10e41fef1524c70846d970268de222e41c594cager@chromium.org __ mov(Operand(esp, 0 * kPointerSize), backtrack_stackpointer()); 900ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ExternalReference grow_stack = 90132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org ExternalReference::re_grow_stack(isolate()); 902ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org __ CallCFunction(grow_stack, num_arguments); 9033291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // If return NULL, we have failed to grow the stack, and 9043291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // must exit with a stack-overflow exception. 905c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ or_(eax, eax); 9063291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ j(equal, &exit_with_exception); 9073291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Otherwise use return value as new stack pointer. 9083291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ mov(backtrack_stackpointer(), eax); 9093291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Restore saved registers and continue. 9103291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ pop(edi); 9113291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ pop(esi); 91237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com SafeReturn(); 9133291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org } 91437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com 9153291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org if (exit_with_exception.is_linked()) { 9163291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // If any of the code above needed to exit with an exception. 9173291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ bind(&exit_with_exception); 9183291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Exit with Result EXCEPTION(-1) to signal thrown exception. 9193291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ mov(eax, EXCEPTION); 92015613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ jmp(&return_eax); 92137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com } 92237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com 923a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org CodeDesc code_desc; 924a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org masm_->GetCode(&code_desc); 925ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Handle<Code> code = 92632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org isolate()->factory()->NewCode(code_desc, 92732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Code::ComputeFlags(Code::REGEXP), 92832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org masm_->CodeObject()); 92932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org PROFILE(isolate(), RegExpCodeCreateEvent(*code, *source)); 93083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org return Handle<HeapObject>::cast(code); 931a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 932a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 933a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 934a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpMacroAssemblerIA32::GoTo(Label* to) { 9358bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org BranchOrBacktrack(no_condition, to); 936a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 937a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 938a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 939a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpMacroAssemblerIA32::IfRegisterGE(int reg, 940a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int comparand, 941a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Label* if_ge) { 942a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org __ cmp(register_location(reg), Immediate(comparand)); 943a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org BranchOrBacktrack(greater_equal, if_ge); 944a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 945a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 946a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 947a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpMacroAssemblerIA32::IfRegisterLT(int reg, 948a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int comparand, 949a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Label* if_lt) { 950a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org __ cmp(register_location(reg), Immediate(comparand)); 951a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org BranchOrBacktrack(less, if_lt); 952a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 953a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 954a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 9553291210ab99f306b74430ebbc4b7d939629e699fager@chromium.orgvoid RegExpMacroAssemblerIA32::IfRegisterEqPos(int reg, 9563291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org Label* if_eq) { 9573291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ cmp(edi, register_location(reg)); 9583291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org BranchOrBacktrack(equal, if_eq); 9593291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org} 9603291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 9613291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 962a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgRegExpMacroAssembler::IrregexpImplementation 963a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org RegExpMacroAssemblerIA32::Implementation() { 964a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return kIA32Implementation; 965a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 966a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 967a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 968a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpMacroAssemblerIA32::LoadCurrentCharacter(int cp_offset, 96937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com Label* on_end_of_input, 97037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com bool check_bounds, 97137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com int characters) { 972ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org ASSERT(cp_offset >= -1); // ^ and \b can look behind one character. 973a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ASSERT(cp_offset < (1<<30)); // Be sane! (And ensure negation works) 97418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org if (check_bounds) { 97518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org CheckPosition(cp_offset + characters - 1, on_end_of_input); 97618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 97737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com LoadCurrentCharacterUnchecked(cp_offset, characters); 978a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 979a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 980a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 981a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpMacroAssemblerIA32::PopCurrentPosition() { 9823291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org Pop(edi); 983a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 984a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 985a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 986a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpMacroAssemblerIA32::PopRegister(int register_index) { 9873291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org Pop(eax); 9883291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ mov(register_location(register_index), eax); 989a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 990a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 991a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 992a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpMacroAssemblerIA32::PushBacktrack(Label* label) { 9933291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org Push(Immediate::CodeRelativeOffset(label)); 99437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com CheckStackLimit(); 995a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 996a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 997a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 998a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpMacroAssemblerIA32::PushCurrentPosition() { 9993291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org Push(edi); 1000a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 1001a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 1002a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 10033291210ab99f306b74430ebbc4b7d939629e699fager@chromium.orgvoid RegExpMacroAssemblerIA32::PushRegister(int register_index, 10043291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org StackCheckFlag check_stack_limit) { 10053291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ mov(eax, register_location(register_index)); 10063291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org Push(eax); 10073291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org if (check_stack_limit) CheckStackLimit(); 1008a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 1009a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 1010a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 1011a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpMacroAssemblerIA32::ReadCurrentPositionFromRegister(int reg) { 1012a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org __ mov(edi, register_location(reg)); 1013a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 1014a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 1015a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 1016a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpMacroAssemblerIA32::ReadStackPointerFromRegister(int reg) { 10173291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ mov(backtrack_stackpointer(), register_location(reg)); 10186f10e41fef1524c70846d970268de222e41c594cager@chromium.org __ add(backtrack_stackpointer(), Operand(ebp, kStackHighEnd)); 1019a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 1020a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 10214a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.orgvoid RegExpMacroAssemblerIA32::SetCurrentPositionFromEnd(int by) { 102283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label after_position; 10234a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org __ cmp(edi, -by * char_size()); 102483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(greater_equal, &after_position, Label::kNear); 10254a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org __ mov(edi, -by * char_size()); 10264a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org // On RegExp code entry (where this operation is used), the character before 10274a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org // the current position is expected to be already loaded. 10284a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org // We have advanced the position, so it's safe to read backwards. 10294a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org LoadCurrentCharacterUnchecked(-1, 1); 10304a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org __ bind(&after_position); 10314a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org} 1032a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 1033e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 1034a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpMacroAssemblerIA32::SetRegister(int register_index, int to) { 1035a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ASSERT(register_index >= num_saved_registers_); // Reserved for positions! 1036a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org __ mov(register_location(register_index), Immediate(to)); 1037a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 1038a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 1039a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 104015613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.orgbool RegExpMacroAssemblerIA32::Succeed() { 1041a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org __ jmp(&success_label_); 104215613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org return global(); 1043a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 1044a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 1045a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 10468bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.orgvoid RegExpMacroAssemblerIA32::WriteCurrentPositionToRegister(int reg, 10478bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org int cp_offset) { 10488bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org if (cp_offset == 0) { 10498bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org __ mov(register_location(reg), edi); 10508bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org } else { 10518bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org __ lea(eax, Operand(edi, cp_offset * char_size())); 10528bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org __ mov(register_location(reg), eax); 10538bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org } 1054a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 1055a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 10568bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org 1057ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgvoid RegExpMacroAssemblerIA32::ClearRegisters(int reg_from, int reg_to) { 1058ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org ASSERT(reg_from <= reg_to); 10593291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ mov(eax, Operand(ebp, kInputStartMinusOne)); 1060ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org for (int reg = reg_from; reg <= reg_to; reg++) { 1061ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org __ mov(register_location(reg), eax); 1062ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org } 10633291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org} 10643291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 10653291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 1066a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpMacroAssemblerIA32::WriteStackPointerToRegister(int reg) { 10676f10e41fef1524c70846d970268de222e41c594cager@chromium.org __ mov(eax, backtrack_stackpointer()); 10686f10e41fef1524c70846d970268de222e41c594cager@chromium.org __ sub(eax, Operand(ebp, kStackHighEnd)); 10696f10e41fef1524c70846d970268de222e41c594cager@chromium.org __ mov(register_location(reg), eax); 1070a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 1071a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 1072a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 1073bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org// Private methods: 10748bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org 1075bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.orgvoid RegExpMacroAssemblerIA32::CallCheckStackGuardState(Register scratch) { 1076ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org static const int num_arguments = 3; 1077ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org __ PrepareCallCFunction(num_arguments, scratch); 1078bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org // RegExp code frame pointer. 1079bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org __ mov(Operand(esp, 2 * kPointerSize), ebp); 1080bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org // Code* of self. 1081bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org __ mov(Operand(esp, 1 * kPointerSize), Immediate(masm_->CodeObject())); 1082bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org // Next address on the stack (will be address of return address). 1083bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org __ lea(eax, Operand(esp, -kPointerSize)); 1084bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org __ mov(Operand(esp, 0 * kPointerSize), eax); 108518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org ExternalReference check_stack_guard = 108632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org ExternalReference::re_check_stack_guard_state(isolate()); 1087ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org __ CallCFunction(check_stack_guard, num_arguments); 1088bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org} 1089bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 1090bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 1091bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org// Helper function for reading a value out of a stack frame. 1092bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.orgtemplate <typename T> 1093bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.orgstatic T& frame_entry(Address re_frame, int frame_offset) { 1094bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org return reinterpret_cast<T&>(Memory::int32_at(re_frame + frame_offset)); 1095bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org} 1096bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 1097bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 1098381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.orgint RegExpMacroAssemblerIA32::CheckStackGuardState(Address* return_address, 1099bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org Code* re_code, 1100bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org Address re_frame) { 1101ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Isolate* isolate = frame_entry<Isolate*>(re_frame, kIsolate); 1102ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ASSERT(isolate == Isolate::Current()); 1103ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (isolate->stack_guard()->IsStackOverflow()) { 1104ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org isolate->StackOverflow(); 1105bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org return EXCEPTION; 110637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com } 110737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com 110837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com // If not real stack overflow the stack guard was used to interrupt 110937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com // execution for another purpose. 111037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com 11110c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // If this is a direct call from JavaScript retry the RegExp forcing the call 11120c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // through the runtime system. Currently the direct call cannot handle a GC. 11130c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org if (frame_entry<int>(re_frame, kDirectCall) == 1) { 11140c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org return RETRY; 11150c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } 11160c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 111737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com // Prepare for possible GC. 11184668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org HandleScope handles(isolate); 111937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com Handle<Code> code_handle(re_code); 11203291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 1121bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org Handle<String> subject(frame_entry<String*>(re_frame, kInputString)); 11224668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org 1123bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org // Current string. 11248e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org bool is_ascii = subject->IsOneByteRepresentationUnderneath(); 1125bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 1126381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org ASSERT(re_code->instruction_start() <= *return_address); 1127381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org ASSERT(*return_address <= 112837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com re_code->instruction_start() + re_code->instruction_size()); 112937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com 1130812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org MaybeObject* result = Execution::HandleStackGuardInterrupt(isolate); 113137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com 113237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com if (*code_handle != re_code) { // Return address no longer valid 113380c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org int delta = code_handle->address() - re_code->address(); 1134381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org // Overwrite the return address on the stack. 1135381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org *return_address += delta; 113637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com } 113737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com 113837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com if (result->IsException()) { 1139bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org return EXCEPTION; 1140bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org } 1141bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 11424668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org Handle<String> subject_tmp = subject; 11434668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org int slice_offset = 0; 11444668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org 11454668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org // Extract the underlying string and the slice offset. 11464668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org if (StringShape(*subject_tmp).IsCons()) { 11474668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org subject_tmp = Handle<String>(ConsString::cast(*subject_tmp)->first()); 11484668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org } else if (StringShape(*subject_tmp).IsSliced()) { 11494668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org SlicedString* slice = SlicedString::cast(*subject_tmp); 11504668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org subject_tmp = Handle<String>(slice->parent()); 11514668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org slice_offset = slice->offset(); 11524668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org } 11534668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org 1154bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org // String might have changed. 11558e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org if (subject_tmp->IsOneByteRepresentation() != is_ascii) { 1156bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org // If we changed between an ASCII and an UC16 string, the specialized 1157bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org // code cannot be used, and we need to restart regexp matching from 1158bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org // scratch (including, potentially, compiling a new version of the code). 1159bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org return RETRY; 116037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com } 1161bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 1162bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org // Otherwise, the content of the string might have moved. It must still 1163bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org // be a sequential or external string with the same content. 1164bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org // Update the start and end pointers in the stack frame to the current 1165bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org // location (whether it has actually moved or not). 11664668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org ASSERT(StringShape(*subject_tmp).IsSequential() || 11674668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org StringShape(*subject_tmp).IsExternal()); 1168bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 1169bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org // The original start address of the characters to match. 1170bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org const byte* start_address = frame_entry<const byte*>(re_frame, kInputStart); 1171bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 1172bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org // Find the current start address of the same character at the current string 1173bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org // position. 1174bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org int start_index = frame_entry<int>(re_frame, kStartIndex); 11754668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org const byte* new_address = StringCharacterPosition(*subject_tmp, 11764668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org start_index + slice_offset); 1177bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 1178bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org if (start_address != new_address) { 1179755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // If there is a difference, update the object pointer and start and end 1180755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // addresses in the RegExp stack frame to match the new value. 1181bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org const byte* end_address = frame_entry<const byte* >(re_frame, kInputEnd); 11824668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org int byte_length = static_cast<int>(end_address - start_address); 1183755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org frame_entry<const String*>(re_frame, kInputString) = *subject; 1184bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org frame_entry<const byte*>(re_frame, kInputStart) = new_address; 1185bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org frame_entry<const byte*>(re_frame, kInputEnd) = new_address + byte_length; 1186394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } else if (frame_entry<const String*>(re_frame, kInputString) != *subject) { 1187394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Subject string might have been a ConsString that underwent 1188394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // short-circuiting during GC. That will not change start_address but 1189394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // will change pointer inside the subject handle. 1190394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com frame_entry<const String*>(re_frame, kInputString) = *subject; 1191bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org } 1192bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 119337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com return 0; 119437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com} 119537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com 119637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com 1197a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgOperand RegExpMacroAssemblerIA32::register_location(int register_index) { 1198a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org ASSERT(register_index < (1<<30)); 1199a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (num_registers_ <= register_index) { 1200a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org num_registers_ = register_index + 1; 1201a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 12023291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org return Operand(ebp, kRegisterZero - register_index * kPointerSize); 1203a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 1204a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 1205a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 120637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.comvoid RegExpMacroAssemblerIA32::CheckPosition(int cp_offset, 120737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com Label* on_outside_input) { 120837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com __ cmp(edi, -cp_offset * char_size()); 120937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com BranchOrBacktrack(greater_equal, on_outside_input); 121037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com} 121137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com 121237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com 1213a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpMacroAssemblerIA32::BranchOrBacktrack(Condition condition, 12147304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Label* to) { 1215a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (condition < 0) { // No condition 1216a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (to == NULL) { 1217a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Backtrack(); 1218a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return; 1219a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 1220a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org __ jmp(to); 1221a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return; 1222a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 1223a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (to == NULL) { 12247304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ j(condition, &backtrack_label_); 1225a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return; 1226a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 12277304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ j(condition, to); 1228a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 1229a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 1230a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 123137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.comvoid RegExpMacroAssemblerIA32::SafeCall(Label* to) { 1232ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org Label return_to; 1233ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org __ push(Immediate::CodeRelativeOffset(&return_to)); 1234ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org __ jmp(to); 1235ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org __ bind(&return_to); 123637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com} 123737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com 123837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com 123937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.comvoid RegExpMacroAssemblerIA32::SafeReturn() { 1240ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org __ pop(ebx); 1241c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ add(ebx, Immediate(masm_->CodeObject())); 1242c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ jmp(ebx); 12435a6af92a1549c81fb61855518f43b712e4c0e469christian.plesner.hansen@gmail.com} 12445a6af92a1549c81fb61855518f43b712e4c0e469christian.plesner.hansen@gmail.com 12455a6af92a1549c81fb61855518f43b712e4c0e469christian.plesner.hansen@gmail.com 12465a6af92a1549c81fb61855518f43b712e4c0e469christian.plesner.hansen@gmail.comvoid RegExpMacroAssemblerIA32::SafeCallTarget(Label* name) { 12475a6af92a1549c81fb61855518f43b712e4c0e469christian.plesner.hansen@gmail.com __ bind(name); 12483291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org} 12493291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 12503291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 12513291210ab99f306b74430ebbc4b7d939629e699fager@chromium.orgvoid RegExpMacroAssemblerIA32::Push(Register source) { 12523291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org ASSERT(!source.is(backtrack_stackpointer())); 12533291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Notice: This updates flags, unlike normal Push. 1254c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ sub(backtrack_stackpointer(), Immediate(kPointerSize)); 12553291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ mov(Operand(backtrack_stackpointer(), 0), source); 12563291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org} 12573291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 12583291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 12593291210ab99f306b74430ebbc4b7d939629e699fager@chromium.orgvoid RegExpMacroAssemblerIA32::Push(Immediate value) { 12603291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Notice: This updates flags, unlike normal Push. 1261c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ sub(backtrack_stackpointer(), Immediate(kPointerSize)); 12623291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ mov(Operand(backtrack_stackpointer(), 0), value); 12633291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org} 12643291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 12653291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 12663291210ab99f306b74430ebbc4b7d939629e699fager@chromium.orgvoid RegExpMacroAssemblerIA32::Pop(Register target) { 12673291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org ASSERT(!target.is(backtrack_stackpointer())); 12683291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ mov(target, Operand(backtrack_stackpointer(), 0)); 12693291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Notice: This updates flags, unlike normal Pop. 1270c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ add(backtrack_stackpointer(), Immediate(kPointerSize)); 12713291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org} 12723291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 12733291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 12743291210ab99f306b74430ebbc4b7d939629e699fager@chromium.orgvoid RegExpMacroAssemblerIA32::CheckPreemption() { 12753291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Check for preemption. 12763291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org Label no_preempt; 1277c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org ExternalReference stack_limit = 127832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org ExternalReference::address_of_stack_limit(isolate()); 1279c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org __ cmp(esp, Operand::StaticVariable(stack_limit)); 1280bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ j(above, &no_preempt); 12813291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 12823291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org SafeCall(&check_preempt_label_); 12833291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 12843291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org __ bind(&no_preempt); 128537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com} 128637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com 128737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com 1288a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid RegExpMacroAssemblerIA32::CheckStackLimit() { 12893811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org Label no_stack_overflow; 12903811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org ExternalReference stack_limit = 129132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org ExternalReference::address_of_regexp_stack_limit(isolate()); 12923811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org __ cmp(backtrack_stackpointer(), Operand::StaticVariable(stack_limit)); 1293bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ j(above, &no_stack_overflow); 1294a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 12953811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org SafeCall(&stack_overflow_label_); 1296a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 12973811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org __ bind(&no_stack_overflow); 1298a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 1299a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 1300a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 130137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.comvoid RegExpMacroAssemblerIA32::LoadCurrentCharacterUnchecked(int cp_offset, 130237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com int characters) { 130337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com if (mode_ == ASCII) { 130437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com if (characters == 4) { 130537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com __ mov(current_character(), Operand(esi, edi, times_1, cp_offset)); 130637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com } else if (characters == 2) { 130737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com __ movzx_w(current_character(), Operand(esi, edi, times_1, cp_offset)); 130837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com } else { 130937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com ASSERT(characters == 1); 131037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com __ movzx_b(current_character(), Operand(esi, edi, times_1, cp_offset)); 131137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com } 131237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com } else { 131337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com ASSERT(mode_ == UC16); 131437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com if (characters == 2) { 131537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com __ mov(current_character(), 1316a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Operand(esi, edi, times_1, cp_offset * sizeof(uc16))); 131737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com } else { 131837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com ASSERT(characters == 1); 131937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com __ movzx_w(current_character(), 132037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com Operand(esi, edi, times_1, cp_offset * sizeof(uc16))); 132137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com } 132237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com } 1323a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 1324a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 1325a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 1326a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#undef __ 1327911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1328c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org#endif // V8_INTERPRETED_REGEXP 1329911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1330a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}} // namespace v8::internal 13319dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 13329dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com#endif // V8_TARGET_ARCH_IA32 1333