// Executor-neutral function activation seam. Runtime owns observable function
// setup and completion normalization; executor packages supply only opaque code
// and private resumable frames. The neutral step surface returns neither a
// host-language continuation nor executor state. Until #631 migrates nested
// guest entry, individual executor steps may still cross the documented
// synchronous compatibility boundary; no stack-safety claim covers those
// operations.

///|
pub enum ExecutorActivationStep {
  ExecutorActivationContinue
  ExecutorActivationNormal(Value)
  ExecutorActivationReturn(Value)
  ExecutorActivationCall(ExecutorCallRequest)
  ExecutorActivationConstruct(ExecutorConstructRequest)
  ExecutorActivationPropertyGet(ExecutorPropertyGetRequest)
  ExecutorActivationPropertyKey(ExecutorPropertyKeyRequest)
  ExecutorActivationComputedPropertyGet(ExecutorComputedPropertyGetRequest)
  ExecutorActivationPropertySet(ExecutorPropertySetRequest)
  ExecutorActivationPropertyUpdate(ExecutorPropertyUpdateRequest)
  ExecutorActivationCoercingAddition(ExecutorCoercingAdditionRequest)
  ExecutorActivationCoercingRelational(ExecutorCoercingRelationalRequest)
  ExecutorActivationCoercingSubtraction(ExecutorCoercingSubtractionRequest)
  ExecutorActivationCoercingMultiplicative(
    ExecutorCoercingMultiplicativeRequest
  )
  ExecutorActivationNumericConversion(ExecutorNumericConversionRequest)
  ExecutorActivationPropertyDelete(ExecutorPropertyDeleteRequest)
  ExecutorActivationIterableSpread(ExecutorIterableSpreadRequest)
  ExecutorActivationCopyDataProperties(ExecutorCopyDataPropertiesRequest)
  ExecutorActivationBinding(ExecutorBindingRequest)
  ExecutorActivationBindingReference(ExecutorBindingReferenceRequest)
  ExecutorActivationBindingReferenceAccess(
    ExecutorBindingReferenceAccessRequest
  )
  ExecutorActivationBindingUpdate(ExecutorBindingUpdateRequest)
  ExecutorActivationReference(ResolvedBindingReference)
}

///|
// Only a finished frame reaches runtime result normalization. Keep this
// distinct from both a pending executor step and a normalized child completion:
// ordinary calls must still distinguish fallthrough from an explicit return.
priv enum ExecutorCompletedStep {
  ExecutorCompletedNormal(Value)
  ExecutorCompletedReturn(Value)
  ExecutorCompletedReference(ResolvedBindingReference)
}

///|
// Preserve the public coordinator result without exposing the private terminal
// representation to executor adapters.
fn ExecutorCompletedStep::to_activation_step(
  self : ExecutorCompletedStep,
) -> ExecutorActivationStep {
  match self {
    ExecutorCompletedNormal(value) => ExecutorActivationNormal(value)
    ExecutorCompletedReturn(value) => ExecutorActivationReturn(value)
    ExecutorCompletedReference(reference) =>
      ExecutorActivationReference(reference)
  }
}

///|
// A closed child completion. Runtime owns the completion boundary so executor
// frames can choose whether an abrupt child result is recoverable without
// translating or copying the original error.
pub enum ExecutorActivationCompletion {
  ExecutorActivationCompletionNormal(Value)
  ExecutorActivationCompletionAbrupt(Error)
  ExecutorActivationCompletionReference(ResolvedBindingReference)
}

///|
priv enum ExecutorActivationRequestOutcome {
  ExecutorActivationRequestChild
  ExecutorActivationRequestValue(Value)
}

///|
pub fn executor_activation_completion_normal(
  value : Value,
) -> ExecutorActivationCompletion {
  ExecutorActivationCompletionNormal(value)
}

///|
pub fn executor_activation_completion_abrupt(
  error : Error,
) -> ExecutorActivationCompletion {
  ExecutorActivationCompletionAbrupt(error)
}

///|
// A closed ordinary-call request. Runtime owns the request fields and the
// coordinator is the only code that may inspect them; executors only create a
// request and later consume its one-shot result through their frame.
pub struct ExecutorCallRequest {
  priv callee : Value
  priv this_value : Value
  priv args : Array[Value]
  priv loc : @token.Loc
}

///|
fn ExecutorCallRequest::ExecutorCallRequest(
  callee~ : Value,
  this_value~ : Value,
  args~ : Array[Value],
  loc~ : @token.Loc,
) -> ExecutorCallRequest {
  { callee, this_value, args: args.copy(), loc, }
}

///|
pub fn executor_activation_call(
  callee : Value,
  this_value : Value,
  args : Array[Value],
  loc : @token.Loc,
) -> ExecutorActivationStep {
  ExecutorActivationCall(ExecutorCallRequest(callee~, this_value~, args~, loc~))
}

///|
// A closed iterable-spread request. Runtime owns iterator acquisition, every
// protocol step, validation, and abrupt completion. The executor supplies only
// the already-evaluated iterable and source location; the eventual batch is
// delivered through the neutral activation completion seam.
pub struct ExecutorIterableSpreadRequest {
  priv iterable : Value
  priv loc : @token.Loc
}

///|
fn ExecutorIterableSpreadRequest::ExecutorIterableSpreadRequest(
  iterable~ : Value,
  loc~ : @token.Loc,
) -> ExecutorIterableSpreadRequest {
  { iterable, loc, }
}

///|
#warnings("-unused_constructor")
pub enum ExecutorIterableSpreadStart {
  ExecutorIterableSpreadCompleted(Array[Value])
  ExecutorIterableSpreadSuspended(ExecutorIterableSpreadRequest)
}

///|
// Acquisition always crosses the executor-neutral seam. Runtime decides
// whether a particular iterator lookup or protocol step completes locally;
// this keeps built-in Array/String handling in one canonical owner without a
// VM-side fast path.
pub fn begin_executor_iterable_spread(
  iterable : Value,
  loc : @token.Loc,
) -> ExecutorIterableSpreadStart {
  ExecutorIterableSpreadSuspended(
    ExecutorIterableSpreadRequest(iterable~, loc~),
  )
}

///|
pub fn executor_activation_iterable_spread_request(
  request : ExecutorIterableSpreadRequest,
) -> ExecutorActivationStep {
  ExecutorActivationIterableSpread(request)
}

///|
// A closed CopyDataProperties request. Runtime owns key snapshotting,
// descriptor/enumerability checks, source reads, and incremental target
// definitions. The compiler/VM supplies only the evaluated target/source and
// an immutable exclusion snapshot.
pub struct ExecutorCopyDataPropertiesRequest {
  priv target : Value
  priv source : Value
  priv excluded_keys : Array[Value]
  priv loc : @token.Loc
}

///|
fn ExecutorCopyDataPropertiesRequest::ExecutorCopyDataPropertiesRequest(
  target~ : Value,
  source~ : Value,
  excluded_keys~ : Array[Value],
  loc~ : @token.Loc,
) -> ExecutorCopyDataPropertiesRequest {
  { target, source, excluded_keys: excluded_keys.copy(), loc, }
}

///|
#warnings("-unused_constructor")
pub enum ExecutorCopyDataPropertiesStart {
  ExecutorCopyDataPropertiesCompleted
  ExecutorCopyDataPropertiesSuspended(ExecutorCopyDataPropertiesRequest)
}

///|
pub fn begin_executor_copy_data_properties(
  _interp : Interpreter,
  target : Value,
  source : Value,
  excluded_keys : Array[Value],
  loc : @token.Loc,
) -> ExecutorCopyDataPropertiesStart {
  match source {
    Null | Undefined => ExecutorCopyDataPropertiesCompleted
    _ =>
      ExecutorCopyDataPropertiesSuspended(
        ExecutorCopyDataPropertiesRequest(
          target~,
          source~,
          excluded_keys~,
          loc~,
        ),
      )
  }
}

///|
pub fn executor_activation_copy_data_properties_request(
  request : ExecutorCopyDataPropertiesRequest,
) -> ExecutorActivationStep {
  ExecutorActivationCopyDataProperties(request)
}

///|
priv enum ExecutorPropertyGetKey {
  ExecutorStringPropertyGetKey(String)
  ExecutorSymbolPropertyGetKey(SymbolData)
}

///|
// A closed property-get request. Runtime owns property lookup and accessor
// admission; executors only provide an already-evaluated target and a sealed
// string or symbol key.
pub struct ExecutorPropertyGetRequest {
  priv target : Value
  priv key : ExecutorPropertyGetKey
  priv receiver : Value
  priv loc : @token.Loc
  priv manage_proxy : Bool
  priv admission : ExecutorPropertyGetAdmission?
}

///|
// A closed property-key request. Runtime owns resumable ToPropertyKey;
// executors supply only the already-evaluated input.
pub struct ExecutorPropertyKeyRequest {
  priv raw_key : Value
  priv loc : @token.Loc
}

///|
fn ExecutorPropertyKeyRequest::ExecutorPropertyKeyRequest(
  raw_key~ : Value,
  loc~ : @token.Loc,
) -> ExecutorPropertyKeyRequest {
  { raw_key, loc, }
}

///|
priv enum ExecutorComputedPropertyGetKey {
  ExecutorRawComputedPropertyGetKey(Value)
  ExecutorSealedComputedPropertyGetKey(ExecutorPropertyGetKey)
}

///|
// A closed computed-property-get request. Runtime owns ToPropertyKey and the
// receiver-aware [[Get]]; executors supply only already-evaluated values.
pub struct ExecutorComputedPropertyGetRequest {
  priv target : Value
  priv key : ExecutorComputedPropertyGetKey
  priv loc : @token.Loc
}

///|
fn ExecutorComputedPropertyGetRequest::ExecutorComputedPropertyGetRequest(
  target~ : Value,
  key~ : ExecutorComputedPropertyGetKey,
  loc~ : @token.Loc,
) -> ExecutorComputedPropertyGetRequest {
  { target, key, loc, }
}

///|
pub enum ExecutorComputedCallPreparationStart {
  ExecutorComputedCallPreparationCompleted(Value)
  ExecutorComputedCallPreparationSuspended(ExecutorComputedPropertyGetRequest)
}

///|
pub enum ExecutorComputedPropertyGetStart {
  ExecutorComputedPropertyGetCompleted(Value)
  ExecutorComputedPropertyGetSuspended(ExecutorActivationStep)
}

///|
pub enum ExecutorPropertyKeyStart {
  ExecutorPropertyKeyCompleted(Value)
  ExecutorPropertyKeySuspended(ExecutorPropertyKeyRequest)
}

///|
fn executor_computed_call_array_fast_path(
  target : Value,
  raw_key : Value,
) -> Value? {
  match (target, raw_key) {
    (Array(data), Number(index)) =>
      if index >= 0.0 && index == index.floor() && index <= 2147483647.0 {
        match array_index_lookup_result(data, index.to_int()) {
          Present(callee) if is_callable(callee) => Some(callee)
          _ => None
        }
      } else {
        None
      }
    _ => None
  }
}

///|
fn executor_computed_property_get_array_fast_path(
  target : Value,
  raw_key : Value,
) -> Value? {
  match (target, raw_key) {
    (Array(data), Number(index)) =>
      if index >= 0.0 && index == index.floor() && index <= 2147483647.0 {
        match array_index_lookup_result(data, index.to_int()) {
          Present(value) => Some(value)
          Hole | OutOfRange | OwnAccessor(_) => None
        }
      } else {
        None
      }
    _ => None
  }
}

///|
fn executor_computed_property_get_request(
  target : Value,
  raw_key : Value,
  loc : @token.Loc,
) -> ExecutorComputedPropertyGetRequest raise Error {
  if is_js_object(raw_key) {
    ExecutorComputedPropertyGetRequest(
      target~,
      key=ExecutorRawComputedPropertyGetKey(raw_key),
      loc~,
    )
  } else {
    let sealed_key = executor_property_get_key_from_value(
      executor_to_property_key_primitive(raw_key),
    )
    ExecutorComputedPropertyGetRequest(
      target~,
      key=ExecutorSealedComputedPropertyGetKey(sealed_key),
      loc~,
    )
  }
}

///|
pub fn begin_executor_property_key(
  raw_key : Value,
  loc : @token.Loc,
) -> ExecutorPropertyKeyStart raise Error {
  if is_js_object(raw_key) {
    ExecutorPropertyKeySuspended(ExecutorPropertyKeyRequest(raw_key~, loc~))
  } else {
    ExecutorPropertyKeyCompleted(executor_to_property_key_primitive(raw_key))
  }
}

///|
pub fn begin_executor_computed_property_get(
  target : Value,
  raw_key : Value,
  loc : @token.Loc,
) -> ExecutorComputedPropertyGetStart raise Error {
  match target {
    Null =>
      match raw_key {
        String_(property_name) =>
          raise @errors.TypeError(
            message="Cannot read properties of null (reading '\{property_name}')",
          )
        _ => raise @errors.TypeError(message="Cannot read properties of null")
      }
    Undefined =>
      match raw_key {
        String_(property_name) =>
          raise @errors.TypeError(
            message="Cannot read properties of undefined (reading '\{property_name}')",
          )
        _ =>
          raise @errors.TypeError(message="Cannot read properties of undefined")
      }
    _ => ()
  }
  match executor_computed_property_get_array_fast_path(target, raw_key) {
    Some(value) => ExecutorComputedPropertyGetCompleted(value)
    None =>
      ExecutorComputedPropertyGetSuspended(
        ExecutorActivationComputedPropertyGet(
          executor_computed_property_get_request(target, raw_key, loc),
        ),
      )
  }
}

///|
pub fn begin_executor_computed_call_preparation(
  target : Value,
  raw_key : Value,
  loc : @token.Loc,
) -> ExecutorComputedCallPreparationStart raise Error {
  match target {
    Null | Undefined =>
      raise @errors.TypeError(
        message="Cannot convert undefined or null to object",
      )
    _ =>
      match executor_computed_call_array_fast_path(target, raw_key) {
        Some(callee) => ExecutorComputedCallPreparationCompleted(callee)
        None =>
          ExecutorComputedCallPreparationSuspended(
            executor_computed_property_get_request(target, raw_key, loc),
          )
      }
  }
}

///|
pub fn executor_activation_property_key_request(
  request : ExecutorPropertyKeyRequest,
) -> ExecutorActivationStep {
  ExecutorActivationPropertyKey(request)
}

///|
pub fn executor_activation_computed_property_get_request(
  request : ExecutorComputedPropertyGetRequest,
) -> ExecutorActivationStep {
  ExecutorActivationComputedPropertyGet(request)
}

///|
fn executor_property_get_key_from_value(
  key : Value,
) -> ExecutorPropertyGetKey raise Error {
  match key {
    String_(property_name) => ExecutorStringPropertyGetKey(property_name)
    Symbol(symbol) => ExecutorSymbolPropertyGetKey(symbol)
    _ =>
      raise @errors.InternalError(
        message="computed property key operation returned a non-key value",
      )
  }
}

