diff --git a/lib/VM/JIT/arm64/JIT.cpp b/lib/VM/JIT/arm64/JIT.cpp index 48fa16055cd..a0c749fd73c 100644 --- a/lib/VM/JIT/arm64/JIT.cpp +++ b/lib/VM/JIT/arm64/JIT.cpp @@ -375,6 +375,14 @@ JITCompiledFunctionPtr JITContext::compileImpl( ip = NEXTINST(PutByValStrict); break; + case inst::OpCode::GetByIndex: + em.getByIndex( + FR(ip->iGetByIndex.op1), + FR(ip->iGetByIndex.op2), + ip->iGetByIndex.op3); + ip = NEXTINST(GetByIndex); + break; + case inst::OpCode::Ret: em.ret(FR(ip->iRet.op1)); ip = NEXTINST(Ret); diff --git a/lib/VM/JIT/arm64/JitEmitter.cpp b/lib/VM/JIT/arm64/JitEmitter.cpp index 5485f888c22..5b1c0e442a6 100644 --- a/lib/VM/JIT/arm64/JitEmitter.cpp +++ b/lib/VM/JIT/arm64/JitEmitter.cpp @@ -898,6 +898,23 @@ void Emitter::getByVal(FR frRes, FR frSource, FR frKey) { frUpdatedWithHWReg(frRes, hwRes); } +void Emitter::getByIndex(FR frRes, FR frSource, uint8_t key) { + comment("// getByIdx r%u, r%u, %u", frRes.index(), frSource.index(), key); + + syncAllTempExcept(frRes != frSource ? frRes : FR()); + syncToMem(frSource); + freeAllTempExcept({}); + + a.mov(a64::x0, xRuntime); + loadFrameAddr(a64::x1, frSource); + a.mov(a64::w2, key); + EMIT_RUNTIME_CALL(*this, _sh_ljs_get_by_index_rjs); + + HWReg hwRes = getOrAllocFRInAnyReg(frRes, false, HWReg::gpX(0)); + movHWReg(hwRes, HWReg::gpX(0)); + frUpdatedWithHWReg(frRes, hwRes); +} + void Emitter::putByIdImpl( FR frTarget, SHSymbolID symID, diff --git a/lib/VM/JIT/arm64/JitEmitter.h b/lib/VM/JIT/arm64/JitEmitter.h index 976ee23e6bf..d474bdb170a 100644 --- a/lib/VM/JIT/arm64/JitEmitter.h +++ b/lib/VM/JIT/arm64/JitEmitter.h @@ -453,6 +453,7 @@ class Emitter { #undef DECL_JCOND void getByVal(FR frRes, FR frSource, FR frKey); + void getByIndex(FR frRes, FR frSource, uint8_t key); #define DECL_PUT_BY_VAL(methodName, commentStr, shFn) \ void methodName(FR frTarget, FR frKey, FR frValue) { \ diff --git a/test/jit/objops.js b/test/jit/objops.js index 902bc2a5913..b25ec357979 100644 --- a/test/jit/objops.js +++ b/test/jit/objops.js @@ -32,6 +32,10 @@ function isIn(a, prop) { return prop in a; } +function getByIndex(o) { + return o[1]; +} + print("foo", foo()); // CHECK: JIT successfully compiled FunctionID 1, 'foo' // CHECK-NEXT: foo 30 @@ -43,3 +47,12 @@ print("isIn", isIn({}, "prop")); // CHECK-NEXT: isIn false print("isIn", isIn({prop: 1}, "prop")); // CHECK-NEXT: isIn true +print("getByIndex", getByIndex(0)); +// CHECK: JIT successfully compiled FunctionID 4, 'getByIndex' +// CHECK-NEXT: getByIndex undefined +print("getByIndex", getByIndex("abc")); +// CHECK-NEXT: getByIndex b +print("getByIndex", getByIndex([10, 20, 30])); +// CHECK-NEXT: getByIndex 20 +print("getByIndex", getByIndex({0:11, 1: 21, 2: 31})); +// CHECK-NEXT: getByIndex 21