Skip to content

Commit 48305e0

Browse files
committed
Add hover/context APIs to wasm component
1 parent 2eafbb2 commit 48305e0

File tree

2 files changed

+191
-22
lines changed

2 files changed

+191
-22
lines changed

objdiff-wasm/src/api.rs

+149-8
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,11 @@ use exports::objdiff::core::{
2525
GuestObjectDiff, Object, ObjectBorrow, ObjectDiff, ObjectDiffBorrow,
2626
},
2727
display::{
28-
ContextMenuItem, DiffText, DiffTextColor, DiffTextOpcode, DiffTextSegment, DiffTextSymbol,
29-
DisplayConfig, Guest as GuestDisplay, HoverItem, InstructionDiffKind, InstructionDiffRow,
30-
SectionDisplay, SectionDisplaySymbol, SymbolDisplay, SymbolFilter, SymbolFlags, SymbolKind,
31-
SymbolRef,
28+
ContextItem, ContextItemCopy, ContextItemNavigate, DiffText, DiffTextColor, DiffTextOpcode,
29+
DiffTextSegment, DiffTextSymbol, DisplayConfig, Guest as GuestDisplay, HoverItem,
30+
HoverItemColor, HoverItemText, InstructionDiffKind, InstructionDiffRow, SectionDisplay,
31+
SectionDisplaySymbol, SymbolDisplay, SymbolFilter, SymbolFlags, SymbolKind,
32+
SymbolNavigationKind, SymbolRef,
3233
},
3334
};
3435

@@ -86,10 +87,6 @@ impl GuestDiff for Component {
8687
}
8788

