diff --git a/third_party/move/move-binary-format/src/deserializer.rs b/third_party/move/move-binary-format/src/deserializer.rs index 1f8712f994ba6a..ba8bf00ef5b790 100644 --- a/third_party/move/move-binary-format/src/deserializer.rs +++ b/third_party/move/move-binary-format/src/deserializer.rs @@ -1650,6 +1650,16 @@ fn load_code(cursor: &mut VersionedCursor, code: &mut Vec) -> BinaryLo )), ); }, + Opcodes::PACK_CLOSURE | Opcodes::PACK_CLOSURE_GENERIC | Opcodes::CALL_CLOSURE + if cursor.version() < VERSION_8 => + { + return Err( + PartialVMError::new(StatusCode::MALFORMED).with_message(format!( + "Closure operations not available before bytecode version {}", + VERSION_8 + )), + ); + }, _ => {}, }; diff --git a/third_party/move/move-binary-format/src/file_format.rs b/third_party/move/move-binary-format/src/file_format.rs index 5cd43f451b224d..7464e12b46e637 100644 --- a/third_party/move/move-binary-format/src/file_format.rs +++ b/third_party/move/move-binary-format/src/file_format.rs @@ -3106,8 +3106,8 @@ pub enum Bytecode { #[group = "closure"] #[description = r#" - `ClosEval(|t1..tn|r has a)` evalutes a closure of the given function type, taking - the captured arguments and mixing in the provided ones on the stack. + `CallClosure(|t1..tn|r has a)` evalutes a closure of the given function type, + taking the captured arguments and mixing in the provided ones on the stack. On top of the stack is the closure being evaluated, underneath the arguments: `[c,vn,..,v1] + stack`. The type of the closure must match the type specified in @@ -3122,7 +3122,8 @@ pub enum Bytecode { The semantics of this instruction can be characterized by the following equation: ``` - CloseEval(ClosPack(f, mask, c1..cn), a1..am) = f(mask.compose(c1..cn, a1..am)) + CallClosure(PackClosure(f, mask, c1..cn), a1..am) == + f(mask.compose(c1..cn, a1..am)) ``` "#] #[static_operands = "[]"] diff --git a/third_party/move/move-binary-format/src/file_format_common.rs b/third_party/move/move-binary-format/src/file_format_common.rs index 599a49efad132c..a320a891480c3f 100644 --- a/third_party/move/move-binary-format/src/file_format_common.rs +++ b/third_party/move/move-binary-format/src/file_format_common.rs @@ -299,6 +299,7 @@ pub enum Opcodes { UNPACK_VARIANT_GENERIC = 0x55, TEST_VARIANT = 0x56, TEST_VARIANT_GENERIC = 0x57, + // Since bytecode version 8 PACK_CLOSURE = 0x58, PACK_CLOSURE_GENERIC = 0x59, CALL_CLOSURE = 0x5A, @@ -513,12 +514,12 @@ pub const VERSION_6: u32 = 6; pub const VERSION_7: u32 = 7; /// Version 8: changes compared to version 7 -/// + TBD +/// + closure instructions pub const VERSION_8: u32 = 8; /// Mark which version is the latest version. Should be set to v8 once features /// are added. -pub const VERSION_MAX: u32 = VERSION_7; +pub const VERSION_MAX: u32 = VERSION_8; /// Mark which version is the default version. This is the version used by default by tools like /// the compiler. Notice that this version might be different from the one supported on nodes. diff --git a/third_party/move/move-bytecode-verifier/src/signature_v2.rs b/third_party/move/move-bytecode-verifier/src/signature_v2.rs index 77ce9de131fa81..503f87a0cbb5a5 100644 --- a/third_party/move/move-bytecode-verifier/src/signature_v2.rs +++ b/third_party/move/move-bytecode-verifier/src/signature_v2.rs @@ -902,7 +902,7 @@ impl<'a, const N: usize> SignatureChecker<'a, N> { let sgn = self.resolver.signature_at(*idx); if sgn.len() != 1 || !matches!(&sgn.0[0], SignatureToken::Function(..)) { return map_err(Err(PartialVMError::new( - StatusCode::CLOSURE_EVAL_REQUIRES_FUNCTION, + StatusCode::CLOSURE_CALL_REQUIRES_FUNCTION, ) .with_message("expected a function type for closure call".to_string()))); } diff --git a/third_party/move/move-core/types/src/vm_status.rs b/third_party/move/move-core/types/src/vm_status.rs index 61781f736c4804..37ddf6d8ec9446 100644 --- a/third_party/move/move-core/types/src/vm_status.rs +++ b/third_party/move/move-core/types/src/vm_status.rs @@ -747,7 +747,7 @@ pub enum StatusCode { // Closure mask invalid INVALID_CLOSURE_MASK = 1132, // Closure eval type is not a function - CLOSURE_EVAL_REQUIRES_FUNCTION = 1133, + CLOSURE_CALL_REQUIRES_FUNCTION = 1133, // Reserved error code for future use RESERVED_VERIFICATION_ERROR_2 = 1134, diff --git a/third_party/move/move-model/bytecode/src/stackless_bytecode_generator.rs b/third_party/move/move-model/bytecode/src/stackless_bytecode_generator.rs index 18d59dcdf3eeac..05de57449c1dfd 100644 --- a/third_party/move/move-model/bytecode/src/stackless_bytecode_generator.rs +++ b/third_party/move/move-model/bytecode/src/stackless_bytecode_generator.rs @@ -296,6 +296,7 @@ impl<'a> StacklessBytecodeGenerator<'a> { MoveBytecode::PackClosure(..) | MoveBytecode::PackClosureGeneric(..) | MoveBytecode::CallClosure(..) => { + // TODO(#15664): implement for closures unimplemented!("stackless bytecode generation for closure opcodes") }, MoveBytecode::Pop => { diff --git a/third_party/move/move-model/src/ty.rs b/third_party/move/move-model/src/ty.rs index 6da025ea9c482e..9ab3ce35bbff7f 100644 --- a/third_party/move/move-model/src/ty.rs +++ b/third_party/move/move-model/src/ty.rs @@ -1395,7 +1395,7 @@ impl Type { ) }, SignatureToken::Function(..) => { - // TODO: implement function conversion + // TODO(#15664): implement function conversion unimplemented!("signature token to model type") }, } diff --git a/third_party/move/move-vm/runtime/src/interpreter.rs b/third_party/move/move-vm/runtime/src/interpreter.rs index 560112a45d266e..f20f3b3b0cd98e 100644 --- a/third_party/move/move-vm/runtime/src/interpreter.rs +++ b/third_party/move/move-vm/runtime/src/interpreter.rs @@ -1728,7 +1728,7 @@ impl Frame { )?; match instruction { - // TODO: implement closures + // TODO(#15664): implement closures Bytecode::PackClosure(..) | Bytecode::PackClosureGeneric(..) | Bytecode::CallClosure(..) => { diff --git a/third_party/move/move-vm/runtime/src/loader/type_loader.rs b/third_party/move/move-vm/runtime/src/loader/type_loader.rs index 1aa31dcd377ea7..7f978379681f30 100644 --- a/third_party/move/move-vm/runtime/src/loader/type_loader.rs +++ b/third_party/move/move-vm/runtime/src/loader/type_loader.rs @@ -32,7 +32,7 @@ pub fn intern_type( Type::Vector(TriompheArc::new(inner_type)) }, SignatureToken::Function(..) => { - // TODO: implement closures + // TODO(#15664): implement closures return Err(PartialVMError::new(StatusCode::UNIMPLEMENTED_FEATURE) .with_message("function types in the type loader".to_owned())); }, diff --git a/third_party/move/move-vm/runtime/src/runtime_type_checks.rs b/third_party/move/move-vm/runtime/src/runtime_type_checks.rs index 7fc950cde81497..fdb8b93bd4b2b1 100644 --- a/third_party/move/move-vm/runtime/src/runtime_type_checks.rs +++ b/third_party/move/move-vm/runtime/src/runtime_type_checks.rs @@ -120,7 +120,7 @@ impl RuntimeTypeCheck for FullRuntimeTypeCheck { instruction: &Bytecode, ) -> PartialVMResult<()> { match instruction { - // TODO: implement closures + // TODO(#15664): implement closures Bytecode::PackClosure(..) | Bytecode::PackClosureGeneric(..) | Bytecode::CallClosure(..) => { @@ -254,7 +254,7 @@ impl RuntimeTypeCheck for FullRuntimeTypeCheck { let ty_builder = resolver.loader().ty_builder(); match instruction { - // TODO: implement closures + // TODO(#15664): implement closures Bytecode::PackClosure(..) | Bytecode::PackClosureGeneric(..) | Bytecode::CallClosure(..) => { diff --git a/third_party/move/tools/move-disassembler/src/disassembler.rs b/third_party/move/tools/move-disassembler/src/disassembler.rs index eee4338aa9459e..d2a8030423905c 100644 --- a/third_party/move/tools/move-disassembler/src/disassembler.rs +++ b/third_party/move/tools/move-disassembler/src/disassembler.rs @@ -570,7 +570,7 @@ impl<'a> Disassembler<'a> { type_param_context: &[SourceName], ) -> Result { Ok(match sig_tok { - // TODO: function types + // TODO(#15664): function types SignatureToken::Function(..) => unimplemented!("disassembling function sig tokens"), SignatureToken::Bool => "bool".to_string(), @@ -647,6 +647,7 @@ impl<'a> Disassembler<'a> { Bytecode::PackClosure(..) | Bytecode::PackClosureGeneric(..) | Bytecode::CallClosure(..) => { + // TODO(#15664): implement bail!("closure opcodes not implemented") }, Bytecode::LdConst(idx) => { diff --git a/third_party/move/tools/move-resource-viewer/src/lib.rs b/third_party/move/tools/move-resource-viewer/src/lib.rs index ba6d7f3eca5151..4fb38b0ae6eab3 100644 --- a/third_party/move/tools/move-resource-viewer/src/lib.rs +++ b/third_party/move/tools/move-resource-viewer/src/lib.rs @@ -376,6 +376,7 @@ impl MoveValueAnnotator { FatType::Vector(Box::new(self.resolve_signature(module, ty, limit)?)) }, SignatureToken::Function(..) => { + // TODO(#15664): implement bail!("function types NYI by fat types") }, SignatureToken::Struct(idx) => {