Skip to content

Commit 86dfaeb

Browse files
committed
feat(jit): spec-driven regex replace fallible helper
1 parent a8159c2 commit 86dfaeb

2 files changed

Lines changed: 30 additions & 49 deletions

File tree

src/vm/jit/builtin_spec.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,22 @@ pub(crate) const TO_STRING_SPEC: BuiltinSpec = BuiltinSpec {
369369
needs_failure_exit: false,
370370
};
371371

372+
// ── Family 3: regex fallible ────────────────────────────────────────
373+
374+
/// `re_replace(pattern, text, replacement)` — fallible helper.
375+
pub(crate) const REGEX_REPLACE_SPEC: BuiltinSpec = BuiltinSpec {
376+
name: "regex_replace",
377+
arity: 3,
378+
inputs: &[
379+
InputRepr::HeapPtr(HeapInputKind::String), // replacement (popped third)
380+
InputRepr::HeapPtr(HeapInputKind::String), // text (popped second)
381+
InputRepr::HeapPtr(HeapInputKind::String), // pattern (popped first)
382+
],
383+
output: OutputKind::Tagged(ValueType::String),
384+
effect: BuiltinEffect::FallibleHelper,
385+
needs_failure_exit: true,
386+
};
387+
372388
/// Look up the spec for a specialized builtin kind, if one exists.
373389
///
374390
/// Returns `None` for builtins not yet covered by the spec-driven
@@ -407,6 +423,7 @@ pub(crate) fn spec_for(
407423
}
408424
super::recorder::SpecializedBuiltinKind::BytesToArrayU8 => Some(&BYTES_TO_ARRAY_U8_SPEC),
409425
super::recorder::SpecializedBuiltinKind::ToString => Some(&TO_STRING_SPEC),
426+
super::recorder::SpecializedBuiltinKind::RegexReplace => Some(&REGEX_REPLACE_SPEC),
410427
_ => None,
411428
}
412429
}

src/vm/jit/recorder.rs

Lines changed: 13 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -3411,16 +3411,10 @@ fn analyze_specialized_builtin_call(
34113411
| SpecializedBuiltinKind::BytesFromArrayU8
34123412
| SpecializedBuiltinKind::BytesToUtf8Ascii
34133413
| SpecializedBuiltinKind::BytesToArrayU8
3414-
| SpecializedBuiltinKind::ToString => {
3414+
| SpecializedBuiltinKind::ToString
3415+
| SpecializedBuiltinKind::RegexReplace => {
34153416
unreachable!("spec-covered builtins are handled by the spec-driven path")
34163417
}
3417-
SpecializedBuiltinKind::RegexReplace => {
3418-
let _ = frame.pop()?;
3419-
let _ = frame.pop()?;
3420-
let _ = frame.pop()?;
3421-
frame.push(ValueInfo::tagged_typed(ValueType::String));
3422-
Ok("regex_replace")
3423-
}
34243418
SpecializedBuiltinKind::TypeOfKnown(_) => {
34253419
let _ = frame.pop()?;
34263420
frame.push(ValueInfo::type_name());
@@ -3535,49 +3529,10 @@ fn emit_specialized_builtin_call(
35353529
| SpecializedBuiltinKind::BytesFromArrayU8
35363530
| SpecializedBuiltinKind::BytesToUtf8Ascii
35373531
| SpecializedBuiltinKind::BytesToArrayU8
3538-
| SpecializedBuiltinKind::ToString => {
3532+
| SpecializedBuiltinKind::ToString
3533+
| SpecializedBuiltinKind::RegexReplace => {
35393534
unreachable!("spec-covered builtins are handled by the spec-driven path")
35403535
}
3541-
SpecializedBuiltinKind::RegexReplace => {
3542-
let replacement = ensure_heap_ptr(
3543-
builder,
3544-
block,
3545-
ip,
3546-
frame.pop()?,
3547-
HeapContainerKind::String.value_type(),
3548-
)?;
3549-
let text = ensure_heap_ptr(
3550-
builder,
3551-
block,
3552-
ip,
3553-
frame.pop()?,
3554-
HeapContainerKind::String.value_type(),
3555-
)?;
3556-
let pattern = ensure_heap_ptr(
3557-
builder,
3558-
block,
3559-
ip,
3560-
frame.pop()?,
3561-
HeapContainerKind::String.value_type(),
3562-
)?;
3563-
let out = builder
3564-
.append_value_inst(
3565-
block,
3566-
ip,
3567-
SsaValueRepr::Tagged,
3568-
SsaInstKind::RegexReplace {
3569-
pattern: pattern.value.id,
3570-
text: text.value.id,
3571-
replacement: replacement.value.id,
3572-
},
3573-
)
3574-
.map(|value| SymbolicValue {
3575-
value,
3576-
info: ValueInfo::tagged_typed(ValueType::String),
3577-
})
3578-
.map_err(|err| TraceRecordError::InvalidIr(err.to_string()))?;
3579-
Ok(("regex_replace", out))
3580-
}
35813536
SpecializedBuiltinKind::TypeOfKnown(value_type) => {
35823537
let _ = frame.pop()?;
35833538
let type_name = match value_type {
@@ -4009,6 +3964,15 @@ fn emit_spec_driven_builtin(
40093964
ValueInfo::tagged_typed(ValueType::String),
40103965
spec.name,
40113966
),
3967+
SpecializedBuiltinKind::RegexReplace => (
3968+
SsaInstKind::RegexReplace {
3969+
pattern: popped[2].value.id,
3970+
text: popped[1].value.id,
3971+
replacement: popped[0].value.id,
3972+
},
3973+
ValueInfo::tagged_typed(ValueType::String),
3974+
spec.name,
3975+
),
40123976
SpecializedBuiltinKind::ArraySet => {
40133977
let value = &popped[0];
40143978
let index = &popped[1];

0 commit comments

Comments
 (0)