From 63eb1990e45434e5e294c7a3d32f7f7d9719ac60 Mon Sep 17 00:00:00 2001 From: Aakash Patel Date: Wed, 28 Aug 2024 07:58:30 -0700 Subject: [PATCH] Add GetByIndex in native backend Reviewed By: tmikov Differential Revision: D61743977 fbshipit-source-id: 71c8e14ed13a70238774f2ef1fb9dc4bb871d1f6 --- include/hermes/VM/static_h.h | 2 ++ lib/BCGen/SH/SH.cpp | 9 +++++++++ lib/VM/StaticH.cpp | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+) diff --git a/include/hermes/VM/static_h.h b/include/hermes/VM/static_h.h index 0f57cfd1666..29153d8ff31 100644 --- a/include/hermes/VM/static_h.h +++ b/include/hermes/VM/static_h.h @@ -499,6 +499,8 @@ SHERMES_EXPORT SHLegacyValue _sh_ljs_get_by_val_rjs( SHRuntime *shr, SHLegacyValue *source, SHLegacyValue *key); +SHERMES_EXPORT SHLegacyValue +_sh_ljs_get_by_index_rjs(SHRuntime *shr, SHLegacyValue *source, uint8_t key); /// Put an enumerable property. SHERMES_EXPORT void _sh_ljs_put_own_by_val( diff --git a/lib/BCGen/SH/SH.cpp b/lib/BCGen/SH/SH.cpp index bf820ae9132..1108d6673e4 100644 --- a/lib/BCGen/SH/SH.cpp +++ b/lib/BCGen/SH/SH.cpp @@ -1298,6 +1298,15 @@ class InstrGen { genStringConstIC(LS) << ");\n"; return; } + // If the prop is a uint8_t constant, generate the special bytecode. + if (auto *litNum = llvh::dyn_cast(inst.getProperty()); + litNum && litNum->isUInt8Representible()) { + os_ << "_sh_ljs_get_by_index_rjs(shr,&"; + generateRegister(*inst.getObject()); + os_ << ", "; + os_ << litNum->asUInt8() << ");\n"; + return; + } os_ << "_sh_ljs_get_by_val_rjs(shr,&"; generateRegister(*inst.getObject()); os_ << ", &"; diff --git a/lib/VM/StaticH.cpp b/lib/VM/StaticH.cpp index 17cdebe3199..f9db2cfb7ff 100644 --- a/lib/VM/StaticH.cpp +++ b/lib/VM/StaticH.cpp @@ -310,6 +310,39 @@ extern "C" SHLegacyValue _sh_ljs_get_by_val_rjs( return res->getHermesValue(); } +extern "C" SHLegacyValue +_sh_ljs_get_by_index_rjs(SHRuntime *shr, SHLegacyValue *source, uint8_t key) { + Handle<> sourceHandle{toPHV(source)}; + Runtime &runtime = getRuntime(shr); + if (LLVM_LIKELY(sourceHandle->isObject())) { + Handle objHandle = Handle::vmcast(sourceHandle); + if (LLVM_LIKELY(objHandle->hasFastIndexProperties())) { + auto ourValue = createPseudoHandle(JSObject::getOwnIndexed( + createPseudoHandle(*objHandle), runtime, key)); + if (LLVM_LIKELY(!ourValue->isEmpty())) { + return ourValue.getHermesValue(); + } + } + } + + // Otherwise... + // This is the "slow path". + auto res = [&]() { + struct : public Locals { + PinnedValue<> key; + } lv; + LocalsRAII lraii{runtime, &lv}; + + lv.key = HermesValue::encodeTrustedNumberValue(key); + return Interpreter::getByValTransient_RJS(runtime, sourceHandle, lv.key); + }(); + + if (LLVM_UNLIKELY(res == ExecutionStatus::EXCEPTION)) { + _sh_throw_current(shr); + } + return res->getHermesValue(); +} + extern "C" SHLegacyValue _sh_catch( SHRuntime *shr, SHLocals *locals,