diff --git a/.github/workflows/test_ruby.yml b/.github/workflows/test_ruby.yml index 39dfaa9de72c..46f6d12a9bf1 100644 --- a/.github/workflows/test_ruby.yml +++ b/.github/workflows/test_ruby.yml @@ -45,6 +45,39 @@ jobs: bazel-cache: ruby_linux/${{ matrix.ruby }}_${{ matrix.bazel }} bazel: test //ruby/... //ruby/tests:ruby_version --test_env=KOKORO_RUBY_VERSION --test_env=BAZEL=true ${{ matrix.ffi == 'FFI' && '--//ruby:ffi=enabled --test_env=PROTOCOL_BUFFERS_RUBY_IMPLEMENTATION=FFI' || '' }} + linux-32bit: + name: Linux 32-bit + runs-on: ubuntu-latest + steps: + - name: Checkout pending changes + uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 + with: + ref: ${{ inputs.safe-checkout }} + submodules: recursive + + - name: Cross compile protoc for i386 + id: cross-compile + uses: protocolbuffers/protobuf-ci/cross-compile-protoc@v2 + with: + image: us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:6.3.0-91a0ac83e968068672bc6001a4d474cfd9a50f1d + credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} + architecture: linux-i386 + + - name: Run tests + uses: protocolbuffers/protobuf-ci/docker@v2 + with: + image: i386/ruby:2.7.3-buster + skip-staleness-check: true + credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} + command: >- + /bin/bash -cex ' + gem install bundler; + cd /workspace/ruby; + bundle; + PROTOC=/workspace/${{ steps.cross-compile.outputs.protoc }} rake; + rake clobber_package gem; + PROTOC=/workspace/${{ steps.cross-compile.outputs.protoc }} rake test' + linux-aarch64: name: Linux aarch64 runs-on: ubuntu-latest diff --git a/ruby/ext/google/protobuf_c/protobuf.c b/ruby/ext/google/protobuf_c/protobuf.c index c9354db4e340..39062cfca65a 100644 --- a/ruby/ext/google/protobuf_c/protobuf.c +++ b/ruby/ext/google/protobuf_c/protobuf.c @@ -276,17 +276,25 @@ static void ObjectCache_Init(VALUE protobuf) { rb_const_set(protobuf, rb_intern("SIZEOF_VALUE"), INT2NUM(SIZEOF_VALUE)); } -VALUE ObjectCache_TryAdd(const void *key, VALUE val) { +static VALUE ObjectCache_GetKey(const void *key) { VALUE key_val = (VALUE)key; PBRUBY_ASSERT((key_val & 3) == 0); - return rb_funcall(weak_obj_cache, item_try_add, 2, LL2NUM(key_val), val); + // Ensure the key can be stored as a Fixnum since 1 bit is needed for + // FIXNUM_FLAG and 1 bit is needed for the sign bit. + VALUE new_key = LL2NUM(key_val >> 2); + PBRUBY_ASSERT(FIXNUM_P(new_key)); + return new_key; +} + +VALUE ObjectCache_TryAdd(const void *key, VALUE val) { + VALUE key_val = ObjectCache_GetKey(key); + return rb_funcall(weak_obj_cache, item_try_add, 2, key_val, val); } // Returns the cached object for this key, if any. Otherwise returns Qnil. VALUE ObjectCache_Get(const void *key) { - VALUE key_val = (VALUE)key; - PBRUBY_ASSERT((key_val & 3) == 0); - return rb_funcall(weak_obj_cache, item_get, 1, LL2NUM(key_val)); + VALUE key_val = ObjectCache_GetKey(key); + return rb_funcall(weak_obj_cache, item_get, 1, key_val); } /*