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
2 changes: 2 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ AllCops:
NewCops: enable
Naming/MethodName:
Enabled: false
Metrics/MethodLength:
Enabled: false
Style/IfUnlessModifier:
Enabled: false
Style/StringLiterals:
Expand Down
158 changes: 158 additions & 0 deletions bin/benchmark
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
#!/usr/bin/env ruby
# frozen_string_literal: true

require "bundler/setup"
require "benchmark"

SIZE = 1_000_000
COLS = 12

def run_objc_hash
dict = ObjRuby::NSMutableDictionary.new

(0...SIZE).each do |i|
if (i % 2).zero?
dict.setObject_forKey("foo", i)
end
end

raise unless dict.count == SIZE / 2

(0...SIZE).each do |i|
unless dict.objectForKey(i)
dict.setObject_forKey("bar", i)
end
end

raise unless dict.count == SIZE
end

def run_ruby_hash
hash = {}

(0...SIZE).each do |i|
if (i % 2).zero?
hash[i] = "foo"
end
end

raise unless hash.size == SIZE / 2

(0...SIZE).each do |i|
unless hash[i]
hash[i] = "bar"
end
end

raise unless hash.size == SIZE
end

def run_objc_set
set = ObjRuby::NSMutableSet.new

(0...SIZE).each do |i|
if (i % 2).zero?
set.addObject(i)
end
end

raise unless set.count == SIZE / 2

(0...SIZE).each do |i|
unless set.containsObject(i)
set.addObject(i)
end
end

raise unless set.count == SIZE
end

def run_ruby_set
set = Set.new

(0...SIZE).each do |i|
if (i % 2).zero?
set << i
end
end

raise unless set.size == SIZE / 2

(0...SIZE).each do |i|
unless set.include?(i)
set << i
end
end

raise unless set.size == SIZE
end

def run_objc_array
array = ObjRuby::NSMutableArray.new

(0...SIZE).each do |i|
if (i % 2).zero?
array.addObject("foo")
end
end

raise unless array.count == SIZE / 2

(0...SIZE).each do |i|
unless (i % 2).zero?
array.addObject("bar")
end
end
raise unless array.count == SIZE
end

def run_ruby_array
array = []

(0...SIZE).each do |i|
if (i % 2).zero?
array << "foo"
end
end

raise unless array.size == SIZE / 2

(0...SIZE).each do |i|
unless (i % 2).zero?
array << "bar"
end
end

raise unless array.size == SIZE
end

Benchmark.bm(COLS) do |bm|
bm.report("Warmup:") do
require "obj_ruby"
require "obj_ruby/cocoa"
end

bm.report("NSDictionary:") do
run_objc_hash
end

bm.report("Hash:") do
run_ruby_hash
end

bm.report("NSSet:") do
run_objc_set
end

bm.report("Set:") do
run_ruby_set
end

bm.report("NSArray:") do
run_objc_array
end

bm.report("Array:") do
run_ruby_array
end
end
1 change: 1 addition & 0 deletions ext/obj_ext/RIGSBridgeSupportParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

@interface RIGSBridgeSupportParser : NSObject<NSXMLParserDelegate>
{
NSString *_className;
NSString *_methodName;
NSString *_functionName;
NSString *_protocolName;
Expand Down
99 changes: 56 additions & 43 deletions ext/obj_ext/RIGSBridgeSupportParser.m
Original file line number Diff line number Diff line change
Expand Up @@ -54,32 +54,27 @@ - (void)parser:(NSXMLParser *)parser
[self parseFunctionWithName:[attributeDict objectForKey:@"name"]];
}
else if ([elementName isEqualToString:@"retval"]) {
[self parseArgWithIndex:-1
type:[attributeDict objectForKey:@"type64"]
printf:nil
block:nil];
[self parseArgWithType:[attributeDict objectForKey:@"type64"]
index:@"-1"
printf:nil
block:nil];
}
else if ([elementName isEqualToString:@"arg"]) {
if (_methodName) {
[self parseArgWithIndex:[attributeDict objectForKey:@"index"] ? [[attributeDict objectForKey:@"index"] intValue] : _argIndex++
type:[attributeDict objectForKey:@"type64"]
printf:[attributeDict objectForKey:@"printf_format"]
block:[attributeDict objectForKey:@"function_pointer"]];
}
else if (_functionName) {
[self parseArgWithIndex:_argIndex++
type:[attributeDict objectForKey:@"type64"]
printf:[attributeDict objectForKey:@"printf_format"]
block:nil];
}
[self parseArgWithType:[attributeDict objectForKey:@"type64"]
index:[attributeDict objectForKey:@"index"]
printf:[attributeDict objectForKey:@"printf_format"]
block:[attributeDict objectForKey:@"function_pointer"]];
}
}

- (void)parser:(NSXMLParser *)parser
didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName {
if ([elementName isEqualToString:@"informal_protocol"]) {
if ([elementName isEqualToString:@"class"]) {
[self finalizeClass];
}
else if ([elementName isEqualToString:@"informal_protocol"]) {
[self finalizeProtocol];
}
else if ([elementName isEqualToString:@"method"]) {
Expand All @@ -88,7 +83,7 @@ - (void)parser:(NSXMLParser *)parser
else if ([elementName isEqualToString:@"function"]) {
[self finalizeFunction];
}
else if ([elementName isEqualToString:@"arg"] || [elementName isEqualToString:@"retval"]) {
else if ([elementName isEqualToString:@"retval"] || [elementName isEqualToString:@"arg"]) {
[self finalizeArg];
}
}
Expand Down Expand Up @@ -139,36 +134,46 @@ - (void)parseProtocolWithName:(NSString*)name
_argDepth = 0;
}

- (void)parseArgWithIndex:(NSInteger)index type:(NSString*)type printf:(NSString*)printf block:(NSString*)block
- (void)parseArgWithType:(NSString*)type index:(NSString*)index printf:(NSString*)printf block:(NSString*)block
{
_argDepth++;

if (_methodName) {
if ([printf isEqualToString:@"true"]) {
_formatStringIndex = index;
if (_argDepth == 1) {
if ([printf isEqualToString:@"true"]) {
_formatStringIndex = [index integerValue];
}
if ([block isEqualToString:@"true"] && [type isEqualToString:@"@?"]) {
_blockIndex = [index integerValue];
_objcTypes = [[type mutableCopy] retain];
}
if (type) {
rb_objc_register_type_arg_from_objc([_methodName UTF8String], [index intValue], [type UTF8String]);
}
}
if ([block isEqualToString:@"true"] && [type isEqualToString:@"@?"]) {
_blockIndex = index;
_objcTypes = [[NSMutableString string] retain];
else {
if (_objcTypes) {
if ([index isEqualToString:@"-1"]) {
[_objcTypes insertString:type atIndex:0];
}
else {
[_objcTypes appendString:type];
}
}
}
if (_objcTypes) {
if (index == -1) {
}
else if (_functionName) {
if (_argDepth == 1) {
if ([printf isEqualToString:@"true"]) {
_formatStringIndex = _argIndex;
}
if ([index isEqualToString:@"-1"]) {
[_objcTypes insertString:type atIndex:0];
}
else {
[_objcTypes appendString:type];
}
}
}
else if (_functionName) {
if ([printf isEqualToString:@"true"]) {
_formatStringIndex = index;
}
if (index == -1) {
[_objcTypes insertString:type atIndex:0];
}
else {
[_objcTypes appendString:type];
_argIndex++;
}
}
}
Expand Down Expand Up @@ -252,11 +257,7 @@ - (void)parseEnumWithName:(NSString*)name value:(NSString*)value

- (void)parseClassWithName:(NSString*)name
{
Class objc_class = NSClassFromString(name);

if (objc_class) {
rb_objc_register_class_from_objc(objc_class);
}
_className = [name retain];
}

- (NSUInteger)parseStructArgCountWithType:(NSString*)type
Expand All @@ -270,6 +271,18 @@ - (NSUInteger)parseStructArgCountWithType:(NSString*)type
return quoteCount / 2;
}

- (void)finalizeClass
{
Class objc_class;

if ((objc_class = NSClassFromString(_className))) {
rb_objc_register_class_from_objc(objc_class);
}

[_className release];
_className = nil;
}

- (void)finalizeProtocol
{
[_protocolName release];
Expand Down Expand Up @@ -306,7 +319,7 @@ - (void)finalizeArg

if (_blockIndex != -1) {
if (_methodName) {
rb_objc_register_block_from_objc([_methodName UTF8String], _blockIndex, [_objcTypes UTF8String]);
rb_objc_register_block_arg_from_objc([_methodName UTF8String], _blockIndex, [_objcTypes UTF8String]);
}

_blockIndex = -1;
Expand Down
5 changes: 3 additions & 2 deletions ext/obj_ext/RIGSCore.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,12 @@ VALUE rb_objc_register_instance_method_from_rb(VALUE rb_class, VALUE rb_method);
void rb_objc_register_float_from_objc(const char *name, double value);
void rb_objc_register_integer_from_objc(const char *name, long long value);
void rb_objc_register_struct_from_objc(const char *key, const char *name, const char *args[], size_t argCount);
void rb_objc_register_format_string_from_objc(const char *selector, size_t index);
void rb_objc_register_block_from_objc(const char *selector, size_t index, const char *objcTypes);
void rb_objc_register_constant_from_objc(const char *name, const char *type);
void rb_objc_register_function_from_objc(const char *name, const char *objcTypes);
void rb_objc_register_protocol_from_objc(const char *selector, const char *objcTypes);
void rb_objc_register_format_string_from_objc(const char *selector, size_t index);
void rb_objc_register_type_arg_from_objc(const char *selector, int index, const char *objcTypes);
void rb_objc_register_block_arg_from_objc(const char *selector, size_t index, const char *objcTypes);

VALUE rb_objc_import(VALUE rb_self, VALUE rb_name);
VALUE rb_objc_new(int rigs_argc, VALUE *rigs_argv, VALUE rb_class);
Expand Down
Loading
Loading