|
17 | 17 |
|
18 | 18 | //! Test call expression and parameter binding.
|
19 | 19 |
|
| 20 | +use std::hint; |
| 21 | + |
| 22 | +use crate as starlark; |
20 | 23 | use crate::assert;
|
21 | 24 | use crate::assert::Assert;
|
| 25 | +use crate::environment::GlobalsBuilder; |
| 26 | +use crate::values::UnpackValue; |
| 27 | +use crate::values::Value; |
22 | 28 |
|
23 | 29 | #[test]
|
24 | 30 | fn funcall_test() {
|
@@ -243,3 +249,50 @@ f(1)
|
243 | 249 | "Missing parameter `y`",
|
244 | 250 | );
|
245 | 251 | }
|
| 252 | + |
| 253 | +#[test] |
| 254 | +fn test_frame_size() { |
| 255 | + #[starlark_module] |
| 256 | + fn natives(builder: &mut GlobalsBuilder) { |
| 257 | + fn stack_ptr(args: Vec<Value>) -> anyhow::Result<usize> { |
| 258 | + drop(args); |
| 259 | + |
| 260 | + // Taking a pointer of a stack variable is UB or something, I don't know. |
| 261 | + // So pass it through `black_box` to skip compiler optimizations. |
| 262 | + let x = 1; |
| 263 | + let ptr = hint::black_box(&x); |
| 264 | + Ok(ptr as *const i32 as usize) |
| 265 | + } |
| 266 | + } |
| 267 | + |
| 268 | + let program = r#" |
| 269 | +def f(x): |
| 270 | + return stack_ptr(x) |
| 271 | +
|
| 272 | +def g(x): |
| 273 | + noop(x) |
| 274 | + return f(x) |
| 275 | +
|
| 276 | +F_PTR = f([]) |
| 277 | +G_F_PTR = g([]) |
| 278 | + "#; |
| 279 | + |
| 280 | + let mut a = Assert::new(); |
| 281 | + a.globals_add(natives); |
| 282 | + let module = a.pass_module(program); |
| 283 | + let one = usize::unpack_value(module.get("F_PTR").unwrap().value()).unwrap(); |
| 284 | + let two = usize::unpack_value(module.get("G_F_PTR").unwrap().value()).unwrap(); |
| 285 | + assert!( |
| 286 | + two < one, |
| 287 | + "stack grows down everywhere we support starlark-rust" |
| 288 | + ); |
| 289 | + // At the moment of writing it is about 1K. |
| 290 | + // Note, actual frame size may be larger a frame contains for loops. |
| 291 | + let frame_native_size = one - two; |
| 292 | + assert!(frame_native_size > 20, "sanity check"); |
| 293 | + assert!( |
| 294 | + frame_native_size < 2024, |
| 295 | + "native frame size is too large: {}, evaluation may result in native stack overflow", |
| 296 | + frame_native_size, |
| 297 | + ); |
| 298 | +} |
0 commit comments