///|
// Runtime-owned name resolution for bytecode instructions whose environment
// chain may contain a live `with` object. Ordinary lexical and global paths
// stay on their existing synchronous helpers; this request is created only
// when a dynamic environment is present.
priv enum ExecutorBindingOperation {
  ExecutorBindingLoad
  ExecutorBindingAssignmentLoad
  ExecutorBindingStore(Value)
  ExecutorBindingTypeof
  ExecutorBindingDirectEvalCallee
}

///|
pub struct ExecutorBindingRequest {
  priv ctx : ExecContext
  priv env : Environment
  priv name : String
  priv operation : ExecutorBindingOperation
  priv loc : @token.Loc
}

///|
fn ExecutorBindingRequest::ExecutorBindingRequest(
  ctx~ : ExecContext,
  env~ : Environment,
  name~ : String,
  operation~ : ExecutorBindingOperation,
  loc~ : @token.Loc,
) -> ExecutorBindingRequest {
  { ctx, env, name, operation, loc, }
}

///|
pub enum ExecutorBindingStart {
  ExecutorBindingCompleted(Value)
  ExecutorBindingSuspended(ExecutorBindingRequest)
}

///|
fn environment_requires_managed_binding(
  env : Environment,
  name : String,
) -> Bool {
  match env.with_object {
    Some(_) => true
    None =>
      match env.bindings.get(name) {
        Some(_) => false
        None =>
          match env.parent {
            Some(parent) => environment_requires_managed_binding(parent, name)
            None => false
          }
      }
  }
}

///|
fn binding_assignment_requires_managed_resolution(
  env : Environment,
  name : String,
) -> Bool {
  match env.with_object {
    Some(_) => true
    None =>
      match env.bindings.get(name) {
        Some(_) => false
        None =>
          match env.parent {
            Some(parent) =>
              binding_assignment_requires_managed_resolution(parent, name)
            None => true
          }
      }
  }
}

///|
fn executor_binding_global_value(
  interp : Interpreter,
  name : String,
) -> Value raise Error {
  match interp.global_this {
    Object(data) =>
      match data.bag.properties.get(name) {
        Some(value) => value
        None => raise @errors.ReferenceError(message="\{name} is not defined")
      }
    _ => raise @errors.ReferenceError(message="\{name} is not defined")
  }
}

///|
fn executor_binding_unresolved(
  interp : Interpreter,
  request : ExecutorBindingRequest,
) -> Value raise Error {
  match request.operation {
    ExecutorBindingLoad => executor_binding_global_value(interp, request.name)
    ExecutorBindingAssignmentLoad | ExecutorBindingDirectEvalCallee =>
      raise @errors.ReferenceError(message="\{request.name} is not defined")
    ExecutorBindingTypeof =>
      match interp.global_this {
        Object(data) =>
          match data.bag.properties.get(request.name) {
            Some(value) => String_(type_of(value))
            None => String_("undefined")
          }
        _ => String_("undefined")
      }
    ExecutorBindingStore(value) => {
      if interp.is_immutable_global(request.name) {
        if request.ctx.strict {
          raise @errors.TypeError(
            message="Cannot assign to read only property '\{request.name}' of object '[object global]'",
          )
        }
        return value
      }
      if request.ctx.strict {
        raise @errors.ReferenceError(message="\{request.name} is not defined")
      }
      interp.global.def(request.name, value, VarBinding)
      interp.mirror_to_global(request.name, value, configurable=true)
      value
    }
  }
}

///|
fn executor_binding_synchronous(
  interp : Interpreter,
  request : ExecutorBindingRequest,
) -> Value raise Error {
  match request.operation {
    ExecutorBindingLoad => interp.get_compiled_name(request.env, request.name)
    ExecutorBindingAssignmentLoad =>
      get_assignment_name_value(request.ctx, request.env, request.name)
    ExecutorBindingStore(value) =>
      interp.assign_compiled_name(request.ctx, request.env, request.name, value)
    ExecutorBindingTypeof =>
      interp.typeof_compiled_name(request.ctx, request.env, request.name)
    ExecutorBindingDirectEvalCallee => load_direct_eval_callee(request.env)
  }
}

///|
fn begin_executor_binding_operation(
  interp : Interpreter,
  request : ExecutorBindingRequest,
) -> ExecutorBindingStart raise Error {
  match request.operation {
    ExecutorBindingStore(_) =>
      @static_semantics.validate_strict_assignment_target_name(
        request.ctx.strict,
        request.name,
      )
    ExecutorBindingAssignmentLoad =>
      @static_semantics.validate_strict_assignment_target_name(
        request.ctx.strict,
        request.name,
      )
    ExecutorBindingTypeof =>
      @static_semantics.validate_strict_identifier_reference(
        request.ctx.strict,
        request.name,
      )
    _ => ()
  }
  let requires_managed_resolution = match request.operation {
    ExecutorBindingAssignmentLoad | ExecutorBindingStore(_) =>
      binding_assignment_requires_managed_resolution(request.env, request.name)
    _ => environment_requires_managed_binding(request.env, request.name)
  }
  if !requires_managed_resolution {
    match request.operation {
      ExecutorBindingStore(value) if interp.is_immutable_global(request.name) => {
        if request.ctx.strict {
          raise @errors.TypeError(
            message="Cannot assign to read only property '\{request.name}' of object '[object global]'",
          )
        }
        return ExecutorBindingCompleted(value)
      }
      _ => ()
    }
    return ExecutorBindingCompleted(
      executor_binding_synchronous(interp, request),
    )
  }
  ExecutorBindingSuspended(request)
}

///|
pub fn begin_executor_binding_load(
  interp : Interpreter,
  ctx : ExecContext,
  env : Environment,
  name : String,
  loc : @token.Loc,
) -> ExecutorBindingStart raise Error {
  begin_executor_binding_operation(
    interp,
    ExecutorBindingRequest(
      ctx~,
      env~,
      name~,
      operation=ExecutorBindingLoad,
      loc~,
    ),
  )
}

///|
pub fn begin_executor_binding_assignment_load(
  interp : Interpreter,
  ctx : ExecContext,
  env : Environment,
  name : String,
  loc : @token.Loc,
) -> ExecutorBindingStart raise Error {
  begin_executor_binding_operation(
    interp,
    ExecutorBindingRequest(
      ctx~,
      env~,
      name~,
      operation=ExecutorBindingAssignmentLoad,
      loc~,
    ),
  )
}

///|
pub fn begin_executor_binding_store(
  interp : Interpreter,
  ctx : ExecContext,
  env : Environment,
  name : String,
  value : Value,
  loc : @token.Loc,
) -> ExecutorBindingStart raise Error {
  begin_executor_binding_operation(
    interp,
    ExecutorBindingRequest(
      ctx~,
      env~,
      name~,
      operation=ExecutorBindingStore(value),
      loc~,
    ),
  )
}

///|
pub fn begin_executor_binding_typeof(
  interp : Interpreter,
  ctx : ExecContext,
  env : Environment,
  name : String,
  loc : @token.Loc,
) -> ExecutorBindingStart raise Error {
  begin_executor_binding_operation(
    interp,
    ExecutorBindingRequest(
      ctx~,
      env~,
      name~,
      operation=ExecutorBindingTypeof,
      loc~,
    ),
  )
}

///|
pub fn begin_executor_binding_direct_eval(
  interp : Interpreter,
  ctx : ExecContext,
  env : Environment,
  loc : @token.Loc,
) -> ExecutorBindingStart raise Error {
  begin_executor_binding_operation(
    interp,
    ExecutorBindingRequest(
      ctx~,
      env~,
      name="eval",
      operation=ExecutorBindingDirectEvalCallee,
      loc~,
    ),
  )
}

///|
priv enum ExecutorBindingPhase {
  ExecutorBindingNeedEnvironment(Environment)
  ExecutorBindingAwaitGlobalHas(Value, ExecutorDeleteHasPropertyOperation)
  ExecutorBindingAwaitHas(
    Environment,
    Value,
    ExecutorDeleteHasPropertyOperation
  )
  ExecutorBindingAwaitRecheck(
    Environment,
    Value,
    ExecutorDeleteHasPropertyOperation
  )
  ExecutorBindingAwaitUnscopables(Environment, Value)
  ExecutorBindingHaveUnscopables(Environment, Value, Value)
  ExecutorBindingAwaitUnscopablesName(Environment, Value)
  ExecutorBindingHaveUnscopablesName(Environment, Value, Value)
  ExecutorBindingAwaitGet
  ExecutorBindingHaveGet(Value)
  ExecutorBindingAwaitSet
  ExecutorBindingComplete(Value)
  ExecutorBindingDone
}

///|
priv struct ExecutorBindingFrame {
  request : ExecutorBindingRequest
  mut phase : ExecutorBindingPhase
}

