| 2342 | } |
| 2343 | |
| 2344 | GcList* addInterfaceMethods(Thread* t, |
| 2345 | GcClass* class_, |
| 2346 | GcHashMap* virtualMap, |
| 2347 | unsigned* virtualCount, |
| 2348 | bool makeList) |
| 2349 | { |
| 2350 | GcArray* itable = cast<GcArray>(t, class_->interfaceTable()); |
| 2351 | if (itable) { |
| 2352 | PROTECT(t, class_); |
| 2353 | PROTECT(t, virtualMap); |
| 2354 | PROTECT(t, itable); |
| 2355 | |
| 2356 | GcList* list = 0; |
| 2357 | PROTECT(t, list); |
| 2358 | |
| 2359 | GcMethod* method = 0; |
| 2360 | PROTECT(t, method); |
| 2361 | |
| 2362 | GcArray* vtable = 0; |
| 2363 | PROTECT(t, vtable); |
| 2364 | |
| 2365 | unsigned stride = (class_->flags() & ACC_INTERFACE) ? 1 : 2; |
| 2366 | for (unsigned i = 0; i < itable->length(); i += stride) { |
| 2367 | vtable = cast<GcArray>( |
| 2368 | t, cast<GcClass>(t, itable->body()[i])->virtualTable()); |
| 2369 | if (vtable) { |
| 2370 | for (unsigned j = 0; j < vtable->length(); ++j) { |
| 2371 | method = cast<GcMethod>(t, vtable->body()[j]); |
| 2372 | GcTriple* n |
| 2373 | = hashMapFindNode(t, virtualMap, method, methodHash, methodEqual); |
| 2374 | if (n == 0) { |
| 2375 | method = makeMethod(t, |
| 2376 | method->vmFlags(), |
| 2377 | method->returnCode(), |
| 2378 | method->parameterCount(), |
| 2379 | method->parameterFootprint(), |
| 2380 | method->flags(), |
| 2381 | (*virtualCount)++, |
| 2382 | 0, |
| 2383 | 0, |
| 2384 | method->name(), |
| 2385 | method->spec(), |
| 2386 | 0, |
| 2387 | class_, |
| 2388 | 0); |
| 2389 | |
| 2390 | hashMapInsert(t, virtualMap, method, method, methodHash); |
| 2391 | |
| 2392 | if (makeList) { |
| 2393 | if (list == 0) { |
| 2394 | list = vm::makeList(t, 0, 0, 0); |
| 2395 | } |
| 2396 | listAppend(t, list, method); |
| 2397 | } |
| 2398 | } |
| 2399 | } |
| 2400 | } |
| 2401 | } |
no test coverage detected