///|
priv enum ExecutorComputedPropertyGetPhase {
  ExecutorComputedPropertyGetNeedKey(Value)
  ExecutorComputedPropertyGetAwaitKey(ExecutorToPropertyKeyOperation)
  ExecutorComputedPropertyGetNeedPropertyGet(ExecutorPropertyGetKey)
  ExecutorComputedPropertyGetAwaitPropertyGet
  ExecutorComputedPropertyGetComplete(Value)
}

///|
priv struct ExecutorComputedPropertyGetFrame {
  request : ExecutorComputedPropertyGetRequest
  mut phase : ExecutorComputedPropertyGetPhase
  mut lookup_target : Value?
}

///|
fn ExecutorComputedPropertyGetFrame::ExecutorComputedPropertyGetFrame(
  request : ExecutorComputedPropertyGetRequest,
) -> ExecutorComputedPropertyGetFrame {
  let phase = match request.key {
    ExecutorRawComputedPropertyGetKey(raw_key) =>
      ExecutorComputedPropertyGetNeedKey(raw_key)
    ExecutorSealedComputedPropertyGetKey(key) =>
      ExecutorComputedPropertyGetNeedPropertyGet(key)
  }
  { request, phase, lookup_target: None, }
}

///|
fn ExecutorComputedPropertyGetFrame::ensure_lookup_target(
  self : ExecutorComputedPropertyGetFrame,
  interp : Interpreter,
) -> Value {
  match self.lookup_target {
    Some(target) => target
    None => {
      let target = box_primitive_call_this(
        self.request.target,
        interp.realm_state,
      )
      self.lookup_target = Some(target)
      target
    }
  }
}

///|
fn ExecutorComputedPropertyGetFrame::complete_key_or_begin_get(
  self : ExecutorComputedPropertyGetFrame,
  key : Value,
  interp : Interpreter,
) -> ExecutorActivationStep raise Error {
  self.begin_property_get(executor_property_get_key_from_value(key), interp)
}

///|
fn ExecutorComputedPropertyGetFrame::begin_property_get(
  self : ExecutorComputedPropertyGetFrame,
  key : ExecutorPropertyGetKey,
  interp : Interpreter,
) -> ExecutorActivationStep {
  self.phase = ExecutorComputedPropertyGetAwaitPropertyGet
  let lookup_target = self.ensure_lookup_target(interp)
  executor_activation_property_get_with_receiver(
    lookup_target,
    key,
    self.request.target,
    self.request.loc,
    true,
  )
}

///|
fn ExecutorComputedPropertyGetFrame::step_frame(
  self : ExecutorComputedPropertyGetFrame,
  interp : Interpreter,
) -> ExecutorActivationStep raise Error {
  match self.phase {
    ExecutorComputedPropertyGetNeedKey(raw_key) => {
      let operation = ExecutorToPropertyKeyOperation(raw_key, self.request.loc)
      match operation.step(interp) {
        ExecutorActivationNormal(key) =>
          self.complete_key_or_begin_get(key, interp)
        step => {
          self.phase = ExecutorComputedPropertyGetAwaitKey(operation)
          step
        }
      }
    }
    ExecutorComputedPropertyGetAwaitKey(operation) =>
      match operation.step(interp) {
        ExecutorActivationNormal(key) =>
          self.complete_key_or_begin_get(key, interp)
        step => {
          self.phase = ExecutorComputedPropertyGetAwaitKey(operation)
          step
        }
      }
    ExecutorComputedPropertyGetNeedPropertyGet(key) =>
      self.complete_key_or_begin_get(
        executor_property_get_key_value(key),
        interp,
      )
    ExecutorComputedPropertyGetAwaitPropertyGet =>
      raise @errors.InternalError(
        message="computed property get stepped while awaiting property get",
      )
    ExecutorComputedPropertyGetComplete(value) =>
      ExecutorActivationNormal(value)
  }
}

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

///|
impl ExecutorActivationFrame for ExecutorComputedPropertyGetFrame with fn deliver_activation_completion(
  self,
  completion,
) {
  match completion {
    ExecutorActivationCompletionAbrupt(error) => raise error
    ExecutorActivationCompletionReference(_) =>
      raise @errors.InternalError(
        message="computed property get received a binding reference completion",
      )
    ExecutorActivationCompletionNormal(value) =>
      match self.phase {
        ExecutorComputedPropertyGetAwaitKey(operation) =>
          operation.deliver_activation_completion(
            ExecutorActivationCompletionNormal(value),
          )
        ExecutorComputedPropertyGetAwaitPropertyGet =>
          self.phase = ExecutorComputedPropertyGetComplete(value)
        ExecutorComputedPropertyGetNeedKey(_)
        | ExecutorComputedPropertyGetNeedPropertyGet(_)
        | ExecutorComputedPropertyGetComplete(_) =>
          raise @errors.InternalError(
            message="computed property get received an unexpected child completion",
          )
      }
  }
}

///|
priv struct ExecutorPropertyKeyFrame {
  operation : ExecutorToPropertyKeyOperation
}

///|
fn ExecutorPropertyKeyFrame::ExecutorPropertyKeyFrame(
  request : ExecutorPropertyKeyRequest,
) -> ExecutorPropertyKeyFrame {
  { operation: ExecutorToPropertyKeyOperation(request.raw_key, request.loc), }
}

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

///|
impl ExecutorActivationFrame for ExecutorPropertyKeyFrame with fn deliver_activation_completion(
  self,
  completion,
) {
  self.operation.deliver_activation_completion(completion)
}

///|
fn ExecutorPropertyGetRequest::ExecutorPropertyGetRequest(
  target~ : Value,
  key~ : ExecutorPropertyGetKey,
  receiver~ : Value,
  loc~ : @token.Loc,
  manage_proxy~ : Bool,
  admission? : ExecutorPropertyGetAdmission? = None,
) -> ExecutorPropertyGetRequest {
  { target, key, receiver, loc, manage_proxy, admission, }
}

///|
pub fn executor_activation_property_get(
  target : Value,
  property_name : String,
  loc : @token.Loc,
) -> ExecutorActivationStep {
  ExecutorActivationPropertyGet(
    ExecutorPropertyGetRequest(
      target~,
      key=ExecutorStringPropertyGetKey(property_name),
      receiver=target,
      loc~,
      manage_proxy=false,
    ),
  )
}

///|
fn executor_activation_symbol_property_get(
  target : Value,
  symbol : SymbolData,
  loc : @token.Loc,
) -> ExecutorActivationStep {
  ExecutorActivationPropertyGet(
    ExecutorPropertyGetRequest(
      target~,
      key=ExecutorSymbolPropertyGetKey(symbol),
      receiver=target,
      loc~,
      manage_proxy=true,
    ),
  )
}

///|
fn executor_activation_property_get_with_receiver(
  target : Value,
  key : ExecutorPropertyGetKey,
  receiver : Value,
  loc : @token.Loc,
  manage_proxy : Bool,
) -> ExecutorActivationStep {
  ExecutorActivationPropertyGet(
    ExecutorPropertyGetRequest(target~, key~, receiver~, loc~, manage_proxy~),
  )
}

///|
fn executor_activation_managed_property_get(
  target : Value,
  property_name : String,
  loc : @token.Loc,
) -> ExecutorActivationStep {
  ExecutorActivationPropertyGet(
    ExecutorPropertyGetRequest(
      target~,
      key=ExecutorStringPropertyGetKey(property_name),
      receiver=target,
      loc~,
      manage_proxy=true,
    ),
  )
}

///|
fn executor_property_get_key_value(key : ExecutorPropertyGetKey) -> Value {
  match key {
    ExecutorStringPropertyGetKey(property_name) => String_(property_name)
    ExecutorSymbolPropertyGetKey(symbol) => Symbol(symbol)
  }
}

///|
// A closed static property-set request. Runtime owns property mutation,
// setter admission, fallback, and assignment-result normalization; executors
// only provide the already-evaluated target, property name, and RHS.
priv enum ExecutorPropertySetKey {
  ExecutorRawPropertySetKey(Value)
  ExecutorSealedPropertySetKey(ExecutorPropertyGetKey)
}

///|
pub struct ExecutorPropertySetRequest {
  priv target : Value
  priv key : ExecutorPropertySetKey
  priv value : Value
  priv receiver : Value
  priv loc : @token.Loc
  priv strict : Bool
  priv manage_proxy : Bool
}

///|
fn ExecutorPropertySetRequest::ExecutorPropertySetRequest(
  target~ : Value,
  key~ : ExecutorPropertySetKey,
  value~ : Value,
  receiver~ : Value,
  loc~ : @token.Loc,
  strict~ : Bool,
  manage_proxy? : Bool = false,
) -> ExecutorPropertySetRequest {
  { target, key, value, receiver, loc, strict, manage_proxy, }
}

///|
pub fn executor_activation_property_set(
  target : Value,
  property_name : String,
  value : Value,
  loc : @token.Loc,
  strict : Bool,
) -> ExecutorActivationStep {
  ExecutorActivationPropertySet(
    ExecutorPropertySetRequest(
      target~,
      key=ExecutorSealedPropertySetKey(
        ExecutorStringPropertyGetKey(property_name),
      ),
      value~,
      receiver=target,
      loc~,
      strict~,
    ),
  )
}

///|
pub enum ExecutorComputedPropertySetStart {
  ExecutorComputedPropertySetCompleted(Value)
  ExecutorComputedPropertySetSuspended(ExecutorActivationStep)
}

///|
priv enum ExecutorComputedPropertySetPhase {
  ExecutorComputedPropertySetNeedKey(Value)
  ExecutorComputedPropertySetAwaitKey(ExecutorToPropertyKeyOperation)
  ExecutorComputedPropertySetAwaitSet
  ExecutorComputedPropertySetComplete
}

///|
priv struct ExecutorComputedPropertySetFrame {
  request : ExecutorPropertySetRequest
  mut phase : ExecutorComputedPropertySetPhase
}

///|
fn ExecutorComputedPropertySetFrame::ExecutorComputedPropertySetFrame(
  request : ExecutorPropertySetRequest,
) -> ExecutorComputedPropertySetFrame {
  let phase = match request.key {
    ExecutorRawPropertySetKey(raw_key) =>
      ExecutorComputedPropertySetNeedKey(raw_key)
    ExecutorSealedPropertySetKey(_) => ExecutorComputedPropertySetComplete
  }
  { request, phase, }
}

///|
fn executor_dense_array_own_data_set(
  target : Value,
  property_name : String,
  value : Value,
) -> Bool {
  guard target is Array(data) else { return false }
  let index64 = match array_index64_from_string(property_name) {
    Some(index) => index
    None => return false
  }
  guard index64 < data.elements.length().to_int64() else { return false }
  let index = index64.to_int()
  guard array_index_lookup_result(data, index) is Present(_) else {
    return false
  }
  match data.bag.descriptors.get(property_name) {
    Some(descriptor) if descriptor.is_accessor || !descriptor.writable => false
    _ => {
      data.elements[index] = value
      true
    }
  }
}

///|
fn begin_executor_sealed_computed_property_set(
  target : Value,
  property_key : ExecutorPropertyGetKey,
  value : Value,
  receiver : Value,
  loc : @token.Loc,
  strict : Bool,
) -> ExecutorComputedPropertySetStart {
  match property_key {
    ExecutorStringPropertyGetKey(property_name) =>
      if executor_dense_array_own_data_set(target, property_name, value) {
        ExecutorComputedPropertySetCompleted(value)
      } else {
        ExecutorComputedPropertySetSuspended(
          executor_activation_managed_property_set_with_receiver(
            target, property_name, value, receiver, loc, strict,
          ),
        )
      }
    ExecutorSymbolPropertyGetKey(symbol) =>
      ExecutorComputedPropertySetSuspended(
        executor_activation_managed_property_set_key_with_receiver(
          target,
          ExecutorSymbolPropertyGetKey(symbol),
          value,
          receiver,
          loc,
          strict,
        ),
      )
  }
}

///|
pub fn begin_executor_computed_property_set(
  target : Value,
  property_key : Value,
  value : Value,
  loc : @token.Loc,
  strict : Bool,
) -> ExecutorComputedPropertySetStart raise Error {
  match target {
    Null =>
      match property_key {
        String_(property_name) =>
          raise @errors.TypeError(
            message="Cannot set properties of null (setting '\{property_name}')",
          )
        _ => raise @errors.TypeError(message="Cannot set properties of null")
      }
    Undefined =>
      match property_key {
        String_(property_name) =>
          raise @errors.TypeError(
            message="Cannot set properties of undefined (setting '\{property_name}')",
          )
        _ =>
          raise @errors.TypeError(message="Cannot set properties of undefined")
      }
    _ => ()
  }
  if is_js_object(property_key) {
    return ExecutorComputedPropertySetSuspended(
      ExecutorActivationPropertySet(
        ExecutorPropertySetRequest(
          target~,
          key=ExecutorRawPropertySetKey(property_key),
          value~,
          receiver=target,
          loc~,
          strict~,
        ),
      ),
    )
  }
  begin_executor_sealed_computed_property_set(
    target,
    executor_property_get_key_from_value(
      executor_to_property_key_primitive(property_key),
    ),
    value,
    target,
    loc,
    strict,
  )
}

///|
fn ExecutorComputedPropertySetFrame::begin_set(
  self : ExecutorComputedPropertySetFrame,
  key : Value,
) -> ExecutorActivationStep raise Error {
  match
    begin_executor_sealed_computed_property_set(
      self.request.target,
      executor_property_get_key_from_value(key),
      self.request.value,
      self.request.receiver,
      self.request.loc,
      self.request.strict,
    ) {
    ExecutorComputedPropertySetCompleted(value) => {
      self.phase = ExecutorComputedPropertySetComplete
      ExecutorActivationNormal(value)
    }
    ExecutorComputedPropertySetSuspended(step) => {
      self.phase = ExecutorComputedPropertySetAwaitSet
      step
    }
  }
}

///|
fn ExecutorComputedPropertySetFrame::step_frame(
  self : ExecutorComputedPropertySetFrame,
  interp : Interpreter,
) -> ExecutorActivationStep raise Error {
  match self.phase {
    ExecutorComputedPropertySetNeedKey(raw_key) => {
      let operation = ExecutorToPropertyKeyOperation(raw_key, self.request.loc)
      match operation.step(interp) {
        ExecutorActivationNormal(key) => self.begin_set(key)
        step => {
          self.phase = ExecutorComputedPropertySetAwaitKey(operation)
          step
        }
      }
    }
    ExecutorComputedPropertySetAwaitKey(operation) =>
      match operation.step(interp) {
        ExecutorActivationNormal(key) => self.begin_set(key)
        step => {
          self.phase = ExecutorComputedPropertySetAwaitKey(operation)
          step
        }
      }
    ExecutorComputedPropertySetAwaitSet =>
      raise @errors.InternalError(
        message="computed property set stepped while awaiting property mutation",
      )
    ExecutorComputedPropertySetComplete =>
      ExecutorActivationNormal(self.request.value)
  }
}

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