///|
fn ExecutorBindingFrame::ExecutorBindingFrame(
  request : ExecutorBindingRequest,
) -> ExecutorBindingFrame {
  { request, phase: ExecutorBindingNeedEnvironment(request.env), }
}

///|
fn ExecutorBindingFrame::parent_or_unresolved(
  self : ExecutorBindingFrame,
  env : Environment,
  interp : Interpreter,
) -> ExecutorActivationStep raise Error {
  match env.parent {
    Some(parent) => {
      self.phase = ExecutorBindingNeedEnvironment(parent)
      ExecutorActivationContinue
    }
    None =>
      match self.request.operation {
        ExecutorBindingAssignmentLoad | ExecutorBindingStore(_) =>
          self.begin_global_has(interp)
        _ => {
          let value = executor_binding_unresolved(interp, self.request)
          self.phase = ExecutorBindingComplete(value)
          ExecutorActivationNormal(value)
        }
      }
  }
}

///|
fn ExecutorBindingFrame::begin_global_has(
  self : ExecutorBindingFrame,
  interp : Interpreter,
) -> ExecutorActivationStep raise Error {
  let obj = interp.global_this
  let operation = ExecutorDeleteHasPropertyOperation(
    target=obj,
    key=String_(self.request.name),
    loc=self.request.loc,
  )
  match operation.step(interp) {
    ExecutorActivationNormal(Bool(has_property)) =>
      self.after_global_has(obj, has_property, interp)
    ExecutorActivationNormal(_) =>
      raise @errors.InternalError(
        message="global binding HasProperty returned a non-boolean",
      )
    step => {
      self.phase = ExecutorBindingAwaitGlobalHas(obj, operation)
      step
    }
  }
}

///|
fn ExecutorBindingFrame::after_global_has(
  self : ExecutorBindingFrame,
  obj : Value,
  has_property : Bool,
  interp : Interpreter,
) -> ExecutorActivationStep raise Error {
  if has_property {
    self.finish_with_object(obj)
  } else {
    let value = executor_binding_unresolved(interp, self.request)
    self.phase = ExecutorBindingComplete(value)
    ExecutorActivationNormal(value)
  }
}

///|
fn ExecutorBindingFrame::finish_with_object(
  self : ExecutorBindingFrame,
  obj : Value,
) -> ExecutorActivationStep {
  match self.request.operation {
    ExecutorBindingStore(value) => {
      self.phase = ExecutorBindingAwaitSet
      executor_activation_managed_property_set(
        obj,
        self.request.name,
        value,
        self.request.loc,
        self.request.ctx.strict,
      )
    }
    _ => {
      self.phase = ExecutorBindingAwaitGet
      executor_activation_managed_property_get(
        obj,
        self.request.name,
        self.request.loc,
      )
    }
  }
}

///|
fn ExecutorBindingFrame::after_has(
  self : ExecutorBindingFrame,
  env : Environment,
  obj : Value,
  has_property : Bool,
  interp : Interpreter,
) -> ExecutorActivationStep raise Error {
  if !has_property {
    return self.parent_or_unresolved(env, interp)
  }
  self.phase = ExecutorBindingAwaitUnscopables(env, obj)
  executor_activation_symbol_property_get(
    obj,
    interp.realm_state.well_known_symbols.unscopables,
    self.request.loc,
  )
}

///|
fn ExecutorBindingFrame::after_unscopables(
  self : ExecutorBindingFrame,
  env : Environment,
  obj : Value,
  unscopables : Value,
  interp : Interpreter,
) -> ExecutorActivationStep raise Error {
  if is_object_value(unscopables) {
    self.phase = ExecutorBindingAwaitUnscopablesName(env, obj)
    return executor_activation_managed_property_get(
      unscopables,
      self.request.name,
      self.request.loc,
    )
  }
  self.begin_recheck(env, obj, interp)
}

///|
fn ExecutorBindingFrame::after_unscopables_name(
  self : ExecutorBindingFrame,
  env : Environment,
  obj : Value,
  unscopables_value : Value,
  interp : Interpreter,
) -> ExecutorActivationStep raise Error {
  if is_truthy(unscopables_value) {
    self.parent_or_unresolved(env, interp)
  } else {
    self.begin_recheck(env, obj, interp)
  }
}

