haku2: on the client
resource indicators are currently unimplemented
This commit is contained in:
parent
45c954cb03
commit
e667c6336a
10 changed files with 437 additions and 364 deletions
|
@ -2,9 +2,9 @@
|
|||
|
||||
extern crate alloc;
|
||||
|
||||
use core::{alloc::Layout, slice};
|
||||
use core::{alloc::Layout, mem, slice};
|
||||
|
||||
use alloc::{boxed::Box, vec::Vec};
|
||||
use alloc::{boxed::Box, string::String, vec::Vec};
|
||||
use haku::{
|
||||
ast::Ast,
|
||||
bytecode::{Chunk, Defs, DefsImage, DefsLimits},
|
||||
|
@ -12,16 +12,13 @@ use haku::{
|
|||
diagnostic::Diagnostic,
|
||||
lexer::{lex, Lexer},
|
||||
parser::{self, IntoAstError, Parser},
|
||||
render::{
|
||||
tiny_skia::{Pixmap, PremultipliedColorU8},
|
||||
RendererLimits,
|
||||
render::tiny_skia::{
|
||||
BlendMode, Color, FillRule, LineCap, Paint, PathBuilder, Pixmap, PremultipliedColorU8,
|
||||
Rect, Shader, Stroke, Transform,
|
||||
},
|
||||
source::SourceCode,
|
||||
system::{ChunkId, System, SystemImage},
|
||||
system::{System, SystemImage},
|
||||
token::Lexis,
|
||||
trampoline::{Cont, Trampoline},
|
||||
value::{Closure, Ref, Vec2},
|
||||
vm::{Exception, Vm, VmImage, VmLimits},
|
||||
};
|
||||
use log::{debug, info};
|
||||
|
||||
|
@ -57,8 +54,7 @@ struct Limits {
|
|||
ref_capacity: usize,
|
||||
fuel: usize,
|
||||
memory: usize,
|
||||
pixmap_stack_capacity: usize,
|
||||
transform_stack_capacity: usize,
|
||||
render_max_depth: usize,
|
||||
}
|
||||
|
||||
impl Default for Limits {
|
||||
|
@ -77,8 +73,7 @@ impl Default for Limits {
|
|||
ref_capacity: 2048,
|
||||
fuel: 65536,
|
||||
memory: 1024 * 1024,
|
||||
pixmap_stack_capacity: 4,
|
||||
transform_stack_capacity: 16,
|
||||
render_max_depth: 256,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -123,8 +118,7 @@ limit_setter!(call_stack_capacity);
|
|||
limit_setter!(ref_capacity);
|
||||
limit_setter!(fuel);
|
||||
limit_setter!(memory);
|
||||
limit_setter!(pixmap_stack_capacity);
|
||||
limit_setter!(transform_stack_capacity);
|
||||
limit_setter!(render_max_depth);
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct Instance {
|
||||
|
@ -134,23 +128,23 @@ struct Instance {
|
|||
system_image: SystemImage,
|
||||
defs: Defs,
|
||||
defs_image: DefsImage,
|
||||
vm: Vm,
|
||||
vm_image: VmImage,
|
||||
|
||||
trampoline: Option<Trampoline>,
|
||||
exception: Option<Exception>,
|
||||
compile_result2: Option<CompileResult>,
|
||||
diagnostics2: Vec<Diagnostic>,
|
||||
}
|
||||
|
||||
impl Instance {
|
||||
fn set_exception(&mut self, exn: Exception) {
|
||||
debug!("setting exception = {exn:?}");
|
||||
self.exception = Some(exn);
|
||||
}
|
||||
#[derive(Debug, Clone)]
|
||||
struct CompileResult {
|
||||
defs_string: String,
|
||||
tags_string: String,
|
||||
chunk: Chunk,
|
||||
closure_spec: ClosureSpec,
|
||||
stats: CompileStats,
|
||||
}
|
||||
|
||||
fn reset_exception(&mut self) {
|
||||
debug!("resetting exception");
|
||||
self.exception = None;
|
||||
}
|
||||
#[derive(Debug, Clone)]
|
||||
struct CompileStats {
|
||||
ast_size: usize,
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
|
@ -164,20 +158,9 @@ unsafe extern "C" fn haku_instance_new(limits: *const Limits) -> *mut Instance {
|
|||
max_defs: limits.max_defs,
|
||||
max_tags: limits.max_tags,
|
||||
});
|
||||
let vm = Vm::new(
|
||||
&defs,
|
||||
&VmLimits {
|
||||
stack_capacity: limits.stack_capacity,
|
||||
call_stack_capacity: limits.call_stack_capacity,
|
||||
ref_capacity: limits.ref_capacity,
|
||||
fuel: limits.fuel,
|
||||
memory: limits.memory,
|
||||
},
|
||||
);
|
||||
|
||||
let system_image = system.image();
|
||||
let defs_image = defs.image();
|
||||
let vm_image = vm.image();
|
||||
|
||||
let instance = Box::new(Instance {
|
||||
limits,
|
||||
|
@ -185,10 +168,8 @@ unsafe extern "C" fn haku_instance_new(limits: *const Limits) -> *mut Instance {
|
|||
system_image,
|
||||
defs,
|
||||
defs_image,
|
||||
vm,
|
||||
vm_image,
|
||||
trampoline: None,
|
||||
exception: None,
|
||||
compile_result2: None,
|
||||
diagnostics2: Vec::new(),
|
||||
});
|
||||
|
||||
let ptr = Box::leak(instance) as *mut _;
|
||||
|
@ -210,21 +191,6 @@ unsafe extern "C" fn haku_reset(instance: *mut Instance) {
|
|||
instance.defs.restore_image(&instance.defs_image);
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn haku_has_exception(instance: *mut Instance) -> bool {
|
||||
(*instance).exception.is_some()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn haku_exception_message(instance: *const Instance) -> *const u8 {
|
||||
(*instance).exception.as_ref().unwrap().message.as_ptr()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn haku_exception_message_len(instance: *const Instance) -> u32 {
|
||||
(*instance).exception.as_ref().unwrap().message.len() as u32
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[repr(C)]
|
||||
enum StatusCode {
|
||||
|
@ -236,10 +202,6 @@ enum StatusCode {
|
|||
ParserUnbalancedEvents,
|
||||
ChunkTooBig,
|
||||
DiagnosticsEmitted,
|
||||
TooManyChunks,
|
||||
OutOfRefSlots,
|
||||
EvalException,
|
||||
RenderException,
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
|
@ -252,14 +214,6 @@ extern "C" fn haku_is_diagnostics_emitted(code: StatusCode) -> bool {
|
|||
code == StatusCode::DiagnosticsEmitted
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
extern "C" fn haku_is_exception(code: StatusCode) -> bool {
|
||||
matches!(
|
||||
code,
|
||||
StatusCode::EvalException | StatusCode::RenderException
|
||||
)
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
extern "C" fn haku_status_string(code: StatusCode) -> *const i8 {
|
||||
match code {
|
||||
|
@ -271,91 +225,162 @@ extern "C" fn haku_status_string(code: StatusCode) -> *const i8 {
|
|||
StatusCode::ParserUnbalancedEvents => c"parser produced unbalanced events",
|
||||
StatusCode::ChunkTooBig => c"compiled bytecode is too large",
|
||||
StatusCode::DiagnosticsEmitted => c"diagnostics were emitted",
|
||||
StatusCode::TooManyChunks => c"too many registered bytecode chunks",
|
||||
StatusCode::OutOfRefSlots => c"out of ref slots (did you forget to restore the VM image?)",
|
||||
StatusCode::EvalException => c"an exception occurred while evaluating your code",
|
||||
StatusCode::RenderException => c"an exception occurred while rendering your brush",
|
||||
}
|
||||
.as_ptr()
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct CompileStats {
|
||||
ast_size: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct RunnableBrush {
|
||||
chunk_id: ChunkId,
|
||||
closure_spec: ClosureSpec,
|
||||
|
||||
compile_stats: CompileStats,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
enum BrushState {
|
||||
#[default]
|
||||
Default,
|
||||
Ready(RunnableBrush),
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
struct Brush {
|
||||
diagnostics: Vec<Diagnostic>,
|
||||
state: BrushState,
|
||||
struct PixmapCanvas {
|
||||
pixmap: Pixmap,
|
||||
pb: PathBuilder,
|
||||
transform: Transform,
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
extern "C" fn haku_brush_new() -> *mut Brush {
|
||||
let ptr = Box::leak(Box::new(Brush::default())) as *mut _;
|
||||
debug!("created brush: {ptr:?}");
|
||||
extern "C" fn haku_pixmap_new(width: u32, height: u32) -> *mut PixmapCanvas {
|
||||
let ptr = Box::leak(Box::new(PixmapCanvas {
|
||||
pixmap: Pixmap::new(width, height).expect("invalid pixmap size"),
|
||||
pb: PathBuilder::new(),
|
||||
transform: Transform::identity(),
|
||||
})) as *mut _;
|
||||
debug!("created pixmap with size {width}x{height}: {ptr:?}");
|
||||
ptr
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn haku_brush_destroy(brush: *mut Brush) {
|
||||
debug!("destroying brush: {brush:?}");
|
||||
drop(Box::from_raw(brush))
|
||||
unsafe extern "C" fn haku_pixmap_destroy(c: *mut PixmapCanvas) {
|
||||
debug!("destroying pixmap: {c:?}");
|
||||
drop(Box::from_raw(c))
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn haku_num_diagnostics(brush: *const Brush) -> u32 {
|
||||
(*brush).diagnostics.len() as u32
|
||||
unsafe extern "C" fn haku_pixmap_data(c: *mut PixmapCanvas) -> *mut u8 {
|
||||
let c = &mut *c;
|
||||
c.pixmap.pixels_mut().as_mut_ptr() as *mut u8
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn haku_diagnostic_start(brush: *const Brush, index: u32) -> u32 {
|
||||
(*brush).diagnostics[index as usize].span().start
|
||||
unsafe extern "C" fn haku_pixmap_clear(c: *mut PixmapCanvas) {
|
||||
let c = &mut *c;
|
||||
c.pixmap
|
||||
.pixels_mut()
|
||||
.fill(PremultipliedColorU8::TRANSPARENT);
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn haku_diagnostic_end(brush: *const Brush, index: u32) -> u32 {
|
||||
(*brush).diagnostics[index as usize].span().end
|
||||
unsafe extern "C" fn haku_pixmap_set_translation(c: *mut PixmapCanvas, x: f32, y: f32) {
|
||||
let c = &mut *c;
|
||||
c.transform = Transform::from_translate(x, y);
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn haku_diagnostic_message(brush: *const Brush, index: u32) -> *const u8 {
|
||||
(*brush).diagnostics[index as usize].message().as_ptr()
|
||||
unsafe extern "C" fn haku_pixmap_begin(c: *mut PixmapCanvas) -> bool {
|
||||
let c = &mut *c;
|
||||
c.pb.clear();
|
||||
true
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn haku_diagnostic_message_len(brush: *const Brush, index: u32) -> u32 {
|
||||
(*brush).diagnostics[index as usize].message().len() as u32
|
||||
unsafe extern "C" fn haku_pixmap_line(
|
||||
c: *mut PixmapCanvas,
|
||||
x1: f32,
|
||||
y1: f32,
|
||||
x2: f32,
|
||||
y2: f32,
|
||||
) -> bool {
|
||||
let c = &mut *c;
|
||||
c.pb.move_to(x1, y1);
|
||||
c.pb.line_to(x2, y2);
|
||||
true
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn haku_compile_brush(
|
||||
unsafe extern "C" fn haku_pixmap_rectangle(
|
||||
c: *mut PixmapCanvas,
|
||||
x: f32,
|
||||
y: f32,
|
||||
width: f32,
|
||||
height: f32,
|
||||
) -> bool {
|
||||
let c = &mut *c;
|
||||
if let Some(rect) = Rect::from_xywh(x, y, width, height) {
|
||||
c.pb.push_rect(rect);
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn haku_pixmap_circle(c: *mut PixmapCanvas, x: f32, y: f32, r: f32) -> bool {
|
||||
let c = &mut *c;
|
||||
c.pb.push_circle(x, y, r);
|
||||
true
|
||||
}
|
||||
|
||||
fn default_paint() -> Paint<'static> {
|
||||
Paint {
|
||||
shader: Shader::SolidColor(Color::BLACK),
|
||||
blend_mode: BlendMode::SourceOver,
|
||||
anti_alias: false,
|
||||
force_hq_pipeline: false,
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn haku_pixmap_fill(c: *mut PixmapCanvas, r: u8, g: u8, b: u8, a: u8) -> bool {
|
||||
let c = &mut *c;
|
||||
let pb = mem::take(&mut c.pb);
|
||||
if let Some(path) = pb.finish() {
|
||||
let paint = Paint {
|
||||
shader: Shader::SolidColor(Color::from_rgba8(r, g, b, a)),
|
||||
..default_paint()
|
||||
};
|
||||
c.pixmap
|
||||
.fill_path(&path, &paint, FillRule::EvenOdd, c.transform, None);
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn haku_pixmap_stroke(
|
||||
c: *mut PixmapCanvas,
|
||||
r: u8,
|
||||
g: u8,
|
||||
b: u8,
|
||||
a: u8,
|
||||
thickness: f32,
|
||||
) -> bool {
|
||||
let c = &mut *c;
|
||||
let pb = mem::take(&mut c.pb);
|
||||
if let Some(path) = pb.finish() {
|
||||
let paint = Paint {
|
||||
shader: Shader::SolidColor(Color::from_rgba8(r, g, b, a)),
|
||||
..default_paint()
|
||||
};
|
||||
c.pixmap.stroke_path(
|
||||
&path,
|
||||
&paint,
|
||||
&Stroke {
|
||||
width: thickness,
|
||||
line_cap: LineCap::Round,
|
||||
..Default::default()
|
||||
},
|
||||
c.transform,
|
||||
None,
|
||||
);
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
// v2 compile-only support
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn haku_compile_brush2(
|
||||
instance: *mut Instance,
|
||||
out_brush: *mut Brush,
|
||||
code_len: u32,
|
||||
code: *const u8,
|
||||
) -> StatusCode {
|
||||
info!("compiling brush");
|
||||
info!("compiling brush (2)");
|
||||
|
||||
let instance = &mut *instance;
|
||||
let brush = &mut *out_brush;
|
||||
|
||||
*brush = Brush::default();
|
||||
|
||||
let code = core::str::from_utf8(slice::from_raw_parts(code, code_len as usize))
|
||||
.expect("invalid UTF-8");
|
||||
|
@ -428,8 +453,8 @@ unsafe extern "C" fn haku_compile_brush(
|
|||
let mut diagnostics = lexer.diagnostics;
|
||||
diagnostics.append(&mut parser_diagnostics);
|
||||
diagnostics.append(&mut compiler.diagnostics);
|
||||
if !diagnostics.is_empty() {
|
||||
brush.diagnostics = diagnostics;
|
||||
instance.diagnostics2 = diagnostics;
|
||||
if !instance.diagnostics2.is_empty() {
|
||||
debug!("compiling failed: diagnostics were emitted");
|
||||
return StatusCode::DiagnosticsEmitted;
|
||||
}
|
||||
|
@ -440,179 +465,82 @@ unsafe extern "C" fn haku_compile_brush(
|
|||
);
|
||||
debug!("compiling: {closure_spec:?}");
|
||||
|
||||
let chunk_id = match instance.system.add_chunk(chunk) {
|
||||
Ok(chunk_id) => chunk_id,
|
||||
Err(_) => return StatusCode::TooManyChunks,
|
||||
};
|
||||
brush.state = BrushState::Ready(RunnableBrush {
|
||||
chunk_id,
|
||||
instance.compile_result2 = Some(CompileResult {
|
||||
defs_string: instance.defs.serialize_defs(),
|
||||
tags_string: instance.defs.serialize_tags(),
|
||||
chunk,
|
||||
closure_spec,
|
||||
compile_stats: CompileStats {
|
||||
stats: CompileStats {
|
||||
ast_size: ast.len(),
|
||||
},
|
||||
});
|
||||
|
||||
info!("brush compiled into {chunk_id:?}");
|
||||
info!("brush code compiled into instance");
|
||||
|
||||
StatusCode::Ok
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
extern "C" fn haku_pixmap_new(width: u32, height: u32) -> *mut Pixmap {
|
||||
let ptr = Box::leak(Box::new(
|
||||
Pixmap::new(width, height).expect("invalid pixmap size"),
|
||||
)) as *mut _;
|
||||
debug!("created pixmap with size {width}x{height}: {ptr:?}");
|
||||
ptr
|
||||
unsafe fn compile_result<'a>(instance: *const Instance) -> &'a CompileResult {
|
||||
let cr = (*instance).compile_result2.as_ref().unwrap();
|
||||
cr
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn haku_pixmap_destroy(pixmap: *mut Pixmap) {
|
||||
debug!("destroying pixmap: {pixmap:?}");
|
||||
drop(Box::from_raw(pixmap))
|
||||
unsafe extern "C" fn haku_num_diagnostics2(instance: *const Instance) -> u32 {
|
||||
(*instance).diagnostics2.len() as u32
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn haku_pixmap_data(pixmap: *mut Pixmap) -> *mut u8 {
|
||||
let pixmap = &mut *pixmap;
|
||||
pixmap.pixels_mut().as_mut_ptr() as *mut u8
|
||||
unsafe extern "C" fn haku_diagnostic_start2(instance: *const Instance, index: u32) -> u32 {
|
||||
(*instance).diagnostics2[index as usize].span().start
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn haku_pixmap_clear(pixmap: *mut Pixmap) {
|
||||
let pixmap = &mut *pixmap;
|
||||
pixmap.pixels_mut().fill(PremultipliedColorU8::TRANSPARENT);
|
||||
unsafe extern "C" fn haku_diagnostic_end2(instance: *const Instance, index: u32) -> u32 {
|
||||
(*instance).diagnostics2[index as usize].span().end
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn haku_begin_brush(instance: *mut Instance, brush: *const Brush) -> StatusCode {
|
||||
let instance = &mut *instance;
|
||||
let brush = &*brush;
|
||||
|
||||
let BrushState::Ready(runnable) = &brush.state else {
|
||||
panic!("brush is not compiled and ready to be used");
|
||||
};
|
||||
|
||||
instance.vm.restore_image(&instance.vm_image);
|
||||
instance.vm.apply_defs(&instance.defs);
|
||||
instance.reset_exception();
|
||||
instance.trampoline = None;
|
||||
|
||||
let Ok(closure_id) = instance.vm.create_ref(Ref::Closure(Closure::chunk(
|
||||
runnable.chunk_id,
|
||||
runnable.closure_spec,
|
||||
))) else {
|
||||
return StatusCode::OutOfRefSlots;
|
||||
};
|
||||
|
||||
instance.reset_exception();
|
||||
let value = match instance.vm.run(&instance.system, closure_id, &[]) {
|
||||
Ok(value) => value,
|
||||
Err(exn) => {
|
||||
instance.set_exception(exn);
|
||||
return StatusCode::EvalException;
|
||||
}
|
||||
};
|
||||
instance.trampoline = Some(Trampoline::new(value));
|
||||
|
||||
StatusCode::Ok
|
||||
unsafe extern "C" fn haku_diagnostic_message2(instance: *const Instance, index: u32) -> *const u8 {
|
||||
(*instance).diagnostics2[index as usize].message().as_ptr()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn haku_cont_kind(instance: *mut Instance) -> Cont {
|
||||
let instance = &mut *instance;
|
||||
instance.trampoline.as_ref().unwrap().cont(&instance.vm)
|
||||
}
|
||||
|
||||
fn wrap_exception(
|
||||
instance: &mut Instance,
|
||||
error_code: StatusCode,
|
||||
f: impl FnOnce(&mut Instance) -> Result<(), Exception>,
|
||||
) -> StatusCode {
|
||||
match f(instance) {
|
||||
Ok(_) => StatusCode::Ok,
|
||||
Err(exn) => {
|
||||
instance.set_exception(exn);
|
||||
error_code
|
||||
}
|
||||
}
|
||||
unsafe extern "C" fn haku_diagnostic_message_len2(instance: *const Instance, index: u32) -> u32 {
|
||||
(*instance).diagnostics2[index as usize].message().len() as u32
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn haku_cont_scribble(
|
||||
instance: *mut Instance,
|
||||
pixmap: *mut Pixmap,
|
||||
translation_x: f32,
|
||||
translation_y: f32,
|
||||
) -> StatusCode {
|
||||
let instance = &mut *instance;
|
||||
instance.reset_exception();
|
||||
|
||||
debug!("cont_scribble: pixmap={pixmap:?} translation_x={translation_x:?} translation_y={translation_y:?} trampoline={:?}", instance.trampoline);
|
||||
|
||||
wrap_exception(instance, StatusCode::RenderException, |instance| {
|
||||
instance.trampoline.as_mut().unwrap().scribble(
|
||||
&instance.vm,
|
||||
&mut *pixmap,
|
||||
Vec2 {
|
||||
x: translation_x,
|
||||
y: translation_y,
|
||||
},
|
||||
&RendererLimits {
|
||||
pixmap_stack_capacity: instance.limits.pixmap_stack_capacity,
|
||||
transform_stack_capacity: instance.limits.transform_stack_capacity,
|
||||
},
|
||||
)
|
||||
})
|
||||
unsafe extern "C" fn haku_defs_len2(instance: *const Instance) -> usize {
|
||||
compile_result(instance).defs_string.len()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn haku_cont_dotter(
|
||||
instance: *mut Instance,
|
||||
from_x: f32,
|
||||
from_y: f32,
|
||||
to_x: f32,
|
||||
to_y: f32,
|
||||
num: f32,
|
||||
) -> StatusCode {
|
||||
let instance = &mut *instance;
|
||||
instance.reset_exception();
|
||||
|
||||
debug!(
|
||||
"cont_dotter: from_x={from_x} from_y={from_y} to_x={to_x} to_y={to_y} trampoline={:?}",
|
||||
instance.trampoline
|
||||
);
|
||||
|
||||
wrap_exception(instance, StatusCode::RenderException, |instance| {
|
||||
instance.trampoline.as_mut().unwrap().dotter(
|
||||
&mut instance.vm,
|
||||
&instance.system,
|
||||
Vec2::new(from_x, from_y),
|
||||
Vec2::new(to_x, to_y),
|
||||
num,
|
||||
)
|
||||
})
|
||||
unsafe extern "C" fn haku_defs2(instance: *const Instance) -> *const u8 {
|
||||
compile_result(instance).defs_string.as_ptr()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn haku_stat_ast_size(brush: *const Brush) -> usize {
|
||||
match &(*brush).state {
|
||||
BrushState::Default => 0,
|
||||
BrushState::Ready(runnable) => runnable.compile_stats.ast_size,
|
||||
}
|
||||
unsafe extern "C" fn haku_tags_len2(instance: *const Instance) -> usize {
|
||||
compile_result(instance).tags_string.len()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn haku_stat_num_refs(instance: *const Instance) -> usize {
|
||||
(*instance).vm.num_refs()
|
||||
unsafe extern "C" fn haku_tags2(instance: *const Instance) -> *const u8 {
|
||||
compile_result(instance).tags_string.as_ptr()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn haku_stat_remaining_fuel(instance: *const Instance) -> usize {
|
||||
(*instance).vm.remaining_fuel()
|
||||
unsafe extern "C" fn haku_bytecode_len2(instance: *const Instance) -> usize {
|
||||
compile_result(instance).chunk.bytecode.len()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn haku_stat_remaining_memory(instance: *const Instance) -> usize {
|
||||
(*instance).vm.remaining_memory()
|
||||
unsafe extern "C" fn haku_bytecode2(instance: *const Instance) -> *const u8 {
|
||||
compile_result(instance).chunk.bytecode.as_ptr()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn haku_local_count2(instance: *const Instance) -> u8 {
|
||||
compile_result(instance).closure_spec.local_count
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue