diff --git a/lib/impure/nre.nim b/lib/impure/nre.nim index 2321dc987b82c..6b947f2235fec 100644 --- a/lib/impure/nre.nim +++ b/lib/impure/nre.nim @@ -74,7 +74,14 @@ when defined(nimPreviewSlimSystem): export options type - Regex* = ref object + RegexDesc = object + pattern*: string + pcreObj: ptr pcre.Pcre ## not nil + pcreExtra: ptr pcre.ExtraData ## nil + + captureNameToId: Table[string, int] + + Regex* = ref RegexDesc ## Represents the pattern that things are matched against, constructed with ## `re(string)`. Examples: `re"foo"`, `re(r"(*ANYCRLF)(?x)foo # ## comment".` @@ -145,11 +152,6 @@ type ## `DOLLAR_ENDONLY`, `FIRSTLINE`, `NO_AUTO_CAPTURE`, ## `JAVASCRIPT_COMPAT`, `U`, `NO_STUDY`. In other PCRE wrappers, you ## will need to pass these as separate flags to PCRE. - pattern*: string - pcreObj: ptr pcre.Pcre ## not nil - pcreExtra: ptr pcre.ExtraData ## nil - - captureNameToId: Table[string, int] RegexMatch* = object ## Usually seen as Option[RegexMatch], it represents the result of an @@ -216,12 +218,28 @@ type ## for whatever reason. The message contains the error ## code. -proc destroyRegex(pattern: Regex) = - `=destroy`(pattern.pattern) - pcre.free_substring(cast[cstring](pattern.pcreObj)) - if pattern.pcreExtra != nil: - pcre.free_study(pattern.pcreExtra) - `=destroy`(pattern.captureNameToId) +when defined(gcDestructors): + when defined(nimAllowNonVarDestructor) and defined(nimPreviewNonVarDestructor): + proc `=destroy`(pattern: RegexDesc) = + `=destroy`(pattern.pattern) + pcre.free_substring(cast[cstring](pattern.pcreObj)) + if pattern.pcreExtra != nil: + pcre.free_study(pattern.pcreExtra) + `=destroy`(pattern.captureNameToId) + else: + proc `=destroy`(pattern: var RegexDesc) = + `=destroy`(pattern.pattern) + pcre.free_substring(cast[cstring](pattern.pcreObj)) + if pattern.pcreExtra != nil: + pcre.free_study(pattern.pcreExtra) + `=destroy`(pattern.captureNameToId) +else: + proc destroyRegex(pattern: Regex) = + `=destroy`(pattern.pattern) + pcre.free_substring(cast[cstring](pattern.pcreObj)) + if pattern.pcreExtra != nil: + pcre.free_study(pattern.pcreExtra) + `=destroy`(pattern.captureNameToId) proc getinfo[T](pattern: Regex, opt: cint): T = let retcode = pcre.fullinfo(pattern.pcreObj, pattern.pcreExtra, opt, addr result) @@ -251,7 +269,10 @@ proc getNameToNumberTable(pattern: Regex): Table[string, int] = result[name] = num proc initRegex(pattern: string, flags: int, study = true): Regex = - new(result, destroyRegex) + when defined(gcDestructors): + result = Regex() + else: + new(result, destroyRegex) result.pattern = pattern var errorMsg: cstring diff --git a/lib/system.nim b/lib/system.nim index 2f9cdc5f91334..def2b32bfbb55 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -125,18 +125,32 @@ proc unsafeAddr*[T](x: T): ptr T {.magic: "Addr", noSideEffect.} = const ThisIsSystem = true -proc new*[T](a: var ref T, finalizer: proc (x: ref T) {.nimcall.}) {. - magic: "NewFinalize", noSideEffect.} - ## Creates a new object of type `T` and returns a safe (traced) - ## reference to it in `a`. - ## - ## When the garbage collector frees the object, `finalizer` is called. - ## The `finalizer` may not keep a reference to the - ## object pointed to by `x`. The `finalizer` cannot prevent the GC from - ## freeing the object. - ## - ## **Note**: The `finalizer` refers to the type `T`, not to the object! - ## This means that for each object of type `T` the finalizer will be called! +when not defined(gcArc) and not defined(gcOrc) and not defined(gcAtomicArc): + proc new*[T](a: var ref T, finalizer: proc (x: ref T) {.nimcall.}) {. + magic: "NewFinalize", noSideEffect.} + ## Creates a new object of type `T` and returns a safe (traced) + ## reference to it in `a`. + ## + ## When the garbage collector frees the object, `finalizer` is called. + ## The `finalizer` may not keep a reference to the + ## object pointed to by `x`. The `finalizer` cannot prevent the GC from + ## freeing the object. + ## + ## **Note**: The `finalizer` refers to the type `T`, not to the object! + ## This means that for each object of type `T` the finalizer will be called! +else: + proc new*[T](a: var ref T, finalizer: proc (x: ref T) {.nimcall.}) {. + magic: "NewFinalize", noSideEffect, deprecated: "`finalizer` is not supported by arc/orc".} + ## Creates a new object of type `T` and returns a safe (traced) + ## reference to it in `a`. + ## + ## When the garbage collector frees the object, `finalizer` is called. + ## The `finalizer` may not keep a reference to the + ## object pointed to by `x`. The `finalizer` cannot prevent the GC from + ## freeing the object. + ## + ## **Note**: The `finalizer` refers to the type `T`, not to the object! + ## This means that for each object of type `T` the finalizer will be called! proc `=wasMoved`*[T](obj: var T) {.magic: "WasMoved", noSideEffect.} = ## Generic `wasMoved`:idx: implementation that can be overridden.