1#[cfg(feature = "jvm")]
2mod env;
3
4#[cfg(feature = "jvm")]
5mod error;
6
7#[cfg(feature = "jvm")]
8mod exec;
9
10#[cfg(feature = "jvm")]
11mod jvm;
12
13mod modules;
14
15#[cfg(feature = "jvm")]
16mod node;
17
18#[cfg(feature = "jvm")]
19mod runtime;
20
21#[cfg(all(test, feature = "jvm"))]
22mod tests;
23
24#[cfg(feature = "jvm")]
25mod vm;
26
27pub use modules::v0;
28pub use modules::v1;
29
30#[cfg(feature = "jvm")]
31use crate::{error::JvmError, exec::Executable, vm::Vm};
32#[cfg(feature = "jvm")]
33use base58::ToBase58;
34#[cfg(feature = "jvm")]
35use jni::{
36 objects::{JByteArray, JClass, JObject, JString},
37 sys::{jint, jlong},
38 JNIEnv,
39};
40#[cfg(feature = "jvm")]
41use log::{debug, error};
42#[cfg(feature = "jvm")]
43use wasmi::Value;
44
45pub const MEMORY: (u32, u32) = (2, 16);
47
48#[cfg(feature = "jvm")]
62#[no_mangle]
63pub extern "system" fn Java_com_wavesenterprise_wasm_core_WASMExecutor_runContract<'local>(
64 mut env: JNIEnv<'local>,
65 _class: JClass<'local>,
66 contract_id: JByteArray<'local>,
67 bytecode: JByteArray<'local>,
68 func_name: JString<'local>,
69 params: JByteArray<'local>,
70 fuel_limit: jlong,
71 callback: JObject<'local>,
72) -> jint {
73 let _ = env_logger::try_init();
74 let contract_id = match env.convert_byte_array(contract_id) {
75 Ok(bytes) => bytes,
76 Err(_) => {
77 error!("{}", JvmError::ByteArrayConversion);
78 return JvmError::ByteArrayConversion.as_jint();
79 }
80 };
81
82 debug!(
83 "Started WEVM to execute the contract: {}",
84 contract_id.clone().to_base58()
85 );
86
87 let bytecode = match env.convert_byte_array(bytecode) {
88 Ok(bytes) => bytes,
89 Err(_) => {
90 error!("{}", JvmError::ByteArrayConversion);
91 return JvmError::ByteArrayConversion.as_jint();
92 }
93 };
94
95 let jvm = match env.get_java_vm() {
96 Ok(jvm) => jvm,
97 Err(_) => {
98 error!("{}", JvmError::GetJavaVM);
99 return JvmError::GetJavaVM.as_jint();
100 }
101 };
102
103 let callback = match env.new_global_ref(callback) {
104 Ok(callback) => callback,
105 Err(_) => {
106 error!("{}", JvmError::NewGlobalRef);
107 return JvmError::NewGlobalRef.as_jint();
108 }
109 };
110
111 let mut vm = match Vm::new(
112 contract_id,
113 bytecode,
114 MEMORY,
115 fuel_limit as u64,
116 modules(),
117 Some(jvm),
118 Some(callback),
119 ) {
120 Ok(vm) => vm,
121 Err(error) => {
122 error!("{}", error);
123 return error.as_jint();
124 }
125 };
126
127 let func_name: String = match env.get_string(&func_name) {
128 Ok(string) => string.into(),
129 Err(_) => {
130 error!("{}", JvmError::NewString);
131 return JvmError::NewString.as_jint();
132 }
133 };
134
135 let params = match env.convert_byte_array(params) {
136 Ok(bytes) => bytes,
137 Err(_) => {
138 error!("{}", JvmError::ByteArrayConversion);
139 return JvmError::ByteArrayConversion.as_jint();
140 }
141 };
142
143 let result = match vm.run(&func_name, ¶ms) {
144 Ok(result) => result,
145 Err(error) => {
146 error!("{}", error);
147 return error.as_jint();
148 }
149 };
150
151 match result[0] {
152 Value::I32(value) => value as jint,
153 _ => 0 as jint,
154 }
155}
156
157#[cfg(feature = "jvm")]
159#[no_mangle]
160pub extern "system" fn Java_com_wavesenterprise_wasm_core_WASMExecutor_validateBytecode<'local>(
161 env: JNIEnv<'local>,
162 _class: JClass<'local>,
163 bytecode: JByteArray<'local>,
164) -> jint {
165 let bytecode = match env.convert_byte_array(bytecode) {
166 Ok(bytes) => bytes,
167 Err(_) => {
168 error!("{}", JvmError::ByteArrayConversion);
169 return JvmError::ByteArrayConversion.as_jint();
170 }
171 };
172
173 match Executable::validate_bytecode(&bytecode) {
174 Ok(_) => 0,
175 Err(error) => {
176 error!("{}", error);
177 error.as_jint()
178 }
179 }
180}
181
182#[cfg(feature = "jvm")]
183fn modules() -> Vec<modules::Module> {
184 let mut vec = vec![];
185 vec.extend(v0::modules::modules());
186 vec.extend(v1::modules::modules());
187 vec
188}