Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions include/natalie/class_object.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ class ClassObject : public ModuleObject {

Value initialize(Env *, Optional<Value>, Block *);

using AllocFunc = Value (*)(Env *, Value);
AllocFunc alloc_func() const { return m_alloc_func; }
void set_alloc_func(AllocFunc func) { m_alloc_func = func; }

bool is_singleton() const { return m_is_singleton; }
void set_is_singleton(bool is_singleton) { m_is_singleton = is_singleton; }

Expand All @@ -82,6 +86,7 @@ class ClassObject : public ModuleObject {
Type m_object_type { Type::Object };
bool m_is_singleton { false };
bool m_is_initialized { false };
AllocFunc m_alloc_func { nullptr };
};

}
6 changes: 6 additions & 0 deletions lib/natalie/compiler/instructions/inline_cpp_instruction.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ def generate_bind_method(transform, ruby_name, cpp_name = ruby_name, arity = -1)
)
end

def generate_alloc_func(transform, cpp_name)
cpp_name = comptime_symbol(cpp_name)
transform.exec("self.as_class()->set_alloc_func(#{cpp_name});")
transform.push_nil
end

def generate_bind_static_method(transform, ruby_name, cpp_name = ruby_name, arity = -1)
ruby_name = comptime_symbol(ruby_name)
cpp_name = comptime_symbol(cpp_name)
Expand Down
1 change: 1 addition & 0 deletions lib/natalie/compiler/pass1.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ def initialize(
attr_reader :file

INLINE_CPP_MACROS = %i[
__alloc_func__
__bind_method__
__bind_static_method__
__call__
Expand Down
5 changes: 2 additions & 3 deletions lib/openssl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -379,12 +379,11 @@ Value OpenSSL_HMAC_digest(Env *env, Value self, Args &&args, Block *) {
return StringObject::create(reinterpret_cast<const char *>(md), md_len, Encoding::ASCII_8BIT);
}

Value OpenSSL_SSL_SSLContext_initialize(Env *env, Value self, Args &&args, Block *) {
args.ensure_argc_is(env, 0); // NATFIXME: Add deprecated version argument
Value OpenSSL_SSL_SSLContext_alloc(Env *env, Value self) {
SSL_CTX *ctx = SSL_CTX_new(TLS_method());
SSL_CTX_set_options(ctx, SSL_OP_NO_COMPRESSION | SSL_OP_ENABLE_MIDDLEBOX_COMPAT);
if (!ctx)
OpenSSL_SSL_raise_error(env, "SSL_CTX_new");
SSL_CTX_set_options(ctx, SSL_OP_NO_COMPRESSION | SSL_OP_ENABLE_MIDDLEBOX_COMPAT);
self->ivar_set(env, "@ctx"_s, VoidPObject::create(ctx, OpenSSL_SSL_CTX_cleanup));
self->ivar_set(env, "@verify_hostname"_s, Value::False());
self->ivar_set(env, "@verify_mode"_s, Value::integer(0));
Expand Down
4 changes: 2 additions & 2 deletions lib/openssl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ class SSLContext
(OpenSSL::SSL::OP_ALL & ~OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS) | OpenSSL::SSL::OP_NO_COMPRESSION,
}.freeze

__bind_method__ :initialize, :OpenSSL_SSL_SSLContext_initialize
__alloc_func__ :OpenSSL_SSL_SSLContext_alloc
__bind_method__ :max_version=, :OpenSSL_SSL_SSLContext_set_max_version
__bind_method__ :min_version=, :OpenSSL_SSL_SSLContext_set_min_version
__bind_method__ :options, :OpenSSL_SSL_SSLContext_options, 0
Expand All @@ -331,7 +331,7 @@ class SSLContext
__bind_method__ :session_cache_mode=, :OpenSSL_SSL_SSLContext_set_session_cache_mode, 1
__bind_method__ :setup, :OpenSSL_SSL_SSLContext_setup

attr_accessor :cert_store, :verify_hostname, :verify_mode
attr_accessor :cert_store, :session_new_cb, :verify_hostname, :verify_mode

alias freeze setup

Expand Down
9 changes: 8 additions & 1 deletion src/object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,10 +156,14 @@ Optional<Value> Object::create(Env *env, ClassObject *klass) {
}

Value Object::_new(Env *env, Value klass_value, Args &&args, Block *block) {
auto obj = create(env, klass_value.as_class());
auto klass = klass_value.as_class();
auto obj = create(env, klass);
if (!obj)
NAT_UNREACHABLE();

if (auto func = klass->alloc_func())
func(env, obj.value());

obj->send(env, "initialize"_s, std::move(args), block);
return obj.value();
}
Expand All @@ -182,6 +186,9 @@ Value Object::allocate(Env *env, Value klass_value, Args &&args, Block *block) {
if (!obj)
env->raise("TypeError", "allocator undefined for {}", klass->inspect_module());

if (auto func = klass->alloc_func())
func(env, obj.value());

return obj.value();
}

Expand Down