Skip to content

Commit

Permalink
feat: create fiddle gem adapter
Browse files Browse the repository at this point in the history
  • Loading branch information
maxirmx committed Dec 29, 2024
1 parent 091bf79 commit 134cf5a
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/tebako-runtime.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ module TebakoRuntime

POST_REQUIRE_MAP = {
"ffi" => "tebako-runtime/adapters/ffi",
"fiddle" => "tebako-runtime/adapters/fiddle",
"jing" => "tebako-runtime/adapters/jing",
"mn2pdf" => "tebako-runtime/adapters/mn2pdf",
"mnconvert" => "tebako-runtime/adapters/mnconvert",
Expand Down
38 changes: 38 additions & 0 deletions lib/tebako-runtime/adapters/fiddle.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# frozen_string_literal: true

# Copyright (c) 2024 [Ribose Inc](https://www.ribose.com).
# All rights reserved.
# This file is a part of tebako
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

require_relative "../memfs"

# Wrapper for Fiddle.dlopen method
# If the library file to be mapped to is within memfs it is extracted to tmp folder
module Fiddle
singleton_class.send(:alias_method, :dlopen_orig, :dlopen)

def self.dlopen(lib)
dlopen_orig(TebakoRuntime.extract_memfs(lib))
end
end
29 changes: 29 additions & 0 deletions spec/pass_through_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

require "rspec"
require "tebako-runtime"

# rubocop:disable Metrics/BlockLength
Expand Down Expand Up @@ -59,5 +60,33 @@
FFI::Platform.send(:remove_const, :PASS_THROUGH) if Object.const_defined?(:PASS_THROUGH)
end
end

it "is transparent for other gems in PASS_THROUGH mode" do
if RUBY_PLATFORM =~ /msys|mingw|cygwin/
if defined?(FFI)
FFI::Platform.send(:remove_const, :OS)
FFI::Platform.send(:remove_const, :ARCH)
FFI::Platform.send(:remove_const, :LIBPREFIX)
FFI::Platform.send(:remove_const, :LIBSUFFIX)
FFI::Platform.send(:remove_const, :PASS_THROUGH)
end
ENV["TEBAKO_PASS_THROUGH"] = "1"
require "fiddle"

expect(defined?(Fiddle)).to_not be_nil

end
end

after do
if RUBY_PLATFORM =~ /msys|mingw|cygwin/
ENV.delete("TEBAKO_PASS_THROUGH")
FFI::Platform.send(:remove_const, :OS) if Object.const_defined?(:OS)
FFI::Platform.send(:remove_const, :ARCH) if Object.const_defined?(:ARCH)
FFI::Platform.send(:remove_const, :LIBPREFIX) if Object.const_defined?(:LIBPREFIX)
FFI::Platform.send(:remove_const, :LIBSUFFIX) if Object.const_defined?(:LIBSUFFIX)
FFI::Platform.send(:remove_const, :PASS_THROUGH) if Object.const_defined?(:PASS_THROUGH)
end
end
end
# rubocop:enable Metrics/BlockLength
11 changes: 11 additions & 0 deletions spec/runtime_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,13 @@ def tmpdir_name
Fiddle.dlopen("test_fiddle")
end

it "provides an adapter for ffi gem" do
expect(TebakoRuntime).to receive(:extract_memfs).with("test_fiddle")
require "fiddle"
expect(Fiddle::Handle).to receive(:new).and_return(double("Fiddle::Handle"))
Fiddle.dlopen("test_fiddle")
end

it "provides an adapter for ffi gem" do
expect(TebakoRuntime).to receive(:extract_memfs).with("test_ffi")
require "ffi"
Expand Down Expand Up @@ -165,6 +172,10 @@ def tmpdir_name
TebakoRuntime::COMPILER_MEMFS = File.join(TebakoRuntime.full_gem_path("tebako-runtime"), "lib")

tfile = File.join(TebakoRuntime.full_gem_path("tebako-runtime"), "lib", "cert", "cacert.pem.mozilla")
if RUBY_PLATFORM =~ /mswin|mingw/
allow(TebakoRuntime).to receive(:extract_memfs).with("kernel32.dll").and_call_original
allow(TebakoRuntime).to receive(:extract_memfs).with("advapi32.dll").and_call_original
end
expect(TebakoRuntime).to receive(:extract_memfs).with(tfile).and_call_original
require "net/http"

Expand Down
1 change: 1 addition & 0 deletions tebako-runtime.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ Gem::Specification.new do |spec|
spec.add_development_dependency "rubocop-rubycw", "~> 0.1"

spec.add_development_dependency "ffi", "~> 1.15"
spec.add_development_dependency "fiddle", "~> 1.0"
spec.add_development_dependency "mn2pdf", "~> 1.79"
spec.add_development_dependency "mnconvert", "~> 1.54"
spec.add_development_dependency "ruby-jing", "~> 0.0.3"
Expand Down

0 comments on commit 134cf5a

Please sign in to comment.