| 3120 | } |
| 3121 | |
| 3122 | object invoke(Thread* t, GcMethod* method) |
| 3123 | { |
| 3124 | PROTECT(t, method); |
| 3125 | |
| 3126 | GcClass* class_; |
| 3127 | PROTECT(t, class_); |
| 3128 | |
| 3129 | if (methodVirtual(t, method)) { |
| 3130 | unsigned parameterFootprint = method->parameterFootprint(); |
| 3131 | class_ = objectClass(t, peekObject(t, t->sp - parameterFootprint)); |
| 3132 | |
| 3133 | if (class_->vmFlags() & BootstrapFlag) { |
| 3134 | resolveClass(t, roots(t)->bootLoader(), class_->name()); |
| 3135 | } |
| 3136 | |
| 3137 | if (method->class_()->flags() & ACC_INTERFACE) { |
| 3138 | method = findInterfaceMethod(t, method, class_); |
| 3139 | } else { |
| 3140 | method = findVirtualMethod(t, method, class_); |
| 3141 | } |
| 3142 | } else { |
| 3143 | class_ = method->class_(); |
| 3144 | } |
| 3145 | |
| 3146 | if (method->flags() & ACC_STATIC) { |
| 3147 | initClass(t, class_); |
| 3148 | } |
| 3149 | |
| 3150 | object result = 0; |
| 3151 | |
| 3152 | if (method->flags() & ACC_NATIVE) { |
| 3153 | unsigned returnCode = invokeNative(t, method); |
| 3154 | |
| 3155 | switch (returnCode) { |
| 3156 | case ByteField: |
| 3157 | case BooleanField: |
| 3158 | case CharField: |
| 3159 | case ShortField: |
| 3160 | case FloatField: |
| 3161 | case IntField: |
| 3162 | result = makeInt(t, popInt(t)); |
| 3163 | break; |
| 3164 | |
| 3165 | case LongField: |
| 3166 | case DoubleField: |
| 3167 | result = makeLong(t, popLong(t)); |
| 3168 | break; |
| 3169 | |
| 3170 | case ObjectField: |
| 3171 | result = popObject(t); |
| 3172 | break; |
| 3173 | |
| 3174 | case VoidField: |
| 3175 | result = 0; |
| 3176 | break; |
| 3177 | |
| 3178 | default: |
| 3179 | abort(t); |
no test coverage detected