///|
impl ExecutorActivationFrame for ExecutorComputedPropertySetFrame with fn deliver_activation_completion(
  self,
  completion,
) {
  match completion {
    ExecutorActivationCompletionAbrupt(error) => raise error
    ExecutorActivationCompletionReference(_) =>
      raise @errors.InternalError(
        message="computed property set received a binding reference completion",
      )
    ExecutorActivationCompletionNormal(value) =>
      match self.phase {
        ExecutorComputedPropertySetAwaitKey(operation) =>
          operation.deliver_activation_completion(
            ExecutorActivationCompletionNormal(value),
          )
        ExecutorComputedPropertySetAwaitSet =>
          self.phase = ExecutorComputedPropertySetComplete
        ExecutorComputedPropertySetNeedKey(_)
        | ExecutorComputedPropertySetComplete =>
          raise @errors.InternalError(
            message="computed property set received an unexpected child completion",
          )
      }
  }
}

///|
fn executor_activation_managed_property_set(
  target : Value,
  property_name : String,
  value : Value,
  loc : @token.Loc,
  strict : Bool,
) -> ExecutorActivationStep {
  executor_activation_managed_property_set_with_receiver(
    target, property_name, value, target, loc, strict,
  )
}

///|
fn executor_activation_managed_property_set_with_receiver(
  target : Value,
  property_name : String,
  value : Value,
  receiver : Value,
  loc : @token.Loc,
  strict : Bool,
) -> ExecutorActivationStep {
  executor_activation_managed_property_set_key_with_receiver(
    target,
    ExecutorStringPropertyGetKey(property_name),
    value,
    receiver,
    loc,
    strict,
  )
}

///|
fn executor_activation_managed_property_set_key_with_receiver(
  target : Value,
  key : ExecutorPropertyGetKey,
  value : Value,
  receiver : Value,
  loc : @token.Loc,
  strict : Bool,
) -> ExecutorActivationStep {
  ExecutorActivationPropertySet(
    ExecutorPropertySetRequest(
      target~,
      key=ExecutorSealedPropertySetKey(key),
      value~,
      receiver~,
      loc~,
      strict~,
      manage_proxy=true,
    ),
  )
}

///|
// A closed addition request. Runtime owns ToPrimitive ordering, conversion
// hooks, final string-or-numeric addition, and abrupt completion; executors
// supply only the already-evaluated operands and source location.
pub struct ExecutorCoercingAdditionRequest {
  priv left : Value
  priv right : Value
  priv loc : @token.Loc
}

///|
fn ExecutorCoercingAdditionRequest::ExecutorCoercingAdditionRequest(
  left~ : Value,
  right~ : Value,
  loc~ : @token.Loc,
) -> ExecutorCoercingAdditionRequest {
  { left, right, loc, }
}

///|
pub fn executor_activation_coercing_addition(
  left : Value,
  right : Value,
  loc : @token.Loc,
) -> ExecutorActivationStep {
  ExecutorActivationCoercingAddition(
    ExecutorCoercingAdditionRequest(left~, right~, loc~),
  )
}

///|
pub fn executor_activation_coercing_addition_request(
  request : ExecutorCoercingAdditionRequest,
) -> ExecutorActivationStep {
  ExecutorActivationCoercingAddition(request)
}

///|
// A closed subtraction request. Runtime owns ToPrimitive(number) ordering,
// Number conversion, and abrupt completion; executors supply only the already-
// evaluated operands and source location.
pub struct ExecutorCoercingSubtractionRequest {
  priv left : Value
  priv right : Value
  priv loc : @token.Loc
}

///|
fn ExecutorCoercingSubtractionRequest::ExecutorCoercingSubtractionRequest(
  left~ : Value,
  right~ : Value,
  loc~ : @token.Loc,
) -> ExecutorCoercingSubtractionRequest {
  { left, right, loc, }
}

///|
pub fn executor_activation_coercing_subtraction(
  left : Value,
  right : Value,
  loc : @token.Loc,
) -> ExecutorActivationStep {
  ExecutorActivationCoercingSubtraction(
    ExecutorCoercingSubtractionRequest(left~, right~, loc~),
  )
}

///|
pub fn executor_activation_coercing_subtraction_request(
  request : ExecutorCoercingSubtractionRequest,
) -> ExecutorActivationStep {
  ExecutorActivationCoercingSubtraction(request)
}

///|
pub fn executor_activation_coercing_multiplicative_request(
  request : ExecutorCoercingMultiplicativeRequest,
) -> ExecutorActivationStep {
  ExecutorActivationCoercingMultiplicative(request)
}

///|
pub fn executor_activation_coercing_multiplicative(
  left : Value,
  right : Value,
  operator : ExecutorMultiplicativeOperator,
  loc : @token.Loc,
) -> ExecutorActivationStep {
  ExecutorActivationCoercingMultiplicative(
    ExecutorCoercingMultiplicativeRequest(left~, right~, operator~, loc~),
  )
}

///|
pub fn executor_activation_coercing_less_than_or_equal(
  left : Value,
  right : Value,
  loc : @token.Loc,
) -> ExecutorActivationStep {
  ExecutorActivationCoercingRelational(
    ExecutorCoercingRelationalRequest(
      left~,
      right~,
      operator=ExecutorRelationalLessThanOrEqual,
      loc~,
    ),
  )
}

///|
pub fn executor_activation_coercing_less_than_or_equal_request(
  request : ExecutorCoercingLessThanOrEqualRequest,
) -> ExecutorActivationStep {
  ExecutorActivationCoercingRelational(
    executor_coercing_relational_request_from_less_than_or_equal(request),
  )
}

///|
pub fn executor_activation_coercing_relational(
  left : Value,
  right : Value,
  loc : @token.Loc,
  operator : ExecutorRelationalOperator,
) -> ExecutorActivationStep {
  ExecutorActivationCoercingRelational(
    ExecutorCoercingRelationalRequest(left~, right~, operator~, loc~),
  )
}

///|
pub fn executor_activation_coercing_relational_request(
  request : ExecutorCoercingRelationalRequest,
) -> ExecutorActivationStep {
  ExecutorActivationCoercingRelational(request)
}

///|
// A closed property-delete request. Runtime owns ToPropertyKey, Proxy trap
// lookup/call, forwarding, invariants, and strict-result normalization. The
// compiler supplies only an already-evaluated target and either a static key
// or the raw computed key value.
pub struct ExecutorPropertyDeleteRequest {
  priv target : Value
  priv key : ExecutorPropertyDeleteKey
  priv strict : Bool
  priv loc : @token.Loc
}

///|
priv enum ExecutorPropertyDeleteKey {
  ExecutorStaticPropertyDeleteKey(String)
  ExecutorComputedPropertyDeleteKey(Value)
}

///|
fn ExecutorPropertyDeleteRequest::ExecutorPropertyDeleteRequest(
  target~ : Value,
  key~ : ExecutorPropertyDeleteKey,
  strict~ : Bool,
  loc~ : @token.Loc,
) -> ExecutorPropertyDeleteRequest {
  { target, key, strict, loc, }
}

///|
pub enum ExecutorPropertyDeleteStart {
  ExecutorPropertyDeleteCompleted(Value)
  ExecutorPropertyDeleteSuspended(ExecutorPropertyDeleteRequest)
}

///|
fn begin_executor_property_delete(
  interp : Interpreter,
  target : Value,
  key : ExecutorPropertyDeleteKey,
  strict : Bool,
  loc : @token.Loc,
) -> ExecutorPropertyDeleteStart raise Error {
  let request = ExecutorPropertyDeleteRequest(target~, key~, strict~, loc~)
  match key {
    ExecutorStaticPropertyDeleteKey(_) if target is Proxy(_) =>
      ExecutorPropertyDeleteSuspended(request)
    ExecutorStaticPropertyDeleteKey(property_name) =>
      ExecutorPropertyDeleteCompleted(
        Bool(
          interp.delete_property_key(target, String_(property_name), strict~),
        ),
      )
    ExecutorComputedPropertyDeleteKey(raw_key) if target is Proxy(_) ||
      is_js_object(raw_key) => ExecutorPropertyDeleteSuspended(request)
    ExecutorComputedPropertyDeleteKey(raw_key) =>
      ExecutorPropertyDeleteCompleted(
        Bool(interp.delete_property_key(target, raw_key, strict~)),
      )
  }
}

///|
pub fn begin_executor_property_delete_static(
  interp : Interpreter,
  target : Value,
  property_name : String,
  strict : Bool,
  loc : @token.Loc,
) -> ExecutorPropertyDeleteStart raise Error {
  begin_executor_property_delete(
    interp,
    target,
    ExecutorStaticPropertyDeleteKey(property_name),
    strict,
    loc,
  )
}

///|
pub fn begin_executor_property_delete_computed(
  interp : Interpreter,
  target : Value,
  raw_key : Value,
  strict : Bool,
  loc : @token.Loc,
) -> ExecutorPropertyDeleteStart raise Error {
  begin_executor_property_delete(
    interp,
    target,
    ExecutorComputedPropertyDeleteKey(raw_key),
    strict,
    loc,
  )
}

///|
pub fn executor_activation_property_delete_request(
  request : ExecutorPropertyDeleteRequest,
) -> ExecutorActivationStep {
  ExecutorActivationPropertyDelete(request)
}

///|
// A closed identifier-update request. Runtime retains the resolved binding
// reference across read, Number-hint conversion, and write; the compiler and
// VM provide only the source update operator and result destination.
pub struct ExecutorBindingUpdateRequest {
  priv ctx : ExecContext
  priv env : Environment
  priv name : String
  priv operator : @ast.UpdateOp
  priv prefix : Bool
  priv loc : @token.Loc
  priv mut phase : ExecutorBindingUpdatePhase
}

///|
priv enum ExecutorBindingUpdatePhase {
  ExecutorBindingUpdateNeedReference(ExecutorBindingReferenceRequest)
  ExecutorBindingUpdateAwaitReference
  ExecutorBindingUpdateNeedGet(ResolvedBindingReference)
  ExecutorBindingUpdateAwaitGet(
    ResolvedBindingReference,
    ExecutorBindingReferenceGetOperation
  )
  ExecutorBindingUpdateHaveCurrent(ResolvedBindingReference, Value)
  ExecutorBindingUpdateAwaitToPrimitive(
    ResolvedBindingReference,
    Value,
    ExecutorToPrimitiveOperation
  )
  ExecutorBindingUpdateAwaitPut(ExecutorBindingReferencePutOperation, Value)
  ExecutorBindingUpdateComplete(Value)
}

///|
fn ExecutorBindingUpdateRequest::ExecutorBindingUpdateRequest(
  ctx~ : ExecContext,
  env~ : Environment,
  name~ : String,
  operator~ : @ast.UpdateOp,
  prefix~ : Bool,
  loc~ : @token.Loc,
  phase~ : ExecutorBindingUpdatePhase,
) -> ExecutorBindingUpdateRequest {
  { ctx, env, name, operator, prefix, loc, phase, }
}

///|
pub enum ExecutorBindingUpdateStart {
  ExecutorBindingUpdateCompleted(Value)
  ExecutorBindingUpdateSuspended(ExecutorBindingUpdateRequest)
}

///|
pub fn begin_executor_binding_update(
  interp : Interpreter,
  ctx : ExecContext,
  env : Environment,
  name : String,
  op : @ast.UpdateOp,
  prefix : Bool,
  loc : @token.Loc,
) -> ExecutorBindingUpdateStart raise Error {
  let reference_request = ExecutorBindingReferenceRequest(
    ctx~,
    env~,
    name~,
    loc~,
  )
  let request = ExecutorBindingUpdateRequest(
    ctx~,
    env~,
    name~,
    operator=op,
    prefix~,
    loc~,
    phase=ExecutorBindingUpdateNeedReference(reference_request),
  )
  match begin_executor_binding_reference(interp, ctx, env, name, loc) {
    ExecutorBindingReferenceSuspended(reference_request) => {
      request.phase = ExecutorBindingUpdateNeedReference(reference_request)
      ExecutorBindingUpdateSuspended(request)
    }
    ExecutorBindingReferenceCompleted(reference) =>
      match begin_executor_binding_reference_get(interp, reference) {
        ExecutorBindingReferenceGetSuspended(_) => {
          request.phase = ExecutorBindingUpdateNeedGet(reference)
          ExecutorBindingUpdateSuspended(request)
        }
        ExecutorBindingReferenceGetCompleted(current) if is_js_object(current) => {
          request.phase = ExecutorBindingUpdateHaveCurrent(reference, current)
          ExecutorBindingUpdateSuspended(request)
        }
        ExecutorBindingReferenceGetCompleted(current) =>
          match reference.kind {
            ResolvedBindingWithObject(_, _) => {
              request.phase = ExecutorBindingUpdateHaveCurrent(
                reference, current,
              )
              ExecutorBindingUpdateSuspended(request)
            }
            _ => {
              let old_number = to_number(current, interp=Some(interp))
              let plan = plan_numeric_update(
                old_number,
                request.operator,
                request.prefix,
              )
              let next_value = plan.assigned_value()
              let result = plan.expression_value()
              match
                begin_executor_binding_reference_put(
                  interp, reference, next_value,
                ) {
                ExecutorBindingReferencePutCompleted(value) => {
                  ignore(value)
                  ExecutorBindingUpdateCompleted(result)
                }
                ExecutorBindingReferencePutSuspended(_) => {
                  request.phase = ExecutorBindingUpdateHaveCurrent(
                    reference, current,
                  )
                  ExecutorBindingUpdateSuspended(request)
                }
              }
            }
          }
      }
  }
}

///|
// Complete a binding update for synchronous runtime owners. Dynamic binding
// resolution and object conversion use the same coordinator as bytecode, so
// a suspended request keeps its one resolved reference through every child.
fn Interpreter::run_binding_update_to_completion(
  self : Interpreter,
  ctx : ExecContext,
  env : Environment,
  name : String,
  op : @ast.UpdateOp,
  prefix : Bool,
  loc : @token.Loc,
) -> Value raise Error {
  match begin_executor_binding_update(self, ctx, env, name, op, prefix, loc) {
    ExecutorBindingUpdateCompleted(value) => value
    ExecutorBindingUpdateSuspended(request) => {
      let frame = ExecutorBindingUpdateFrame(request)
      match
        self.run_executor_activation_coordinator(
          frame as &ExecutorActivationFrame,
        ) {
        ExecutorActivationNormal(value) | ExecutorActivationReturn(value) =>
          value
        _ =>
          raise @errors.InternalError(
            message="binding update coordinator returned a pending activation",
          )
      }
    }
  }
}

///|
pub fn executor_activation_binding_update_request(
  request : ExecutorBindingUpdateRequest,
) -> ExecutorActivationStep {
  ExecutorActivationBindingUpdate(request)
}

///|
priv struct ExecutorBindingUpdateFrame {
  request : ExecutorBindingUpdateRequest
}

