diff --git a/Cargo.lock b/Cargo.lock index 29176c6cc9..b93776d118 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -970,11 +970,12 @@ checksum = "8cab7a364d15cde1e505267766a2d3c4e22a843e1a601f0fa7564c0f82ced11c" [[package]] name = "regress" -version = "0.1.4" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d669f9db16c334d72d7f92d52874373eb0df8f642230401952a6901872fee4c5" +checksum = "8ade8c280902120cc06e8694a76a5aa846e875df975da904d5a1a025fa7a5b4e" dependencies = [ "memchr", + "structopt", ] [[package]] diff --git a/boa/Cargo.toml b/boa/Cargo.toml index 64c3b17cb4..ebc62ac621 100644 --- a/boa/Cargo.toml +++ b/boa/Cargo.toml @@ -21,7 +21,7 @@ gc = { version = "0.3.6", features = ["derive"] } serde_json = "1.0.59" rand = "0.7.3" num-traits = "0.2.12" -regress = "0.1.4" +regress = "0.2.0" rustc-hash = "1.1.0" num-bigint = { version = "0.3.0", features = ["serde"] } num-integer = "0.1.43" diff --git a/boa/src/builtins/regexp/mod.rs b/boa/src/builtins/regexp/mod.rs index 3e2e0afa9b..2f489a7ed1 100644 --- a/boa/src/builtins/regexp/mod.rs +++ b/boa/src/builtins/regexp/mod.rs @@ -17,7 +17,7 @@ use crate::{ value::{RcString, Value}, BoaProfiler, Context, Result, }; -use regress::{Flags, Regex}; +use regress::Regex; #[cfg(test)] mod tests; @@ -32,7 +32,7 @@ pub struct RegExp { use_last_index: bool, /// String of parsed flags. - flags: String, + flags: Box, /// Flag 's' - dot matches newline characters. dot_all: bool, @@ -52,10 +52,11 @@ pub struct RegExp { /// Flag 'u' - Unicode. unicode: bool, - pub(crate) original_source: String, - original_flags: String, + pub(crate) original_source: Box, + original_flags: Box, } +// Only safe while regress::Regex doesn't implement Trace itself. unsafe impl Trace for RegExp { empty_trace!(); } @@ -99,26 +100,32 @@ impl RegExp { /// Create a new `RegExp` pub(crate) fn constructor(this: &Value, args: &[Value], _: &mut Context) -> Result { let arg = args.get(0).ok_or_else(Value::undefined)?; - let mut regex_body = String::new(); - let mut regex_flags = String::new(); - match arg { + + let (regex_body, mut regex_flags) = match arg { Value::String(ref body) => { // first argument is a string -> use it as regex pattern - regex_body = body.to_string(); + ( + body.to_string().into_boxed_str(), + String::new().into_boxed_str(), + ) } Value::Object(ref obj) => { let obj = obj.borrow(); if let Some(regex) = obj.as_regexp() { // first argument is another `RegExp` object, so copy its pattern and flags - regex_body = regex.original_source.clone(); - regex_flags = regex.original_flags.clone(); + (regex.original_source.clone(), regex.original_flags.clone()) + } else { + ( + String::new().into_boxed_str(), + String::new().into_boxed_str(), + ) } } _ => return Err(Value::undefined()), - } + }; // if a second argument is given and it's a string, use it as flags if let Some(Value::String(flags)) = args.get(1) { - regex_flags = flags.to_string(); + regex_flags = flags.to_string().into_boxed_str(); } // parse flags @@ -154,12 +161,12 @@ impl RegExp { sorted_flags.push('y'); } - let matcher = Regex::newf(regex_body.as_str(), Flags::from(sorted_flags.as_str())) + let matcher = Regex::with_flags(®ex_body, sorted_flags.as_str()) .expect("failed to create matcher"); let regexp = RegExp { matcher, use_last_index: global || sticky, - flags: sorted_flags, + flags: sorted_flags.into_boxed_str(), dot_all, global, ignore_case, @@ -314,7 +321,7 @@ impl RegExp { let result = if let Some(m) = regex.matcher.find_from(arg_str.as_str(), last_index).next() { if regex.use_last_index { - last_index = m.total().end; + last_index = m.end(); } true } else { @@ -355,7 +362,7 @@ impl RegExp { let result = { if let Some(m) = regex.matcher.find_from(arg_str.as_str(), last_index).next() { if regex.use_last_index { - last_index = m.total().end; + last_index = m.end(); } let groups = m.captures.len() + 1; let mut result = Vec::with_capacity(groups); @@ -370,10 +377,7 @@ impl RegExp { } let result = Value::from(result); - result.set_property( - "index", - DataDescriptor::new(m.total().start, Attribute::all()), - ); + result.set_property("index", DataDescriptor::new(m.start(), Attribute::all())); result.set_property("input", DataDescriptor::new(arg_str, Attribute::all())); result } else { @@ -412,7 +416,7 @@ impl RegExp { if flags.contains('g') { let mut matches = Vec::new(); for mat in matcher.find_iter(&arg) { - matches.push(Value::from(&arg[mat.total()])); + matches.push(Value::from(&arg[mat.range()])); } if matches.is_empty() { return Ok(Value::null()); @@ -476,10 +480,7 @@ impl RegExp { let match_val = Value::from(match_vec); - match_val.set_property( - "index", - DataDescriptor::new(mat.total().start, Attribute::all()), - ); + match_val.set_property("index", DataDescriptor::new(mat.start(), Attribute::all())); match_val.set_property( "input", DataDescriptor::new(arg_str.clone(), Attribute::all()), diff --git a/boa/src/builtins/string/mod.rs b/boa/src/builtins/string/mod.rs index 0610f51bb1..992f8ee237 100644 --- a/boa/src/builtins/string/mod.rs +++ b/boa/src/builtins/string/mod.rs @@ -513,7 +513,7 @@ impl String { if let Some(regexp) = obj.as_regexp() { // first argument is another `RegExp` object, so copy its pattern and flags - return regexp.original_source.clone(); + return regexp.original_source.clone().into(); } "undefined".to_string() } @@ -587,16 +587,16 @@ impl String { } (Some('&'), _) => { // $& - result.push_str(&primitive_val[mat.total()]); + result.push_str(&primitive_val[mat.range()]); } (Some('`'), _) => { // $` - let start_of_match = mat.total().start; + let start_of_match = mat.start(); result.push_str(&primitive_val[..start_of_match]); } (Some('\''), _) => { // $' - let end_of_match = mat.total().end; + let end_of_match = mat.end(); result.push_str(&primitive_val[end_of_match..]); } (Some(second), Some(third)) @@ -666,7 +666,7 @@ impl String { .collect(); // Returns the starting byte offset of the match - let start = mat.total().start; + let start = mat.start(); results.push(Value::from(start)); // Push the whole string being examined results.push(Value::from(primitive_val.to_string())); @@ -682,7 +682,7 @@ impl String { }; Ok(Value::from(primitive_val.replacen( - &primitive_val[mat.total()], + &primitive_val[mat.range()], &replace_value, 1, )))