luau/tools/natvis/VM.natvis
Alexander McCord d21b6fdb93
Sync to upstream/release/617 (#1204)
# What's Changed

* Fix a case where the stack wasn't completely cleaned up where
`debug.info` errored when passed `"f"` option and a thread.
* Fix a case of uninitialized field in `luaF_newproto`.

### New Type Solver

* When a local is captured in a function, don't add a new entry to the
`DfgScope::bindings` if the capture occurs within a loop.
* Fix a poor performance characteristic during unification by not trying
to simplify an intersection.
* Fix a case of multiple constraints mutating the same blocked type
causing incorrect inferences.
* Fix a case of assertion failure when overload resolution encounters a
return typepack mismatch.
* When refining a property of the top `table` type, we no longer signal
an unknown property error.
* Fix a misuse of free types when trying to infer the type of a
subscript expression.
* Fix a case of assertion failure when trying to resolve an overload
from `never`.

### Native Code Generation

* Fix dead store optimization issues caused by partial stores.

---

### Internal Contributors

Co-authored-by: Aaron Weiss <aaronweiss@roblox.com>
Co-authored-by: Andy Friesen <afriesen@roblox.com>
Co-authored-by: Aviral Goel <agoel@roblox.com>
Co-authored-by: David Cope <dcope@roblox.com>
Co-authored-by: Lily Brown <lbrown@roblox.com>
Co-authored-by: Vyacheslav Egorov <vegorov@roblox.com>

---------

Co-authored-by: Aaron Weiss <aaronweiss@roblox.com>
Co-authored-by: Andy Friesen <afriesen@roblox.com>
Co-authored-by: Vighnesh <vvijay@roblox.com>
Co-authored-by: Aviral Goel <agoel@roblox.com>
Co-authored-by: David Cope <dcope@roblox.com>
Co-authored-by: Lily Brown <lbrown@roblox.com>
Co-authored-by: Vyacheslav Egorov <vegorov@roblox.com>
2024-03-15 16:37:39 -07:00

286 lines
13 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<Type Name="lua_TValue">
<DisplayString Condition="tt == lua_Type::LUA_TNIL">nil</DisplayString>
<DisplayString Condition="tt == lua_Type::LUA_TBOOLEAN">{(bool)value.b}</DisplayString>
<DisplayString Condition="tt == lua_Type::LUA_TLIGHTUSERDATA">lightuserdata {(uintptr_t)value.p,h} tag: {extra[0]}</DisplayString>
<DisplayString Condition="tt == lua_Type::LUA_TNUMBER">number = {value.n}</DisplayString>
<DisplayString Condition="tt == lua_Type::LUA_TVECTOR">vector = {value.v[0]}, {value.v[1]}, {*(float*)&amp;extra}</DisplayString>
<DisplayString Condition="tt == lua_Type::LUA_TSTRING">{value.gc->ts}</DisplayString>
<DisplayString Condition="tt == lua_Type::LUA_TTABLE">{value.gc->h}</DisplayString>
<DisplayString Condition="tt == lua_Type::LUA_TFUNCTION">function {value.gc->cl,view(short)}</DisplayString>
<DisplayString Condition="tt == lua_Type::LUA_TUSERDATA">userdata {value.gc->u}</DisplayString>
<DisplayString Condition="tt == lua_Type::LUA_TTHREAD">thread {value.gc->th}</DisplayString>
<DisplayString Condition="tt == lua_Type::LUA_TBUFFER">buffer {value.gc->buf} size={value.gc->buf.len}</DisplayString>
<DisplayString Condition="tt == lua_Type::LUA_TPROTO">proto {value.gc->p}</DisplayString>
<DisplayString Condition="tt == lua_Type::LUA_TUPVAL">upvalue {value.gc->uv}</DisplayString>
<DisplayString Condition="tt == lua_Type::LUA_TDEADKEY">deadkey</DisplayString>
<DisplayString>empty</DisplayString>
<Expand>
<Item Name="[lightuserdata]" Condition="tt == lua_Type::LUA_TLIGHTUSERDATA">value.p</Item>
<Item Name="[string]" Condition="tt == lua_Type::LUA_TSTRING">value.gc->ts</Item>
<Item Name="[table]" Condition="tt == lua_Type::LUA_TTABLE">value.gc->h</Item>
<Item Name="[C function]" Condition="tt == lua_Type::LUA_TFUNCTION &amp;&amp; value.gc-&gt;cl.isC">value.gc->cl</Item>
<Item Name="[Lua function]" Condition="tt == lua_Type::LUA_TFUNCTION &amp;&amp; !value.gc-&gt;cl.isC">value.gc->cl</Item>
<Item Name="[userdata]" Condition="tt == lua_Type::LUA_TUSERDATA">value.gc->u</Item>
<Item Name="[thread]" Condition="tt == lua_Type::LUA_TTHREAD">value.gc->th</Item>
<Item Name="[buffer]" Condition="tt == lua_Type::LUA_TBUFFER">value.gc->buf</Item>
<Item Name="[proto]" Condition="tt == lua_Type::LUA_TPROTO">value.gc->p</Item>
<Item Name="[upvalue]" Condition="tt == lua_Type::LUA_TUPVAL">value.gc->uv</Item>
<Item Name="[tag]" Condition="tt == lua_Type::LUA_TLIGHTUSERDATA">extra[0]</Item>
<Synthetic Name="[gc]" Condition="tt >= lua_Type::LUA_TSTRING">
<DisplayString Condition="value.gc-&gt;gch.marked &amp; 8">fixed ({(int)value.gc-&gt;gch.marked})</DisplayString>
<DisplayString Condition="value.gc-&gt;gch.marked &amp; 4">black ({(int)value.gc-&gt;gch.marked})</DisplayString>
<DisplayString Condition="value.gc-&gt;gch.marked &amp; 1">white ({(int)value.gc-&gt;gch.marked})</DisplayString>
<DisplayString Condition="value.gc-&gt;gch.marked &amp; 2">white ({(int)value.gc-&gt;gch.marked})</DisplayString>
<DisplayString Condition="(value.gc-&gt;gch.marked &amp; 3) == 0">gray ({(int)value.gc-&gt;gch.marked})</DisplayString>
</Synthetic>
</Expand>
</Type>
<Type Name="TKey">
<DisplayString Condition="tt == lua_Type::LUA_TNIL">nil</DisplayString>
<DisplayString Condition="tt == lua_Type::LUA_TBOOLEAN">{(bool)value.b}</DisplayString>
<DisplayString Condition="tt == lua_Type::LUA_TLIGHTUSERDATA">lightuserdata {(uintptr_t)value.p,h} tag: {extra[0]}</DisplayString>
<DisplayString Condition="tt == lua_Type::LUA_TNUMBER">number = {value.n}</DisplayString>
<DisplayString Condition="tt == lua_Type::LUA_TVECTOR">vector = {value.v[0]}, {value.v[1]}, {*(float*)&amp;extra}</DisplayString>
<DisplayString Condition="tt == lua_Type::LUA_TSTRING">{value.gc->ts}</DisplayString>
<DisplayString Condition="tt == lua_Type::LUA_TTABLE">{value.gc->h}</DisplayString>
<DisplayString Condition="tt == lua_Type::LUA_TFUNCTION">function {value.gc->cl,view(short)}</DisplayString>
<DisplayString Condition="tt == lua_Type::LUA_TUSERDATA">userdata {value.gc->u}</DisplayString>
<DisplayString Condition="tt == lua_Type::LUA_TTHREAD">thread {value.gc->th}</DisplayString>
<DisplayString Condition="tt == lua_Type::LUA_TBUFFER">buffer {value.gc->buf} size={value.gc->buf.len}</DisplayString>
<DisplayString Condition="tt == lua_Type::LUA_TPROTO">proto {value.gc->p}</DisplayString>
<DisplayString Condition="tt == lua_Type::LUA_TUPVAL">upvalue {value.gc->uv}</DisplayString>
<DisplayString Condition="tt == lua_Type::LUA_TDEADKEY">deadkey</DisplayString>
<DisplayString>empty</DisplayString>
<Expand>
<Item Name="[lightuserdata]" Condition="tt == lua_Type::LUA_TLIGHTUSERDATA">(void**)value.p</Item>
<Item Name="[string]" Condition="tt == lua_Type::LUA_TSTRING">value.gc->ts</Item>
<Item Name="[table]" Condition="tt == lua_Type::LUA_TTABLE">value.gc->h</Item>
<Item Name="[C function]" Condition="tt == lua_Type::LUA_TFUNCTION &amp;&amp; value.gc-&gt;cl.isC">value.gc->cl</Item>
<Item Name="[Lua function]" Condition="tt == lua_Type::LUA_TFUNCTION &amp;&amp; !value.gc-&gt;cl.isC">value.gc->cl</Item>
<Item Name="[userdata]" Condition="tt == lua_Type::LUA_TUSERDATA">value.gc->u</Item>
<Item Name="[thread]" Condition="tt == lua_Type::LUA_TTHREAD">value.gc->th</Item>
<Item Name="[buffer]" Condition="tt == lua_Type::LUA_TBUFFER">value.gc->buf</Item>
<Item Name="[proto]" Condition="tt == lua_Type::LUA_TPROTO">value.gc->p</Item>
<Item Name="[upvalue]" Condition="tt == lua_Type::LUA_TUPVAL">value.gc->uv</Item>
<Item Name="[tag]" Condition="tt == lua_Type::LUA_TLIGHTUSERDATA">extra[0]</Item>
<Item Name="[next]">next</Item>
</Expand>
</Type>
<Type Name="LuaNode">
<DisplayString Condition="key.tt != lua_Type::LUA_TNIL || val.tt != lua_Type::LUA_TNIL">{key,na} = {val}</DisplayString>
<DisplayString Condition="key.tt == lua_Type::LUA_TNIL &amp;&amp; val.tt == 0">---</DisplayString>
</Type>
<Type Name="Table">
<DisplayString>table</DisplayString>
<Expand>
<Item Name="metatable" Condition="metatable">metatable</Item>
<Synthetic Name="hash">
<DisplayString>[size] {1&lt;&lt;lsizenode}</DisplayString>
<Expand>
<IndexListItems>
<Size>1&lt;&lt;lsizenode</Size>
<ValueNode>node[$i]</ValueNode>
</IndexListItems>
</Expand>
</Synthetic>
<Synthetic Name="array">
<DisplayString>[size] {sizearray}</DisplayString>
<Expand>
<IndexListItems>
<Size>sizearray</Size>
<ValueNode>array[$i]</ValueNode>
</IndexListItems>
</Expand>
</Synthetic>
</Expand>
</Type>
<Type Name="Udata">
<Expand>
<CustomListItems>
<Variable Name="count" InitialValue="1&lt;&lt;metatable->lsizenode" />
<Variable Name="i" InitialValue="0" />
<Size>1</Size>
<Loop>
<Break Condition="i &gt;= count" />
<If Condition="metatable->node[i].key.tt == lua_Type::LUA_TSTRING">
<If Condition="strcmp(metatable-&gt;node[i].key.value.gc->ts.data, &quot;__type&quot;) == 0">
<Item Name="[type]">metatable-&gt;node[i].val</Item>
<Break/>
</If>
</If>
<Exec>i = i + 1</Exec>
</Loop>
<If Condition="i == count">
<Item Name="[type]">"unknown",sb</Item>
</If>
</CustomListItems>
<Item Name="tag">tag</Item>
<Item Name="len">len</Item>
<Item Name="metatable">metatable</Item>
<Item Name="data">data</Item>
</Expand>
</Type>
<Type Name="Closure">
<DisplayString Condition="isC == 1" IncludeView="short">{c.f,na}</DisplayString>
<DisplayString Condition="isC == 0" IncludeView="short">{l.p,na}</DisplayString>
<DisplayString Condition="isC == 1" ExcludeView="short">{c}</DisplayString>
<DisplayString Condition="isC == 0" ExcludeView="short">{l}</DisplayString>
<DisplayString>invalid</DisplayString>
</Type>
<Type Name="TString">
<DisplayString>{data,s}</DisplayString>
</Type>
<Type Name="CallInfo">
<Intrinsic Name="cl" Category="Property" Expression="func->value.gc->cl"/>
<Intrinsic Name="isC" Category="Property" Expression="cl().isC"/>
<Intrinsic Name="proto" Category="Property" Expression="cl().l.p"/>
<Intrinsic Name="pcRel" Category="Property" Expression="savedpc ? savedpc - proto()->code - 1 : 0"/>
<Intrinsic Name="line" Category="Property" Expression="proto()->abslineinfo[pcRel() >> proto()->linegaplog2] + proto()->lineinfo[pcRel()]"/>
<!-- Special frames -->
<DisplayString Condition="!func">empty</DisplayString>
<DisplayString Condition="func->tt != lua_Type::LUA_TFUNCTION">none</DisplayString>
<!-- Lua functions-->
<DisplayString Condition="!isC() &amp;&amp; proto()->debugname">{proto()->source->data,sb}:{line()} function {proto()->debugname->data,sb}()</DisplayString>
<DisplayString Condition="!isC()">{proto()->source->data,sb}:{line()} function()</DisplayString>
<!-- C functions-->
<DisplayString Condition="isC() &amp;&amp; cl().c.debugname">=[C] function {cl().c.debugname,sb}() {cl().c.f,na}</DisplayString>
<DisplayString Condition="isC()">=[C] {cl().c.f,na}</DisplayString>
</Type>
<Type Name ="lua_State">
<DisplayString Condition="ci">{ci,na}</DisplayString>
<DisplayString>thread</DisplayString>
<Expand>
<Synthetic Name="[call stack]">
<DisplayString>{ci-base_ci} frames</DisplayString>
<Expand>
<IndexListItems>
<Size>ci-base_ci</Size>
<!-- the +1 is omitted here to avoid some issues with a blank call -->
<ValueNode>
base_ci[ci-base_ci - $i]
</ValueNode>
</IndexListItems>
</Expand>
</Synthetic>
<Synthetic Name="[top frame stack]">
<DisplayString>{top-base} values</DisplayString>
<Expand>
<ArrayItems>
<Size>top-base</Size>
<ValuePointer>base</ValuePointer>
</ArrayItems>
</Expand>
</Synthetic>
<Synthetic Name="[stack]">
<DisplayString>{top-stack} values</DisplayString>
<Expand>
<ArrayItems>
<Size>top-stack</Size>
<ValuePointer>stack</ValuePointer>
</ArrayItems>
</Expand>
</Synthetic>
<Synthetic Name="[open upvals]" Condition="openupval != 0">
<Expand>
<LinkedListItems>
<HeadPointer>openupval</HeadPointer>
<NextPointer>u.open.threadnext</NextPointer>
<ValueNode>this</ValueNode>
</LinkedListItems>
</Expand>
</Synthetic>
<Item Name="globals">gt</Item>
<Item Name="userdata">userdata</Item>
</Expand>
</Type>
<Type Name="Proto">
<DisplayString Condition="debugname">{source->data,sb}:{linedefined} function {debugname->data,sb} [{(int)numparams} arg, {(int)nups} upval]</DisplayString>
<DisplayString Condition="!debugname">{source->data,sb}:{linedefined} [{(int)numparams} arg, {(int)nups} upval]</DisplayString>
<Expand>
<Item Name="debugname">debugname</Item>
<Synthetic Name="[constants]">
<DisplayString>constants</DisplayString>
<Expand>
<IndexListItems>
<Size>sizek</Size>
<ValueNode>k[$i]</ValueNode>
</IndexListItems>
</Expand>
</Synthetic>
<Synthetic Name="[locals]">
<DisplayString>locals</DisplayString>
<Expand>
<IndexListItems>
<Size>sizelocvars</Size>
<ValueNode>locvars[$i]</ValueNode>
</IndexListItems>
</Expand>
</Synthetic>
<Synthetic Name="[bytecode]">
<DisplayString>bytecode</DisplayString>
<Expand>
<IndexListItems>
<Size>sizecode</Size>
<ValueNode>code[$i]</ValueNode>
</IndexListItems>
</Expand>
</Synthetic>
<Synthetic Name="[functions]">
<DisplayString>functions</DisplayString>
<Expand>
<IndexListItems>
<Size>sizep</Size>
<ValueNode>p[$i]</ValueNode>
</IndexListItems>
</Expand>
</Synthetic>
<Synthetic Name="[upvals]">
<DisplayString>upvals</DisplayString>
<Expand>
<IndexListItems>
<Size>sizeupvalues</Size>
<ValueNode>upvalues[$i]</ValueNode>
</IndexListItems>
</Expand>
</Synthetic>
<Item Name="source">source</Item>
</Expand>
</Type>
<Type Name="GCheader">
<Expand>
<Synthetic Name="[type]">
<DisplayString>{(lua_Type)tt}</DisplayString>
</Synthetic>
<Synthetic Name="[gc]">
<DisplayString Condition="marked &amp; 8">fixed ({(int)marked})</DisplayString>
<DisplayString Condition="marked &amp; 4">black ({(int)marked})</DisplayString>
<DisplayString Condition="marked &amp; 1">white ({(int)marked})</DisplayString>
<DisplayString Condition="marked &amp; 2">white ({(int)marked})</DisplayString>
<DisplayString Condition="(marked &amp; 3) == 0">gray ({(int)marked})</DisplayString>
<DisplayString>unknown</DisplayString>
</Synthetic>
<Item Name="memcat">memcat</Item>
</Expand>
</Type>
</AutoVisualizer>