///|
fn ExecutorBindingFrame::begin_recheck(
  self : ExecutorBindingFrame,
  env : Environment,
  obj : Value,
  interp : Interpreter,
) -> ExecutorActivationStep raise Error {
  let operation = ExecutorDeleteHasPropertyOperation(
    target=obj,
    key=String_(self.request.name),
    loc=self.request.loc,
  )
  match operation.step(interp) {
    ExecutorActivationNormal(Bool(has_property)) =>
      self.after_recheck(obj, has_property)
    ExecutorActivationNormal(_) =>
      raise @errors.InternalError(
        message="binding HasProperty recheck returned a non-boolean",
      )
    step => {
      self.phase = ExecutorBindingAwaitRecheck(env, obj, operation)
      step
    }
  }
}

///|
fn ExecutorBindingFrame::after_recheck(
  self : ExecutorBindingFrame,
  obj : Value,
  has_property : Bool,
) -> ExecutorActivationStep raise Error {
  if !has_property {
    match self.request.operation {
      ExecutorBindingStore(value) => {
        if self.request.ctx.strict {
          raise @errors.ReferenceError(
            message="\{self.request.name} is not defined",
          )
        }
        self.phase = ExecutorBindingAwaitSet
        executor_activation_managed_property_set(
          obj,
          self.request.name,
          value,
          self.request.loc,
          false,
        )
      }
      ExecutorBindingTypeof => {
        if self.request.ctx.strict {
          raise @errors.ReferenceError(
            message="\{self.request.name} is not defined",
          )
        }
        let result = String_("undefined")
        self.phase = ExecutorBindingComplete(result)
        ExecutorActivationNormal(result)
      }
      _ => {
        if self.request.ctx.strict {
          raise @errors.ReferenceError(
            message="\{self.request.name} is not defined",
          )
        }
        self.phase = ExecutorBindingComplete(Undefined)
        ExecutorActivationNormal(Undefined)
      }
    }
  } else {
    self.finish_with_object(obj)
  }
}

///|
fn ExecutorBindingFrame::step_environment(
  self : ExecutorBindingFrame,
  env : Environment,
  interp : Interpreter,
) -> ExecutorActivationStep raise Error {
  match env.with_object {
    Some(obj) => {
      let operation = ExecutorDeleteHasPropertyOperation(
        target=obj,
        key=String_(self.request.name),
        loc=self.request.loc,
      )
      match operation.step(interp) {
        ExecutorActivationNormal(Bool(has_property)) =>
          self.after_has(env, obj, has_property, interp)
        ExecutorActivationNormal(_) =>
          raise @errors.InternalError(
            message="binding HasProperty returned a non-boolean",
          )
        step => {
          self.phase = ExecutorBindingAwaitHas(env, obj, operation)
          step
        }
      }
    }
    None =>
      match env.bindings.get(self.request.name) {
        Some(_) => {
          let value = executor_binding_synchronous(interp, {
            ..self.request,
            env,
          })
          self.phase = ExecutorBindingComplete(value)
          ExecutorActivationNormal(value)
        }
        None => self.parent_or_unresolved(env, interp)
      }
  }
}

///|
impl ExecutorActivationFrame for ExecutorBindingFrame with fn step(self, interp) {
  match self.phase {
    ExecutorBindingNeedEnvironment(env) => self.step_environment(env, interp)
    ExecutorBindingAwaitGlobalHas(obj, operation) =>
      match operation.step(interp) {
        ExecutorActivationNormal(Bool(has_property)) =>
          self.after_global_has(obj, has_property, interp)
        ExecutorActivationNormal(_) =>
          raise @errors.InternalError(
            message="global binding HasProperty returned a non-boolean",
          )
        step => {
          self.phase = ExecutorBindingAwaitGlobalHas(obj, operation)
          step
        }
      }
    ExecutorBindingAwaitHas(env, obj, operation) =>
      match operation.step(interp) {
        ExecutorActivationNormal(Bool(has_property)) =>
          self.after_has(env, obj, has_property, interp)
        ExecutorActivationNormal(_) =>
          raise @errors.InternalError(
            message="binding HasProperty returned a non-boolean",
          )
        step => {
          self.phase = ExecutorBindingAwaitHas(env, obj, operation)
          step
        }
      }
    ExecutorBindingAwaitRecheck(env, obj, operation) =>
      match operation.step(interp) {
        ExecutorActivationNormal(Bool(has_property)) =>
          self.after_recheck(obj, has_property)
        ExecutorActivationNormal(_) =>
          raise @errors.InternalError(
            message="binding HasProperty recheck returned a non-boolean",
          )
        step => {
          self.phase = ExecutorBindingAwaitRecheck(env, obj, operation)
          step
        }
      }
    ExecutorBindingAwaitUnscopables(_, _) =>
      raise @errors.InternalError(
        message="binding frame stepped while awaiting unscopables",
      )
    ExecutorBindingHaveUnscopables(env, obj, value) =>
      self.after_unscopables(env, obj, value, interp)
    ExecutorBindingAwaitUnscopablesName(_, _) =>
      raise @errors.InternalError(
        message="binding frame stepped while awaiting unscopables name",
      )
    ExecutorBindingHaveUnscopablesName(env, obj, value) =>
      self.after_unscopables_name(env, obj, value, interp)
    ExecutorBindingAwaitGet =>
      raise @errors.InternalError(
        message="binding frame stepped while awaiting get",
      )
    ExecutorBindingHaveGet(value) => {
      let result = match self.request.operation {
        ExecutorBindingTypeof => String_(type_of(value))
        _ => value
      }
      self.phase = ExecutorBindingComplete(result)
      ExecutorActivationNormal(result)
    }
    ExecutorBindingAwaitSet =>
      raise @errors.InternalError(
        message="binding frame stepped while awaiting set",
      )
    ExecutorBindingComplete(value) => {
      self.phase = ExecutorBindingDone
      ExecutorActivationNormal(value)
    }
    ExecutorBindingDone =>
      raise @errors.InternalError(
        message="binding frame stepped after completion",
      )
  }
}

