-
-
Notifications
You must be signed in to change notification settings - Fork 174
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix id encoded with incorrect signedness. #662
base: master
Are you sure you want to change the base?
Changes from 2 commits
5a89c5f
919fc7f
82507ce
9180194
12f211e
a164f84
e88ef7f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,10 +4,10 @@ import { debug, window } from "vscode"; | |
import { StoppedEvent, TerminatedEvent } from "@vscode/debugadapter"; | ||
import { VariantEncoder } from "./variables/variant_encoder"; | ||
import { VariantDecoder } from "./variables/variant_decoder"; | ||
import { RawObject } from "./variables/variants"; | ||
import { ObjectId, RawObject } from "./variables/variants"; | ||
import { GodotStackFrame, GodotVariable, GodotStackVars } from "../debug_runtime"; | ||
import { GodotDebugSession } from "./debug_session"; | ||
import { parse_next_scene_node, split_buffers, build_sub_values } from "./helpers"; | ||
import { parse_next_scene_node, split_buffers } from "./helpers"; | ||
import { get_configuration, get_free_port, createLogger, verify_godot_version, get_project_version, clean_godot_path } from "../../utils"; | ||
import { prompt_for_godot_executable } from "../../utils/prompts"; | ||
import { subProcess, killSubProcesses } from "../../utils/subspawn"; | ||
|
@@ -374,16 +374,21 @@ export class ServerController { | |
break; | ||
} | ||
case "scene:inspect_object": { | ||
const id = BigInt(command.parameters[0]); | ||
let id = BigInt(command.parameters[0]); | ||
const className: string = command.parameters[1]; | ||
const properties: any[] = command.parameters[2]; | ||
|
||
// scene:inspect_object returns the id as an unsigned 64 bit integer, but it is decoded as a signed 64 bit integer, | ||
// thus we need to convert it to its equivalent unsigned value here. | ||
if(id < 0) | ||
id = id + BigInt(2) ** BigInt(64); | ||
|
||
const rawObject = new RawObject(className); | ||
properties.forEach((prop) => { | ||
rawObject.set(prop[0], prop[5]); | ||
}); | ||
const inspectedVariable = { name: "", value: rawObject }; | ||
build_sub_values(inspectedVariable); | ||
this.build_sub_values(inspectedVariable); | ||
if (this.session.inspect_callbacks.has(BigInt(id))) { | ||
this.session.inspect_callbacks.get(BigInt(id))( | ||
inspectedVariable.name, | ||
|
@@ -411,8 +416,12 @@ export class ServerController { | |
break; | ||
} | ||
case "stack_frame_vars": { | ||
this.partialStackVars.reset(command.parameters[0]); | ||
this.session.set_scopes(this.partialStackVars); | ||
const stack_var_count = command.parameters[0]; | ||
this.partialStackVars.reset(stack_var_count); | ||
|
||
if(stack_var_count <= 0) | ||
this.session.set_scopes(this.partialStackVars); | ||
|
||
break; | ||
} | ||
case "stack_frame_var": { | ||
|
@@ -551,7 +560,7 @@ export class ServerController { | |
} | ||
|
||
const variable: GodotVariable = { name, value, type }; | ||
build_sub_values(variable); | ||
this.build_sub_values(variable); | ||
|
||
const scopeName = ["locals", "members", "globals"][scope]; | ||
this.partialStackVars[scopeName].push(variable); | ||
|
@@ -561,4 +570,64 @@ export class ServerController { | |
this.session.set_scopes(this.partialStackVars); | ||
} | ||
} | ||
|
||
private build_sub_values(va: GodotVariable) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. build_sub_values was moved from helpers.ts to server_controller.ts and was converted to a method of ServerController, since only this object used it anyways and a ServerController instance was required in the new version. Additionally, any time a GodotVariable is constructed, GodotDebugSession.add_to_inspections is called on it, ensuring all sub values of a variable gets inspected as well. |
||
const value = va.value; | ||
|
||
let subValues: GodotVariable[] = undefined; | ||
|
||
if (value && Array.isArray(value)) { | ||
subValues = value.map((va, i) => { | ||
const gd_var = { | ||
name: `${i}`, | ||
value: va, | ||
} as GodotVariable; | ||
|
||
if(gd_var.value instanceof ObjectId) | ||
this.session.add_to_inspections([ gd_var ]); | ||
|
||
return gd_var; | ||
}); | ||
} else if (value instanceof Map) { | ||
subValues = Array.from(value.keys()).map((va) => { | ||
if (typeof va["stringify_value"] === "function") { | ||
const gd_var = { | ||
name: `${va.type_name()}${va.stringify_value()}`, | ||
value: value.get(va), | ||
} as GodotVariable; | ||
|
||
if(gd_var.value instanceof ObjectId) | ||
this.session.add_to_inspections([ gd_var ]); | ||
|
||
return gd_var; | ||
} else { | ||
const gd_var = { | ||
name: `${va}`, | ||
value: value.get(va), | ||
} as GodotVariable; | ||
|
||
if(gd_var.value instanceof ObjectId) | ||
this.session.add_to_inspections([ gd_var ]); | ||
|
||
return gd_var; | ||
} | ||
}); | ||
} else if (value && typeof value["sub_values"] === "function") { | ||
subValues = value.sub_values().map((sva) => { | ||
const gd_var = { | ||
name: sva.name, | ||
value: sva.value, | ||
} as GodotVariable; | ||
|
||
if(gd_var.value instanceof ObjectId) | ||
this.session.add_to_inspections([ gd_var ]); | ||
|
||
return gd_var; | ||
}); | ||
} | ||
|
||
va.sub_values = subValues; | ||
|
||
subValues?.forEach(this.build_sub_values.bind(this)); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if set_scopes is called here every time the stack_frame_vars command is handled, it leads to the issue seen in the second image in the following comment:
#662 (comment)
This if statement makes sure GodotDebugSession.ongoing_inspections is not of length 0 (if Objects are present in the current stack frame) the first time set_scopes is called, thus preventing GodotDebugSession.got_scope.notify being called too early.