1// Copyright 2017 Istio Authors 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package il 16 17import ( 18 "testing" 19) 20 21type builderTest struct { 22 n string 23 i func(*Builder) 24 e []uint32 25} 26 27var builderTests = []builderTest{ 28 { 29 n: "and", 30 i: func(b *Builder) { 31 b.And() 32 }, 33 e: []uint32{ 34 uint32(And), 35 }, 36 }, 37 { 38 n: "xor", 39 i: func(b *Builder) { 40 b.Xor() 41 }, 42 e: []uint32{ 43 uint32(Xor), 44 }, 45 }, 46 { 47 n: "not", 48 i: func(b *Builder) { 49 b.Not() 50 }, 51 e: []uint32{ 52 uint32(Not), 53 }, 54 }, 55 { 56 n: "or", 57 i: func(b *Builder) { 58 b.Or() 59 }, 60 e: []uint32{ 61 uint32(Or), 62 }, 63 }, 64 { 65 n: "eqstring", 66 i: func(b *Builder) { 67 b.EQString() 68 }, 69 e: []uint32{ 70 uint32(EqS), 71 }, 72 }, 73 { 74 n: "aeqstring", 75 i: func(b *Builder) { 76 b.AEQString("abv") 77 }, 78 e: []uint32{ 79 uint32(AEqS), 80 1, //str index 81 }, 82 }, 83 { 84 n: "eqinteger", 85 i: func(b *Builder) { 86 b.EQInteger() 87 }, 88 e: []uint32{ 89 uint32(EqI), 90 }, 91 }, 92 { 93 n: "aeqinteger", 94 i: func(b *Builder) { 95 b.AEQInteger(345) 96 }, 97 e: []uint32{ 98 uint32(AEqI), 99 345, 100 0, 101 }, 102 }, 103 { 104 n: "eqbool", 105 i: func(b *Builder) { 106 b.EQBool() 107 }, 108 e: []uint32{ 109 uint32(EqB), 110 }, 111 }, 112 { 113 n: "aeqbool", 114 i: func(b *Builder) { 115 b.AEQBool(true) 116 }, 117 e: []uint32{ 118 uint32(AEqB), 119 1, 120 }, 121 }, 122 { 123 n: "eqdouble", 124 i: func(b *Builder) { 125 b.EQDouble() 126 }, 127 e: []uint32{ 128 uint32(EqD), 129 }, 130 }, 131 { 132 n: "aeqdouble", 133 i: func(b *Builder) { 134 b.AEQDouble(10.123) 135 }, 136 e: []uint32{ 137 uint32(AEqD), 138 3676492005, 139 1076117241, 140 }, 141 }, 142 { 143 n: "ret", 144 i: func(b *Builder) { 145 b.Ret() 146 }, 147 e: []uint32{ 148 uint32(Ret), 149 }, 150 }, 151 { 152 n: "call", 153 i: func(b *Builder) { 154 b.Call("foo") 155 }, 156 e: []uint32{ 157 uint32(Call), 158 1, //str index 159 }, 160 }, 161 { 162 n: "resolveint", 163 i: func(b *Builder) { 164 b.ResolveInt("foo") 165 }, 166 e: []uint32{ 167 uint32(ResolveI), 168 1, //str index 169 }, 170 }, 171 { 172 n: "tresolveint", 173 i: func(b *Builder) { 174 b.TResolveInt("foo") 175 }, 176 e: []uint32{ 177 uint32(TResolveI), 178 1, //str index 179 }, 180 }, 181 { 182 n: "resolvebool", 183 i: func(b *Builder) { 184 b.ResolveBool("foo") 185 }, 186 e: []uint32{ 187 uint32(ResolveB), 188 1, //str index 189 }, 190 }, 191 { 192 n: "tresolvebool", 193 i: func(b *Builder) { 194 b.TResolveBool("foo") 195 }, 196 e: []uint32{ 197 uint32(TResolveB), 198 1, //str index 199 }, 200 }, 201 { 202 n: "resolvestring", 203 i: func(b *Builder) { 204 b.ResolveString("foo") 205 }, 206 e: []uint32{ 207 uint32(ResolveS), 208 1, //str index 209 }, 210 }, 211 { 212 n: "tresolvestring", 213 i: func(b *Builder) { 214 b.TResolveString("foo") 215 }, 216 e: []uint32{ 217 uint32(TResolveS), 218 1, //str index 219 }, 220 }, 221 { 222 n: "resolvedouble", 223 i: func(b *Builder) { 224 b.ResolveDouble("foo") 225 }, 226 e: []uint32{ 227 uint32(ResolveD), 228 1, //str index 229 }, 230 }, 231 { 232 n: "tresolvedouble", 233 i: func(b *Builder) { 234 b.TResolveDouble("foo") 235 }, 236 e: []uint32{ 237 uint32(TResolveD), 238 1, //str index 239 }, 240 }, 241 { 242 n: "resolveinterface", 243 i: func(b *Builder) { 244 b.ResolveInterface("foo") 245 }, 246 e: []uint32{ 247 uint32(ResolveF), 248 1, //str index 249 }, 250 }, 251 { 252 n: "tresolveinterface", 253 i: func(b *Builder) { 254 b.TResolveInterface("foo") 255 }, 256 e: []uint32{ 257 uint32(TResolveF), 258 1, //str index 259 }, 260 }, 261 { 262 n: "apushbool", 263 i: func(b *Builder) { 264 b.APushBool(true) 265 }, 266 e: []uint32{ 267 uint32(APushB), 268 1, 269 }, 270 }, 271 { 272 n: "apushstr", 273 i: func(b *Builder) { 274 b.APushStr("ABV") 275 }, 276 e: []uint32{ 277 uint32(APushS), 278 1, //str index 279 }, 280 }, 281 { 282 n: "apushdouble", 283 i: func(b *Builder) { 284 b.APushDouble(123.456) 285 }, 286 e: []uint32{ 287 uint32(APushD), 288 446676599, 289 1079958831, 290 }, 291 }, 292 { 293 n: "apushint", 294 i: func(b *Builder) { 295 b.APushInt(456) 296 }, 297 e: []uint32{ 298 uint32(APushI), 299 456, 300 0, 301 }, 302 }, 303 { 304 n: "lookup", 305 i: func(b *Builder) { 306 b.Lookup() 307 }, 308 e: []uint32{ 309 uint32(Lookup), 310 }, 311 }, 312 { 313 n: "nlookup", 314 i: func(b *Builder) { 315 b.NLookup() 316 }, 317 e: []uint32{ 318 uint32(NLookup), 319 }, 320 }, 321 { 322 n: "alookup", 323 i: func(b *Builder) { 324 b.ALookup("abc") 325 }, 326 e: []uint32{ 327 uint32(ALookup), 328 1, //str index 329 }, 330 }, 331 { 332 n: "anlookup", 333 i: func(b *Builder) { 334 b.ANLookup("abc") 335 }, 336 e: []uint32{ 337 uint32(ANLookup), 338 1, //str index 339 }, 340 }, 341 { 342 n: "tlookup", 343 i: func(b *Builder) { 344 b.TLookup() 345 }, 346 e: []uint32{ 347 uint32(TLookup), 348 }, 349 }, 350 { 351 n: "adds", 352 i: func(b *Builder) { 353 b.AddString() 354 }, 355 e: []uint32{ 356 uint32(AddS), 357 }, 358 }, 359 { 360 n: "addi", 361 i: func(b *Builder) { 362 b.AddInteger() 363 }, 364 e: []uint32{ 365 uint32(AddI), 366 }, 367 }, 368 { 369 n: "addd", 370 i: func(b *Builder) { 371 b.AddDouble() 372 }, 373 e: []uint32{ 374 uint32(AddD), 375 }, 376 }, 377 { 378 n: "labels", 379 i: func(b *Builder) { 380 l := b.AllocateLabel() 381 b.Nop() 382 b.Jmp(l) 383 b.Nop() 384 b.Jnz(l) 385 b.Nop() 386 b.Jz(l) 387 b.Nop() 388 b.SetLabelPos(l) 389 b.Nop() 390 b.Jmp(l) 391 b.Nop() 392 b.Jnz(l) 393 b.Nop() 394 b.Jz(l) 395 b.Nop() 396 b.Jmp("LLL") 397 b.SetLabelPos("LLL") 398 b.Nop() 399 }, 400 e: []uint32{ 401 uint32(Nop), 402 uint32(Jmp), 403 10, // label address 404 uint32(Nop), 405 uint32(Jnz), 406 10, // label address 407 uint32(Nop), 408 uint32(Jz), 409 10, // label address 410 uint32(Nop), 411 uint32(Nop), // label points to here 412 uint32(Jmp), 413 10, // label address 414 uint32(Nop), 415 uint32(Jnz), 416 10, // label address 417 uint32(Nop), 418 uint32(Jz), 419 10, // label address 420 uint32(Nop), 421 uint32(Jmp), 422 22, 423 uint32(Nop), 424 }, 425 }, 426} 427 428func Test(t *testing.T) { 429 for _, test := range builderTests { 430 t.Run(test.n, func(tt *testing.T) { 431 p := NewProgram() 432 b := NewBuilder(p.strings) 433 test.i(b) 434 body := b.Build() 435 436 same := (len(body) == len(test.e)) 437 if same { 438 for i := 0; i < len(body); i++ { 439 if body[i] != test.e[i] { 440 same = false 441 break 442 } 443 } 444 } 445 446 if !same { 447 tt.Logf("Expected:\n%v\n", test.e) 448 tt.Logf("Actual:\n%v\n", body) 449 tt.Fatal() 450 } 451 }) 452 } 453} 454 455func TestSetLabelPosTwicePanics(t *testing.T) { 456 defer func() { 457 if r := recover(); r == nil { 458 t.Error("The code did not panic") 459 } 460 }() 461 462 p := NewProgram() 463 b := NewBuilder(p.strings) 464 b.SetLabelPos("l") 465 b.SetLabelPos("l") // Try setting again. 466} 467