///|
impl ExecutorActivationFrame for ExecutorBindingFrame with fn deliver_activation_completion(
  self,
  completion,
) {
  match completion {
    ExecutorActivationCompletionAbrupt(error) => raise error
    ExecutorActivationCompletionReference(_) =>
      raise @errors.InternalError(
        message="binding frame received an unexpected binding reference completion",
      )
    ExecutorActivationCompletionNormal(value) =>
      match self.phase {
        ExecutorBindingAwaitGlobalHas(_, operation) =>
          operation.deliver_activation_completion(
            ExecutorActivationCompletionNormal(value),
          )
        ExecutorBindingAwaitHas(_, _, operation) =>
          operation.deliver_activation_completion(
            ExecutorActivationCompletionNormal(value),
          )
        ExecutorBindingAwaitRecheck(_, _, operation) =>
          operation.deliver_activation_completion(
            ExecutorActivationCompletionNormal(value),
          )
        ExecutorBindingAwaitUnscopables(env, obj) =>
          self.phase = ExecutorBindingHaveUnscopables(env, obj, value)
        ExecutorBindingAwaitUnscopablesName(env, obj) =>
          self.phase = ExecutorBindingHaveUnscopablesName(env, obj, value)
        ExecutorBindingAwaitGet => self.phase = ExecutorBindingHaveGet(value)
        ExecutorBindingAwaitSet => {
          let result = match self.request.operation {
            ExecutorBindingStore(value) => value
            _ =>
              raise @errors.InternalError(
                message="binding set completion had a non-store operation",
              )
          }
          self.phase = ExecutorBindingComplete(result)
        }
        ExecutorBindingNeedEnvironment(_)
        | ExecutorBindingHaveUnscopables(_, _, _)
        | ExecutorBindingHaveUnscopablesName(_, _, _)
        | ExecutorBindingHaveGet(_)
        | ExecutorBindingComplete(_)
        | ExecutorBindingDone =>
          raise @errors.InternalError(
            message="binding received an unexpected child completion",
          )
      }
  }
}

///|
pub fn executor_activation_binding_request(
  request : ExecutorBindingRequest,
) -> ExecutorActivationStep {
  ExecutorActivationBinding(request)
}

///|
fn executor_binding_completion(
  step : ExecutorCompletedStep,
) -> ExecutorActivationCompletion {
  match step {
    ExecutorCompletedNormal(value) | ExecutorCompletedReturn(value) =>
      ExecutorActivationCompletionNormal(value)
    ExecutorCompletedReference(_) =>
      ExecutorActivationCompletionAbrupt(
        @errors.InternalError(
          message="binding frame completed with a pending activation step",
        ),
      )
  }
}

///|
priv enum ExecutorProxyPropertySetPhase {
  ExecutorProxyPropertySetNeedTrap
  ExecutorProxyPropertySetAwaitTrapLookup
  ExecutorProxyPropertySetHaveTrap(Value)
  ExecutorProxyPropertySetAwaitTrapCall
  ExecutorProxyPropertySetHaveTrapResult(Value)
  ExecutorProxyPropertySetAwaitForward
  ExecutorProxyPropertySetComplete(Value)
  ExecutorProxyPropertySetDone
}

