| 7145 | } |
| 7146 | |
| 7147 | uint64_t invokeNativeSlow(MyThread* t, GcMethod* method, void* function) |
| 7148 | { |
| 7149 | PROTECT(t, method); |
| 7150 | |
| 7151 | unsigned footprint = method->parameterFootprint() + 1; |
| 7152 | if (method->flags() & ACC_STATIC) { |
| 7153 | ++footprint; |
| 7154 | } |
| 7155 | unsigned count = method->parameterCount() + 2; |
| 7156 | |
| 7157 | THREAD_RUNTIME_ARRAY(t, uintptr_t, args, footprint); |
| 7158 | unsigned argOffset = 0; |
| 7159 | THREAD_RUNTIME_ARRAY(t, uint8_t, types, count); |
| 7160 | unsigned typeOffset = 0; |
| 7161 | |
| 7162 | RUNTIME_ARRAY_BODY(args)[argOffset++] = reinterpret_cast<uintptr_t>(t); |
| 7163 | RUNTIME_ARRAY_BODY(types)[typeOffset++] = POINTER_TYPE; |
| 7164 | |
| 7165 | uintptr_t* sp = static_cast<uintptr_t*>(t->stack) + t->arch->frameFooterSize() |
| 7166 | + t->arch->frameReturnAddressSize(); |
| 7167 | |
| 7168 | GcJclass* jclass = 0; |
| 7169 | PROTECT(t, jclass); |
| 7170 | |
| 7171 | if (method->flags() & ACC_STATIC) { |
| 7172 | jclass = getJClass(t, method->class_()); |
| 7173 | RUNTIME_ARRAY_BODY(args)[argOffset++] |
| 7174 | = reinterpret_cast<uintptr_t>(&jclass); |
| 7175 | } else { |
| 7176 | RUNTIME_ARRAY_BODY(args)[argOffset++] = reinterpret_cast<uintptr_t>(sp++); |
| 7177 | } |
| 7178 | RUNTIME_ARRAY_BODY(types)[typeOffset++] = POINTER_TYPE; |
| 7179 | |
| 7180 | MethodSpecIterator it( |
| 7181 | t, reinterpret_cast<const char*>(method->spec()->body().begin())); |
| 7182 | |
| 7183 | while (it.hasNext()) { |
| 7184 | unsigned type = RUNTIME_ARRAY_BODY(types)[typeOffset++] |
| 7185 | = fieldType(t, fieldCode(t, *it.next())); |
| 7186 | |
| 7187 | switch (type) { |
| 7188 | case INT8_TYPE: |
| 7189 | case INT16_TYPE: |
| 7190 | case INT32_TYPE: |
| 7191 | case FLOAT_TYPE: |
| 7192 | RUNTIME_ARRAY_BODY(args)[argOffset++] = *(sp++); |
| 7193 | break; |
| 7194 | |
| 7195 | case INT64_TYPE: |
| 7196 | case DOUBLE_TYPE: { |
| 7197 | memcpy(RUNTIME_ARRAY_BODY(args) + argOffset, sp, 8); |
| 7198 | argOffset += (8 / BytesPerWord); |
| 7199 | sp += 2; |
| 7200 | } break; |
| 7201 | |
| 7202 | case POINTER_TYPE: { |
| 7203 | if (*sp) { |
| 7204 | RUNTIME_ARRAY_BODY(args)[argOffset++] = reinterpret_cast<uintptr_t>(sp); |
no test coverage detected