[turbolizer] Display block names in disassembly pane
Bug: v8:7327 Change-Id: Ia8e5d51b12cc86734523860af88d4c3948e0f0c0 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1660614 Commit-Queue: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Daniel Clifford <danno@chromium.org> Cr-Commit-Position: refs/heads/master@{#63371}
This commit is contained in:
parent
5812aabb0b
commit
98dfac7526
@ -2433,6 +2433,23 @@ MaybeHandle<Code> Pipeline::GenerateCodeForCodeStub(
|
|||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct BlockStartsAsJSON {
|
||||||
|
const ZoneVector<int>* block_starts;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& out, const BlockStartsAsJSON& s) {
|
||||||
|
out << ", \"blockIdToOffset\": {";
|
||||||
|
bool need_comma = false;
|
||||||
|
for (size_t i = 0; i < s.block_starts->size(); ++i) {
|
||||||
|
if (need_comma) out << ", ";
|
||||||
|
int offset = (*s.block_starts)[i];
|
||||||
|
out << "\"" << i << "\":" << offset;
|
||||||
|
need_comma = true;
|
||||||
|
}
|
||||||
|
out << "},";
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
wasm::WasmCompilationResult Pipeline::GenerateCodeForWasmNativeStub(
|
wasm::WasmCompilationResult Pipeline::GenerateCodeForWasmNativeStub(
|
||||||
wasm::WasmEngine* wasm_engine, CallDescriptor* call_descriptor,
|
wasm::WasmEngine* wasm_engine, CallDescriptor* call_descriptor,
|
||||||
@ -2503,7 +2520,9 @@ wasm::WasmCompilationResult Pipeline::GenerateCodeForWasmNativeStub(
|
|||||||
|
|
||||||
if (info.trace_turbo_json_enabled()) {
|
if (info.trace_turbo_json_enabled()) {
|
||||||
TurboJsonFile json_of(&info, std::ios_base::app);
|
TurboJsonFile json_of(&info, std::ios_base::app);
|
||||||
json_of << "{\"name\":\"disassembly\",\"type\":\"disassembly\",\"data\":\"";
|
json_of << "{\"name\":\"disassembly\",\"type\":\"disassembly\""
|
||||||
|
<< BlockStartsAsJSON{&code_generator->block_starts()}
|
||||||
|
<< "\"data\":\"";
|
||||||
#ifdef ENABLE_DISASSEMBLER
|
#ifdef ENABLE_DISASSEMBLER
|
||||||
std::stringstream disassembler_stream;
|
std::stringstream disassembler_stream;
|
||||||
Disassembler::Decode(
|
Disassembler::Decode(
|
||||||
@ -2696,7 +2715,9 @@ void Pipeline::GenerateCodeForWasmFunction(
|
|||||||
|
|
||||||
if (data.info()->trace_turbo_json_enabled()) {
|
if (data.info()->trace_turbo_json_enabled()) {
|
||||||
TurboJsonFile json_of(data.info(), std::ios_base::app);
|
TurboJsonFile json_of(data.info(), std::ios_base::app);
|
||||||
json_of << "{\"name\":\"disassembly\",\"type\":\"disassembly\",\"data\":\"";
|
json_of << "{\"name\":\"disassembly\",\"type\":\"disassembly\""
|
||||||
|
<< BlockStartsAsJSON{&code_generator->block_starts()}
|
||||||
|
<< "\"data\":\"";
|
||||||
#ifdef ENABLE_DISASSEMBLER
|
#ifdef ENABLE_DISASSEMBLER
|
||||||
std::stringstream disassembler_stream;
|
std::stringstream disassembler_stream;
|
||||||
Disassembler::Decode(
|
Disassembler::Decode(
|
||||||
@ -2934,23 +2955,6 @@ void PipelineImpl::AssembleCode(Linkage* linkage,
|
|||||||
data->EndPhaseKind();
|
data->EndPhaseKind();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct BlockStartsAsJSON {
|
|
||||||
const ZoneVector<int>* block_starts;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& out, const BlockStartsAsJSON& s) {
|
|
||||||
out << ", \"blockIdToOffset\": {";
|
|
||||||
bool need_comma = false;
|
|
||||||
for (size_t i = 0; i < s.block_starts->size(); ++i) {
|
|
||||||
if (need_comma) out << ", ";
|
|
||||||
int offset = (*s.block_starts)[i];
|
|
||||||
out << "\"" << i << "\":" << offset;
|
|
||||||
need_comma = true;
|
|
||||||
}
|
|
||||||
out << "},";
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
MaybeHandle<Code> PipelineImpl::FinalizeCode(bool retire_broker) {
|
MaybeHandle<Code> PipelineImpl::FinalizeCode(bool retire_broker) {
|
||||||
PipelineData* data = this->data_;
|
PipelineData* data = this->data_;
|
||||||
if (data->broker() && retire_broker) {
|
if (data->broker() && retire_broker) {
|
||||||
|
47
tools/turbolizer/package-lock.json
generated
47
tools/turbolizer/package-lock.json
generated
@ -1687,9 +1687,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"js-yaml": {
|
"js-yaml": {
|
||||||
"version": "3.12.1",
|
"version": "3.13.1",
|
||||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.1.tgz",
|
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
|
||||||
"integrity": "sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA==",
|
"integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"argparse": "^1.0.7",
|
"argparse": "^1.0.7",
|
||||||
@ -2344,9 +2344,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"mixin-deep": {
|
"mixin-deep": {
|
||||||
"version": "1.3.1",
|
"version": "1.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
|
||||||
"integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==",
|
"integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"for-in": "^1.0.2",
|
"for-in": "^1.0.2",
|
||||||
"is-extendable": "^1.0.1"
|
"is-extendable": "^1.0.1"
|
||||||
@ -2872,9 +2872,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"set-value": {
|
"set-value": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
|
||||||
"integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==",
|
"integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"extend-shallow": "^2.0.1",
|
"extend-shallow": "^2.0.1",
|
||||||
"is-extendable": "^0.1.1",
|
"is-extendable": "^0.1.1",
|
||||||
@ -3407,35 +3407,14 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"union-value": {
|
"union-value": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
|
||||||
"integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=",
|
"integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"arr-union": "^3.1.0",
|
"arr-union": "^3.1.0",
|
||||||
"get-value": "^2.0.6",
|
"get-value": "^2.0.6",
|
||||||
"is-extendable": "^0.1.1",
|
"is-extendable": "^0.1.1",
|
||||||
"set-value": "^0.4.3"
|
"set-value": "^2.0.1"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"extend-shallow": {
|
|
||||||
"version": "2.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
|
|
||||||
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
|
|
||||||
"requires": {
|
|
||||||
"is-extendable": "^0.1.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"set-value": {
|
|
||||||
"version": "0.4.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz",
|
|
||||||
"integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=",
|
|
||||||
"requires": {
|
|
||||||
"extend-shallow": "^2.0.1",
|
|
||||||
"is-extendable": "^0.1.1",
|
|
||||||
"is-plain-object": "^2.0.1",
|
|
||||||
"to-object-path": "^0.3.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"universalify": {
|
"universalify": {
|
||||||
|
@ -32,7 +32,7 @@ export class DisassemblyView extends TextView {
|
|||||||
pane.setAttribute('id', "disassembly");
|
pane.setAttribute('id', "disassembly");
|
||||||
pane.innerHTML =
|
pane.innerHTML =
|
||||||
`<pre id='disassembly-text-pre' class='prettyprint prettyprinted'>
|
`<pre id='disassembly-text-pre' class='prettyprint prettyprinted'>
|
||||||
<ul id='disassembly-list' class='nolinenums noindent'>
|
<ul class='disassembly-list nolinenums noindent'>
|
||||||
</ul>
|
</ul>
|
||||||
</pre>`;
|
</pre>`;
|
||||||
|
|
||||||
@ -46,6 +46,16 @@ export class DisassemblyView extends TextView {
|
|||||||
associateData: (text, fragment: HTMLElement) => {
|
associateData: (text, fragment: HTMLElement) => {
|
||||||
const matches = text.match(/(?<address>0?x?[0-9a-fA-F]{8,16})(?<addressSpace>\s+)(?<offset>[0-9a-f]+)(?<offsetSpace>\s*)/);
|
const matches = text.match(/(?<address>0?x?[0-9a-fA-F]{8,16})(?<addressSpace>\s+)(?<offset>[0-9a-f]+)(?<offsetSpace>\s*)/);
|
||||||
const offset = Number.parseInt(matches.groups["offset"], 16);
|
const offset = Number.parseInt(matches.groups["offset"], 16);
|
||||||
|
const blockIds = view.sourceResolver.getBlockIdsForOffset(offset);
|
||||||
|
const blockIdElement = document.createElement("SPAN");
|
||||||
|
blockIdElement.className = "block-id com linkable-text";
|
||||||
|
blockIdElement.innerText = "";
|
||||||
|
if (blockIds && blockIds.length > 0) {
|
||||||
|
blockIds.forEach(blockId => view.addHtmlElementForBlockId(blockId, fragment));
|
||||||
|
blockIdElement.innerText = `B${blockIds.join(",")}:`;
|
||||||
|
blockIdElement.dataset.blockId = `${blockIds.join(",")}`;
|
||||||
|
}
|
||||||
|
fragment.appendChild(blockIdElement);
|
||||||
const addressElement = document.createElement("SPAN");
|
const addressElement = document.createElement("SPAN");
|
||||||
addressElement.className = "instruction-address";
|
addressElement.className = "instruction-address";
|
||||||
addressElement.innerText = matches.groups["address"];
|
addressElement.innerText = matches.groups["address"];
|
||||||
@ -58,11 +68,13 @@ export class DisassemblyView extends TextView {
|
|||||||
fragment.classList.add('tag');
|
fragment.classList.add('tag');
|
||||||
|
|
||||||
if (!Number.isNaN(offset)) {
|
if (!Number.isNaN(offset)) {
|
||||||
const pcOffset = view.sourceResolver.getKeyPcOffset(offset);
|
let pcOffset = view.sourceResolver.getKeyPcOffset(offset);
|
||||||
|
if (pcOffset == -1) pcOffset = Number(offset);
|
||||||
fragment.dataset.pcOffset = `${pcOffset}`;
|
fragment.dataset.pcOffset = `${pcOffset}`;
|
||||||
addressElement.classList.add('linkable-text');
|
addressElement.classList.add('linkable-text');
|
||||||
offsetElement.classList.add('linkable-text');
|
offsetElement.classList.add('linkable-text');
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const UNCLASSIFIED_STYLE = {
|
const UNCLASSIFIED_STYLE = {
|
||||||
@ -79,11 +91,20 @@ export class DisassemblyView extends TextView {
|
|||||||
fragment.innerHTML = text;
|
fragment.innerHTML = text;
|
||||||
const replacer = (match, hexOffset) => {
|
const replacer = (match, hexOffset) => {
|
||||||
const offset = Number.parseInt(hexOffset, 16);
|
const offset = Number.parseInt(hexOffset, 16);
|
||||||
const keyOffset = view.sourceResolver.getKeyPcOffset(offset);
|
let keyOffset = view.sourceResolver.getKeyPcOffset(offset);
|
||||||
return `<span class="tag linkable-text" data-pc-offset="${keyOffset}">${match}</span>`;
|
if (keyOffset == -1) keyOffset = Number(offset);
|
||||||
|
const blockIds = view.sourceResolver.getBlockIdsForOffset(offset);
|
||||||
|
let block = "";
|
||||||
|
let blockIdData = "";
|
||||||
|
if (blockIds && blockIds.length > 0) {
|
||||||
|
block = `B${blockIds.join(",")} `;
|
||||||
|
blockIdData = `data-block-id="${blockIds.join(",")}"`;
|
||||||
|
}
|
||||||
|
return `<span class="tag linkable-text" data-pc-offset="${keyOffset}" ${blockIdData}>${block}${match}</span>`;
|
||||||
};
|
};
|
||||||
const html = text.replace(/<.0?x?([0-9a-fA-F]+)>/g, replacer);
|
const html = text.replace(/<.0?x?([0-9a-fA-F]+)>/g, replacer);
|
||||||
fragment.innerHTML = html;
|
fragment.innerHTML = html;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const OPCODE_STYLE = {
|
const OPCODE_STYLE = {
|
||||||
@ -91,12 +112,14 @@ export class DisassemblyView extends TextView {
|
|||||||
};
|
};
|
||||||
const BLOCK_HEADER_STYLE = {
|
const BLOCK_HEADER_STYLE = {
|
||||||
associateData: function (text, fragment) {
|
associateData: function (text, fragment) {
|
||||||
|
if (view.sourceResolver.hasBlockStartInfo()) return false;
|
||||||
const matches = /\d+/.exec(text);
|
const matches = /\d+/.exec(text);
|
||||||
if (!matches) return;
|
if (!matches) return true;
|
||||||
const blockId = matches[0];
|
const blockId = matches[0];
|
||||||
fragment.dataset.blockId = blockId;
|
fragment.dataset.blockId = blockId;
|
||||||
fragment.innerHTML = text;
|
fragment.innerHTML = text;
|
||||||
fragment.className = "com block";
|
fragment.className = "com block";
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const SOURCE_POSITION_HEADER_STYLE = {
|
const SOURCE_POSITION_HEADER_STYLE = {
|
||||||
@ -135,7 +158,7 @@ export class DisassemblyView extends TextView {
|
|||||||
|
|
||||||
const linkHandler = (e: MouseEvent) => {
|
const linkHandler = (e: MouseEvent) => {
|
||||||
if (!(e.target instanceof HTMLElement)) return;
|
if (!(e.target instanceof HTMLElement)) return;
|
||||||
const offsetAsString = e.target.dataset.pcOffset ? e.target.dataset.pcOffset : e.target.parentElement.dataset.pcOffset;
|
const offsetAsString = typeof e.target.dataset.pcOffset != "undefined" ? e.target.dataset.pcOffset : e.target.parentElement.dataset.pcOffset;
|
||||||
const offset = Number.parseInt(offsetAsString, 10);
|
const offset = Number.parseInt(offsetAsString, 10);
|
||||||
if ((typeof offsetAsString) != "undefined" && !Number.isNaN(offset)) {
|
if ((typeof offsetAsString) != "undefined" && !Number.isNaN(offset)) {
|
||||||
view.offsetSelection.select([offset], true);
|
view.offsetSelection.select([offset], true);
|
||||||
@ -156,12 +179,12 @@ export class DisassemblyView extends TextView {
|
|||||||
|
|
||||||
const linkHandlerBlock = e => {
|
const linkHandlerBlock = e => {
|
||||||
const blockId = e.target.dataset.blockId;
|
const blockId = e.target.dataset.blockId;
|
||||||
if (typeof blockId != "undefined" && !Number.isNaN(blockId)) {
|
if (typeof blockId != "undefined") {
|
||||||
e.stopPropagation();
|
const blockIds = blockId.split(",");
|
||||||
if (!e.shiftKey) {
|
if (!e.shiftKey) {
|
||||||
view.selectionHandler.clear();
|
view.selectionHandler.clear();
|
||||||
}
|
}
|
||||||
view.blockSelectionHandler.select([blockId], true);
|
view.blockSelectionHandler.select(blockIds, true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
view.divNode.addEventListener('click', linkHandlerBlock);
|
view.divNode.addEventListener('click', linkHandlerBlock);
|
||||||
|
@ -118,6 +118,8 @@ export class SourceResolver {
|
|||||||
instructionToPCOffset: Array<number>;
|
instructionToPCOffset: Array<number>;
|
||||||
pcOffsetToInstructions: Map<number, Array<number>>;
|
pcOffsetToInstructions: Map<number, Array<number>>;
|
||||||
pcOffsets: Array<number>;
|
pcOffsets: Array<number>;
|
||||||
|
blockIdToPCOffset: Array<number>;
|
||||||
|
blockStartPCtoBlockIds: Map<number, Array<number>>;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
// Maps node ids to source positions.
|
// Maps node ids to source positions.
|
||||||
@ -147,6 +149,16 @@ export class SourceResolver {
|
|||||||
// Maps PC offsets to instructions.
|
// Maps PC offsets to instructions.
|
||||||
this.pcOffsetToInstructions = new Map();
|
this.pcOffsetToInstructions = new Map();
|
||||||
this.pcOffsets = [];
|
this.pcOffsets = [];
|
||||||
|
this.blockIdToPCOffset = [];
|
||||||
|
this.blockStartPCtoBlockIds = new Map();
|
||||||
|
}
|
||||||
|
|
||||||
|
getBlockIdsForOffset(offset): Array<number> {
|
||||||
|
return this.blockStartPCtoBlockIds.get(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
hasBlockStartInfo() {
|
||||||
|
return this.blockIdToPCOffset.length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
setSources(sources, mainBackup) {
|
setSources(sources, mainBackup) {
|
||||||
@ -447,6 +459,15 @@ export class SourceResolver {
|
|||||||
switch (phase.type) {
|
switch (phase.type) {
|
||||||
case 'disassembly':
|
case 'disassembly':
|
||||||
this.disassemblyPhase = phase;
|
this.disassemblyPhase = phase;
|
||||||
|
if (phase['blockIdToOffset']) {
|
||||||
|
for (const [blockId, pc] of Object.entries<number>(phase['blockIdToOffset'])) {
|
||||||
|
this.blockIdToPCOffset[blockId] = pc;
|
||||||
|
if (!this.blockStartPCtoBlockIds.has(pc)) {
|
||||||
|
this.blockStartPCtoBlockIds.set(pc, []);
|
||||||
|
}
|
||||||
|
this.blockStartPCtoBlockIds.get(pc).push(Number(blockId));
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'schedule':
|
case 'schedule':
|
||||||
this.phaseNames.set(phase.name, this.phases.length);
|
this.phaseNames.set(phase.name, this.phases.length);
|
||||||
|
@ -129,6 +129,10 @@ export abstract class TextView extends PhaseView {
|
|||||||
if (this.divNode.parentNode == null) return;
|
if (this.divNode.parentNode == null) return;
|
||||||
const mkVisible = new ViewElements(this.divNode.parentNode as HTMLElement);
|
const mkVisible = new ViewElements(this.divNode.parentNode as HTMLElement);
|
||||||
const view = this;
|
const view = this;
|
||||||
|
const elementsToSelect = view.divNode.querySelectorAll(`[data-pc-offset]`);
|
||||||
|
for (const el of elementsToSelect) {
|
||||||
|
el.classList.toggle("selected", false);
|
||||||
|
}
|
||||||
for (const [blockId, elements] of this.blockIdToHtmlElementsMap.entries()) {
|
for (const [blockId, elements] of this.blockIdToHtmlElementsMap.entries()) {
|
||||||
const isSelected = view.blockSelection.isSelected(blockId);
|
const isSelected = view.blockSelection.isSelected(blockId);
|
||||||
for (const element of elements) {
|
for (const element of elements) {
|
||||||
@ -136,10 +140,6 @@ export abstract class TextView extends PhaseView {
|
|||||||
element.classList.toggle("selected", isSelected);
|
element.classList.toggle("selected", isSelected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const elementsToSelect = view.divNode.querySelectorAll(`[data-pc-offset]`);
|
|
||||||
for (const el of elementsToSelect) {
|
|
||||||
el.classList.toggle("selected", false);
|
|
||||||
}
|
|
||||||
for (const key of this.nodeIdToHtmlElementsMap.keys()) {
|
for (const key of this.nodeIdToHtmlElementsMap.keys()) {
|
||||||
for (const element of this.nodeIdToHtmlElementsMap.get(key)) {
|
for (const element of this.nodeIdToHtmlElementsMap.get(key)) {
|
||||||
element.classList.toggle("selected", false);
|
element.classList.toggle("selected", false);
|
||||||
@ -170,7 +170,9 @@ export abstract class TextView extends PhaseView {
|
|||||||
const fragment = document.createElement("SPAN");
|
const fragment = document.createElement("SPAN");
|
||||||
|
|
||||||
if (typeof style.associateData == 'function') {
|
if (typeof style.associateData == 'function') {
|
||||||
style.associateData(text, fragment);
|
if (style.associateData(text, fragment) === false) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (style.css != undefined) {
|
if (style.css != undefined) {
|
||||||
const css = isIterable(style.css) ? style.css : [style.css];
|
const css = isIterable(style.css) ? style.css : [style.css];
|
||||||
@ -198,7 +200,7 @@ export abstract class TextView extends PhaseView {
|
|||||||
const text = matches[0];
|
const text = matches[0];
|
||||||
if (text != '') {
|
if (text != '') {
|
||||||
const fragment = view.createFragment(matches[0], style);
|
const fragment = view.createFragment(matches[0], style);
|
||||||
result.push(fragment);
|
if (fragment !== null) result.push(fragment);
|
||||||
}
|
}
|
||||||
line = line.substr(matches[0].length);
|
line = line.substr(matches[0].length);
|
||||||
}
|
}
|
||||||
|
@ -696,3 +696,9 @@ text {
|
|||||||
padding-left: .5ex;
|
padding-left: .5ex;
|
||||||
outline: 1px dotted grey;
|
outline: 1px dotted grey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ul.disassembly-list .block-id {
|
||||||
|
width: 4ex;
|
||||||
|
display: block;
|
||||||
|
padding-top: 2px;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user