blob: 550c6ee106ad0615d6d3750505f922b3f7c37cea [file] [log] [blame]
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "interpreter.h"
18
19#include <math.h>
20
21#include "common_throws.h"
22#include "dex_instruction.h"
23#include "invoke_arg_array_builder.h"
24#include "logging.h"
25#include "object.h"
26#include "object_utils.h"
27#include "runtime_support.h"
28#include "ScopedLocalRef.h"
29#include "scoped_thread_state_change.h"
30#include "thread.h"
31
32namespace art {
33namespace interpreter {
34
35static void DoMonitorEnter(Thread* self, Object* ref) NO_THREAD_SAFETY_ANALYSIS {
36 ref->MonitorEnter(self);
37}
38
39static void DoMonitorExit(Thread* self, Object* ref) NO_THREAD_SAFETY_ANALYSIS {
40 ref->MonitorExit(self);
41}
42
43static void DoInvoke(Thread* self, MethodHelper& mh, ShadowFrame& shadow_frame,
44 const DecodedInstruction& dec_insn, InvokeType type, bool is_range,
45 JValue* result)
46 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
47 Object* receiver;
48 if (type == kStatic) {
49 receiver = NULL;
50 } else {
51 receiver = shadow_frame.GetReference(dec_insn.vC);
52 if (UNLIKELY(receiver == NULL)) {
53 ThrowNullPointerExceptionForMethodAccess(shadow_frame.GetMethod(), dec_insn.vB, type);
54 result->SetJ(0);
55 return;
56 }
57 }
58 uint32_t method_idx = dec_insn.vB;
59 AbstractMethod* target_method = FindMethodFromCode(method_idx, receiver,
60 shadow_frame.GetMethod(), self, true,
61 type);
62 if (UNLIKELY(target_method == NULL)) {
63 CHECK(self->IsExceptionPending());
64 result->SetJ(0);
65 return;
66 }
67 mh.ChangeMethod(target_method);
68 ArgArray arg_array(mh.GetShorty(), mh.GetShortyLength());
69 if (is_range) {
70 arg_array.BuildArgArray(shadow_frame, dec_insn.vC + (type != kStatic ? 1 : 0));
71 } else {
72 arg_array.BuildArgArray(shadow_frame, dec_insn.arg + (type != kStatic ? 1 : 0));
73 }
74 target_method->Invoke(self, receiver, arg_array.get(), result);
75 if (!mh.GetReturnType()->IsPrimitive() && result->GetL() != NULL) {
76 CHECK(mh.GetReturnType()->IsAssignableFrom(result->GetL()->GetClass()));
77 }
78 mh.ChangeMethod(shadow_frame.GetMethod());
79}
80
81static void DoFieldGet(Thread* self, ShadowFrame& shadow_frame,
82 const DecodedInstruction& dec_insn, FindFieldType find_type,
83 Primitive::Type field_type)
84 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
85 bool is_static = (find_type == StaticObjectRead) || (find_type == StaticPrimitiveRead);
86 uint32_t field_idx = is_static ? dec_insn.vB : dec_insn.vC;
87 Field* f = FindFieldFromCode(field_idx, shadow_frame.GetMethod(), self,
88 find_type, Primitive::FieldSize(field_type));
89 if (LIKELY(f != NULL)) {
90 Object* obj;
91 if (is_static) {
92 obj = f->GetDeclaringClass();
93 } else {
94 obj = shadow_frame.GetReference(dec_insn.vB);
95 if (UNLIKELY(obj == NULL)) {
96 ThrowNullPointerExceptionForFieldAccess(f, true);
97 }
98 }
99 switch (field_type) {
100 case Primitive::kPrimBoolean:
101 shadow_frame.SetVReg(dec_insn.vA, f->GetBoolean(obj));
102 break;
103 case Primitive::kPrimByte:
104 shadow_frame.SetVReg(dec_insn.vA, f->GetByte(obj));
105 break;
106 case Primitive::kPrimChar:
107 shadow_frame.SetVReg(dec_insn.vA, f->GetChar(obj));
108 break;
109 case Primitive::kPrimShort:
110 shadow_frame.SetVReg(dec_insn.vA, f->GetShort(obj));
111 break;
112 case Primitive::kPrimInt:
113 shadow_frame.SetVReg(dec_insn.vA, f->GetInt(obj));
114 break;
115 case Primitive::kPrimLong:
116 shadow_frame.SetVRegLong(dec_insn.vA, f->GetLong(obj));
117 break;
118 case Primitive::kPrimNot:
119 shadow_frame.SetReferenceAndVReg(dec_insn.vA, f->GetObject(obj));
120 break;
121 default:
122 LOG(FATAL) << "Unreachable: " << field_type;
123 }
124 }
125}
126
127static void DoFieldPut(Thread* self, ShadowFrame& shadow_frame,
128 const DecodedInstruction& dec_insn, FindFieldType find_type,
129 Primitive::Type field_type)
130 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
131 bool is_static = (find_type == StaticObjectWrite) || (find_type == StaticPrimitiveWrite);
132 uint32_t field_idx = is_static ? dec_insn.vB : dec_insn.vC;
133 Field* f = FindFieldFromCode(field_idx, shadow_frame.GetMethod(), self,
134 find_type, Primitive::FieldSize(field_type));
135 if (LIKELY(f != NULL)) {
136 Object* obj;
137 if (is_static) {
138 obj = f->GetDeclaringClass();
139 } else {
140 obj = shadow_frame.GetReference(dec_insn.vB);
141 if (UNLIKELY(obj == NULL)) {
142 ThrowNullPointerExceptionForFieldAccess(f, false);
143 }
144 }
145 switch (field_type) {
146 case Primitive::kPrimBoolean:
147 f->SetBoolean(obj, shadow_frame.GetVReg(dec_insn.vA));
148 break;
149 case Primitive::kPrimByte:
150 f->SetByte(obj, shadow_frame.GetVReg(dec_insn.vA));
151 shadow_frame.SetVReg(dec_insn.vA, f->GetByte(obj));
152 break;
153 case Primitive::kPrimChar:
154 f->SetChar(obj, shadow_frame.GetVReg(dec_insn.vA));
155 shadow_frame.SetVReg(dec_insn.vA, f->GetChar(obj));
156 break;
157 case Primitive::kPrimShort:
158 f->SetShort(obj, shadow_frame.GetVReg(dec_insn.vA));
159 shadow_frame.SetVReg(dec_insn.vA, f->GetShort(obj));
160 break;
161 case Primitive::kPrimInt:
162 f->SetInt(obj, shadow_frame.GetVReg(dec_insn.vA));
163 shadow_frame.SetVReg(dec_insn.vA, f->GetInt(obj));
164 break;
165 case Primitive::kPrimLong:
166 f->SetLong(obj, shadow_frame.GetVRegLong(dec_insn.vA));
167 shadow_frame.SetVRegLong(dec_insn.vA, f->GetLong(obj));
168 break;
169 case Primitive::kPrimNot:
170 f->SetObj(obj, shadow_frame.GetReference(dec_insn.vA));
171 break;
172 default:
173 LOG(FATAL) << "Unreachable: " << field_type;
174 }
175 }
176}
177
178static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* code_item,
179 ShadowFrame& shadow_frame) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
180 const uint16_t* insns = code_item->insns_;
181 const Instruction* inst = Instruction::At(insns + shadow_frame.GetDexPC());
182 JValue result_register;
183 while (true) {
184 shadow_frame.SetDexPC(inst->GetDexPc(insns));
185 DecodedInstruction dec_insn(inst);
186 const bool kTracing = true;
187 if (kTracing) {
188 LOG(INFO) << PrettyMethod(shadow_frame.GetMethod())
189 << StringPrintf("\n0x%x: %s\nReferences:",
190 inst->GetDexPc(insns), inst->DumpString(&mh.GetDexFile()).c_str());
191 for (size_t i = 0; i < shadow_frame.NumberOfReferences(); ++i) {
192 Object* o = shadow_frame.GetReference(i);
193 if (o != NULL) {
194 if (o->GetClass()->IsStringClass() && o->AsString()->GetCharArray() != NULL) {
195 LOG(INFO) << i << ": java.lang.String " << static_cast<void*>(o)
196 << " \"" << o->AsString()->ToModifiedUtf8() << "\"";
197 } else {
198 LOG(INFO) << i << ": " << PrettyTypeOf(o) << " " << static_cast<void*>(o);
199 }
200 } else {
201 LOG(INFO) << i << ": null";
202 }
203 }
204 LOG(INFO) << "vregs:";
205 for (size_t i = 0; i < shadow_frame.NumberOfReferences(); ++i) {
206 LOG(INFO) << StringPrintf("%d: %08x", i, shadow_frame.GetVReg(i));
207 }
208 }
209 const Instruction* next_inst = inst->Next();
210 switch (dec_insn.opcode) {
211 case Instruction::NOP:
212 break;
213 case Instruction::MOVE:
214 case Instruction::MOVE_FROM16:
215 case Instruction::MOVE_16:
216 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB));
217 break;
218 case Instruction::MOVE_WIDE:
219 case Instruction::MOVE_WIDE_FROM16:
220 case Instruction::MOVE_WIDE_16:
221 shadow_frame.SetVRegLong(dec_insn.vA, shadow_frame.GetVRegLong(dec_insn.vB));
222 break;
223 case Instruction::MOVE_OBJECT:
224 case Instruction::MOVE_OBJECT_FROM16:
225 case Instruction::MOVE_OBJECT_16:
226 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB));
227 shadow_frame.SetReference(dec_insn.vA, shadow_frame.GetReference(dec_insn.vB));
228 break;
229 case Instruction::MOVE_RESULT:
230 shadow_frame.SetVReg(dec_insn.vA, result_register.GetI());
231 break;
232 case Instruction::MOVE_RESULT_WIDE:
233 shadow_frame.SetVRegLong(dec_insn.vA, result_register.GetJ());
234 break;
235 case Instruction::MOVE_RESULT_OBJECT:
236 shadow_frame.SetReferenceAndVReg(dec_insn.vA, result_register.GetL());
237 break;
238 case Instruction::MOVE_EXCEPTION: {
239 Throwable* exception = self->GetException();
240 self->ClearException();
241 shadow_frame.SetReferenceAndVReg(dec_insn.vA, exception);
242 break;
243 }
244 case Instruction::RETURN_VOID: {
245 JValue result;
246 result.SetJ(0);
247 return result;
248 }
249 case Instruction::RETURN: {
250 JValue result;
251 result.SetJ(0);
252 result.SetI(shadow_frame.GetVReg(dec_insn.vA));
253 return result;
254 }
255 case Instruction::RETURN_WIDE: {
256 JValue result;
257 result.SetJ(shadow_frame.GetVRegLong(dec_insn.vA));
258 return result;
259 }
260 case Instruction::RETURN_OBJECT: {
261 JValue result;
262 result.SetJ(0);
263 result.SetL(shadow_frame.GetReference(dec_insn.vA));
264 return result;
265 }
266 case Instruction::CONST_4: {
267 int32_t val = (dec_insn.vB << 28) >> 28;
268 shadow_frame.SetVReg(dec_insn.vA, val);
269 if (val == 0) {
270 shadow_frame.SetReference(dec_insn.vA, NULL);
271 }
272 break;
273 }
274 case Instruction::CONST_16: {
275 int32_t val = static_cast<int16_t>(dec_insn.vB);
276 shadow_frame.SetVReg(dec_insn.vA, val);
277 if (val == 0) {
278 shadow_frame.SetReference(dec_insn.vA, NULL);
279 }
280 break;
281 }
282 case Instruction::CONST: {
283 int32_t val = dec_insn.vB;
284 shadow_frame.SetVReg(dec_insn.vA, val);
285 if (val == 0) {
286 shadow_frame.SetReference(dec_insn.vA, NULL);
287 }
288 break;
289 }
290 case Instruction::CONST_HIGH16: {
291 int32_t val = dec_insn.vB << 16;
292 shadow_frame.SetVReg(dec_insn.vA, val);
293 if (val == 0) {
294 shadow_frame.SetReference(dec_insn.vA, NULL);
295 }
296 break;
297 }
298 case Instruction::CONST_WIDE_16: {
299 int64_t val = static_cast<int16_t>(dec_insn.vB);
300 shadow_frame.SetVReg(dec_insn.vA, val);
301 shadow_frame.SetVReg(dec_insn.vA + 1, val >> 32);
302 break;
303 }
304 case Instruction::CONST_WIDE_32: {
305 int64_t val = static_cast<int32_t>(dec_insn.vB);
306 shadow_frame.SetVReg(dec_insn.vA, val);
307 shadow_frame.SetVReg(dec_insn.vA + 1, val >> 32);
308 break;
309 }
310 case Instruction::CONST_WIDE:
311 shadow_frame.SetVReg(dec_insn.vA, dec_insn.vB_wide);
312 shadow_frame.SetVReg(dec_insn.vA + 1, dec_insn.vB_wide >> 32);
313 break;
314 case Instruction::CONST_WIDE_HIGH16:
315 shadow_frame.SetVRegLong(dec_insn.vA + 1, static_cast<uint64_t>(dec_insn.vB) << 48);
316 break;
317 case Instruction::CONST_STRING:
318 case Instruction::CONST_STRING_JUMBO: {
319 if (UNLIKELY(!String::GetJavaLangString()->IsInitialized())) {
320 Runtime::Current()->GetClassLinker()->EnsureInitialized(String::GetJavaLangString(),
321 true, true);
322 }
323 String* s = mh.ResolveString(dec_insn.vB);
324 shadow_frame.SetReferenceAndVReg(dec_insn.vA, s);
325 break;
326 }
327 case Instruction::CONST_CLASS:
328 shadow_frame.SetReference(dec_insn.vA, mh.ResolveClass(dec_insn.vB));
329 break;
330 case Instruction::MONITOR_ENTER:
331 DoMonitorEnter(self, shadow_frame.GetReference(dec_insn.vA));
332 break;
333 case Instruction::MONITOR_EXIT:
334 DoMonitorExit(self, shadow_frame.GetReference(dec_insn.vA));
335 break;
336 case Instruction::CHECK_CAST: {
337 Class* c = mh.ResolveClass(dec_insn.vB);
338 Object* obj = shadow_frame.GetReference(dec_insn.vA);
339 if (UNLIKELY(obj != NULL && !obj->InstanceOf(c))) {
340 self->ThrowNewExceptionF("Ljava/lang/ClassCastException;",
341 "%s cannot be cast to %s",
342 PrettyDescriptor(obj->GetClass()).c_str(),
343 PrettyDescriptor(c).c_str());
344 }
345 break;
346 }
347 case Instruction::INSTANCE_OF: {
348 Class* c = mh.ResolveClass(dec_insn.vC);
349 Object* obj = shadow_frame.GetReference(dec_insn.vB);
350 shadow_frame.SetVReg(dec_insn.vA, (obj != NULL && obj->InstanceOf(c)) ? 1 : 0);
351 break;
352 }
353 case Instruction::ARRAY_LENGTH: {
354 Array* array = shadow_frame.GetReference(dec_insn.vB)->AsArray();
355 if (UNLIKELY(array == NULL)) {
356 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
357 break;
358 }
359 shadow_frame.SetVReg(dec_insn.vA, array->GetLength());
360 break;
361 }
362 case Instruction::NEW_INSTANCE: {
363 Object* obj = AllocObjectFromCode(dec_insn.vB, shadow_frame.GetMethod(), self, true);
364 shadow_frame.SetReferenceAndVReg(dec_insn.vA, obj);
365 break;
366 }
367 case Instruction::NEW_ARRAY: {
368 int32_t length = shadow_frame.GetVReg(dec_insn.vB);
369 Object* obj = AllocArrayFromCode(dec_insn.vC, shadow_frame.GetMethod(), length, self, true);
370 shadow_frame.SetReferenceAndVReg(dec_insn.vA, obj);
371 break;
372 }
373 case Instruction::FILLED_NEW_ARRAY:
374 case Instruction::FILLED_NEW_ARRAY_RANGE:
375 UNIMPLEMENTED(FATAL) << inst->DumpString(&mh.GetDexFile());
376 break;
377 case Instruction::CMPL_FLOAT: {
378 float val1 = shadow_frame.GetVRegFloat(dec_insn.vB);
379 float val2 = shadow_frame.GetVRegFloat(dec_insn.vC);
380 int32_t result;
381 if (val1 == val2) {
382 result = 0;
383 } else if (val1 > val2) {
384 result = 1;
385 } else {
386 result = -1;
387 }
388 shadow_frame.SetVReg(dec_insn.vA, result);
389 break;
390 }
391 case Instruction::CMPG_FLOAT: {
392 float val1 = shadow_frame.GetVRegFloat(dec_insn.vB);
393 float val2 = shadow_frame.GetVRegFloat(dec_insn.vC);
394 int32_t result;
395 if (val1 == val2) {
396 result = 0;
397 } else if (val1 < val2) {
398 result = -1;
399 } else {
400 result = 1;
401 }
402 shadow_frame.SetVReg(dec_insn.vA, result);
403 break;
404 }
405 case Instruction::CMPL_DOUBLE: {
406 double val1 = shadow_frame.GetVRegDouble(dec_insn.vB);
407 double val2 = shadow_frame.GetVRegDouble(dec_insn.vC);
408 int32_t result;
409 if (val1 == val2) {
410 result = 0;
411 } else if (val1 > val2) {
412 result = 1;
413 } else {
414 result = -1;
415 }
416 shadow_frame.SetVReg(dec_insn.vA, result);
417 break;
418 }
419
420 case Instruction::CMPG_DOUBLE: {
421 double val1 = shadow_frame.GetVRegDouble(dec_insn.vB);
422 double val2 = shadow_frame.GetVRegDouble(dec_insn.vC);
423 int32_t result;
424 if (val1 == val2) {
425 result = 0;
426 } else if (val1 < val2) {
427 result = -1;
428 } else {
429 result = 1;
430 }
431 shadow_frame.SetVReg(dec_insn.vA, result);
432 break;
433 }
434 case Instruction::CMP_LONG: {
435 int64_t val1 = shadow_frame.GetVRegLong(dec_insn.vB);
436 int64_t val2 = shadow_frame.GetVRegLong(dec_insn.vC);
437 int32_t result;
438 if (val1 < val2) {
439 result = -1;
440 } else if (val1 == val2) {
441 result = 0;
442 } else {
443 result = 1;
444 }
445 shadow_frame.SetVReg(dec_insn.vA, result);
446 break;
447 }
448 case Instruction::THROW: {
449 Throwable* t = shadow_frame.GetReference(dec_insn.vA)->AsThrowable();
450 self->SetException(t);
451 break;
452 }
453 case Instruction::GOTO:
454 case Instruction::GOTO_16:
455 case Instruction::GOTO_32: {
456 uint32_t dex_pc = inst->GetDexPc(insns);
457 next_inst = Instruction::At(insns + dex_pc + dec_insn.vA);
458 break;
459 }
460 case Instruction::PACKED_SWITCH:
461 UNIMPLEMENTED(FATAL) << inst->DumpString(&mh.GetDexFile());
462 break;
463 case Instruction::SPARSE_SWITCH: {
464 uint32_t dex_pc = inst->GetDexPc(insns);
465 const uint16_t* switchData = insns + dex_pc + dec_insn.vB;
466 int32_t testVal = shadow_frame.GetVReg(dec_insn.vA);
467 CHECK_EQ(switchData[0], static_cast<uint16_t>(Instruction::kSparseSwitchSignature));
468 uint16_t size = switchData[1];
469 CHECK_GT(size, 0);
470 const int32_t* keys = reinterpret_cast<const int32_t*>(&switchData[2]);
471 CHECK(IsAligned<4>(keys));
472 const int32_t* entries = keys + size;
473 CHECK(IsAligned<4>(entries));
474 int lo = 0;
475 int hi = size - 1;
476 while (lo <= hi) {
477 int mid = (lo + hi) / 2;
478 int32_t foundVal = keys[mid];
479 if (testVal < foundVal) {
480 hi = mid - 1;
481 } else if (testVal > foundVal) {
482 lo = mid + 1;
483 } else {
484 next_inst = Instruction::At(insns + dex_pc + entries[mid]);
485 break;
486 }
487 }
488 break;
489 }
490 case Instruction::FILL_ARRAY_DATA: {
491 Array* array = shadow_frame.GetReference(dec_insn.vA)->AsArray();
492 if (UNLIKELY(array == NULL)) {
493 Thread::Current()->ThrowNewExceptionF("Ljava/lang/NullPointerException;",
494 "null array in FILL_ARRAY_DATA");
495 break;
496 }
497 DCHECK(array->IsArrayInstance() && !array->IsObjectArray());
498 uint32_t dex_pc = inst->GetDexPc(insns);
499 const Instruction::ArrayDataPayload* payload =
500 reinterpret_cast<const Instruction::ArrayDataPayload*>(insns + dex_pc + dec_insn.vB);
501 if (UNLIKELY(static_cast<int32_t>(payload->element_count) > array->GetLength())) {
502 Thread::Current()->ThrowNewExceptionF("Ljava/lang/ArrayIndexOutOfBoundsException;",
503 "failed FILL_ARRAY_DATA; length=%d, index=%d",
504 array->GetLength(), payload->element_count);
505 break;
506 }
507 uint32_t size_in_bytes = payload->element_count * payload->element_width;
508 memcpy(array->GetRawData(payload->element_width), payload->data, size_in_bytes);
509 break;
510 }
511 case Instruction::IF_EQ: {
512 if (shadow_frame.GetVReg(dec_insn.vA) == shadow_frame.GetVReg(dec_insn.vB)) {
513 uint32_t dex_pc = inst->GetDexPc(insns);
514 next_inst = Instruction::At(insns + dex_pc + dec_insn.vC);
515 }
516 break;
517 }
518 case Instruction::IF_NE: {
519 if (shadow_frame.GetVReg(dec_insn.vA) != shadow_frame.GetVReg(dec_insn.vB)) {
520 uint32_t dex_pc = inst->GetDexPc(insns);
521 next_inst = Instruction::At(insns + dex_pc + dec_insn.vC);
522 }
523 break;
524 }
525 case Instruction::IF_LT: {
526 if (shadow_frame.GetVReg(dec_insn.vA) < shadow_frame.GetVReg(dec_insn.vB)) {
527 uint32_t dex_pc = inst->GetDexPc(insns);
528 next_inst = Instruction::At(insns + dex_pc + dec_insn.vC);
529 }
530 break;
531 }
532 case Instruction::IF_GE: {
533 if (shadow_frame.GetVReg(dec_insn.vA) >= shadow_frame.GetVReg(dec_insn.vB)) {
534 uint32_t dex_pc = inst->GetDexPc(insns);
535 next_inst = Instruction::At(insns + dex_pc + dec_insn.vC);
536 }
537 break;
538 }
539 case Instruction::IF_GT: {
540 if (shadow_frame.GetVReg(dec_insn.vA) > shadow_frame.GetVReg(dec_insn.vB)) {
541 uint32_t dex_pc = inst->GetDexPc(insns);
542 next_inst = Instruction::At(insns + dex_pc + dec_insn.vC);
543 }
544 break;
545 }
546 case Instruction::IF_LE: {
547 if (shadow_frame.GetVReg(dec_insn.vA) <= shadow_frame.GetVReg(dec_insn.vB)) {
548 uint32_t dex_pc = inst->GetDexPc(insns);
549 next_inst = Instruction::At(insns + dex_pc + dec_insn.vC);
550 }
551 break;
552 }
553 case Instruction::IF_EQZ: {
554 if (shadow_frame.GetVReg(dec_insn.vA) == 0) {
555 uint32_t dex_pc = inst->GetDexPc(insns);
556 next_inst = Instruction::At(insns + dex_pc + dec_insn.vB);
557 }
558 break;
559 }
560 case Instruction::IF_NEZ: {
561 if (shadow_frame.GetVReg(dec_insn.vA) != 0) {
562 uint32_t dex_pc = inst->GetDexPc(insns);
563 next_inst = Instruction::At(insns + dex_pc + dec_insn.vB);
564 }
565 break;
566 }
567 case Instruction::IF_LTZ: {
568 if (shadow_frame.GetVReg(dec_insn.vA) < 0) {
569 uint32_t dex_pc = inst->GetDexPc(insns);
570 next_inst = Instruction::At(insns + dex_pc + dec_insn.vB);
571 }
572 break;
573 }
574 case Instruction::IF_GEZ: {
575 if (shadow_frame.GetVReg(dec_insn.vA) >= 0) {
576 uint32_t dex_pc = inst->GetDexPc(insns);
577 next_inst = Instruction::At(insns + dex_pc + dec_insn.vB);
578 }
579 break;
580 }
581 case Instruction::IF_GTZ: {
582 if (shadow_frame.GetVReg(dec_insn.vA) > 0) {
583 uint32_t dex_pc = inst->GetDexPc(insns);
584 next_inst = Instruction::At(insns + dex_pc + dec_insn.vB);
585 }
586 break;
587 }
588 case Instruction::IF_LEZ: {
589 if (shadow_frame.GetVReg(dec_insn.vA) <= 0) {
590 uint32_t dex_pc = inst->GetDexPc(insns);
591 next_inst = Instruction::At(insns + dex_pc + dec_insn.vB);
592 }
593 break;
594 }
595 case Instruction::AGET_BOOLEAN: {
596 BooleanArray* a = shadow_frame.GetReference(dec_insn.vB)->AsBooleanArray();
597 if (UNLIKELY(a == NULL)) {
598 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
599 break;
600 }
601 int32_t index = shadow_frame.GetVReg(dec_insn.vC);
602 shadow_frame.SetVReg(dec_insn.vA, a->Get(index));
603 break;
604 }
605 case Instruction::AGET_BYTE: {
606 ByteArray* a = shadow_frame.GetReference(dec_insn.vB)->AsByteArray();
607 if (UNLIKELY(a == NULL)) {
608 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
609 break;
610 }
611 int32_t index = shadow_frame.GetVReg(dec_insn.vC);
612 shadow_frame.SetVReg(dec_insn.vA, a->Get(index));
613 break;
614 }
615 case Instruction::AGET_CHAR: {
616 CharArray* a = shadow_frame.GetReference(dec_insn.vB)->AsCharArray();
617 if (UNLIKELY(a == NULL)) {
618 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
619 break;
620 }
621 int32_t index = shadow_frame.GetVReg(dec_insn.vC);
622 shadow_frame.SetVReg(dec_insn.vA, a->Get(index));
623 break;
624 }
625 case Instruction::AGET_SHORT: {
626 ShortArray* a = shadow_frame.GetReference(dec_insn.vB)->AsShortArray();
627 if (UNLIKELY(a == NULL)) {
628 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
629 break;
630 }
631 int32_t index = shadow_frame.GetVReg(dec_insn.vC);
632 shadow_frame.SetVReg(dec_insn.vA, a->Get(index));
633 break;
634 }
635 case Instruction::AGET: {
636 IntArray* a = shadow_frame.GetReference(dec_insn.vB)->AsIntArray();
637 if (UNLIKELY(a == NULL)) {
638 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
639 break;
640 }
641 int32_t index = shadow_frame.GetVReg(dec_insn.vC);
642 shadow_frame.SetVReg(dec_insn.vA, a->Get(index));
643 break;
644 }
645 case Instruction::AGET_WIDE: {
646 LongArray* a = shadow_frame.GetReference(dec_insn.vB)->AsLongArray();
647 if (UNLIKELY(a == NULL)) {
648 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
649 break;
650 }
651 int32_t index = shadow_frame.GetVReg(dec_insn.vC);
652 shadow_frame.SetVRegLong(dec_insn.vA, a->Get(index));
653 break;
654 }
655 case Instruction::AGET_OBJECT: {
656 ObjectArray<Object>* a = shadow_frame.GetReference(dec_insn.vB)->AsObjectArray<Object>();
657 if (UNLIKELY(a == NULL)) {
658 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
659 break;
660 }
661 int32_t index = shadow_frame.GetVReg(dec_insn.vC);
662 Object* o = a->Get(index);
663 shadow_frame.SetReferenceAndVReg(dec_insn.vA, o);
664 break;
665 }
666 case Instruction::APUT_BOOLEAN: {
667 uint8_t val = shadow_frame.GetVReg(dec_insn.vA);
668 BooleanArray* a = shadow_frame.GetReference(dec_insn.vB)->AsBooleanArray();
669 if (UNLIKELY(a == NULL)) {
670 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
671 break;
672 }
673 int32_t index = shadow_frame.GetVReg(dec_insn.vC);
674 a->Set(index, val);
675 break;
676 }
677 case Instruction::APUT_BYTE: {
678 int8_t val = shadow_frame.GetVReg(dec_insn.vA);
679 ByteArray* a = shadow_frame.GetReference(dec_insn.vB)->AsByteArray();
680 if (UNLIKELY(a == NULL)) {
681 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
682 break;
683 }
684 int32_t index = shadow_frame.GetVReg(dec_insn.vC);
685 a->Set(index, val);
686 break;
687 }
688 case Instruction::APUT_CHAR: {
689 uint16_t val = shadow_frame.GetVReg(dec_insn.vA);
690 CharArray* a = shadow_frame.GetReference(dec_insn.vB)->AsCharArray();
691 if (UNLIKELY(a == NULL)) {
692 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
693 break;
694 }
695 int32_t index = shadow_frame.GetVReg(dec_insn.vC);
696 a->Set(index, val);
697 break;
698 }
699 case Instruction::APUT_SHORT: {
700 int16_t val = shadow_frame.GetVReg(dec_insn.vA);
701 ShortArray* a = shadow_frame.GetReference(dec_insn.vB)->AsShortArray();
702 if (UNLIKELY(a == NULL)) {
703 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
704 break;
705 }
706 int32_t index = shadow_frame.GetVReg(dec_insn.vC);
707 a->Set(index, val);
708 break;
709 }
710 case Instruction::APUT: {
711 int32_t val = shadow_frame.GetVReg(dec_insn.vA);
712 IntArray* a = shadow_frame.GetReference(dec_insn.vB)->AsIntArray();
713 if (UNLIKELY(a == NULL)) {
714 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
715 break;
716 }
717 int32_t index = shadow_frame.GetVReg(dec_insn.vC);
718 a->Set(index, val);
719 break;
720 }
721 case Instruction::APUT_WIDE: {
722 int64_t val = shadow_frame.GetVRegLong(dec_insn.vA);
723 LongArray* a = shadow_frame.GetReference(dec_insn.vB)->AsLongArray();
724 if (UNLIKELY(a == NULL)) {
725 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
726 break;
727 }
728 int32_t index = shadow_frame.GetVReg(dec_insn.vC);
729 a->Set(index, val);
730 break;
731 }
732 case Instruction::APUT_OBJECT: {
733 Object* val = shadow_frame.GetReference(dec_insn.vA);
734 ObjectArray<Object>* a = shadow_frame.GetReference(dec_insn.vB)->AsObjectArray<Object>();
735 if (UNLIKELY(a == NULL)) {
736 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
737 break;
738 }
739 int32_t index = shadow_frame.GetVReg(dec_insn.vC);
740 a->Set(index, val);
741 break;
742 }
743 case Instruction::IGET_BOOLEAN:
744 DoFieldGet(self, shadow_frame, dec_insn, InstancePrimitiveRead, Primitive::kPrimBoolean);
745 break;
746 case Instruction::IGET_BYTE:
747 DoFieldGet(self, shadow_frame, dec_insn, InstancePrimitiveRead, Primitive::kPrimByte);
748 break;
749 case Instruction::IGET_CHAR:
750 DoFieldGet(self, shadow_frame, dec_insn, InstancePrimitiveRead, Primitive::kPrimChar);
751 break;
752 case Instruction::IGET_SHORT:
753 DoFieldGet(self, shadow_frame, dec_insn, InstancePrimitiveRead, Primitive::kPrimShort);
754 break;
755 case Instruction::IGET:
756 DoFieldGet(self, shadow_frame, dec_insn, InstancePrimitiveRead, Primitive::kPrimInt);
757 break;
758 case Instruction::IGET_WIDE:
759 DoFieldGet(self, shadow_frame, dec_insn, InstancePrimitiveRead, Primitive::kPrimLong);
760 break;
761 case Instruction::IGET_OBJECT:
762 DoFieldGet(self, shadow_frame, dec_insn, InstanceObjectRead, Primitive::kPrimNot);
763 break;
764 case Instruction::SGET_BOOLEAN:
765 DoFieldGet(self, shadow_frame, dec_insn, StaticPrimitiveRead, Primitive::kPrimBoolean);
766 break;
767 case Instruction::SGET_BYTE:
768 DoFieldGet(self, shadow_frame, dec_insn, StaticPrimitiveRead, Primitive::kPrimByte);
769 break;
770 case Instruction::SGET_CHAR:
771 DoFieldGet(self, shadow_frame, dec_insn, StaticPrimitiveRead, Primitive::kPrimChar);
772 break;
773 case Instruction::SGET_SHORT:
774 DoFieldGet(self, shadow_frame, dec_insn, StaticPrimitiveRead, Primitive::kPrimShort);
775 break;
776 case Instruction::SGET:
777 DoFieldGet(self, shadow_frame, dec_insn, StaticPrimitiveRead, Primitive::kPrimInt);
778 break;
779 case Instruction::SGET_WIDE:
780 DoFieldGet(self, shadow_frame, dec_insn, StaticPrimitiveRead, Primitive::kPrimLong);
781 break;
782 case Instruction::SGET_OBJECT:
783 DoFieldGet(self, shadow_frame, dec_insn, StaticObjectRead, Primitive::kPrimNot);
784 break;
785 case Instruction::IPUT_BOOLEAN:
786 DoFieldPut(self, shadow_frame, dec_insn, InstancePrimitiveWrite, Primitive::kPrimBoolean);
787 break;
788 case Instruction::IPUT_BYTE:
789 DoFieldPut(self, shadow_frame, dec_insn, InstancePrimitiveWrite, Primitive::kPrimByte);
790 break;
791 case Instruction::IPUT_CHAR:
792 DoFieldPut(self, shadow_frame, dec_insn, InstancePrimitiveWrite, Primitive::kPrimChar);
793 break;
794 case Instruction::IPUT_SHORT:
795 DoFieldPut(self, shadow_frame, dec_insn, InstancePrimitiveWrite, Primitive::kPrimShort);
796 break;
797 case Instruction::IPUT:
798 DoFieldPut(self, shadow_frame, dec_insn, InstancePrimitiveWrite, Primitive::kPrimInt);
799 break;
800 case Instruction::IPUT_WIDE:
801 DoFieldPut(self, shadow_frame, dec_insn, InstancePrimitiveWrite, Primitive::kPrimLong);
802 break;
803 case Instruction::IPUT_OBJECT:
804 DoFieldPut(self, shadow_frame, dec_insn, InstanceObjectWrite, Primitive::kPrimNot);
805 break;
806 case Instruction::SPUT_BOOLEAN:
807 DoFieldPut(self, shadow_frame, dec_insn, StaticPrimitiveWrite, Primitive::kPrimBoolean);
808 break;
809 case Instruction::SPUT_BYTE:
810 DoFieldPut(self, shadow_frame, dec_insn, StaticPrimitiveWrite, Primitive::kPrimByte);
811 break;
812 case Instruction::SPUT_CHAR:
813 DoFieldPut(self, shadow_frame, dec_insn, StaticPrimitiveWrite, Primitive::kPrimChar);
814 break;
815 case Instruction::SPUT_SHORT:
816 DoFieldPut(self, shadow_frame, dec_insn, StaticPrimitiveWrite, Primitive::kPrimShort);
817 break;
818 case Instruction::SPUT:
819 DoFieldPut(self, shadow_frame, dec_insn, StaticPrimitiveWrite, Primitive::kPrimInt);
820 break;
821 case Instruction::SPUT_WIDE:
822 DoFieldPut(self, shadow_frame, dec_insn, StaticPrimitiveWrite, Primitive::kPrimLong);
823 break;
824 case Instruction::SPUT_OBJECT:
825 DoFieldPut(self, shadow_frame, dec_insn, StaticObjectWrite, Primitive::kPrimNot);
826 break;
827 case Instruction::INVOKE_VIRTUAL:
828 DoInvoke(self, mh, shadow_frame, dec_insn, kVirtual, false, &result_register);
829 break;
830 case Instruction::INVOKE_VIRTUAL_RANGE:
831 DoInvoke(self, mh, shadow_frame, dec_insn, kVirtual, true, &result_register);
832 break;
833 case Instruction::INVOKE_SUPER:
834 DoInvoke(self, mh, shadow_frame, dec_insn, kSuper, false, &result_register);
835 break;
836 case Instruction::INVOKE_SUPER_RANGE:
837 DoInvoke(self, mh, shadow_frame, dec_insn, kSuper, true, &result_register);
838 break;
839 case Instruction::INVOKE_DIRECT:
840 DoInvoke(self, mh, shadow_frame, dec_insn, kDirect, false, &result_register);
841 break;
842 case Instruction::INVOKE_DIRECT_RANGE:
843 DoInvoke(self, mh, shadow_frame, dec_insn, kDirect, true, &result_register);
844 break;
845 case Instruction::INVOKE_INTERFACE:
846 DoInvoke(self, mh, shadow_frame, dec_insn, kInterface, false, &result_register);
847 break;
848 case Instruction::INVOKE_INTERFACE_RANGE:
849 DoInvoke(self, mh, shadow_frame, dec_insn, kInterface, true, &result_register);
850 break;
851 case Instruction::INVOKE_STATIC:
852 DoInvoke(self, mh, shadow_frame, dec_insn, kStatic, false, &result_register);
853 break;
854 case Instruction::INVOKE_STATIC_RANGE:
855 DoInvoke(self, mh, shadow_frame, dec_insn, kStatic, true, &result_register);
856 break;
857 case Instruction::NEG_INT:
858 shadow_frame.SetVReg(dec_insn.vA, -shadow_frame.GetVReg(dec_insn.vB));
859 break;
860 case Instruction::NOT_INT:
861 shadow_frame.SetVReg(dec_insn.vA, 0 ^ shadow_frame.GetVReg(dec_insn.vB));
862 break;
863 case Instruction::NEG_LONG:
864 shadow_frame.SetVRegLong(dec_insn.vA, -shadow_frame.GetVRegLong(dec_insn.vB));
865 break;
866 case Instruction::NOT_LONG:
867 shadow_frame.SetVRegLong(dec_insn.vA, 0 ^ shadow_frame.GetVRegLong(dec_insn.vB));
868 break;
869 case Instruction::NEG_FLOAT:
870 shadow_frame.SetVRegFloat(dec_insn.vA, -shadow_frame.GetVRegFloat(dec_insn.vB));
871 break;
872 case Instruction::NEG_DOUBLE:
873 shadow_frame.SetVRegDouble(dec_insn.vA, -shadow_frame.GetVRegDouble(dec_insn.vB));
874 break;
875 case Instruction::INT_TO_LONG:
876 shadow_frame.SetVRegLong(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB));
877 break;
878 case Instruction::INT_TO_FLOAT:
879 shadow_frame.SetVRegFloat(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB));
880 break;
881 case Instruction::INT_TO_DOUBLE:
882 shadow_frame.SetVRegDouble(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB));
883 break;
884 case Instruction::LONG_TO_INT:
885 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVRegLong(dec_insn.vB));
886 break;
887 case Instruction::LONG_TO_FLOAT:
888 shadow_frame.SetVRegFloat(dec_insn.vA, shadow_frame.GetVRegLong(dec_insn.vB));
889 break;
890 case Instruction::LONG_TO_DOUBLE:
891 shadow_frame.SetVRegDouble(dec_insn.vA, shadow_frame.GetVRegLong(dec_insn.vB));
892 break;
893 case Instruction::FLOAT_TO_INT:
894 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVRegFloat(dec_insn.vB));
895 break;
896 case Instruction::FLOAT_TO_LONG:
897 shadow_frame.SetVRegLong(dec_insn.vA, shadow_frame.GetVRegFloat(dec_insn.vB));
898 break;
899 case Instruction::FLOAT_TO_DOUBLE:
900 shadow_frame.SetVRegDouble(dec_insn.vA, shadow_frame.GetVRegFloat(dec_insn.vB));
901 break;
902 case Instruction::DOUBLE_TO_INT:
903 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVRegDouble(dec_insn.vB));
904 break;
905 case Instruction::DOUBLE_TO_LONG:
906 shadow_frame.SetVRegLong(dec_insn.vA, shadow_frame.GetVRegDouble(dec_insn.vB));
907 break;
908 case Instruction::DOUBLE_TO_FLOAT:
909 shadow_frame.SetVRegFloat(dec_insn.vA, shadow_frame.GetVRegDouble(dec_insn.vB));
910 break;
911 case Instruction::INT_TO_BYTE:
912 shadow_frame.SetVReg(dec_insn.vA, static_cast<int8_t>(shadow_frame.GetVReg(dec_insn.vB)));
913 break;
914 case Instruction::INT_TO_CHAR:
915 shadow_frame.SetVReg(dec_insn.vA, static_cast<uint16_t>(shadow_frame.GetVReg(dec_insn.vB)));
916 break;
917 case Instruction::INT_TO_SHORT:
918 shadow_frame.SetVReg(dec_insn.vA, static_cast<int16_t>(shadow_frame.GetVReg(dec_insn.vB)));
919 break;
920 case Instruction::ADD_INT:
921 shadow_frame.SetVReg(dec_insn.vA,
922 shadow_frame.GetVReg(dec_insn.vB) + shadow_frame.GetVReg(dec_insn.vC));
923 break;
924 case Instruction::SUB_INT:
925 shadow_frame.SetVReg(dec_insn.vA,
926 shadow_frame.GetVReg(dec_insn.vB) - shadow_frame.GetVReg(dec_insn.vC));
927 break;
928 case Instruction::MUL_INT:
929 shadow_frame.SetVReg(dec_insn.vA,
930 shadow_frame.GetVReg(dec_insn.vB) * shadow_frame.GetVReg(dec_insn.vC));
931 break;
932 case Instruction::REM_INT:
933 shadow_frame.SetVReg(dec_insn.vA,
934 shadow_frame.GetVReg(dec_insn.vB) % shadow_frame.GetVReg(dec_insn.vC));
935 break;
936 case Instruction::DIV_INT:
937 shadow_frame.SetVReg(dec_insn.vA,
938 shadow_frame.GetVReg(dec_insn.vB) / shadow_frame.GetVReg(dec_insn.vC));
939 break;
940 case Instruction::SHL_INT:
941 shadow_frame.SetVReg(dec_insn.vA,
942 shadow_frame.GetVReg(dec_insn.vB) << shadow_frame.GetVReg(dec_insn.vC));
943 break;
944 case Instruction::SHR_INT:
945 shadow_frame.SetVReg(dec_insn.vA,
946 shadow_frame.GetVReg(dec_insn.vB) >> shadow_frame.GetVReg(dec_insn.vC));
947 break;
948 case Instruction::USHR_INT:
949 shadow_frame.SetVReg(dec_insn.vA,
950 static_cast<uint32_t>(shadow_frame.GetVReg(dec_insn.vB)) >>
951 shadow_frame.GetVReg(dec_insn.vC));
952 break;
953 case Instruction::AND_INT:
954 shadow_frame.SetVReg(dec_insn.vA,
955 shadow_frame.GetVReg(dec_insn.vB) & shadow_frame.GetVReg(dec_insn.vC));
956 break;
957 case Instruction::OR_INT:
958 shadow_frame.SetVReg(dec_insn.vA,
959 shadow_frame.GetVReg(dec_insn.vB) | shadow_frame.GetVReg(dec_insn.vC));
960 break;
961 case Instruction::XOR_INT:
962 shadow_frame.SetVReg(dec_insn.vA,
963 shadow_frame.GetVReg(dec_insn.vB) ^ shadow_frame.GetVReg(dec_insn.vC));
964 break;
965 case Instruction::ADD_LONG:
966 shadow_frame.SetVRegLong(dec_insn.vA,
967 shadow_frame.GetVRegLong(dec_insn.vB) +
968 shadow_frame.GetVRegLong(dec_insn.vC));
969 break;
970 case Instruction::SUB_LONG:
971 shadow_frame.SetVRegLong(dec_insn.vA,
972 shadow_frame.GetVRegLong(dec_insn.vB) -
973 shadow_frame.GetVRegLong(dec_insn.vC));
974 break;
975 case Instruction::MUL_LONG:
976 shadow_frame.SetVRegLong(dec_insn.vA,
977 shadow_frame.GetVRegLong(dec_insn.vB) *
978 shadow_frame.GetVRegLong(dec_insn.vC));
979 break;
980 case Instruction::DIV_LONG:
981 shadow_frame.SetVRegLong(dec_insn.vA,
982 shadow_frame.GetVRegLong(dec_insn.vB) /
983 shadow_frame.GetVRegLong(dec_insn.vC));
984 break;
985 case Instruction::REM_LONG:
986 shadow_frame.SetVRegLong(dec_insn.vA,
987 shadow_frame.GetVRegLong(dec_insn.vB) %
988 shadow_frame.GetVRegLong(dec_insn.vC));
989 break;
990 case Instruction::AND_LONG:
991 shadow_frame.SetVRegLong(dec_insn.vA,
992 shadow_frame.GetVRegLong(dec_insn.vB) &
993 shadow_frame.GetVRegLong(dec_insn.vC));
994 break;
995 case Instruction::OR_LONG:
996 shadow_frame.SetVRegLong(dec_insn.vA,
997 shadow_frame.GetVRegLong(dec_insn.vB) |
998 shadow_frame.GetVRegLong(dec_insn.vC));
999 break;
1000 case Instruction::XOR_LONG:
1001 shadow_frame.SetVRegLong(dec_insn.vA,
1002 shadow_frame.GetVRegLong(dec_insn.vB) ^
1003 shadow_frame.GetVRegLong(dec_insn.vC));
1004 break;
1005 case Instruction::SHL_LONG:
1006 shadow_frame.SetVRegLong(dec_insn.vA,
1007 shadow_frame.GetVRegLong(dec_insn.vB) <<
1008 shadow_frame.GetVReg(dec_insn.vC));
1009 break;
1010 case Instruction::SHR_LONG:
1011 shadow_frame.SetVRegLong(dec_insn.vA,
1012 shadow_frame.GetVRegLong(dec_insn.vB) >>
1013 shadow_frame.GetVReg(dec_insn.vC));
1014 break;
1015 case Instruction::USHR_LONG:
1016 shadow_frame.SetVRegLong(dec_insn.vA,
1017 static_cast<uint64_t>(shadow_frame.GetVRegLong(dec_insn.vB)) >>
1018 shadow_frame.GetVReg(dec_insn.vC));
1019 break;
1020 case Instruction::ADD_FLOAT:
1021 shadow_frame.SetVRegFloat(dec_insn.vA,
1022 shadow_frame.GetVRegFloat(dec_insn.vB) +
1023 shadow_frame.GetVRegFloat(dec_insn.vC));
1024 break;
1025 case Instruction::SUB_FLOAT:
1026 shadow_frame.SetVRegFloat(dec_insn.vA,
1027 shadow_frame.GetVRegFloat(dec_insn.vB) -
1028 shadow_frame.GetVRegFloat(dec_insn.vC));
1029 break;
1030 case Instruction::MUL_FLOAT:
1031 shadow_frame.SetVRegFloat(dec_insn.vA,
1032 shadow_frame.GetVRegFloat(dec_insn.vB) *
1033 shadow_frame.GetVRegFloat(dec_insn.vC));
1034 break;
1035 case Instruction::DIV_FLOAT:
1036 shadow_frame.SetVRegFloat(dec_insn.vA,
1037 shadow_frame.GetVRegFloat(dec_insn.vB) /
1038 shadow_frame.GetVRegFloat(dec_insn.vC));
1039 break;
1040 case Instruction::REM_FLOAT:
1041 shadow_frame.SetVRegFloat(dec_insn.vA,
1042 fmodf(shadow_frame.GetVRegFloat(dec_insn.vB),
1043 shadow_frame.GetVRegFloat(dec_insn.vC)));
1044 break;
1045 case Instruction::ADD_DOUBLE:
1046 shadow_frame.SetVRegDouble(dec_insn.vA,
1047 shadow_frame.GetVRegDouble(dec_insn.vB) +
1048 shadow_frame.GetVRegDouble(dec_insn.vC));
1049 break;
1050 case Instruction::SUB_DOUBLE:
1051 shadow_frame.SetVRegDouble(dec_insn.vA,
1052 shadow_frame.GetVRegDouble(dec_insn.vB) -
1053 shadow_frame.GetVRegDouble(dec_insn.vC));
1054 break;
1055 case Instruction::MUL_DOUBLE:
1056 shadow_frame.SetVRegDouble(dec_insn.vA,
1057 shadow_frame.GetVRegDouble(dec_insn.vB) *
1058 shadow_frame.GetVRegDouble(dec_insn.vC));
1059 break;
1060 case Instruction::DIV_DOUBLE:
1061 shadow_frame.SetVRegDouble(dec_insn.vA,
1062 shadow_frame.GetVRegDouble(dec_insn.vB) /
1063 shadow_frame.GetVRegDouble(dec_insn.vC));
1064 break;
1065 case Instruction::REM_DOUBLE:
1066 shadow_frame.SetVRegDouble(dec_insn.vA,
1067 fmod(shadow_frame.GetVRegDouble(dec_insn.vB),
1068 shadow_frame.GetVRegDouble(dec_insn.vC)));
1069 break;
1070 case Instruction::ADD_INT_2ADDR:
1071 shadow_frame.SetVReg(dec_insn.vA,
1072 shadow_frame.GetVReg(dec_insn.vA) + shadow_frame.GetVReg(dec_insn.vB));
1073 break;
1074 case Instruction::SUB_INT_2ADDR:
1075 shadow_frame.SetVReg(dec_insn.vA,
1076 shadow_frame.GetVReg(dec_insn.vA) - shadow_frame.GetVReg(dec_insn.vB));
1077 break;
1078 case Instruction::MUL_INT_2ADDR:
1079 shadow_frame.SetVReg(dec_insn.vA,
1080 shadow_frame.GetVReg(dec_insn.vA) * shadow_frame.GetVReg(dec_insn.vB));
1081 break;
1082 case Instruction::REM_INT_2ADDR:
1083 shadow_frame.SetVReg(dec_insn.vA,
1084 shadow_frame.GetVReg(dec_insn.vA) % shadow_frame.GetVReg(dec_insn.vB));
1085 break;
1086 case Instruction::SHL_INT_2ADDR:
1087 shadow_frame.SetVReg(dec_insn.vA,
1088 shadow_frame.GetVReg(dec_insn.vA) << shadow_frame.GetVReg(dec_insn.vB));
1089 break;
1090 case Instruction::SHR_INT_2ADDR:
1091 shadow_frame.SetVReg(dec_insn.vA,
1092 shadow_frame.GetVReg(dec_insn.vA) >> shadow_frame.GetVReg(dec_insn.vB));
1093 break;
1094 case Instruction::USHR_INT_2ADDR:
1095 shadow_frame.SetVReg(dec_insn.vA,
1096 static_cast<uint32_t>(shadow_frame.GetVReg(dec_insn.vA)) >>
1097 shadow_frame.GetVReg(dec_insn.vB));
1098 break;
1099 case Instruction::AND_INT_2ADDR:
1100 shadow_frame.SetVReg(dec_insn.vA,
1101 shadow_frame.GetVReg(dec_insn.vA) & shadow_frame.GetVReg(dec_insn.vB));
1102 break;
1103 case Instruction::OR_INT_2ADDR:
1104 shadow_frame.SetVReg(dec_insn.vA,
1105 shadow_frame.GetVReg(dec_insn.vA) | shadow_frame.GetVReg(dec_insn.vB));
1106 break;
1107 case Instruction::XOR_INT_2ADDR:
1108 shadow_frame.SetVReg(dec_insn.vA,
1109 shadow_frame.GetVReg(dec_insn.vA) ^ shadow_frame.GetVReg(dec_insn.vB));
1110 break;
1111 case Instruction::DIV_INT_2ADDR:
1112 shadow_frame.SetVReg(dec_insn.vA,
1113 shadow_frame.GetVReg(dec_insn.vA) / shadow_frame.GetVReg(dec_insn.vB));
1114 break;
1115 case Instruction::ADD_LONG_2ADDR:
1116 shadow_frame.SetVRegLong(dec_insn.vA,
1117 shadow_frame.GetVRegLong(dec_insn.vA) +
1118 shadow_frame.GetVRegLong(dec_insn.vB));
1119 break;
1120 case Instruction::SUB_LONG_2ADDR:
1121 shadow_frame.SetVRegLong(dec_insn.vA,
1122 shadow_frame.GetVRegLong(dec_insn.vA) -
1123 shadow_frame.GetVRegLong(dec_insn.vB));
1124 break;
1125 case Instruction::MUL_LONG_2ADDR:
1126 shadow_frame.SetVRegLong(dec_insn.vA,
1127 shadow_frame.GetVRegLong(dec_insn.vA) +
1128 shadow_frame.GetVRegLong(dec_insn.vB));
1129 break;
1130 case Instruction::DIV_LONG_2ADDR:
1131 shadow_frame.SetVRegLong(dec_insn.vA,
1132 shadow_frame.GetVRegLong(dec_insn.vA) /
1133 shadow_frame.GetVRegLong(dec_insn.vB));
1134 break;
1135 case Instruction::REM_LONG_2ADDR:
1136 shadow_frame.SetVRegLong(dec_insn.vA,
1137 shadow_frame.GetVRegLong(dec_insn.vA) %
1138 shadow_frame.GetVRegLong(dec_insn.vB));
1139 break;
1140 case Instruction::AND_LONG_2ADDR:
1141 shadow_frame.SetVRegLong(dec_insn.vA,
1142 shadow_frame.GetVRegLong(dec_insn.vA) &
1143 shadow_frame.GetVRegLong(dec_insn.vB));
1144 break;
1145 case Instruction::OR_LONG_2ADDR:
1146 shadow_frame.SetVRegLong(dec_insn.vA,
1147 shadow_frame.GetVRegLong(dec_insn.vA) |
1148 shadow_frame.GetVRegLong(dec_insn.vB));
1149 break;
1150 case Instruction::XOR_LONG_2ADDR:
1151 shadow_frame.SetVRegLong(dec_insn.vA,
1152 shadow_frame.GetVRegLong(dec_insn.vA) ^
1153 shadow_frame.GetVRegLong(dec_insn.vB));
1154 break;
1155 case Instruction::SHL_LONG_2ADDR:
1156 shadow_frame.SetVRegLong(dec_insn.vA,
1157 shadow_frame.GetVRegLong(dec_insn.vA) <<
1158 shadow_frame.GetVReg(dec_insn.vB));
1159 break;
1160 case Instruction::SHR_LONG_2ADDR:
1161 shadow_frame.SetVRegLong(dec_insn.vA,
1162 shadow_frame.GetVRegLong(dec_insn.vA) >>
1163 shadow_frame.GetVReg(dec_insn.vB));
1164 break;
1165 case Instruction::USHR_LONG_2ADDR:
1166 shadow_frame.SetVRegLong(dec_insn.vA,
1167 static_cast<uint64_t>(shadow_frame.GetVRegLong(dec_insn.vA)) >>
1168 shadow_frame.GetVReg(dec_insn.vB));
1169 break;
1170 case Instruction::ADD_FLOAT_2ADDR:
1171 shadow_frame.SetVRegFloat(dec_insn.vA,
1172 shadow_frame.GetVRegFloat(dec_insn.vA) +
1173 shadow_frame.GetVRegFloat(dec_insn.vB));
1174 break;
1175 case Instruction::SUB_FLOAT_2ADDR:
1176 shadow_frame.SetVRegFloat(dec_insn.vA,
1177 shadow_frame.GetVRegFloat(dec_insn.vA) -
1178 shadow_frame.GetVRegFloat(dec_insn.vB));
1179 break;
1180 case Instruction::MUL_FLOAT_2ADDR:
1181 shadow_frame.SetVRegFloat(dec_insn.vA,
1182 shadow_frame.GetVRegFloat(dec_insn.vA) *
1183 shadow_frame.GetVRegFloat(dec_insn.vB));
1184 break;
1185 case Instruction::DIV_FLOAT_2ADDR:
1186 shadow_frame.SetVRegFloat(dec_insn.vA,
1187 shadow_frame.GetVRegFloat(dec_insn.vA) /
1188 shadow_frame.GetVRegFloat(dec_insn.vB));
1189 break;
1190 case Instruction::REM_FLOAT_2ADDR:
1191 shadow_frame.SetVRegFloat(dec_insn.vA,
1192 fmodf(shadow_frame.GetVRegFloat(dec_insn.vA),
1193 shadow_frame.GetVRegFloat(dec_insn.vB)));
1194 break;
1195 case Instruction::ADD_DOUBLE_2ADDR:
1196 shadow_frame.SetVRegDouble(dec_insn.vA,
1197 shadow_frame.GetVRegDouble(dec_insn.vA) +
1198 shadow_frame.GetVRegDouble(dec_insn.vB));
1199 break;
1200 case Instruction::SUB_DOUBLE_2ADDR:
1201 shadow_frame.SetVRegDouble(dec_insn.vA,
1202 shadow_frame.GetVRegDouble(dec_insn.vA) -
1203 shadow_frame.GetVRegDouble(dec_insn.vB));
1204 break;
1205 case Instruction::MUL_DOUBLE_2ADDR:
1206 shadow_frame.SetVRegDouble(dec_insn.vA,
1207 shadow_frame.GetVRegDouble(dec_insn.vA) *
1208 shadow_frame.GetVRegDouble(dec_insn.vB));
1209 break;
1210 case Instruction::DIV_DOUBLE_2ADDR:
1211 shadow_frame.SetVRegDouble(dec_insn.vA,
1212 shadow_frame.GetVRegDouble(dec_insn.vA) /
1213 shadow_frame.GetVRegDouble(dec_insn.vB));
1214 break;
1215 case Instruction::REM_DOUBLE_2ADDR:
1216 shadow_frame.SetVRegDouble(dec_insn.vA,
1217 fmod(shadow_frame.GetVRegDouble(dec_insn.vA),
1218 shadow_frame.GetVRegDouble(dec_insn.vB)));
1219 break;
1220 case Instruction::ADD_INT_LIT16:
1221 case Instruction::ADD_INT_LIT8:
1222 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) + dec_insn.vC);
1223 break;
1224 case Instruction::RSUB_INT:
1225 case Instruction::RSUB_INT_LIT8:
1226 shadow_frame.SetVReg(dec_insn.vA, dec_insn.vC - shadow_frame.GetVReg(dec_insn.vB));
1227 break;
1228 case Instruction::MUL_INT_LIT16:
1229 case Instruction::MUL_INT_LIT8:
1230 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) * dec_insn.vC);
1231 break;
1232 case Instruction::DIV_INT_LIT16:
1233 case Instruction::DIV_INT_LIT8:
1234 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) / dec_insn.vC);
1235 break;
1236 case Instruction::REM_INT_LIT16:
1237 case Instruction::REM_INT_LIT8:
1238 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) % dec_insn.vC);
1239 break;
1240 case Instruction::AND_INT_LIT16:
1241 case Instruction::AND_INT_LIT8:
1242 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) & dec_insn.vC);
1243 break;
1244 case Instruction::OR_INT_LIT16:
1245 case Instruction::OR_INT_LIT8:
1246 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) | dec_insn.vC);
1247 break;
1248 case Instruction::XOR_INT_LIT16:
1249 case Instruction::XOR_INT_LIT8:
1250 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) ^ dec_insn.vC);
1251 break;
1252 case Instruction::SHL_INT_LIT8:
1253 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) << dec_insn.vC);
1254 break;
1255 case Instruction::SHR_INT_LIT8:
1256 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) >> dec_insn.vC);
1257 break;
1258 case Instruction::USHR_INT_LIT8:
1259 shadow_frame.SetVReg(dec_insn.vA,
1260 static_cast<uint32_t>(shadow_frame.GetVReg(dec_insn.vB)) >>
1261 dec_insn.vC);
1262 break;
1263 default:
1264 LOG(FATAL) << "Unexpected instruction: " << inst->DumpString(&mh.GetDexFile());
1265 break;
1266 }
1267 if (UNLIKELY(self->IsExceptionPending())) {
1268 uint32_t found_dex_pc =
1269 shadow_frame.GetMethod()->FindCatchBlock(self->GetException()->GetClass(),
1270 inst->GetDexPc(insns));
1271 if (found_dex_pc == DexFile::kDexNoIndex) {
1272 JValue result;
1273 result.SetJ(0);
1274 return result; // Handler in caller.
1275 } else {
1276 next_inst = Instruction::At(insns + found_dex_pc);
1277 }
1278 }
1279 inst = next_inst;
1280 }
1281}
1282
1283void EnterInterpreterFromInvoke(Thread* self, AbstractMethod* method, Object* receiver,
1284 JValue* args, JValue* result) {
1285 MethodHelper mh(method);
1286 const DexFile::CodeItem* code_item = mh.GetCodeItem();
1287 uint16_t num_regs;
1288 uint16_t num_ins;
1289 if (code_item != NULL) {
1290 num_regs = code_item->registers_size_;
1291 num_ins = code_item->ins_size_;
1292 } else {
1293 DCHECK(method->IsNative());
1294 num_regs = num_ins = AbstractMethod::NumArgRegisters(mh.GetShorty());
1295 if (!method->IsStatic()) {
1296 num_regs++;
1297 num_ins++;
1298 }
1299 }
1300 // Set up shadow frame with matching number of reference slots to vregs.
1301 ShadowFrame* last_shadow_frame = self->GetManagedStack()->GetTopShadowFrame();
1302 UniquePtr<ShadowFrame> shadow_frame(ShadowFrame::Create(num_regs, num_regs,
1303 (last_shadow_frame == NULL) ? NULL : last_shadow_frame->GetLink(),
1304 method, 0));
1305 self->PushShadowFrame(shadow_frame.get());
1306 size_t cur_reg = num_regs - num_ins;
1307 if (!method->IsStatic()) {
1308 CHECK(receiver != NULL);
1309 shadow_frame->SetReferenceAndVReg(cur_reg, receiver);
1310 ++cur_reg;
1311 } else if (!method->GetDeclaringClass()->IsInitializing()) {
1312 Runtime::Current()->GetClassLinker()->EnsureInitialized(method->GetDeclaringClass(),
1313 true, true);
1314 CHECK(method->GetDeclaringClass()->IsInitializing());
1315 }
1316 StringPiece shorty(mh.GetShorty());
1317 size_t arg_pos = 0;
1318 for (; cur_reg < num_regs; ++cur_reg, ++arg_pos) {
1319 DCHECK_LT(arg_pos + 1, mh.GetShortyLength());
1320 switch (shorty[arg_pos + 1]) {
1321 case 'L': {
1322 Object* o = args[arg_pos].GetL();
1323 shadow_frame->SetReferenceAndVReg(cur_reg, o);
1324 break;
1325 }
1326 case 'J': case 'D':
1327 shadow_frame->SetVRegLong(cur_reg, args[arg_pos].GetJ());
1328 cur_reg++;
1329 break;
1330 default:
1331 shadow_frame->SetVReg(cur_reg, args[arg_pos].GetI());
1332 break;
1333 }
1334 }
1335 if (!method->IsNative()) {
1336 JValue r = Execute(self, mh, code_item, *shadow_frame.get());
1337 if (result != NULL) {
1338 *result = r;
1339 }
1340 } else {
1341 // TODO: The following enters JNI code using a typedef-ed function rather than the JNI compiler,
1342 // it should be removed and JNI compiled stubs used instead.
1343 ScopedObjectAccessUnchecked soa(self);
1344 if (method->IsStatic()) {
1345 if (shorty == "L") {
1346 typedef jobject (fnptr)(JNIEnv*, jclass);
1347 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
1348 ScopedLocalRef<jclass> klass(soa.Env(),
1349 soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
1350 ScopedThreadStateChange tsc(self, kNative);
1351 result->SetL(soa.Decode<Object*>(fn(soa.Env(), klass.get())));
1352 } else if (shorty == "V") {
1353 typedef void (fnptr)(JNIEnv*, jclass);
1354 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
1355 ScopedLocalRef<jclass> klass(soa.Env(),
1356 soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
1357 ScopedThreadStateChange tsc(self, kNative);
1358 fn(soa.Env(), klass.get());
1359 } else if (shorty == "Z") {
1360 typedef jboolean (fnptr)(JNIEnv*, jclass);
1361 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
1362 ScopedLocalRef<jclass> klass(soa.Env(),
1363 soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
1364 ScopedThreadStateChange tsc(self, kNative);
1365 result->SetZ(fn(soa.Env(), klass.get()));
1366 } else if (shorty == "BI") {
1367 typedef jbyte (fnptr)(JNIEnv*, jclass, jint);
1368 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
1369 ScopedLocalRef<jclass> klass(soa.Env(),
1370 soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
1371 ScopedThreadStateChange tsc(self, kNative);
1372 result->SetB(fn(soa.Env(), klass.get(), args[0].GetI()));
1373 } else if (shorty == "II") {
1374 typedef jint (fnptr)(JNIEnv*, jclass, jint);
1375 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
1376 ScopedLocalRef<jclass> klass(soa.Env(),
1377 soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
1378 ScopedThreadStateChange tsc(self, kNative);
1379 result->SetI(fn(soa.Env(), klass.get(), args[0].GetI()));
1380 } else if (shorty == "LL") {
1381 typedef jobject (fnptr)(JNIEnv*, jclass, jobject);
1382 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
1383 ScopedLocalRef<jclass> klass(soa.Env(),
1384 soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
1385 ScopedLocalRef<jobject> arg0(soa.Env(),
1386 soa.AddLocalReference<jobject>(args[0].GetL()));
1387 ScopedThreadStateChange tsc(self, kNative);
1388 result->SetL(soa.Decode<Object*>(fn(soa.Env(), klass.get(), arg0.get())));
1389 } else if (shorty == "IIZ") {
1390 typedef jint (fnptr)(JNIEnv*, jclass, jint, jboolean);
1391 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
1392 ScopedLocalRef<jclass> klass(soa.Env(),
1393 soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
1394 ScopedThreadStateChange tsc(self, kNative);
1395 result->SetI(fn(soa.Env(), klass.get(), args[0].GetI(), args[1].GetZ()));
1396 } else if (shorty == "ILI") {
1397 typedef jint (fnptr)(JNIEnv*, jclass, jobject, jint);
1398 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
1399 ScopedLocalRef<jclass> klass(soa.Env(),
1400 soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
1401 ScopedLocalRef<jobject> arg0(soa.Env(),
1402 soa.AddLocalReference<jobject>(args[0].GetL()));
1403 ScopedThreadStateChange tsc(self, kNative);
1404 result->SetI(fn(soa.Env(), klass.get(), arg0.get(), args[1].GetI()));
1405 } else if (shorty == "SIZ") {
1406 typedef jshort (fnptr)(JNIEnv*, jclass, jint, jboolean);
1407 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
1408 ScopedLocalRef<jclass> klass(soa.Env(),
1409 soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
1410 ScopedThreadStateChange tsc(self, kNative);
1411 result->SetS(fn(soa.Env(), klass.get(), args[0].GetI(), args[1].GetZ()));
1412 } else if (shorty == "VIZ") {
1413 typedef void (fnptr)(JNIEnv*, jclass, jint, jboolean);
1414 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
1415 ScopedLocalRef<jclass> klass(soa.Env(),
1416 soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
1417 ScopedThreadStateChange tsc(self, kNative);
1418 fn(soa.Env(), klass.get(), args[0].GetI(), args[1].GetZ());
1419 } else if (shorty == "ZLL") {
1420 typedef jboolean (fnptr)(JNIEnv*, jclass, jobject, jobject);
1421 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
1422 ScopedLocalRef<jclass> klass(soa.Env(),
1423 soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
1424 ScopedLocalRef<jobject> arg0(soa.Env(),
1425 soa.AddLocalReference<jobject>(args[0].GetL()));
1426 ScopedLocalRef<jobject> arg1(soa.Env(),
1427 soa.AddLocalReference<jobject>(args[1].GetL()));
1428 ScopedThreadStateChange tsc(self, kNative);
1429 result->SetZ(fn(soa.Env(), klass.get(), arg0.get(), arg1.get()));
1430 } else if (shorty == "ZILL") {
1431 typedef jboolean (fnptr)(JNIEnv*, jclass, jint, jobject, jobject);
1432 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
1433 ScopedLocalRef<jclass> klass(soa.Env(),
1434 soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
1435 ScopedLocalRef<jobject> arg1(soa.Env(),
1436 soa.AddLocalReference<jobject>(args[1].GetL()));
1437 ScopedLocalRef<jobject> arg2(soa.Env(),
1438 soa.AddLocalReference<jobject>(args[2].GetL()));
1439 ScopedThreadStateChange tsc(self, kNative);
1440 result->SetZ(fn(soa.Env(), klass.get(), args[0].GetI(), arg1.get(), arg2.get()));
1441 } else if (shorty == "VILII") {
1442 typedef void (fnptr)(JNIEnv*, jclass, jint, jobject, jint, jint);
1443 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
1444 ScopedLocalRef<jclass> klass(soa.Env(),
1445 soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
1446 ScopedLocalRef<jobject> arg1(soa.Env(),
1447 soa.AddLocalReference<jobject>(args[1].GetL()));
1448 ScopedThreadStateChange tsc(self, kNative);
1449 fn(soa.Env(), klass.get(), args[0].GetI(), arg1.get(), args[2].GetI(), args[3].GetI());
1450 } else if (shorty == "VLILII") {
1451 typedef void (fnptr)(JNIEnv*, jclass, jobject, jint, jobject, jint, jint);
1452 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
1453 ScopedLocalRef<jclass> klass(soa.Env(),
1454 soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
1455 ScopedLocalRef<jobject> arg0(soa.Env(),
1456 soa.AddLocalReference<jobject>(args[0].GetL()));
1457 ScopedLocalRef<jobject> arg2(soa.Env(),
1458 soa.AddLocalReference<jobject>(args[2].GetL()));
1459 ScopedThreadStateChange tsc(self, kNative);
1460 fn(soa.Env(), klass.get(), arg0.get(), args[1].GetI(), arg2.get(), args[3].GetI(),
1461 args[4].GetI());
1462 } else {
1463 LOG(FATAL) << "Do something with static native method: " << PrettyMethod(method)
1464 << " shorty: " << shorty;
1465 }
1466 } else {
1467 if (shorty == "L") {
1468 typedef jobject (fnptr)(JNIEnv*, jobject);
1469 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
1470 ScopedLocalRef<jobject> rcvr(soa.Env(),
1471 soa.AddLocalReference<jobject>(receiver));
1472 ScopedThreadStateChange tsc(self, kNative);
1473 result->SetL(soa.Decode<Object*>(fn(soa.Env(), rcvr.get())));
1474 } else if (shorty == "LL") {
1475 typedef jobject (fnptr)(JNIEnv*, jobject, jobject);
1476 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
1477 ScopedLocalRef<jobject> rcvr(soa.Env(),
1478 soa.AddLocalReference<jobject>(receiver));
1479 ScopedLocalRef<jobject> arg0(soa.Env(),
1480 soa.AddLocalReference<jobject>(args[0].GetL()));
1481 ScopedThreadStateChange tsc(self, kNative);
1482 result->SetL(soa.Decode<Object*>(fn(soa.Env(), rcvr.get(), arg0.get())));
1483 } else if (shorty == "III") {
1484 typedef jint (fnptr)(JNIEnv*, jobject, jint, jint);
1485 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
1486 ScopedLocalRef<jobject> rcvr(soa.Env(),
1487 soa.AddLocalReference<jobject>(receiver));
1488 ScopedThreadStateChange tsc(self, kNative);
1489 result->SetI(fn(soa.Env(), rcvr.get(), args[0].GetI(), args[1].GetI()));
1490 } else {
1491 LOG(FATAL) << "Do something with native method: " << PrettyMethod(method)
1492 << " shorty: " << shorty;
1493 }
1494 }
1495 }
1496 self->PopShadowFrame();
1497}
1498
1499} // namespace interpreter
1500} // namespace art