///|
fn ExecutorBindingUpdateFrame::ExecutorBindingUpdateFrame(
  request : ExecutorBindingUpdateRequest,
) -> ExecutorBindingUpdateFrame {
  { request, }
}

///|
fn ExecutorBindingUpdateFrame::begin_put(
  self : ExecutorBindingUpdateFrame,
  interp : Interpreter,
  reference : ResolvedBindingReference,
  old_number : Double,
) -> ExecutorActivationStep raise Error {
  let plan = plan_numeric_update(
    old_number,
    self.request.operator,
    self.request.prefix,
  )
  let next_value = plan.assigned_value()
  let result = plan.expression_value()
  match begin_executor_binding_reference_put(interp, reference, next_value) {
    ExecutorBindingReferencePutCompleted(value) => {
      ignore(value)
      self.request.phase = ExecutorBindingUpdateComplete(result)
      ExecutorActivationNormal(result)
    }
    ExecutorBindingReferencePutSuspended(operation) => {
      self.request.phase = ExecutorBindingUpdateAwaitPut(operation, result)
      operation.step(interp)
    }
  }
}

///|
fn ExecutorBindingUpdateFrame::begin_to_primitive(
  self : ExecutorBindingUpdateFrame,
  interp : Interpreter,
  reference : ResolvedBindingReference,
  current : Value,
) -> ExecutorActivationStep raise Error {
  let operation = ExecutorToPrimitiveOperation(
    current,
    ExecutorToPrimitiveNumber,
    self.request.loc,
  )
  match operation.step(interp) {
    ExecutorActivationNormal(value) =>
      self.begin_put(interp, reference, to_number(value, interp=Some(interp)))
    step => {
      self.request.phase = ExecutorBindingUpdateAwaitToPrimitive(
        reference, current, operation,
      )
      step
    }
  }
}

///|
fn ExecutorBindingUpdateFrame::advance_get(
  self : ExecutorBindingUpdateFrame,
  interp : Interpreter,
  reference : ResolvedBindingReference,
  operation : ExecutorBindingReferenceGetOperation,
) -> ExecutorActivationStep raise Error {
  match operation.step(interp) {
    ExecutorActivationNormal(value) => {
      self.request.phase = ExecutorBindingUpdateHaveCurrent(reference, value)
      self.step_frame(interp)
    }
    step => {
      self.request.phase = ExecutorBindingUpdateAwaitGet(reference, operation)
      step
    }
  }
}

///|
fn ExecutorBindingUpdateFrame::step_frame(
  self : ExecutorBindingUpdateFrame,
  interp : Interpreter,
) -> ExecutorActivationStep raise Error {
  match self.request.phase {
    ExecutorBindingUpdateNeedReference(reference_request) => {
      self.request.phase = ExecutorBindingUpdateAwaitReference
      ExecutorActivationBindingReference(reference_request)
    }
    ExecutorBindingUpdateNeedGet(reference) =>
      match begin_executor_binding_reference_get(interp, reference) {
        ExecutorBindingReferenceGetCompleted(value) => {
          self.request.phase = ExecutorBindingUpdateHaveCurrent(
            reference, value,
          )
          self.step_frame(interp)
        }
        ExecutorBindingReferenceGetSuspended(operation) =>
          self.advance_get(interp, reference, operation)
      }
    ExecutorBindingUpdateHaveCurrent(reference, current) =>
      if is_js_object(current) {
        self.begin_to_primitive(interp, reference, current)
      } else {
        self.begin_put(
          interp,
          reference,
          to_number(current, interp=Some(interp)),
        )
      }
    ExecutorBindingUpdateAwaitToPrimitive(reference, current, operation) =>
      match operation.step(interp) {
        ExecutorActivationNormal(value) =>
          self.begin_put(
            interp,
            reference,
            to_number(value, interp=Some(interp)),
          )
        step => {
          self.request.phase = ExecutorBindingUpdateAwaitToPrimitive(
            reference, current, operation,
          )
          step
        }
      }
    ExecutorBindingUpdateAwaitGet(reference, operation) =>
      self.advance_get(interp, reference, operation)
    ExecutorBindingUpdateAwaitPut(operation, result) =>
      match operation.step(interp) {
        ExecutorActivationNormal(_) => {
          self.request.phase = ExecutorBindingUpdateComplete(result)
          ExecutorActivationNormal(result)
        }
        step => {
          self.request.phase = ExecutorBindingUpdateAwaitPut(operation, result)
          step
        }
      }
    ExecutorBindingUpdateComplete(result) => ExecutorActivationNormal(result)
    ExecutorBindingUpdateAwaitReference =>
      raise @errors.InternalError(
        message="binding update stepped while awaiting a child completion",
      )
  }
}

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

///|
impl ExecutorActivationFrame for ExecutorBindingUpdateFrame with fn deliver_activation_completion(
  self,
  completion,
) {
  match completion {
    ExecutorActivationCompletionAbrupt(error) => raise error
    ExecutorActivationCompletionReference(reference) =>
      match self.request.phase {
        ExecutorBindingUpdateAwaitReference =>
          self.request.phase = ExecutorBindingUpdateNeedGet(reference)
        _ =>
          raise @errors.InternalError(
            message="binding update received an unexpected binding reference",
          )
      }
    ExecutorActivationCompletionNormal(value) =>
      match self.request.phase {
        ExecutorBindingUpdateAwaitGet(_, operation) =>
          operation.deliver_activation_completion(
            ExecutorActivationCompletionNormal(value),
          )
        ExecutorBindingUpdateAwaitToPrimitive(_, _, operation) =>
          operation.deliver_activation_completion(
            ExecutorActivationCompletionNormal(value),
          )
        ExecutorBindingUpdateAwaitPut(operation, _) =>
          operation.deliver_activation_completion(
            ExecutorActivationCompletionNormal(value),
          )
        ExecutorBindingUpdateNeedReference(_)
        | ExecutorBindingUpdateAwaitReference
        | ExecutorBindingUpdateNeedGet(_)
        | ExecutorBindingUpdateHaveCurrent(_, _)
        | ExecutorBindingUpdateComplete(_) =>
          raise @errors.InternalError(
            message="binding update received an unexpected child completion",
          )
      }
  }
}

///|
// A closed static property-update request. Runtime owns the resumable
// get/convert/set pipeline and prefix/postfix result selection; executors only
// provide the already-evaluated target and update syntax.
pub struct ExecutorPropertyUpdateRequest {
  priv target : Value
  priv property_name : String
  priv operator : @ast.UpdateOp
  priv prefix : Bool
  priv member_loc : @token.Loc
  priv loc : @token.Loc
  priv strict : Bool
}

///|
fn ExecutorPropertyUpdateRequest::ExecutorPropertyUpdateRequest(
  target~ : Value,
  property_name~ : String,
  operator~ : @ast.UpdateOp,
  prefix~ : Bool,
  member_loc~ : @token.Loc,
  loc~ : @token.Loc,
  strict~ : Bool,
) -> ExecutorPropertyUpdateRequest {
  { target, property_name, operator, prefix, member_loc, loc, strict, }
}

///|
fn executor_activation_property_update(
  target : Value,
  property_name : String,
  operator : @ast.UpdateOp,
  prefix : Bool,
  member_loc : @token.Loc,
  loc : @token.Loc,
  strict : Bool,
) -> ExecutorActivationStep {
  ExecutorActivationPropertyUpdate(
    ExecutorPropertyUpdateRequest(
      target~,
      property_name~,
      operator~,
      prefix~,
      member_loc~,
      loc~,
      strict~,
    ),
  )
}

///|
pub fn executor_activation_property_increment(
  target : Value,
  property_name : String,
  prefix : Bool,
  member_loc : @token.Loc,
  loc : @token.Loc,
  strict : Bool,
) -> ExecutorActivationStep {
  executor_activation_property_update(
    target,
    property_name,
    @ast.Increment,
    prefix,
    member_loc,
    loc,
    strict,
  )
}

///|
pub fn executor_activation_property_decrement(
  target : Value,
  property_name : String,
  prefix : Bool,
  member_loc : @token.Loc,
  loc : @token.Loc,
  strict : Bool,
) -> ExecutorActivationStep {
  executor_activation_property_update(
    target,
    property_name,
    @ast.Decrement,
    prefix,
    member_loc,
    loc,
    strict,
  )
}

///|
// Admit an already-evaluated computed property only when its key is an exact
// primitive string and the existing callback-free ordinary-own accessor
// classifier can seal the getter and executable. The compiler receives only
// the resulting activation request; object-shape rules stay runtime-owned.
pub fn executor_activation_computed_property_get_if_admitted(
  target : Value,
  key : Value,
  loc : @token.Loc,
) -> ExecutorActivationStep? {
  match key {
    String_(property_name) =>
      match direct_executor_property_getter(target, property_name) {
        Some((getter, executable)) =>
          Some(
            ExecutorActivationPropertyGet(
              ExecutorPropertyGetRequest(
                target~,
                key=ExecutorStringPropertyGetKey(property_name),
                receiver=target,
                loc~,
                manage_proxy=false,
                admission=Some(
                  ExecutorPropertyGetAdmission(getter~, executable~),
                ),
              ),
            ),
          )
        None => None
      }
    _ => None
  }
}

///|
priv struct ExecutorPropertyGetAdmission {
  getter : Value
  executable : ExecutorCallableData
}

///|
fn ExecutorPropertyGetAdmission::ExecutorPropertyGetAdmission(
  getter~ : Value,
  executable~ : ExecutorCallableData,
) -> ExecutorPropertyGetAdmission {
  { getter, executable, }
}

///|
// A closed direct-construction request. Runtime retains ownership of
// constructability, prototype selection, instance allocation, new.target, and
// constructor completion; executors only provide already-evaluated operands.
pub struct ExecutorConstructRequest {
  priv ctor : Value
  priv args : Array[Value]
  priv loc : @token.Loc
}

///|
fn ExecutorConstructRequest::ExecutorConstructRequest(
  ctor~ : Value,
  args~ : Array[Value],
  loc~ : @token.Loc,
) -> ExecutorConstructRequest {
  { ctor, args: args.copy(), loc, }
}

///|
pub fn executor_activation_construct(
  ctor : Value,
  args : Array[Value],
  loc : @token.Loc,
) -> ExecutorActivationStep {
  ExecutorActivationConstruct(ExecutorConstructRequest(ctor~, args~, loc~))
}

///|
pub fn executor_activation_continue() -> ExecutorActivationStep {
  ExecutorActivationContinue
}

///|
pub fn executor_activation_normal(value : Value) -> ExecutorActivationStep {
  ExecutorActivationNormal(value)
}

///|
pub fn executor_activation_return(value : Value) -> ExecutorActivationStep {
  ExecutorActivationReturn(value)
}

///|
pub struct PreparedExecutorActivation {
  ctx : ExecContext
  env : Environment
  args : Array[Value]
}

///|
fn PreparedExecutorActivation::PreparedExecutorActivation(
  ctx~ : ExecContext,
  env~ : Environment,
  args~ : Array[Value],
) -> PreparedExecutorActivation {
  { ctx, env, args: args.copy(), }
}

///|
pub fn PreparedExecutorActivation::context(
  self : PreparedExecutorActivation,
) -> ExecContext {
  self.ctx
}

///|
pub fn PreparedExecutorActivation::environment(
  self : PreparedExecutorActivation,
) -> Environment {
  self.env
}

///|
pub fn PreparedExecutorActivation::arguments(
  self : PreparedExecutorActivation,
) -> ArrayView[Value] {
  self.args.view()
}

///|
pub(open) trait ExecutorActivationFrame {
  fn step(Self, Interpreter) -> ExecutorActivationStep raise Error
  fn deliver_activation_completion(Self, ExecutorActivationCompletion) -> Unit raise Error
}

///|
pub(open) trait ExecutorCode {
  fn start(Self, Interpreter, PreparedExecutorActivation) -> &ExecutorActivationFrame raise Error
}

///|
priv enum ExecutorCallableKind {
  OrdinaryExecutorCallable
  ArrowExecutorCallable
}

///|
// Runtime-owned metadata for a callable executor body. The code capability is
// mode-neutral and remains recoverable before entry so a managed dispatcher can
// start the private executor frame without invoking a final-value callback.
pub struct ExecutorCallableData {
  priv name : String
  priv params : Array[String]
  priv closure : Environment
  priv strict : Bool
  priv code : &ExecutorCode
  priv rest_param : String?
  priv constructable : Bool
  priv self_name : String?
  priv define_arguments_object : Bool
  // A compiler may prove that this callable has no observable activation
  // bindings. Such a callable can execute against its closure directly.
  priv needs_own_environment : Bool
  priv kind : ExecutorCallableKind
  priv activation_capability_summary : ExecutorActivationCapabilitySummary?
  // Exact parser text for prepared bytecode functions. This is source
  // metadata only and never participates in execution or capability checks.
  priv source_text : String?
}

///|
pub fn ExecutorCallableData::name(self : ExecutorCallableData) -> String {
  self.name
}

///|
pub fn ExecutorCallableData::length(self : ExecutorCallableData) -> Int {
  self.params.length()
}

///|
pub fn ExecutorCallableData::source_text(
  self : ExecutorCallableData,
) -> String? {
  self.source_text
}

///|
pub fn ExecutorCallableData::is_constructable(
  self : ExecutorCallableData,
) -> Bool {
  self.constructable
}

///|
pub fn ExecutorCallableData::start_frame(
  self : ExecutorCallableData,
  interp : Interpreter,
  prepared : PreparedExecutorActivation,
) -> &ExecutorActivationFrame raise Error {
  self.code.start(interp, prepared)
}

///|
priv struct ExecutorActivationCleanup {
  observation : ActivationObservationToken
  active_realm : ActiveCalleeRealmValueScope
  property_scope : ClearedActiveCalleeRealmScope?
  saved_in_default : Bool
  saved_param_default_conflicts : @set.Set[String]?
}

///|
priv enum ExecutorChildCompletion {
  ExecutorChildCall(ExecutorCallableKind)
  ExecutorChildArrayForEach
  ExecutorChildConstruct(Value)
  ExecutorChildPropertyGet
  ExecutorChildPropertyKey
  ExecutorChildComputedPropertyGet
  ExecutorChildPropertySet(Value)
  ExecutorChildPropertyUpdate
  ExecutorChildCoercingAddition
  ExecutorChildCoercingRelational
  ExecutorChildCoercingSubtraction
  ExecutorChildCoercingMultiplicative
  ExecutorChildNumericConversion
  ExecutorChildPropertyDelete
  ExecutorChildIterableSpread
  ExecutorChildCopyDataProperties
  ExecutorChildBinding
  ExecutorChildBindingReference
  ExecutorChildBindingReferenceAccess
  ExecutorChildBindingUpdate
}

///|
priv enum ExecutorProxyPropertyGetPhase {
  ExecutorProxyPropertyGetNeedTrap
  ExecutorProxyPropertyGetAwaitTrapLookup
  ExecutorProxyPropertyGetHaveTrap(Value)
  ExecutorProxyPropertyGetAwaitTrapCall
  ExecutorProxyPropertyGetHaveTrapResult(Value)
  ExecutorProxyPropertyGetAwaitForward
  ExecutorProxyPropertyGetComplete(Value)
}