///|
priv struct ExecutorProxyPropertySetFrame {
  target : Value
  handler : Value
  key : ExecutorPropertyGetKey
  value : Value
  receiver : Value
  strict : Bool
  loc : @token.Loc
  mut phase : ExecutorProxyPropertySetPhase
}

///|
fn ExecutorProxyPropertySetFrame::ExecutorProxyPropertySetFrame(
  target~ : Value,
  handler~ : Value,
  key~ : ExecutorPropertyGetKey,
  value~ : Value,
  receiver~ : Value,
  strict~ : Bool,
  loc~ : @token.Loc,
) -> ExecutorProxyPropertySetFrame {
  {
    target,
    handler,
    key,
    value,
    receiver,
    strict,
    loc,
    phase: ExecutorProxyPropertySetNeedTrap,
  }
}

///|
fn ExecutorProxyPropertySetFrame::step_frame(
  self : ExecutorProxyPropertySetFrame,
  interp : Interpreter,
) -> ExecutorActivationStep raise Error {
  match self.phase {
    ExecutorProxyPropertySetNeedTrap => {
      self.phase = ExecutorProxyPropertySetAwaitTrapLookup
      executor_activation_managed_property_get(self.handler, "set", self.loc)
    }
    ExecutorProxyPropertySetAwaitTrapLookup
    | ExecutorProxyPropertySetAwaitTrapCall
    | ExecutorProxyPropertySetAwaitForward =>
      raise @errors.InternalError(
        message="proxy set frame stepped while awaiting a child activation",
      )
    ExecutorProxyPropertySetHaveTrap(trap) =>
      match trap {
        Undefined | Null => {
          self.phase = ExecutorProxyPropertySetAwaitForward
          executor_activation_managed_property_set_key_with_receiver(
            self.target,
            self.key,
            self.value,
            self.receiver,
            self.loc,
            self.strict,
          )
        }
        _ if !is_callable(trap) =>
          raise @errors.TypeError(
            message="'set' on proxy: trap is not a function",
          )
        _ => {
          self.phase = ExecutorProxyPropertySetAwaitTrapCall
          executor_activation_call(
            trap,
            self.handler,
            [
              self.target,
              executor_property_get_key_value(self.key),
              self.value,
              self.receiver,
            ],
            self.loc,
          )
        }
      }
    ExecutorProxyPropertySetHaveTrapResult(result) =>
      if !is_truthy(result) {
        if self.strict {
          raise @errors.TypeError(
            message="'set' on proxy: trap returned falsish",
          )
        }
        self.phase = ExecutorProxyPropertySetComplete(self.value)
        ExecutorActivationContinue
      } else {
        check_proxy_set_trap_invariants_with_interp(
          Some(interp),
          self.target,
          executor_property_get_key_value(self.key),
          self.value,
        )
        self.phase = ExecutorProxyPropertySetComplete(self.value)
        ExecutorActivationContinue
      }
    ExecutorProxyPropertySetComplete(value) => {
      self.phase = ExecutorProxyPropertySetDone
      ExecutorActivationNormal(value)
    }
    ExecutorProxyPropertySetDone =>
      raise @errors.InternalError(
        message="proxy set frame stepped after completion",
      )
  }
}

///|
impl ExecutorActivationFrame for ExecutorProxyPropertySetFrame with fn step(
  self,
  interp,
) {
  self.step_frame(interp)
}

///|
impl ExecutorActivationFrame for ExecutorProxyPropertySetFrame with fn deliver_activation_completion(
  self,
  completion,
) {
  match completion {
    ExecutorActivationCompletionAbrupt(error) => raise error
    ExecutorActivationCompletionReference(_) =>
      raise @errors.InternalError(
        message="proxy set frame received an unexpected binding reference completion",
      )
    ExecutorActivationCompletionNormal(value) =>
      match self.phase {
        ExecutorProxyPropertySetAwaitTrapLookup =>
          self.phase = ExecutorProxyPropertySetHaveTrap(value)
        ExecutorProxyPropertySetAwaitTrapCall =>
          self.phase = ExecutorProxyPropertySetHaveTrapResult(value)
        ExecutorProxyPropertySetAwaitForward =>
          self.phase = ExecutorProxyPropertySetComplete(self.value)
        _ =>
          raise @errors.InternalError(
            message="proxy set frame received an unexpected child completion",
          )
      }
  }
}