package org.jruby.runtime.callsite;

import org.jruby.RubyClass;
import org.jruby.runtime.CallType;
import org.jruby.runtime.builtin.IRubyObject;

import static org.jruby.RubyBasicObject.getMetaClass;

A bi-morphic call-site.
@noteused as a base for mixed Fixnum/Float ops
/** * A bi-morphic call-site. * * @note used as a base for mixed Fixnum/Float ops */
abstract class BimorphicCallSite extends CachingCallSite { protected CacheEntry secondaryCache = CacheEntry.NULL_CACHE; public BimorphicCallSite(String methodName) { super(methodName, CallType.NORMAL); } public final CacheEntry getSecondaryCache() { return secondaryCache; } protected CacheEntry setSecondaryCache(CacheEntry entry, IRubyObject self) { return secondaryCache = entry; } public final CacheEntry retrieveSecondaryCache(IRubyObject self) { RubyClass selfType = getMetaClass(self); CacheEntry cache = this.secondaryCache; if (cache.typeOk(selfType)) { return cache; } return cacheAndGetSecondary(self, selfType, methodName); } public boolean isSecondaryBuiltin(IRubyObject self) { RubyClass selfType = getMetaClass(self); CacheEntry cache = this.secondaryCache; if (cache.typeOk(selfType)) { return cache.method.isBuiltin(); } return cacheAndGetSecondary(self, selfType, methodName).method.isBuiltin(); // false for method.isUndefined() } private CacheEntry cacheAndGetSecondary(IRubyObject self, RubyClass selfType, String methodName) { CacheEntry entry = selfType.searchWithCache(methodName); if (!entry.method.isUndefined()) entry = setSecondaryCache(entry, self); return entry; } }