///|
priv struct ExecutorProxyPropertyGetFrame {
  target : Value
  handler : Value
  key : ExecutorPropertyGetKey
  receiver : Value
  loc : @token.Loc
  mut phase : ExecutorProxyPropertyGetPhase
}

///|
fn ExecutorProxyPropertyGetFrame::ExecutorProxyPropertyGetFrame(
  target~ : Value,
  handler~ : Value,
  key~ : ExecutorPropertyGetKey,
  receiver~ : Value,
  loc~ : @token.Loc,
) -> ExecutorProxyPropertyGetFrame {
  {
    target,
    handler,
    key,
    receiver,
    loc,
    phase: ExecutorProxyPropertyGetNeedTrap,
  }
}

///|
fn reduce_executor_proxy_property_get_completion(
  phase : ExecutorProxyPropertyGetPhase,
  completion : ExecutorActivationCompletion,
) -> ExecutorProxyPropertyGetPhase raise Error {
  match completion {
    ExecutorActivationCompletionAbrupt(error) => raise error
    ExecutorActivationCompletionReference(_) =>
      raise @errors.InternalError(
        message="proxy property get received a binding reference completion",
      )
    ExecutorActivationCompletionNormal(value) =>
      match phase {
        ExecutorProxyPropertyGetAwaitTrapLookup =>
          ExecutorProxyPropertyGetHaveTrap(value)
        ExecutorProxyPropertyGetAwaitTrapCall =>
          ExecutorProxyPropertyGetHaveTrapResult(value)
        ExecutorProxyPropertyGetAwaitForward =>
          ExecutorProxyPropertyGetComplete(value)
        ExecutorProxyPropertyGetNeedTrap
        | ExecutorProxyPropertyGetHaveTrap(_)
        | ExecutorProxyPropertyGetHaveTrapResult(_)
        | ExecutorProxyPropertyGetComplete(_) =>
          raise @errors.InternalError(
            message="Proxy property get received an unexpected child completion",
          )
      }
  }
}

///|
impl ExecutorActivationFrame for ExecutorProxyPropertyGetFrame with fn step(
  self,
  interp,
) {
  match self.phase {
    ExecutorProxyPropertyGetNeedTrap => {
      self.phase = ExecutorProxyPropertyGetAwaitTrapLookup
      executor_activation_managed_property_get(self.handler, "get", self.loc)
    }
    ExecutorProxyPropertyGetHaveTrap(trap) =>
      match trap {
        Undefined | Null => {
          self.phase = ExecutorProxyPropertyGetAwaitForward
          executor_activation_property_get_with_receiver(
            self.target,
            self.key,
            self.receiver,
            self.loc,
            true,
          )
        }
        _ if is_callable(trap) => {
          self.phase = ExecutorProxyPropertyGetAwaitTrapCall
          ExecutorActivationCall(
            ExecutorCallRequest(
              callee=trap,
              this_value=self.handler,
              args=[
                self.target,
                executor_property_get_key_value(self.key),
                self.receiver,
              ],
              loc=self.loc,
            ),
          )
        }
        _ =>
          raise @errors.TypeError(
            message="'get' on proxy: trap is not a function",
          )
      }
    ExecutorProxyPropertyGetHaveTrapResult(result) => {
      validate_proxy_get_trap_result(
        interp,
        self.target,
        executor_property_get_key_value(self.key),
        result,
      )
      self.phase = ExecutorProxyPropertyGetComplete(result)
      ExecutorActivationNormal(result)
    }
    ExecutorProxyPropertyGetComplete(result) => ExecutorActivationNormal(result)
    ExecutorProxyPropertyGetAwaitTrapLookup
    | ExecutorProxyPropertyGetAwaitTrapCall
    | ExecutorProxyPropertyGetAwaitForward =>
      raise @errors.InternalError(
        message="Proxy property get stepped while awaiting a child completion",
      )
  }
}

///|
impl ExecutorActivationFrame for ExecutorProxyPropertyGetFrame with fn deliver_activation_completion(
  self,
  completion,
) {
  self.phase = reduce_executor_proxy_property_get_completion(
    self.phase,
    completion,
  )
}

///|
priv enum ExecutorPropertyUpdatePhase {
  ExecutorPropertyUpdateNeedGet
  ExecutorPropertyUpdateAwaitGet
  ExecutorPropertyUpdateHaveCurrent(Value)
  ExecutorPropertyUpdateAwaitToPrimitive(ExecutorToPrimitiveOperation)
  ExecutorPropertyUpdateAwaitSet(Value)
  ExecutorPropertyUpdateComplete(Value)
}

///|
priv struct ExecutorPropertyUpdateFrame {
  request : ExecutorPropertyUpdateRequest
  mut phase : ExecutorPropertyUpdatePhase
}

///|
fn ExecutorPropertyUpdateFrame::ExecutorPropertyUpdateFrame(
  request : ExecutorPropertyUpdateRequest,
) -> ExecutorPropertyUpdateFrame {
  { request, phase: ExecutorPropertyUpdateNeedGet, }
}

///|
fn plan_executor_property_update_set(
  request : ExecutorPropertyUpdateRequest,
  old_number : Double,
) -> (ExecutorPropertyUpdatePhase, ExecutorActivationStep) {
  let plan = plan_numeric_update(old_number, request.operator, request.prefix)
  let next_value = plan.assigned_value()
  let result = plan.expression_value()
  (
    ExecutorPropertyUpdateAwaitSet(result),
    executor_activation_property_set(
      request.target,
      request.property_name,
      next_value,
      request.loc,
      request.strict,
    ),
  )
}

///|
fn reduce_executor_property_update_completion(
  phase : ExecutorPropertyUpdatePhase,
  completion : ExecutorActivationCompletion,
) -> ExecutorPropertyUpdatePhase raise Error {
  match completion {
    ExecutorActivationCompletionAbrupt(error) => raise error
    ExecutorActivationCompletionReference(_) =>
      raise @errors.InternalError(
        message="property update received a binding reference completion",
      )
    ExecutorActivationCompletionNormal(value) =>
      match phase {
        ExecutorPropertyUpdateAwaitGet =>
          ExecutorPropertyUpdateHaveCurrent(value)
        ExecutorPropertyUpdateAwaitToPrimitive(operation) => {
          operation.deliver_activation_completion(
            ExecutorActivationCompletionNormal(value),
          )
          ExecutorPropertyUpdateAwaitToPrimitive(operation)
        }
        ExecutorPropertyUpdateAwaitSet(result) =>
          ExecutorPropertyUpdateComplete(result)
        ExecutorPropertyUpdateNeedGet
        | ExecutorPropertyUpdateHaveCurrent(_)
        | ExecutorPropertyUpdateComplete(_) =>
          raise @errors.InternalError(
            message="property update received an unexpected child completion",
          )
      }
  }
}

///|
fn ExecutorPropertyUpdateFrame::begin_to_primitive(
  self : ExecutorPropertyUpdateFrame,
  current : Value,
  interp : Interpreter,
) -> ExecutorActivationStep raise Error {
  let operation = ExecutorToPrimitiveOperation(
    current,
    ExecutorToPrimitiveNumber,
    self.request.loc,
  )
  match operation.step(interp) {
    ExecutorActivationNormal(value) =>
      self.begin_set(to_number(value, interp=Some(interp)))
    step => {
      self.phase = ExecutorPropertyUpdateAwaitToPrimitive(operation)
      step
    }
  }
}

///|
fn ExecutorPropertyUpdateFrame::begin_set(
  self : ExecutorPropertyUpdateFrame,
  old_number : Double,
) -> ExecutorActivationStep {
  let (next_phase, step) = plan_executor_property_update_set(
    self.request,
    old_number,
  )
  self.phase = next_phase
  step
}

///|
impl ExecutorActivationFrame for ExecutorPropertyUpdateFrame with fn step(
  self,
  interp,
) {
  match self.phase {
    ExecutorPropertyUpdateNeedGet => {
      self.phase = ExecutorPropertyUpdateAwaitGet
      executor_activation_property_get(
        self.request.target,
        self.request.property_name,
        self.request.member_loc,
      )
    }
    ExecutorPropertyUpdateHaveCurrent(current) =>
      if is_js_object(current) {
        self.begin_to_primitive(current, interp)
      } else {
        self.begin_set(to_number(current, interp=Some(interp)))
      }
    ExecutorPropertyUpdateAwaitToPrimitive(operation) =>
      match operation.step(interp) {
        ExecutorActivationNormal(value) =>
          self.begin_set(to_number(value, interp=Some(interp)))
        step => {
          self.phase = ExecutorPropertyUpdateAwaitToPrimitive(operation)
          step
        }
      }
    ExecutorPropertyUpdateComplete(result) => ExecutorActivationNormal(result)
    ExecutorPropertyUpdateAwaitGet =>
      raise @errors.InternalError(
        message="property update stepped while awaiting a child completion",
      )
    ExecutorPropertyUpdateAwaitSet(_) =>
      raise @errors.InternalError(
        message="property update stepped while awaiting a child completion",
      )
  }
}

///|
impl ExecutorActivationFrame for ExecutorPropertyUpdateFrame with fn deliver_activation_completion(
  self,
  completion,
) {
  self.phase = reduce_executor_property_update_completion(
    self.phase,
    completion,
  )
}

///|
priv enum ExecutorActivationStart {
  ExecutorStartCall(ExecutorCallRequest)
  ExecutorStartConstruct(ExecutorConstructRequest)
  ExecutorStartPropertySet(ExecutorCallRequest, Value)
}

///|
priv struct ExecutorActivationStackEntry {
  frame : &ExecutorActivationFrame
  completion : ExecutorChildCompletion?
  cleanup : ExecutorActivationCleanup?
  graph_cursor : TreeExecutorGraphCursor?
}

///|
fn Interpreter::restore_executor_activation_resources(
  self : Interpreter,
  active_realm : ActiveCalleeRealmValueScope,
  saved_in_default : Bool,
  saved_param_default_conflicts : @set.Set[String]?,
  failure : Error?,
) -> Unit {
  self.in_nonarrow_param_default_eval = saved_in_default
  self.param_default_eval_var_conflicts = saved_param_default_conflicts
  finish_active_callee_realm_value(self.realm_state, active_realm, failure~)
}

///|
fn Interpreter::finish_executor_activation(
  self : Interpreter,
  cleanup : ExecutorActivationCleanup,
  failure : Error?,
) -> Unit raise Error {
  self.restore_executor_activation_resources(
    cleanup.active_realm,
    cleanup.saved_in_default,
    cleanup.saved_param_default_conflicts,
    failure,
  )
  let release_error : Error? = try {
    cleanup.observation.release()
    None
  } catch {
    InvalidActivationObservationTransition(message) =>
      Some(
        @errors.InternalError(
          message="executor activation release is invalid: " + message,
        ),
      )
  }
  match cleanup.property_scope {
    Some(scope) => finish_cleared_active_callee_realm(self.realm_state, scope)
    None => ()
  }
  match release_error {
    Some(error) => raise error
    None => ()
  }
}

///|
fn reject_executor_activation_observation(
  attempt : ActivationEntryAttempt,
) -> Unit raise Error {
  attempt.reject() catch {
    InvalidActivationObservationTransition(message) =>
      raise @errors.InternalError(
        message="executor activation rejection is invalid: " + message,
      )
  }
}

///|
fn release_rejected_executor_activation_observation(
  attempt : ActivationEntryAttempt,
) -> Unit raise Error {
  attempt.release_after_rejection() catch {
    InvalidActivationObservationTransition(message) =>
      raise @errors.InternalError(
        message="executor rejected activation release is invalid: " + message,
      )
  }
}

///|
fn observe_executor_activation_entry(
  interp : Interpreter,
) -> ActivationEntryAttempt raise Error {
  observe_activation_entry(
    interp.execution_control_activation_observation_port(),
  )
}

///|
fn Interpreter::start_executor_activation(
  self : Interpreter,
  executable : ExecutorCallableData,
  start : ExecutorActivationStart,
  property_scope : ClearedActiveCalleeRealmScope?,
  graph_cursor? : TreeExecutorGraphCursor? = None,
) -> ExecutorActivationStackEntry raise Error {
  let callee = match start {
    ExecutorStartCall(request) => request.callee
    ExecutorStartConstruct(request) => request.ctor
    ExecutorStartPropertySet(request, _) => request.callee
  }
  let observation = {
    errdefer (match property_scope {
      Some(scope) => finish_cleared_active_callee_realm(self.realm_state, scope)
      None => ()
    })
    observe_executor_activation_entry(self)
  }
  // Save the caller directly: no guest work requires an intermediate empty realm.
  let active_realm = begin_active_callee_realm_value(self.realm_state, callee)
  let saved_in_default = self.in_nonarrow_param_default_eval
  let saved_param_default_conflicts = self.param_default_eval_var_conflicts
  self.in_nonarrow_param_default_eval = false
  self.param_default_eval_var_conflicts = None
  let setup : Result[(&ExecutorActivationFrame, ExecutorChildCompletion), Error] = Ok(
    match start {
      ExecutorStartCall(request) => {
        let prepared = self.prepare_executor_callable_call(
          executable,
          request.callee,
          request.this_value,
          request.args,
        )
        (
          executable.start_frame(self, prepared),
          ExecutorChildCall(executable.kind),
        )
      }
      ExecutorStartPropertySet(request, value) => {
        let prepared = self.prepare_executor_callable_call(
          executable,
          request.callee,
          request.this_value,
          request.args,
        )
        (
          executable.start_frame(self, prepared),
          ExecutorChildPropertySet(value),
        )
      }
      ExecutorStartConstruct(request) => {
        let proto = self.get_prototype_from_constructor(
          request.ctor,
          request.loc,
        )
        let instance = make_constructor_instance(proto, "Object")
        let prepared = self.prepare_executor_activation(
          request.ctor,
          instance,
          request.args,
          executable.params,
          executable.rest_param,
          executable.closure,
          executable.strict,
          Some(request.ctor),
          !executable.constructable,
          executable.self_name,
          executable.define_arguments_object,
        )
        (
          executable.start_frame(self, prepared),
          ExecutorChildConstruct(instance),
        )
      }
    },
  ) catch {
    error => Err(error)
  }
  match setup {
    Err(error) => {
      reject_executor_activation_observation(observation)
      self.restore_executor_activation_resources(
        active_realm,
        saved_in_default,
        saved_param_default_conflicts,
        Some(error),
      )
      let release_error : Error? = try {
        release_rejected_executor_activation_observation(observation)
        None
      } catch {
        error => Some(error)
      }
      match property_scope {
        Some(scope) =>
          finish_cleared_active_callee_realm(self.realm_state, scope)
        None => ()
      }
      match release_error {
        Some(cleanup_error) => raise cleanup_error
        None => raise error
      }
    }
    Ok((frame, completion)) => {
      let accepted = observation.accept()
      {
        frame,
        completion: Some(completion),
        cleanup: Some({
          observation: accepted,
          active_realm,
          property_scope,
          saved_in_default,
          saved_param_default_conflicts,
        }),
        graph_cursor,
      }
    }
  }
}

