|
4 | 4 | "fmt"
|
5 | 5 | "os"
|
6 | 6 | "runtime"
|
7 |
| - "strings" |
8 | 7 | "sync/atomic"
|
9 | 8 | "testing"
|
10 | 9 | "time"
|
@@ -148,6 +147,33 @@ func TestLua(t *testing.T) {
|
148 | 147 | testScriptDir(t, luaTests, "_lua5.1-tests")
|
149 | 148 | }
|
150 | 149 |
|
| 150 | +func TestMergingLoadNilBug2(t *testing.T) { |
| 151 | + // there was a bug where the LOADNIL merging optimisation would merge LOADNILs that were the targets of |
| 152 | + // JMP instructions, causing the JMP to jump to the wrong location and breaking the logic and resulting in |
| 153 | + // a panic. |
| 154 | + s := ` |
| 155 | + id = "foo" |
| 156 | +
|
| 157 | + function get_def() |
| 158 | + return {} |
| 159 | + end |
| 160 | +
|
| 161 | + function test() |
| 162 | + local def = id ~= nil and get_def() or nil |
| 163 | + if def ~= nil then |
| 164 | + print("def is not nil") |
| 165 | + end |
| 166 | + end |
| 167 | +
|
| 168 | + test() |
| 169 | +` |
| 170 | + L := NewState() |
| 171 | + defer L.Close() |
| 172 | + if err := L.DoString(s); err != nil { |
| 173 | + t.Error(err) |
| 174 | + } |
| 175 | +} |
| 176 | + |
151 | 177 | func TestMergingLoadNilBug(t *testing.T) {
|
152 | 178 | // there was a bug where a multiple load nils were being incorrectly merged, and the following code exposed it
|
153 | 179 | s := `
|
@@ -185,48 +211,50 @@ func TestMergingLoadNilBug(t *testing.T) {
|
185 | 211 | }
|
186 | 212 | }
|
187 | 213 |
|
188 |
| -func TestMergingLoadNil(t *testing.T) { |
189 |
| - // multiple nil assignments to consecutive registers should be merged |
190 |
| - s := ` |
191 |
| - function test() |
192 |
| - local a = 0 |
193 |
| - local b = 1 |
194 |
| - local c = 2 |
195 |
| -
|
196 |
| - -- this should generate just one LOADNIL byte code instruction |
197 |
| - a = nil |
198 |
| - b = nil |
199 |
| - c = nil |
200 |
| -
|
201 |
| - print(a,b,c) |
202 |
| - end |
203 |
| -
|
204 |
| - test()` |
205 |
| - |
206 |
| - chunk, err := parse.Parse(strings.NewReader(s), "test") |
207 |
| - if err != nil { |
208 |
| - t.Fatal(err) |
209 |
| - } |
210 |
| - |
211 |
| - compiled, err := Compile(chunk, "test") |
212 |
| - if err != nil { |
213 |
| - t.Fatal(err) |
214 |
| - } |
215 |
| - |
216 |
| - if len(compiled.FunctionPrototypes) != 1 { |
217 |
| - t.Fatal("expected 1 function prototype") |
218 |
| - } |
219 |
| - |
220 |
| - // there should be exactly 1 LOADNIL instruction in the byte code generated for the above |
221 |
| - // anymore, and the LOADNIL merging is not working correctly |
222 |
| - count := 0 |
223 |
| - for _, instr := range compiled.FunctionPrototypes[0].Code { |
224 |
| - if opGetOpCode(instr) == OP_LOADNIL { |
225 |
| - count++ |
226 |
| - } |
227 |
| - } |
228 |
| - |
229 |
| - if count != 1 { |
230 |
| - t.Fatalf("expected 1 LOADNIL instruction, found %d", count) |
231 |
| - } |
232 |
| -} |
| 214 | +// This test is disabled because the LOADNIL merging optimisation has been disabled. See the comment in the |
| 215 | +// AddLoadNil() function for more information. |
| 216 | +//func TestMergingLoadNil(t *testing.T) { |
| 217 | +// // multiple nil assignments to consecutive registers should be merged |
| 218 | +// s := ` |
| 219 | +// function test() |
| 220 | +// local a = 0 |
| 221 | +// local b = 1 |
| 222 | +// local c = 2 |
| 223 | +// |
| 224 | +// -- this should generate just one LOADNIL byte code instruction |
| 225 | +// a = nil |
| 226 | +// b = nil |
| 227 | +// c = nil |
| 228 | +// |
| 229 | +// print(a,b,c) |
| 230 | +// end |
| 231 | +// |
| 232 | +// test()` |
| 233 | +// |
| 234 | +// chunk, err := parse.Parse(strings.NewReader(s), "test") |
| 235 | +// if err != nil { |
| 236 | +// t.Fatal(err) |
| 237 | +// } |
| 238 | +// |
| 239 | +// compiled, err := Compile(chunk, "test") |
| 240 | +// if err != nil { |
| 241 | +// t.Fatal(err) |
| 242 | +// } |
| 243 | +// |
| 244 | +// if len(compiled.FunctionPrototypes) != 1 { |
| 245 | +// t.Fatal("expected 1 function prototype") |
| 246 | +// } |
| 247 | +// |
| 248 | +// // there should be exactly 1 LOADNIL instruction in the byte code generated for the above |
| 249 | +// // anymore, and the LOADNIL merging is not working correctly |
| 250 | +// count := 0 |
| 251 | +// for _, instr := range compiled.FunctionPrototypes[0].Code { |
| 252 | +// if opGetOpCode(instr) == OP_LOADNIL { |
| 253 | +// count++ |
| 254 | +// } |
| 255 | +// } |
| 256 | +// |
| 257 | +// if count != 1 { |
| 258 | +// t.Fatalf("expected 1 LOADNIL instruction, found %d", count) |
| 259 | +// } |
| 260 | +//} |
0 commit comments