Skip to content

Commit

Permalink
Improve internalization of functions to clean stack traces
Browse files Browse the repository at this point in the history
  • Loading branch information
mikearnaldi committed May 21, 2024
1 parent 5fb0b33 commit 86d13ec
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 49 deletions.
5 changes: 5 additions & 0 deletions .changeset/giant-cows-grab.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"effect": patch
---

Improve internalization of functions to clean stack traces
23 changes: 23 additions & 0 deletions packages/effect/src/Utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -784,3 +784,26 @@ export const structuralRegion = <A>(body: () => A, tester?: (a: unknown, b: unkn
structuralRegionState.tester = currentTester
}
}

export const {
/**
* @since 3.2.2
* @status experimental
* @category tracing
*/
internalCall,
/**
* @since 3.2.2
* @status experimental
* @category tracing
*/
internalGeneratorCall
} = (() => {
const internalCall = <A>(body: () => A): A => body()
const internalGeneratorCall = <A>(body: () => A): A => body()

Object.defineProperty(internalCall, "name", { value: "effect_internal_function" })
Object.defineProperty(internalGeneratorCall, "name", { value: "effect_internal_generator" })

return { internalCall, internalGeneratorCall }
})()
15 changes: 10 additions & 5 deletions packages/effect/src/internal/cause.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1057,15 +1057,20 @@ const prettyErrorStack = (message: string, stack: string, span?: Span | undefine
const lines = stack.split("\n")

for (let i = 1; i < lines.length; i++) {
if (lines[i].includes("effect_cutpoint") || lines[i].includes("Generator.next")) {
if (lines[i].includes("effect_internal_function")) {
out.pop()
break
}
out.push(
lines[i].replace(/at .*effect_instruction_i.*\((.*)\)/, "at $1").replace(/EffectPrimitive\.\w+/, "<anonymous>")
)
if (lines[i].includes("effect_instruction_i")) {
if (lines[i].includes("effect_internal_generator")) {
out.pop()
out.pop()
break
}
out.push(
lines[i]
.replace(/at .*effect_instruction_i.*\((.*)\)/, "at $1")
.replace(/EffectPrimitive\.\w+/, "<anonymous>")
)
}

if (span) {
Expand Down
16 changes: 7 additions & 9 deletions packages/effect/src/internal/core-effect.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { internalCall, internalGeneratorCall } from "effect/Utils"
import * as Arr from "../Array.js"
import type * as Cause from "../Cause.js"
import * as Chunk from "../Chunk.js"
Expand Down Expand Up @@ -771,13 +772,16 @@ export const gen: typeof Effect.gen = function() {
}
return core.suspend(() => {
const iterator = f(pipe)
const state = iterator.next()
const state = internalGeneratorCall(() => iterator.next())
const run = (
state: IteratorYieldResult<any> | IteratorReturnResult<any>
): Effect.Effect<any, any, any> => {
return (state.done
? core.succeed(state.value)
: core.flatMap(yieldWrapGet(state.value) as any, (val: any) => run(iterator.next(val))))
: core.flatMap(
yieldWrapGet(state.value) as any,
(val: any) => run(internalGeneratorCall(() => iterator.next(val)))
))
}
return run(state)
})
Expand Down Expand Up @@ -2166,18 +2170,12 @@ export const functionWithSpan = <Args extends Array<any>, Ret extends Effect.Eff
captureStackTrace = stack.slice(2).join("\n").trim()
}
}
// eslint-disable-next-line @typescript-eslint/no-this-alias
const self = this
const args = arguments
return core.suspend(() => {
const opts = typeof options.options === "function"
? options.options.apply(null, arguments as any)
: options.options

return withSpan(
core.custom(options.body, function() {
return this.effect_instruction_i0.apply(self, args as any)
}),
core.suspend(() => internalCall(() => options.body.apply(this, arguments as any))),
opts.name,
{
...opts,
Expand Down
24 changes: 10 additions & 14 deletions packages/effect/src/internal/core.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { internalCall } from "effect/Utils"
import * as Arr from "../Array.js"
import type * as Cause from "../Cause.js"
import * as Chunk from "../Chunk.js"
Expand Down Expand Up @@ -459,10 +460,6 @@ export const as: {
/* @internal */
export const asVoid = <A, E, R>(self: Effect.Effect<A, E, R>): Effect.Effect<void, E, R> => as(self, void 0)

function commitCallCutpoint(this: any) {
return this.effect_cutpoint()
}

/* @internal */
export const custom: {
<X, A, E, R>(i0: X, body: (this: { effect_instruction_i0: X }) => Effect.Effect<A, E, R>): Effect.Effect<A, E, R>
Expand All @@ -481,24 +478,23 @@ export const custom: {
): Effect.Effect<A, E, R>
} = function() {
const wrapper = new EffectPrimitive(OpCodes.OP_COMMIT) as any
wrapper.commit = commitCallCutpoint
switch (arguments.length) {
case 2: {
wrapper.effect_instruction_i0 = arguments[0]
wrapper.effect_cutpoint = arguments[1]
wrapper.commit = arguments[1]
break
}
case 3: {
wrapper.effect_instruction_i0 = arguments[0]
wrapper.effect_instruction_i1 = arguments[1]
wrapper.effect_cutpoint = arguments[2]
wrapper.commit = arguments[2]
break
}
case 4: {
wrapper.effect_instruction_i0 = arguments[0]
wrapper.effect_instruction_i1 = arguments[1]
wrapper.effect_instruction_i2 = arguments[2]
wrapper.effect_cutpoint = arguments[3]
wrapper.commit = arguments[3]
break
}
default: {
Expand Down Expand Up @@ -538,9 +534,9 @@ export const async = <A, E = never, R = never>(
let controllerRef: AbortController | void = undefined
if (this.effect_instruction_i0.length !== 1) {
controllerRef = new AbortController()
cancelerRef = this.effect_instruction_i0(proxyResume, controllerRef.signal)
cancelerRef = internalCall(() => this.effect_instruction_i0(proxyResume, controllerRef!.signal))
} else {
cancelerRef = (this.effect_instruction_i0 as any)(proxyResume)
cancelerRef = internalCall(() => (this.effect_instruction_i0 as any)(proxyResume))
}
return (cancelerRef || controllerRef) ?
onInterrupt(effect, (_) => {
Expand Down Expand Up @@ -1011,8 +1007,8 @@ export const interruptibleMask = <A, E, R>(
effect.effect_instruction_i0 = RuntimeFlagsPatch.enable(_runtimeFlags.Interruption)
effect.effect_instruction_i1 = (oldFlags: RuntimeFlags.RuntimeFlags) =>
_runtimeFlags.interruption(oldFlags)
? this.effect_instruction_i0(interruptible)
: this.effect_instruction_i0(uninterruptible)
? internalCall(() => this.effect_instruction_i0(interruptible))
: internalCall(() => this.effect_instruction_i0(uninterruptible))
return effect
})

Expand Down Expand Up @@ -1327,8 +1323,8 @@ export const uninterruptibleMask = <A, E, R>(
effect.effect_instruction_i0 = RuntimeFlagsPatch.disable(_runtimeFlags.Interruption)
effect.effect_instruction_i1 = (oldFlags: RuntimeFlags.RuntimeFlags) =>
_runtimeFlags.interruption(oldFlags)
? this.effect_instruction_i0(interruptible)
: this.effect_instruction_i0(uninterruptible)
? internalCall(() => this.effect_instruction_i0(interruptible))
: internalCall(() => this.effect_instruction_i0(uninterruptible))
return effect
})

Expand Down
27 changes: 15 additions & 12 deletions packages/effect/src/internal/fiberRuntime.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { internalCall } from "effect/Utils"
import * as RA from "../Array.js"
import * as Boolean from "../Boolean.js"
import type * as Cause from "../Cause.js"
Expand Down Expand Up @@ -146,7 +147,7 @@ const contOpSuccess = {
cont: core.OnSuccess,
value: unknown
) => {
return cont.effect_instruction_i1(value)
return internalCall(() => cont.effect_instruction_i1(value))
},
["OnStep"]: (
_: FiberRuntime<any, any>,
Expand All @@ -160,7 +161,7 @@ const contOpSuccess = {
cont: core.OnSuccessAndFailure,
value: unknown
) => {
return cont.effect_instruction_i2(value)
return internalCall(() => cont.effect_instruction_i2(value))
},
[OpCodes.OP_REVERT_FLAGS]: (
self: FiberRuntime<any, any>,
Expand All @@ -179,10 +180,10 @@ const contOpSuccess = {
cont: core.While,
value: unknown
) => {
cont.effect_instruction_i2(value)
if (cont.effect_instruction_i0()) {
internalCall(() => cont.effect_instruction_i2(value))
if (internalCall(() => cont.effect_instruction_i0())) {
self.pushStack(cont)
return cont.effect_instruction_i1()
return internalCall(() => cont.effect_instruction_i1())
} else {
return core.void
}
Expand Down Expand Up @@ -1073,7 +1074,7 @@ export class FiberRuntime<in out A, in out E = never> implements Fiber.RuntimeFi
}

[OpCodes.OP_SYNC](op: core.Primitive & { _op: OpCodes.OP_SYNC }) {
const value = op.effect_instruction_i0()
const value = internalCall(() => op.effect_instruction_i0())
const cont = this.getNextSuccessCont()
if (cont !== undefined) {
if (!(cont._op in contOpSuccess)) {
Expand Down Expand Up @@ -1112,7 +1113,7 @@ export class FiberRuntime<in out A, in out E = never> implements Fiber.RuntimeFi
case OpCodes.OP_ON_FAILURE:
case OpCodes.OP_ON_SUCCESS_AND_FAILURE: {
if (!(_runtimeFlags.interruptible(this._runtimeFlags) && this.isInterrupted())) {
return cont.effect_instruction_i1(cause)
return internalCall(() => cont.effect_instruction_i1(cause))
} else {
return core.exitFailCause(internalCause.stripFailures(cause))
}
Expand Down Expand Up @@ -1143,9 +1144,11 @@ export class FiberRuntime<in out A, in out E = never> implements Fiber.RuntimeFi
}

[OpCodes.OP_WITH_RUNTIME](op: core.Primitive & { _op: OpCodes.OP_WITH_RUNTIME }) {
return op.effect_instruction_i0(
this as FiberRuntime<unknown, unknown>,
FiberStatus.running(this._runtimeFlags) as FiberStatus.Running
return internalCall(() =>
op.effect_instruction_i0(
this as FiberRuntime<unknown, unknown>,
FiberStatus.running(this._runtimeFlags) as FiberStatus.Running
)
)
}

Expand Down Expand Up @@ -1207,7 +1210,7 @@ export class FiberRuntime<in out A, in out E = never> implements Fiber.RuntimeFi
// Since we updated the flags, we need to revert them
const revertFlags = _runtimeFlags.diff(newRuntimeFlags, oldRuntimeFlags)
this.pushStack(new core.RevertFlags(revertFlags, op))
return op.effect_instruction_i1(oldRuntimeFlags)
return internalCall(() => op.effect_instruction_i1!(oldRuntimeFlags))
} else {
return core.exitVoid
}
Expand Down Expand Up @@ -1259,7 +1262,7 @@ export class FiberRuntime<in out A, in out E = never> implements Fiber.RuntimeFi
}

[OpCodes.OP_COMMIT](op: core.Primitive & { _op: OpCodes.OP_COMMIT }) {
return op.commit()
return internalCall(() => op.commit())
}

/**
Expand Down
23 changes: 14 additions & 9 deletions packages/effect/src/internal/stm/core.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { internalCall } from "effect/Utils"
import * as Cause from "../../Cause.js"
import * as Context from "../../Context.js"
import * as Effect from "../../Effect.js"
Expand Down Expand Up @@ -504,15 +505,17 @@ export class STMDriver<in out R, out E, out A> {
case "Commit": {
switch (current.effect_instruction_i0) {
case OpCodes.OP_DIE: {
exit = TExit.die(current.effect_instruction_i1())
exit = TExit.die(internalCall(() => current.effect_instruction_i1()))
break
}
case OpCodes.OP_FAIL: {
const cont = this.nextFailure()
if (cont === undefined) {
exit = TExit.fail(current.effect_instruction_i1())
exit = TExit.fail(internalCall(() => current.effect_instruction_i1()))
} else {
curr = cont.effect_instruction_i2(current.effect_instruction_i1()) as Primitive
curr = internalCall(() =>
cont.effect_instruction_i2(internalCall(() => current.effect_instruction_i1())) as Primitive
)
}
break
}
Expand All @@ -521,7 +524,7 @@ export class STMDriver<in out R, out E, out A> {
if (cont === undefined) {
exit = TExit.retry
} else {
curr = cont.effect_instruction_i2() as Primitive
curr = internalCall(() => cont.effect_instruction_i2() as Primitive)
}
break
}
Expand All @@ -530,7 +533,9 @@ export class STMDriver<in out R, out E, out A> {
break
}
case OpCodes.OP_WITH_STM_RUNTIME: {
curr = current.effect_instruction_i1(this as STMDriver<unknown, unknown, unknown>) as Primitive
curr = internalCall(() =>
current.effect_instruction_i1(this as STMDriver<unknown, unknown, unknown>) as Primitive
)
break
}
case OpCodes.OP_ON_SUCCESS:
Expand All @@ -542,7 +547,7 @@ export class STMDriver<in out R, out E, out A> {
}
case OpCodes.OP_PROVIDE: {
const env = this.env
this.env = current.effect_instruction_i2(env)
this.env = internalCall(() => current.effect_instruction_i2(env))
curr = pipe(
current.effect_instruction_i1,
ensuring(sync(() => (this.env = env)))
Expand All @@ -555,17 +560,17 @@ export class STMDriver<in out R, out E, out A> {
if (cont === undefined) {
exit = TExit.succeed(value)
} else {
curr = cont.effect_instruction_i2(value) as Primitive
curr = internalCall(() => cont.effect_instruction_i2(value) as Primitive)
}
break
}
case OpCodes.OP_SYNC: {
const value = current.effect_instruction_i1()
const value = internalCall(() => current.effect_instruction_i1())
const cont = this.nextSuccess()
if (cont === undefined) {
exit = TExit.succeed(value)
} else {
curr = cont.effect_instruction_i2(value) as Primitive
curr = internalCall(() => cont.effect_instruction_i2(value) as Primitive)
}
break
}
Expand Down

0 comments on commit 86d13ec

Please sign in to comment.