///|
fn Interpreter::complete_executor_child(
  self : Interpreter,
  stack : Array[ExecutorActivationStackEntry],
  completion : ExecutorActivationCompletion,
) -> Unit raise Error {
  let entry = stack.pop().unwrap()
  let failure = match completion {
    ExecutorActivationCompletionAbrupt(error) => Some(error)
    ExecutorActivationCompletionNormal(_) => None
    ExecutorActivationCompletionReference(_) => None
  }
  match entry.cleanup {
    Some(cleanup) => self.finish_executor_activation(cleanup, failure)
    None => ()
  }
  let parent = stack[stack.length() - 1].frame
  parent.deliver_activation_completion(completion)
}

///|
fn Interpreter::complete_executor_step(
  self : Interpreter,
  stack : Array[ExecutorActivationStackEntry],
  step : ExecutorCompletedStep,
) -> Unit raise Error {
  let completion = match stack[stack.length() - 1].completion {
    Some(ExecutorChildCall(kind)) =>
      ExecutorActivationCompletionNormal(executor_call_completion(kind, step))
    Some(ExecutorChildArrayForEach) => executor_array_for_each_completion(step)
    Some(ExecutorChildConstruct(instance)) =>
      ExecutorActivationCompletionNormal(
        executor_construct_completion(step, instance),
      )
    Some(ExecutorChildPropertyGet)
    | Some(ExecutorChildPropertyKey)
    | Some(ExecutorChildComputedPropertyGet) =>
      executor_value_operation_completion(step)
    Some(ExecutorChildPropertySet(value)) =>
      executor_property_set_completion(value)
    Some(ExecutorChildPropertyUpdate) =>
      executor_property_update_completion(step)
    Some(ExecutorChildCoercingAddition) =>
      executor_coercing_addition_completion(step)
    Some(ExecutorChildCoercingRelational) =>
      executor_coercing_relational_completion(step)
    Some(ExecutorChildCoercingSubtraction) =>
      executor_coercing_subtraction_completion(step)
    Some(ExecutorChildCoercingMultiplicative) =>
      executor_coercing_multiplicative_completion(step)
    Some(ExecutorChildNumericConversion) =>
      executor_numeric_conversion_completion(step)
    Some(ExecutorChildPropertyDelete) =>
      executor_property_delete_completion(step)
    Some(ExecutorChildIterableSpread) =>
      executor_iterable_spread_completion(step)
    Some(ExecutorChildCopyDataProperties) =>
      executor_copy_data_properties_completion(step)
    Some(ExecutorChildBinding) => executor_binding_completion(step)
    Some(ExecutorChildBindingReference) =>
      executor_binding_reference_completion(step)
    Some(ExecutorChildBindingReferenceAccess) =>
      executor_binding_completion(step)
    Some(ExecutorChildBindingUpdate) => executor_binding_update_completion(step)
    None => ExecutorActivationCompletionNormal(Undefined)
  }
  self.complete_executor_child(stack, completion)
}

///|
fn executor_array_for_each_completion(
  step : ExecutorCompletedStep,
) -> ExecutorActivationCompletion {
  match step {
    ExecutorCompletedNormal(_) | ExecutorCompletedReturn(_) =>
      ExecutorActivationCompletionNormal(Undefined)
    ExecutorCompletedReference(_) =>
      ExecutorActivationCompletionAbrupt(
        @errors.InternalError(message="forEach frame completed without a value"),
      )
  }
}

///|
fn executor_binding_reference_completion(
  step : ExecutorCompletedStep,
) -> ExecutorActivationCompletion {
  match step {
    ExecutorCompletedReference(reference) =>
      ExecutorActivationCompletionReference(reference)
    ExecutorCompletedNormal(_) | ExecutorCompletedReturn(_) =>
      ExecutorActivationCompletionAbrupt(
        @errors.InternalError(
          message="binding reference frame completed without a reference",
        ),
      )
  }
}

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

///|
fn executor_iterable_spread_completion(
  step : ExecutorCompletedStep,
) -> ExecutorActivationCompletion {
  match step {
    ExecutorCompletedNormal(value) | ExecutorCompletedReturn(value) =>
      ExecutorActivationCompletionNormal(value)
    ExecutorCompletedReference(_) =>
      ExecutorActivationCompletionAbrupt(
        @errors.InternalError(
          message="iterable spread frame completed without a value",
        ),
      )
  }
}

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

///|
fn Interpreter::deliver_executor_activation_error(
  self : Interpreter,
  stack : Array[ExecutorActivationStackEntry],
  index : Int,
  error : Error,
) -> Unit raise Error {
  if index == 0 {
    raise error
  } else {
    self.complete_executor_child(
      stack,
      ExecutorActivationCompletionAbrupt(error),
    ) catch {
      nested_error =>
        self.deliver_executor_activation_error(
          stack,
          stack.length() - 1,
          nested_error,
        )
    }
  }
}

///|
fn deliver_executor_activation_request_error(
  frame : &ExecutorActivationFrame,
  error : Error,
) -> Unit raise Error {
  frame.deliver_activation_completion(ExecutorActivationCompletionAbrupt(error))
}

///|
fn deliver_executor_activation_request(
  frame : &ExecutorActivationFrame,
  requested : Result[ExecutorActivationRequestOutcome, Error],
) -> Unit raise Error {
  match requested {
    Ok(ExecutorActivationRequestChild) => ()
    Ok(ExecutorActivationRequestValue(value)) =>
      frame.deliver_activation_completion(
        ExecutorActivationCompletionNormal(value),
      )
    Err(error) => deliver_executor_activation_request_error(frame, error)
  }
}

///|
fn direct_executor_constructor_with_data_prototype(
  ctor : Value,
) -> ExecutorCallableData? {
  match ctor {
    Object(object_data) =>
      match object_data.callable {
        Some(ExecutorCallable(executable)) if executable.constructable =>
          match object_data.bag.descriptors.get("prototype") {
            Some(descriptor) if !descriptor.is_accessor &&
              object_data.bag.properties.contains("prototype") =>
              Some(executable)
            _ => None
          }
        _ => None
      }
    _ => None
  }
}

///|
// Callback-free admission for an exact own accessor. Computed-property
// admission deliberately retains this narrower boundary.
fn direct_executor_property_getter(
  target : Value,
  property_name : String,
) -> (Value, ExecutorCallableData)? {
  match target {
    Object(data) if data.class_name == "Object" &&
      data.callable is None &&
      data.arraybuffer_state is None &&
      data.bag.internal_slots.is_empty() &&
      data.bag.host_slots.is_empty() =>
      match data.bag.descriptors.get(property_name) {
        Some(descriptor) if descriptor.is_accessor =>
          match descriptor.getter {
            Some(getter) =>
              match getter {
                Object({ callable: Some(ExecutorCallable(executable)), .. }) =>
                  Some((getter, executable))
                _ => None
              }
            None => None
          }
        _ => None
      }
    _ => None
  }
}

///|
// Callback-free lookup for the iterative static-property slice. A plain
// ordinary prototype chain is inspected directly so no guest code runs before
// the property scope and executor activation are installed. The original
// target remains the receiver when an inherited getter is selected.
fn direct_executor_property_getter_in_plain_chain(
  target : Value,
  property_name : String,
) -> (Value, ExecutorCallableData)? {
  for current = target {
    match current {
      Object(data) if data.class_name == "Object" &&
        data.callable is None &&
        data.arraybuffer_state is None &&
        data.bag.internal_slots.is_empty() &&
        data.bag.host_slots.is_empty() =>
        match data.bag.descriptors.get(property_name) {
          Some(descriptor) if descriptor.is_accessor =>
            match descriptor.getter {
              Some(getter) =>
                match getter {
                  Object({ callable: Some(ExecutorCallable(executable)), .. }) =>
                    break Some((getter, executable))
                  _ => break None
                }
              None => break None
            }
          Some(_) => break None
          None =>
            if data.bag.properties.contains(property_name) {
              break None
            } else {
              continue data.prototype
            }
        }
      _ => break None
    }
  }
}

///|
// Callback-free admission for the one iterative static-property mutation
// slice. This mirrors the getter classifier but admits only an exact own
// accessor setter carrying sealed executor data.
fn direct_executor_property_setter(
  target : Value,
  property_name : String,
) -> (Value, ExecutorCallableData)? {
  for current = target {
    match current {
      Object(data) if data.class_name == "Object" &&
        data.callable is None &&
        data.arraybuffer_state is None &&
        data.bag.internal_slots.is_empty() &&
        data.bag.host_slots.is_empty() =>
        match data.bag.descriptors.get(property_name) {
          Some(descriptor) if descriptor.is_accessor =>
            match descriptor.setter {
              Some(setter) =>
                match setter {
                  Object({ callable: Some(ExecutorCallable(executable)), .. }) =>
                    break Some((setter, executable))
                  _ => break None
                }
              None => break None
            }
          Some(_) => break None
          None =>
            if data.bag.properties.contains(property_name) {
              break None
            } else {
              continue data.prototype
            }
        }
      _ => break None
    }
  }
}

///|
fn direct_executor_symbol_property_setter_in_plain_chain(
  target : Value,
  symbol_id : Int,
) -> (Value, ExecutorCallableData)? {
  for current = target {
    match current {
      Object(data) if data.class_name == "Object" &&
        data.callable is None &&
        data.arraybuffer_state is None &&
        data.bag.internal_slots.is_empty() &&
        data.bag.host_slots.is_empty() =>
        match data.bag.symbol_descriptors.get(symbol_id) {
          Some(descriptor) if descriptor.is_accessor =>
            match descriptor.setter {
              Some(setter) =>
                match setter {
                  Object({ callable: Some(ExecutorCallable(executable)), .. }) =>
                    break Some((setter, executable))
                  _ => break None
                }
              None => break None
            }
          Some(_) => break None
          None =>
            if data.bag.symbol_properties.contains(symbol_id) {
              break None
            } else {
              continue data.prototype
            }
        }
      _ => break None
    }
  }
}

///|
// Callback-free lookup for an executor-backed symbol accessor on a plain
// ordinary prototype chain. The original target remains the receiver.
fn direct_executor_symbol_property_getter_in_plain_chain(
  target : Value,
  symbol_id : Int,
) -> (Value, ExecutorCallableData)? {
  for current = target {
    match current {
      Object(data) if data.class_name == "Object" &&
        data.callable is None &&
        data.arraybuffer_state is None &&
        data.bag.internal_slots.is_empty() &&
        data.bag.host_slots.is_empty() =>
        match data.bag.symbol_descriptors.get(symbol_id) {
          Some(descriptor) if descriptor.is_accessor =>
            match descriptor.getter {
              Some(getter) =>
                match getter {
                  Object({ callable: Some(ExecutorCallable(executable)), .. }) =>
                    break Some((getter, executable))
                  _ => break None
                }
              None => break None
            }
          Some(_) => break None
          None =>
            if data.bag.symbol_properties.contains(symbol_id) {
              break None
            } else {
              continue data.prototype
            }
        }
      _ => break None
    }
  }
}

///|
// Find the first Proxy reached by an ordinary [[Get]] prototype walk before
// the requested key is found. This inspection is callback-free; the caller
// keeps the original receiver when it resumes lookup at the Proxy boundary.
fn direct_executor_proxy_boundary_in_plain_chain(
  target : Value,
  key : ExecutorPropertyGetKey,
) -> Value? {
  for current = target {
    match current {
      Proxy(_) => break Some(current)
      Object(data) if data.class_name == "Object" &&
        data.callable is None &&
        data.arraybuffer_state is None &&
        data.bag.internal_slots.is_empty() &&
        data.bag.host_slots.is_empty() => {
        let has_own = match key {
          ExecutorStringPropertyGetKey(property_name) =>
            data.bag.descriptors.contains(property_name) ||
            data.bag.properties.contains(property_name)
          ExecutorSymbolPropertyGetKey(symbol) =>
            data.bag.symbol_descriptors.contains(symbol.id) ||
            data.bag.symbol_properties.contains(symbol.id)
        }
        if has_own {
          break None
        } else {
          continue data.prototype
        }
      }
      _ => break None
    }
  }
}

///|
fn Interpreter::executor_activation_fallback_call(
  self : Interpreter,
  callee : Value,
  this_value : Value,
  args : Array[Value],
  loc : @token.Loc,
) -> ExecutorActivationRequestOutcome raise Error {
  ExecutorActivationRequestValue(self.call_value(callee, this_value, args, loc))
}

