Roughly speaking, '?' means that the operation might throw an exception, which should be propagated if thrown, and '!' means that the operation should never fail. (In Rust terms, '? ToObject(this value)" -> "ToObject(thisValue)?", and "! ToObject(this value)" -> "ToObject(thisValue).unwrap()".)
See: https://tc39.es/ecma262/multipage/notational-conventions.htm...