8889
impl GuestDisplay for Component {
89-
fn symbol_context(_obj: ObjectBorrow, _symbol: SymbolRef) -> Vec<ContextMenuItem> { todo!() }
90-
91-
fn symbol_hover(_obj: ObjectBorrow, _symbol: SymbolRef) -> Vec<HoverItem> { todo!() }
92-
9390
fn display_sections(
9491
diff: ObjectDiffBorrow,
9592
filter: SymbolFilter,
@@ -202,6 +199,102 @@ impl GuestDisplay for Component {
202199
.unwrap();
203200
InstructionDiffRow { segments, diff_kind: InstructionDiffKind::from(row.kind) }
204201
}
202+
203+
fn symbol_context(
204+
diff: ObjectDiffBorrow,
205+
symbol_display: SectionDisplaySymbol,
206+
) -> Vec<ContextItem> {
207+
let obj_diff = diff.get::<ResourceObjectDiff>();
208+
let obj = obj_diff.0.as_ref();
209+
diff::display::symbol_context(obj, symbol_display.symbol as usize)
210+
.into_iter()
211+
.map(|item| ContextItem::from(item))
212+
.collect()
213+
}
214+
215+
fn symbol_hover(
216+
diff: ObjectDiffBorrow,
217+
symbol_display: SectionDisplaySymbol,
218+
) -> Vec<HoverItem> {
219+
let obj_diff = diff.get::<ResourceObjectDiff>();
220+
let obj = obj_diff.0.as_ref();
221+
diff::display::symbol_hover(obj, symbol_display.symbol as usize, 0 /* TODO */)
222+
.into_iter()
223+
.map(|item| HoverItem::from(item))
224+
.collect()
225+
}
226+
227+
fn instruction_context(
228+
diff: ObjectDiffBorrow,
229+
symbol_display: SectionDisplaySymbol,
230+
row_index: u32,
231+
diff_config: DiffConfigBorrow,
232+
) -> Result<Vec<ContextItem>, String> {
233+
let obj_diff = diff.get::<ResourceObjectDiff>();
234+
let obj = obj_diff.0.as_ref();
235+
let obj_diff = &obj_diff.1;
236+
let symbol_idx = symbol_display.symbol as usize;
237+
let symbol_diff = if symbol_display.is_mapping_symbol {
238+
obj_diff
239+
.mapping_symbols
240+
.iter()
241+
.find(|s| s.symbol_index == symbol_idx)
242+
.map(|s| &s.symbol_diff)
243+
.unwrap()
244+
} else {
245+
&obj_diff.symbols[symbol_idx]
246+
};
247+
let row = &symbol_diff.instruction_rows[row_index as usize];
248+
let Some(ins_ref) = row.ins_ref else {
249+
return Ok(Vec::new());
250+
};
251+
let diff_config = diff_config.get::<ResourceDiffConfig>().0.borrow();
252+
let Some(resolved) = obj.resolve_instruction_ref(symbol_idx, ins_ref) else {
253+
return Err("Failed to resolve instruction".into());
254+
};
255+
let ins =
256+
obj.arch.process_instruction(resolved, &diff_config).map_err(|e| e.to_string())?;
257+
Ok(diff::display::instruction_context(obj, resolved, &ins)
258+
.into_iter()
259+
.map(|item| ContextItem::from(item))
260+
.collect())
261+
}
262+
263+
fn instruction_hover(
264+
diff: ObjectDiffBorrow,
265+
symbol_display: SectionDisplaySymbol,
266+
row_index: u32,
267+
diff_config: DiffConfigBorrow,
268+
) -> Result<Vec<HoverItem>, String> {
269+
let obj_diff = diff.get::<ResourceObjectDiff>();
270+
let obj = obj_diff.0.as_ref();
271+
let obj_diff = &obj_diff.1;
272+
let symbol_idx = symbol_display.symbol as usize;
273+
let symbol_diff = if symbol_display.is_mapping_symbol {
274+
obj_diff
275+
.mapping_symbols
276+
.iter()
277+
.find(|s| s.symbol_index == symbol_idx)
278+
.map(|s| &s.symbol_diff)
279+
.unwrap()
280+
} else {
281+
&obj_diff.symbols[symbol_idx]
282+
};
283+
let row = &symbol_diff.instruction_rows[row_index as usize];
284+
let Some(ins_ref) = row.ins_ref else {
285+
return Ok(Vec::new());
286+
};
287+
let diff_config = diff_config.get::<ResourceDiffConfig>().0.borrow();
288+
let Some(resolved) = obj.resolve_instruction_ref(symbol_idx, ins_ref) else {
289+
return Err("Failed to resolve instruction".into());
290+
};
291+
let ins =
292+
obj.arch.process_instruction(resolved, &diff_config).map_err(|e| e.to_string())?;
293+
Ok(diff::display::instruction_hover(obj, resolved, &ins)
294+
.into_iter()
295+
.map(|item| HoverItem::from(item))
296+
.collect())
297+
}
205298
}
206299

207300
impl From<obj::SymbolKind> for SymbolKind {
@@ -342,4 +435,52 @@ impl GuestObjectDiff for ResourceObjectDiff {
342435
}
343436
}
344437

438+
impl From<diff::display::HoverItem> for HoverItem {
439+
fn from(item: diff::display::HoverItem) -> Self {
440+
match item {
441+
diff::display::HoverItem::Text { label, value, color } => {
442+
HoverItem::Text(HoverItemText { label, value, color: HoverItemColor::from(color) })
443+
}
444+
diff::display::HoverItem::Separator => HoverItem::Separator,
445+
}
446+
}
447+
}
448+
449+
impl From<diff::display::HoverItemColor> for HoverItemColor {
450+
fn from(color: diff::display::HoverItemColor) -> Self {
451+
match color {
452+
diff::display::HoverItemColor::Normal => HoverItemColor::Normal,
453+
diff::display::HoverItemColor::Emphasized => HoverItemColor::Emphasized,
454+
diff::display::HoverItemColor::Special => HoverItemColor::Special,
455+
}
456+
}
457+
}
458+
459+
impl From<diff::display::ContextItem> for ContextItem {
460+
fn from(item: diff::display::ContextItem) -> Self {
461+
match item {
462+
diff::display::ContextItem::Copy { value, label } => {
463+
ContextItem::Copy(ContextItemCopy { value, label })
464+
}
465+
diff::display::ContextItem::Navigate { label, symbol_index, kind } => {
466+
ContextItem::Navigate(ContextItemNavigate {
467+
label,
468+
symbol: symbol_index as SymbolRef,
469+
kind: SymbolNavigationKind::from(kind),
470+
})
471+
}
472+
diff::display::ContextItem::Separator => ContextItem::Separator,
473+
}
474+
}
475+
}
476+
477+
impl From<diff::display::SymbolNavigationKind> for SymbolNavigationKind {
478+
fn from(kind: diff::display::SymbolNavigationKind) -> Self {
479+
match kind {
480+
diff::display::SymbolNavigationKind::Normal => SymbolNavigationKind::Normal,
481+
diff::display::SymbolNavigationKind::Extab => SymbolNavigationKind::Extab,
482+
}
483+
}
484+
}
485+
345486
export!(Component);

objdiff-wasm/wit/objdiff.wit

+42-14
Original file line numberDiff line numberDiff line change
@@ -108,18 +108,26 @@ interface display {
108108
row-count: u32,
109109
}
110110

111-
record context-menu-item-copy {
111+
enum symbol-navigation-kind {
112+
normal,
113+
extab,
114+
}
115+
116+
record context-item-copy {
112117
value: string,
113118
label: option<string>,
114119
}
115120

116-
record context-menu-item-navigate {
121+
record context-item-navigate {
117122
label: string,
123+
symbol: symbol-ref,
124+
kind: symbol-navigation-kind,
118125
}
119126

120-
variant context-menu-item {
121-
copy(context-menu-item-copy),
122-
navigate(context-menu-item-navigate),
127+
variant context-item {
128+
copy(context-item-copy),
129+
navigate(context-item-navigate),
130+
separator,
123131
}
124132

125133
enum hover-item-color {
@@ -128,11 +136,17 @@ interface display {
128136
special,
129137
}
130138

131-
record hover-item {
132-
text: string,
139+
record hover-item-text {
140+
label: string,
141+
value: string,
133142
color: hover-item-color,
134143
}
135144

145+
variant hover-item {
146+
text(hover-item-text),
147+
separator,
148+
}
149+
136150
record diff-text-opcode {
137151
mnemonic: string,
138152
opcode: u16,
@@ -216,22 +230,36 @@ interface display {
216230
symbol: section-display-symbol,
217231
) -> symbol-display;
218232

233+
display-instruction-row: func(
234+
diff: borrow<object-diff>,
235+
symbol: section-display-symbol,
236+
row-index: u32,
237+
config: borrow<diff-config>,
238+
) -> instruction-diff-row;
239+
219240
symbol-context: func(
220-
object: borrow<object>,
221-
symbol: symbol-ref,
222-
) -> list<context-menu-item>;
241+
diff: borrow<object-diff>,
242+
symbol: section-display-symbol,
243+
) -> list<context-item>;
223244

224245
symbol-hover: func(
225-
object: borrow<object>,
226-
symbol: symbol-ref,
246+
diff: borrow<object-diff>,
247+
symbol: section-display-symbol,
227248
) -> list<hover-item>;
228249

229-
display-instruction-row: func(
250+
instruction-context: func(
230251
diff: borrow<object-diff>,
231252
symbol: section-display-symbol,
232253
row-index: u32,
233254
config: borrow<diff-config>,
234-
) -> instruction-diff-row;
255+
) -> result<list<context-item>, string>;
256+
257+
instruction-hover: func(
258+
diff: borrow<object-diff>,
259+
symbol: section-display-symbol,
260+
row-index: u32,
261+
config: borrow<diff-config>,
262+
) -> result<list<hover-item>, string>;
235263
}
236264

237265
world api {

0 commit comments

Comments
 (0)