///|
fn Interpreter::handle_executor_activation_step(
  self : Interpreter,
  stack : Array[ExecutorActivationStackEntry],
  index : Int,
  step : ExecutorActivationStep,
) -> ExecutorCompletedStep? raise Error {
  let frame = stack[index].frame
  match step {
    ExecutorActivationContinue => None
    ExecutorActivationNormal(value) =>
      if index == 0 {
        Some(ExecutorCompletedNormal(value))
      } else {
        self.complete_executor_step(stack, ExecutorCompletedNormal(value))
        None
      }
    ExecutorActivationReturn(value) =>
      if index == 0 {
        Some(ExecutorCompletedReturn(value))
      } else {
        self.complete_executor_step(stack, ExecutorCompletedReturn(value))
        None
      }
    ExecutorActivationReference(reference) =>
      if index == 0 {
        Some(ExecutorCompletedReference(reference))
      } else {
        self.complete_executor_step(
          stack,
          ExecutorCompletedReference(reference),
        )
        None
      }
    ExecutorActivationCopyDataProperties(request) => {
      let copy_frame = ExecutorCopyDataPropertiesFrame(request)
      stack.push({
        frame: copy_frame as &ExecutorActivationFrame,
        completion: Some(ExecutorChildCopyDataProperties),
        cleanup: None,
        graph_cursor: None,
      })
      None
    }
    ExecutorActivationBinding(request) => {
      let binding_frame = ExecutorBindingFrame(request)
      stack.push({
        frame: binding_frame as &ExecutorActivationFrame,
        completion: Some(ExecutorChildBinding),
        cleanup: None,
        graph_cursor: None,
      })
      None
    }
    ExecutorActivationBindingReference(request) => {
      let binding_frame = ExecutorBindingReferenceFrame(request)
      stack.push({
        frame: binding_frame as &ExecutorActivationFrame,
        completion: Some(ExecutorChildBindingReference),
        cleanup: None,
        graph_cursor: None,
      })
      None
    }
    ExecutorActivationBindingReferenceAccess(request) => {
      let binding_frame = ExecutorBindingReferenceAccessFrame(request)
      stack.push({
        frame: binding_frame as &ExecutorActivationFrame,
        completion: Some(ExecutorChildBindingReferenceAccess),
        cleanup: None,
        graph_cursor: None,
      })
      None
    }
    ExecutorActivationBindingUpdate(request) => {
      let binding_update_frame = ExecutorBindingUpdateFrame(request)
      stack.push({
        frame: binding_update_frame as &ExecutorActivationFrame,
        completion: Some(ExecutorChildBindingUpdate),
        cleanup: None,
        graph_cursor: None,
      })
      None
    }
    ExecutorActivationCall(request) => {
      let requested : Result[ExecutorActivationRequestOutcome, Error] = Ok(
        {
          let (forwarded_callee, forwarded_this_value, forwarded_args) = self.resolve_call_forwarding(
            request.callee,
            request.this_value,
            request.args,
          )
          match
            executor_array_for_each_request(
              self,
              forwarded_callee,
              forwarded_this_value,
              forwarded_args,
              request.loc,
            ) {
            Some(array_request) => {
              let array_frame = ExecutorArrayForEachFrame(array_request)
              stack.push({
                frame: array_frame as &ExecutorActivationFrame,
                completion: Some(ExecutorChildArrayForEach),
                cleanup: None,
                graph_cursor: None,
              })
              ExecutorActivationRequestChild
            }
            None =>
              match stack[index].graph_cursor {
                Some(graph_cursor) => {
                  let edge = match
                    tree_executor_graph_select_edge(
                      graph_cursor,
                      forwarded_callee,
                      forwarded_args.length(),
                    ) {
                    Some(edge) => edge
                    None =>
                      raise @errors.InternalError(
                        message="executor activation graph proof was violated by an unmatched call",
                      )
                  }
                  let admission = match
                    tree_executor_graph_target(graph_cursor, edge) {
                    Some(admission) => admission
                    None =>
                      raise @errors.InternalError(
                        message="executor activation graph target was invalid",
                      )
                  }
                  let forwarded_request = ExecutorCallRequest(
                    callee=forwarded_callee,
                    this_value=forwarded_this_value,
                    args=forwarded_args,
                    loc=request.loc,
                  )
                  stack.push(
                    self.start_executor_activation(
                      admission.executable,
                      ExecutorStartCall(forwarded_request),
                      None,
                      graph_cursor=Some(admission.cursor),
                    ),
                  )
                  ExecutorActivationRequestChild
                }
                None =>
                  match forwarded_callee {
                    Object({ callable: Some(ExecutorCallable(executable)), .. }) => {
                      let forwarded_request = ExecutorCallRequest(
                        callee=forwarded_callee,
                        this_value=forwarded_this_value,
                        args=forwarded_args,
                        loc=request.loc,
                      )
                      stack.push(
                        self.start_executor_activation(
                          executable,
                          ExecutorStartCall(forwarded_request),
                          None,
                        ),
                      )
                      ExecutorActivationRequestChild
                    }
                    Object({ callable: Some(UserFunc(data)), .. }) =>
                      match
                        tree_executor_callable_admission(
                          forwarded_callee, data, forwarded_args,
                        ) {
                        Some(admission) => {
                          let forwarded_request = ExecutorCallRequest(
                            callee=forwarded_callee,
                            this_value=forwarded_this_value,
                            args=forwarded_args,
                            loc=request.loc,
                          )
                          stack.push(
                            self.start_executor_activation(
                              admission.executable,
                              ExecutorStartCall(forwarded_request),
                              None,
                              graph_cursor=Some(admission.cursor),
                            ),
                          )
                          ExecutorActivationRequestChild
                        }
                        None =>
                          self.executor_activation_fallback_call(
                            forwarded_callee,
                            forwarded_this_value,
                            forwarded_args,
                            request.loc,
                          )
                      }
                    _ =>
                      self.executor_activation_fallback_call(
                        forwarded_callee,
                        forwarded_this_value,
                        forwarded_args,
                        request.loc,
                      )
                  }
              }
          }
        },
      ) catch {
        error => Err(error)
      }
      deliver_executor_activation_request(frame, requested)
      None
    }
    ExecutorActivationConstruct(request) => {
      let requested : Result[ExecutorActivationRequestOutcome, Error] = Ok(
        match direct_executor_constructor_with_data_prototype(request.ctor) {
          Some(executable) => {
            stack.push(
              self.start_executor_activation(
                executable,
                ExecutorStartConstruct(request),
                None,
              ),
            )
            ExecutorActivationRequestChild
          }
          None =>
            ExecutorActivationRequestValue(
              self.construct_value(request.ctor, request.args, request.loc),
            )
        },
      ) catch {
        error => Err(error)
      }
      deliver_executor_activation_request(frame, requested)
      None
    }
    ExecutorActivationPropertyKey(request) => {
      let property_key_frame = ExecutorPropertyKeyFrame(request)
      stack.push({
        frame: property_key_frame as &ExecutorActivationFrame,
        completion: Some(ExecutorChildPropertyKey),
        cleanup: None,
        graph_cursor: None,
      })
      None
    }
    ExecutorActivationComputedPropertyGet(request) => {
      let property_get_frame = ExecutorComputedPropertyGetFrame(request)
      stack.push({
        frame: property_get_frame as &ExecutorActivationFrame,
        completion: Some(ExecutorChildComputedPropertyGet),
        cleanup: None,
        graph_cursor: None,
      })
      None
    }
    ExecutorActivationPropertyGet(request) => {
      let requested : Result[ExecutorActivationRequestOutcome, Error] = Ok(
        {
          let proxy_boundary = if request.manage_proxy {
            direct_executor_proxy_boundary_in_plain_chain(
              request.target,
              request.key,
            )
          } else {
            None
          }
          match proxy_boundary {
            Some(Proxy(proxy_data)) => {
              let handler = match proxy_data.handler {
                Some(handler) => handler
                None =>
                  raise @errors.TypeError(
                    message="Cannot perform 'get' on a proxy that has been revoked",
                  )
              }
              let target = match proxy_data.target {
                Some(target) => target
                None =>
                  raise @errors.TypeError(
                    message="Cannot perform 'get' on a proxy that has been revoked",
                  )
              }
              let proxy_frame = ExecutorProxyPropertyGetFrame(
                target~,
                handler~,
                key=request.key,
                receiver=request.receiver,
                loc=request.loc,
              )
              stack.push({
                frame: proxy_frame as &ExecutorActivationFrame,
                completion: Some(ExecutorChildPropertyGet),
                cleanup: None,
                graph_cursor: None,
              })
              return None
            }
            _ => ()
          }
          let admitted = match request.admission {
            Some(admission) => Some((admission.getter, admission.executable))
            None =>
              match request.key {
                ExecutorStringPropertyGetKey(property_name) =>
                  direct_executor_property_getter_in_plain_chain(
                    request.target,
                    property_name,
                  )
                ExecutorSymbolPropertyGetKey(symbol) =>
                  direct_executor_symbol_property_getter_in_plain_chain(
                    request.target,
                    symbol.id,
                  )
              }
          }
          match admitted {
            Some((getter, executable)) => {
              let property_scope = begin_cleared_active_callee_realm(
                self.realm_state,
              )
              let call_request = ExecutorCallRequest(
                callee=getter,
                this_value=request.receiver,
                args=[],
                loc=request.loc,
              )
              stack.push(
                self.start_executor_activation(
                  executable,
                  ExecutorStartCall(call_request),
                  Some(property_scope),
                ),
              )
              ExecutorActivationRequestChild
            }
            None =>
              ExecutorActivationRequestValue(
                match request.key {
                  ExecutorStringPropertyGetKey(property_name) =>
                    if request.manage_proxy {
                      self.get_property_key_with_receiver(
                        request.target,
                        String_(property_name),
                        request.receiver,
                        request.loc,
                      )
                    } else {
                      self.get_property(
                        request.target,
                        property_name,
                        request.loc,
                      )
                    }
                  ExecutorSymbolPropertyGetKey(symbol) =>
                    if request.manage_proxy {
                      self.get_property_key_with_receiver(
                        request.target,
                        Symbol(symbol),
                        request.receiver,
                        request.loc,
                      )
                    } else {
                      self.get_computed_property(
                        request.target,
                        Symbol(symbol),
                        request.loc,
                      )
                    }
                },
              )
          }
        },
      ) catch {
        error => Err(error)
      }
      deliver_executor_activation_request(frame, requested)
      None
    }
    ExecutorActivationPropertySet(request) => {
      let key = match request.key {
        ExecutorRawPropertySetKey(_) => {
          let set_frame = ExecutorComputedPropertySetFrame(request)
          stack.push({
            frame: set_frame as &ExecutorActivationFrame,
            completion: Some(ExecutorChildPropertySet(request.value)),
            cleanup: None,
            graph_cursor: None,
          })
          return None
        }
        ExecutorSealedPropertySetKey(key) => key
      }
      if request.manage_proxy {
        let proxy_boundary = direct_executor_proxy_boundary_in_plain_chain(
          request.target,
          key,
        )
        match proxy_boundary {
          Some(Proxy(proxy_data)) => {
            let handler = match proxy_data.handler {
              Some(handler) => handler
              None =>
                raise @errors.TypeError(
                  message="Cannot perform 'set' on a proxy that has been revoked",
                )
            }
            let target = match proxy_data.target {
              Some(target) => target
              None =>
                raise @errors.TypeError(
                  message="Cannot perform 'set' on a proxy that has been revoked",
                )
            }
            let proxy_frame = ExecutorProxyPropertySetFrame(
              target~,
              handler~,
              key~,
              value=request.value,
              receiver=request.receiver,
              strict=request.strict,
              loc=request.loc,
            )
            stack.push({
              frame: proxy_frame as &ExecutorActivationFrame,
              completion: Some(ExecutorChildPropertySet(request.value)),
              cleanup: None,
              graph_cursor: None,
            })
            return None
          }
          _ => ()
        }
      }
      let requested : Result[ExecutorActivationRequestOutcome, Error] = Ok(
        match
          (match key {
            ExecutorStringPropertyGetKey(property_name) =>
              direct_executor_property_setter(request.target, property_name)
            ExecutorSymbolPropertyGetKey(symbol) =>
              direct_executor_symbol_property_setter_in_plain_chain(
                request.target,
                symbol.id,
              )
          }) {
          Some((setter, executable)) => {
            let property_scope = begin_cleared_active_callee_realm(
              self.realm_state,
            )
            let call_request = ExecutorCallRequest(
              callee=setter,
              this_value=request.receiver,
              args=[request.value],
              loc=request.loc,
            )
            stack.push(
              self.start_executor_activation(
                executable,
                ExecutorStartPropertySet(call_request, request.value),
                Some(property_scope),
              ),
            )
            ExecutorActivationRequestChild
          }
          None =>
            ExecutorActivationRequestValue(
              match key {
                ExecutorStringPropertyGetKey(property_name) =>
                  self.set_property(
                    request.target,
                    property_name,
                    request.value,
                    request.loc,
                    strict=request.strict,
                    receiver=request.receiver,
                  )
                ExecutorSymbolPropertyGetKey(symbol) =>
                  self.set_computed_property(
                    request.target,
                    Symbol(symbol),
                    request.value,
                    request.loc,
                    strict=request.strict,
                    receiver=request.receiver,
                  )
              },
            )
        },
      ) catch {
        error => Err(error)
      }
      deliver_executor_activation_request(frame, requested)
      None
    }
    ExecutorActivationPropertyUpdate(request) => {
      let update_frame = ExecutorPropertyUpdateFrame(request)
      stack.push({
        frame: update_frame as &ExecutorActivationFrame,
        completion: Some(ExecutorChildPropertyUpdate),
        cleanup: None,
        graph_cursor: None,
      })
      None
    }
    ExecutorActivationCoercingAddition(request) => {
      let addition_frame = ExecutorCoercingAdditionFrame(request)
      stack.push({
        frame: addition_frame as &ExecutorActivationFrame,
        completion: Some(ExecutorChildCoercingAddition),
        cleanup: None,
        graph_cursor: None,
      })
      None
    }
    ExecutorActivationCoercingRelational(request) => {
      let relational_frame = ExecutorCoercingRelationalFrame(request)
      stack.push({
        frame: relational_frame as &ExecutorActivationFrame,
        completion: Some(ExecutorChildCoercingRelational),
        cleanup: None,
        graph_cursor: None,
      })
      None
    }
    ExecutorActivationCoercingSubtraction(request) => {
      let subtraction_frame = ExecutorCoercingSubtractionFrame(request)
      stack.push({
        frame: subtraction_frame as &ExecutorActivationFrame,
        completion: Some(ExecutorChildCoercingSubtraction),
        cleanup: None,
        graph_cursor: None,
      })
      None
    }
    ExecutorActivationCoercingMultiplicative(request) => {
      let multiplicative_frame = ExecutorCoercingMultiplicativeFrame(request)
      stack.push({
        frame: multiplicative_frame as &ExecutorActivationFrame,
        completion: Some(ExecutorChildCoercingMultiplicative),
        cleanup: None,
        graph_cursor: None,
      })
      None
    }
    ExecutorActivationNumericConversion(request) => {
      let conversion_frame = ExecutorNumericConversionFrame(request)
      stack.push({
        frame: conversion_frame as &ExecutorActivationFrame,
        completion: Some(ExecutorChildNumericConversion),
        cleanup: None,
        graph_cursor: None,
      })
      None
    }
    ExecutorActivationPropertyDelete(request) => {
      let delete_frame = ExecutorPropertyDeleteFrame(request)
      stack.push({
        frame: delete_frame as &ExecutorActivationFrame,
        completion: Some(ExecutorChildPropertyDelete),
        cleanup: None,
        graph_cursor: None,
      })
      None
    }
    ExecutorActivationIterableSpread(request) => {
      let spread_frame = ExecutorIterableSpreadFrame(request)
      stack.push({
        frame: spread_frame as &ExecutorActivationFrame,
        completion: Some(ExecutorChildIterableSpread),
        cleanup: None,
        graph_cursor: None,
      })
      None
    }
  }
}

///|
// Drive one root entry and every exact executor-backed ordinary call or static
// property getter/setter it requests. Root ownership is carried by the entry:
// public top-level frames have none, while admitted ordinary-call roots own
// cleanup.
fn Interpreter::drive_executor_activation_stack(
  self : Interpreter,
  stack : Array[ExecutorActivationStackEntry],
) -> ExecutorCompletedStep raise Error {
  try {
    while true {
      guard !stack.is_empty() else { return ExecutorCompletedNormal(Undefined) }
      let index = stack.length() - 1
      let frame = stack[index].frame
      let stepped : Result[ExecutorActivationStep, Error] = Ok(frame.step(self)) catch {
        error => Err(error)
      }
      match stepped {
        Err(error) =>
          self.deliver_executor_activation_error(stack, index, error)
        Ok(step) => {
          let handled_result : Result[ExecutorCompletedStep?, Error] = Ok(
            self.handle_executor_activation_step(stack, index, step),
          ) catch {
            error => Err(error)
          }
          match handled_result {
            Err(error) => {
              if index < stack.length() {
                self.deliver_executor_activation_error(stack, index, error)
              }
              raise error
            }
            Ok(handled) =>
              match handled {
                Some(result) => {
                  let root = stack.pop().unwrap()
                  match root.cleanup {
                    Some(cleanup) =>
                      self.finish_executor_activation(cleanup, None)
                    None => ()
                  }
                  return result
                }
                None => ()
              }
          }
        }
      }
    }
  } catch {
    error => {
      let mut first_cleanup_error : Error? = None
      while !stack.is_empty() {
        let entry = stack.pop().unwrap()
        match entry.cleanup {
          Some(cleanup) => {
            let cleanup_error : Error? = try {
              self.finish_executor_activation(cleanup, Some(error))
              None
            } catch {
              cleanup_error => Some(cleanup_error)
            }
            match (first_cleanup_error, cleanup_error) {
              (None, Some(cleanup_error)) =>
                first_cleanup_error = Some(cleanup_error)
              _ => ()
            }
          }
          None => ()
        }
      }
      match first_cleanup_error {
        Some(cleanup_error) => raise cleanup_error
        None => raise error
      }
    }
  }
  ExecutorCompletedNormal(Undefined)
}

///|
// Drive a top-level executor frame that does not represent an acquired guest
// activation. Managed ordinary-call roots use the owned entry point below.
pub fn Interpreter::run_executor_activation_coordinator(
  self : Interpreter,
  root : &ExecutorActivationFrame,
) -> ExecutorActivationStep raise Error {
  self
  .drive_executor_activation_stack([
    { frame: root, completion: None, cleanup: None, graph_cursor: None, },
  ])
  .to_activation_step()
}

///|
// Enter one already-admitted ordinary call as an owned coordinator root. The
// same entry owns depth observation, realm state, the sealed graph cursor, and
// exactly-once cleanup on both normal and abrupt completion.
fn Interpreter::run_admitted_executor_call_root(
  self : Interpreter,
  executable : ExecutorCallableData,
  request : ExecutorCallRequest,
  graph_cursor : TreeExecutorGraphCursor,
) -> ExecutorCompletedStep raise Error {
  let root = self.start_executor_activation(
    executable,
    ExecutorStartCall(request),
    None,
    graph_cursor=Some(graph_cursor),
  )
  self.drive_executor_activation_stack([root])
}

///|
// Prepare an ordinary call without entering executor code. This is the
// hand-off used by a managed dispatcher: runtime owns observable activation
// semantics, while the caller may push the private frame returned by
// `start_frame` instead of invoking the synchronous compatibility adapter.
pub fn Interpreter::prepare_executor_callable_call(
  self : Interpreter,
  executable : ExecutorCallableData,
  callee : Value,
  this_value : Value,
  args : Array[Value],
) -> PreparedExecutorActivation raise Error {
  match executable.kind {
    OrdinaryExecutorCallable =>
      if executable.needs_own_environment {
        self.prepare_executor_activation(
          callee,
          this_value,
          args,
          executable.params,
          executable.rest_param,
          executable.closure,
          executable.strict,
          None,
          !executable.constructable,
          executable.self_name,
          executable.define_arguments_object,
        )
      } else {
        PreparedExecutorActivation(
          ctx={ strict: executable.strict, current_generator: None, },
          env=executable.closure,
          args~,
        )
      }
    ArrowExecutorCallable => prepare_executor_arrow_activation(executable, args)
  }
}

///|
fn Interpreter::drive_executor_activation(
  self : Interpreter,
  code : &ExecutorCode,
  prepared : PreparedExecutorActivation,
) -> ExecutorCompletedStep raise Error {
  let frame = code.start(self, prepared)
  self.drive_executor_activation_stack([
    { frame, completion: None, cleanup: None, graph_cursor: None, },
  ])
}

///|
fn bind_executor_parameters(
  env : Environment,
  params : Array[String],
  args : Array[Value],
) -> Unit raise Error {
  for i, param in params {
    let value = if i < args.length() { args[i] } else { Undefined }
    if env.bindings.contains(param) {
      env.assign(param, value)
    } else {
      env.def_parameter(param, value)
    }
  }
}

///|
fn bind_executor_rest_parameter(
  env : Environment,
  positional_count : Int,
  rest_param : String?,
  args : Array[Value],
) -> Unit raise Error {
  match rest_param {
    Some(name) => {
      let rest : Array[Value] = []
      for i = positional_count; i < args.length(); i = i + 1 {
        rest.push(args[i])
      }
      env.def_parameter(name, make_array(rest))
    }
    None => ()
  }
}

///|
fn prepare_executor_arrow_activation(
  executable : ExecutorCallableData,
  args : Array[Value],
) -> PreparedExecutorActivation raise Error {
  let ctx : ExecContext = {
    strict: executable.strict,
    current_generator: None,
  }
  let env = Environment::new(parent=Some(executable.closure))
  env.is_var_scope = true
  bind_executor_parameters(env, executable.params, args)
  bind_executor_rest_parameter(
    env,
    executable.params.length(),
    executable.rest_param,
    args,
  )
  PreparedExecutorActivation(ctx~, env~, args~)
}

///|
fn Interpreter::prepare_executor_activation(
  self : Interpreter,
  callee : Value,
  this_value : Value,
  args : Array[Value],
  params : Array[String],
  rest_param : String?,
  closure : Environment,
  strict : Bool,
  new_target : Value?,
  is_method : Bool,
  self_name : String?,
  define_arguments_object : Bool,
) -> PreparedExecutorActivation raise Error {
  let ctx : ExecContext = { strict, current_generator: None, }
  let env = Environment::new(parent=Some(closure))
  env.is_var_scope = true
  env.def_builtin("[[EvalMethodContext]]", Bool(is_method))
  let effective_this = if strict {
    this_value
  } else {
    self.normalize_sloppy_this(this_value)
  }
  env.def("this", effective_this, LetBinding)
  env.def("", new_target.unwrap_or(Undefined), LetBinding)
  bind_executor_parameters(env, params, args)
  bind_executor_rest_parameter(env, params.length(), rest_param, args)
  if define_arguments_object && !params_include_arguments(params, rest_param) {
    match rest_param {
      Some(_) =>
        self.define_unmapped_arguments_object(env, args, callee, strict)
      None =>
        self.define_simple_arguments_object(env, args, callee, strict, params)
    }
  }
  match self_name {
    Some(name) if !env.bindings.contains(name) =>
      env.def(name, callee, FunctionNameBinding)
    _ => ()
  }
  PreparedExecutorActivation(ctx~, env~, args~)
}

///|
fn executor_call_completion(
  kind : ExecutorCallableKind,
  step : ExecutorCompletedStep,
) -> Value raise Error {
  match step {
    ExecutorCompletedNormal(_) => Undefined
    ExecutorCompletedReturn(value) => value
    ExecutorCompletedReference(_) =>
      raise @errors.InternalError(
        message=match kind {
          OrdinaryExecutorCallable =>
            "executor call completed with a binding reference"
          ArrowExecutorCallable =>
            "executor arrow call completed with a binding reference"
        },
      )
  }
}

///|
fn executor_construct_completion(
  step : ExecutorCompletedStep,
  instance : Value,
) -> Value raise Error {
  match step {
    ExecutorCompletedReturn(value) if is_object_like_for_constructor_return(
        value,
      ) => value
    ExecutorCompletedNormal(_) | ExecutorCompletedReturn(_) => instance
    ExecutorCompletedReference(_) =>
      raise @errors.InternalError(
        message="executor construct completed with a binding reference",
      )
  }
}

///|
fn executor_property_set_completion(
  rhs : Value,
) -> ExecutorActivationCompletion {
  ExecutorActivationCompletionNormal(rhs)
}

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

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

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

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

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

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

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

///|
fn Interpreter::run_executor_function(
  self : Interpreter,
  executable : ExecutorCallableData,
  callee : Value,
  context : CallContext,
  this_value : Value,
  args : Array[Value],
) -> Value raise Error {
  let saved_in_default = self.in_nonarrow_param_default_eval
  self.in_nonarrow_param_default_eval = false
  let result : Value = {
    errdefer {
      self.in_nonarrow_param_default_eval = saved_in_default
    }
    if context.is_constructing() {
      let new_target = context.new_target().unwrap_or(callee)
      let proto = self.get_prototype_from_constructor(
        new_target,
        @token.Loc::default(),
      )
      let instance = make_constructor_instance(proto, "Object")
      let prepared = self.prepare_executor_activation(
        callee,
        instance,
        args,
        executable.params,
        executable.rest_param,
        executable.closure,
        executable.strict,
        Some(new_target),
        !executable.constructable,
        executable.self_name,
        executable.define_arguments_object,
      )
      executor_construct_completion(
        self.drive_executor_activation(executable.code, prepared),
        instance,
      )
    } else {
      let prepared = self.prepare_executor_callable_call(
        executable, callee, this_value, args,
      )
      executor_call_completion(
        executable.kind,
        self.drive_executor_activation(executable.code, prepared),
      )
    }
  }
  self.in_nonarrow_param_default_eval = saved_in_default
  result
}

///|
fn make_executor_callable_with_capability(
  function_name : String,
  params : Array[String],
  closure : Environment,
  strict : Bool,
  code : &ExecutorCode,
  rest_param : String?,
  constructable : Bool,
  self_name : String?,
  define_arguments_object : Bool,
  kind : ExecutorCallableKind,
  activation_capability_summary : ExecutorActivationCapabilitySummary?,
  source_text : String?,
  needs_own_environment? : Bool = true,
) -> Value {
  let realm_state = match closure.interpreter_context {
    Some(interp) => Some(interp.realm_state)
    None => closure.realm_state
  }
  let executable : ExecutorCallableData = {
    name: function_name,
    params: params.copy(),
    closure,
    strict,
    code,
    rest_param,
    constructable,
    self_name,
    define_arguments_object,
    needs_own_environment,
    kind,
    activation_capability_summary,
    source_text,
  }
  let function = build_func_object(
    function_name,
    params.length(),
    ExecutorCallable(executable),
    realm_state~,
  )
  if constructable {
    let prototype = make_constructor_instance(
      get_obj_proto(realm_state~),
      "Object",
    )
    match function {
      Object(function_data) => {
        function_data.bag.properties["prototype"] = prototype
        function_data.bag.descriptors["prototype"] = {
          writable: true,
          enumerable: false,
          configurable: false,
          getter: None,
          setter: None,
          is_accessor: false,
        }
      }
      _ => ()
    }
    match prototype {
      Object(prototype_data) => {
        prototype_data.bag.properties["constructor"] = function
        prototype_data.bag.descriptors["constructor"] = {
          writable: true,
          enumerable: false,
          configurable: true,
          getter: None,
          setter: None,
          is_accessor: false,
        }
      }
      _ => ()
    }
  }
  function
}

///|
pub fn[T : ExecutorCode] make_executor_function(
  name : String?,
  params : Array[String],
  closure : Environment,
  strict : Bool,
  code : T,
  rest_param? : String? = None,
  constructable? : Bool = true,
  call_self_name? : Bool = false,
  define_arguments_object? : Bool = true,
) -> Value {
  let function_name = name.unwrap_or("")
  let self_name = if call_self_name { name } else { None }
  make_executor_callable_with_capability(
    function_name,
    params,
    closure,
    strict,
    code as &ExecutorCode,
    rest_param,
    constructable,
    self_name,
    define_arguments_object,
    OrdinaryExecutorCallable,
    None,
    None,
  )
}

///|
/// ExecutorCode providers are trusted to supply code corresponding to
/// `source_body`; runtime admission cannot prove otherwise.
pub fn[T : ExecutorCode] make_classified_executor_function(
  name : String?,
  params : Array[String],
  closure : Environment,
  strict : Bool,
  code : T,
  source_body : Array[@ast.Stmt],
  rest_param? : String? = None,
  constructable? : Bool = true,
  call_self_name? : Bool = false,
  define_arguments_object? : Bool = true,
) -> Value {
  let function_name = name.unwrap_or("")
  let self_name = if call_self_name { name } else { None }
  make_executor_callable_with_capability(
    function_name,
    params,
    closure,
    strict,
    code as &ExecutorCode,
    rest_param,
    constructable,
    self_name,
    define_arguments_object,
    OrdinaryExecutorCallable,
    executor_activation_capability_summary(params, source_body),
    None,
  )
}

///|
// Prepared executor providers supply an immutable capability proof. Unlike
// make_classified_executor_function, this boundary never accepts executable
// source AST; compiler-produced bytecode can therefore not regain a source
// traversal during function creation.
pub fn[T : ExecutorCode] make_prepared_executor_function(
  name : String?,
  params : Array[String],
  closure : Environment,
  strict : Bool,
  code : T,
  activation_capability_summary : ExecutorActivationCapabilitySummary?,
  source_text? : String? = None,
  rest_param? : String? = None,
  constructable? : Bool = true,
  call_self_name? : Bool = false,
  define_arguments_object? : Bool = true,
  needs_own_environment? : Bool = true,
) -> Value {
  let function_name = name.unwrap_or("")
  let self_name = if call_self_name { name } else { None }
  make_executor_callable_with_capability(
    function_name,
    params,
    closure,
    strict,
    code as &ExecutorCode,
    rest_param,
    constructable,
    self_name,
    define_arguments_object,
    OrdinaryExecutorCallable,
    activation_capability_summary,
    source_text,
    needs_own_environment~,
  )
}

///|
pub fn[T : ExecutorCode] make_executor_arrow_function(
  params : Array[String],
  closure : Environment,
  strict : Bool,
  code : T,
  rest_param? : String? = None,
) -> Value {
  make_executor_callable_with_capability(
    "",
    params,
    closure,
    strict,
    code as &ExecutorCode,
    rest_param,
    false,
    None,
    false,
    ArrowExecutorCallable,
    None,
    None,
  )
}

///|
/// ExecutorCode providers are trusted to supply code corresponding to
/// `source_body`; runtime admission cannot prove otherwise.
pub fn[T : ExecutorCode] make_classified_executor_arrow_function(
  params : Array[String],
  closure : Environment,
  strict : Bool,
  code : T,
  source_body : Array[@ast.Stmt],
  rest_param? : String? = None,
) -> Value {
  make_executor_callable_with_capability(
    "",
    params,
    closure,
    strict,
    code as &ExecutorCode,
    rest_param,
    false,
    None,
    false,
    ArrowExecutorCallable,
    executor_activation_capability_summary(params, source_body),
    None,
  )
}

///|
// Prepared arrow providers carry the immutable capability proof produced
// before execution and never accept executable source AST.
pub fn[T : ExecutorCode] make_prepared_executor_arrow_function(
  params : Array[String],
  closure : Environment,
  strict : Bool,
  code : T,
  activation_capability_summary : ExecutorActivationCapabilitySummary?,
  source_text? : String? = None,
  rest_param? : String? = None,
) -> Value {
  make_executor_callable_with_capability(
    "",
    params,
    closure,
    strict,
    code as &ExecutorCode,
    rest_param,
    false,
    None,
    false,
    ArrowExecutorCallable,
    activation_capability_summary,
    source_text,
  )
}