[macruby-changes] [2242] MacRuby/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Thu Aug 6 10:59:51 PDT 2009
Revision: 2242
http://trac.macosforge.org/projects/ruby/changeset/2242
Author: pthomson at apple.com
Date: 2009-08-06 10:59:51 -0700 (Thu, 06 Aug 2009)
Log Message:
-----------
Speed improvements to the YAML parsing stages.
Modified Paths:
--------------
MacRuby/trunk/ext/libyaml/rubyext.c
MacRuby/trunk/lib/yaml/rubytypes.rb
Modified: MacRuby/trunk/ext/libyaml/rubyext.c
===================================================================
--- MacRuby/trunk/ext/libyaml/rubyext.c 2009-08-06 09:18:40 UTC (rev 2241)
+++ MacRuby/trunk/ext/libyaml/rubyext.c 2009-08-06 17:59:51 UTC (rev 2242)
@@ -16,17 +16,15 @@
#include "yaml.h"
// Ideas to speed this up:
-// embed the yaml_parser_t and yaml_emitter_t into the parser/emitter structs
-// rather than just keep pointers to them; this means fewer mallocs
// have the resolver be an opaque CFMutableDictionary mapping C strings to VALUES
// store that dictionary in the parser, fewer ivar accesses
typedef struct rb_yaml_parser_s {
struct RBasic basic; // holds the class information
- yaml_parser_t *parser; // the parser object.
+ yaml_parser_t parser; // the parser object.
VALUE input; // a reference to the object that's providing input
-
+
VALUE resolver; // used to determine how to unserialize objects.
yaml_event_t event; // the event that is currently being parsed.
@@ -37,20 +35,27 @@
typedef struct rb_yaml_emitter_s {
struct RBasic basic; // holds the class information
- yaml_emitter_t *emitter; // the emitter object
+ yaml_emitter_t emitter; // the emitter object
VALUE output; // the object to which we are writing
} rb_yaml_emitter_t;
#define RYAMLEmitter(val) ((rb_yaml_emitter_t*)val)
+typedef struct rb_yaml_resolver_s {
+ struct RBasic basic;
+ CFMutableDictionaryRef tags;
+} rb_yaml_resolver_t;
+
+#define RYAMLResolver(val) ((rb_yaml_resolver_t*)val)
+
static VALUE rb_mYAML;
static VALUE rb_mLibYAML;
static VALUE rb_cParser;
static VALUE rb_cEmitter;
static VALUE rb_cResolver;
-static ID id_tags_ivar;
+
static ID id_plain;
static ID id_quote2;
@@ -76,8 +81,7 @@
parser->event_valid = false;
- GC_WB(&parser->parser, ALLOC(yaml_parser_t));
- yaml_parser_initialize(parser->parser);
+ yaml_parser_initialize(&parser->parser);
return (VALUE)parser;
}
@@ -100,7 +104,7 @@
{
rb_yaml_parser_t *rbparser = RYAMLParser(self);
rbparser->input = input; // do we need to retain this?
- yaml_parser_t *parser = rbparser->parser;
+ yaml_parser_t *parser = &rbparser->parser;
if (!NIL_P(input))
{
assert(parser != NULL);
@@ -200,10 +204,10 @@
static VALUE
rb_yaml_parser_error(VALUE self, SEL sel)
{
- return rb_yaml_parser_generate_error(RYAMLParser(self)->parser);
+ return rb_yaml_parser_generate_error(&(RYAMLParser(self)->parser));
}
-static bool
+static inline bool
yaml_next_event(rb_yaml_parser_t *parser)
{
if (parser->event_valid)
@@ -211,9 +215,9 @@
yaml_event_delete(&parser->event);
parser->event_valid = false;
}
- if (yaml_parser_parse(parser->parser, &parser->event) == -1)
+ if (yaml_parser_parse(&parser->parser, &parser->event) == -1)
{
- rb_exc_raise(rb_yaml_parser_generate_error(parser->parser));
+ rb_exc_raise(rb_yaml_parser_generate_error(&parser->parser));
parser->event_valid = false;
} else
{
@@ -223,11 +227,11 @@
}
#define NEXT_EVENT() yaml_next_event(parser)
-static VALUE get_node(rb_yaml_parser_t *parser);
+static inline VALUE get_node(rb_yaml_parser_t *parser);
-static VALUE interpret_value(rb_yaml_parser_t *parser, VALUE result, VALUE tag)
+static inline VALUE interpret_value(rb_yaml_parser_t *parser, VALUE result, VALUE tag)
{
- VALUE handler = rb_hash_lookup(rb_ivar_get(parser->resolver, id_tags_ivar), tag);
+ VALUE handler = rb_hash_lookup((VALUE)(RYAMLResolver(parser->resolver)->tags), tag);
if (rb_vm_respond_to(handler, sel_call, 0))
{
return rb_vm_call_with_cache(call_cache, handler, sel_call, 1, &result);
@@ -299,7 +303,7 @@
return interpret_value(parser, hash, tag);
}
-static VALUE get_node(rb_yaml_parser_t *parser)
+static inline VALUE get_node(rb_yaml_parser_t *parser)
{
VALUE node;
NEXT_EVENT();
@@ -372,11 +376,8 @@
rb_yaml_parser_finalize(void *rcv, SEL sel)
{
rb_yaml_parser_t *rbparser = RYAMLParser(rcv);
- if((rbparser != NULL) && (rbparser->parser != NULL))
- {
- yaml_parser_delete(rbparser->parser);
- rbparser->parser = NULL;
- }
+ yaml_parser_delete(&rbparser->parser);
+
if (rb_yaml_parser_finalize_super != NULL)
{
((void(*)(void *, SEL))rb_yaml_parser_finalize_super)(rcv, sel);
@@ -422,19 +423,11 @@
}
static VALUE
-rb_yaml_resolver_initialize(VALUE self, SEL sel)
-{
- rb_ivar_set(self, id_tags_ivar, rb_hash_new());
- return self;
-}
-
-static VALUE
rb_yaml_emitter_alloc(VALUE klass, SEL sel)
{
NEWOBJ(emitter, struct rb_yaml_emitter_s);
OBJSETUP(emitter, klass, T_OBJECT);
- GC_WB(&emitter->emitter, ALLOC(yaml_emitter_t));
- yaml_emitter_initialize(emitter->emitter);
+ yaml_emitter_initialize(&emitter->emitter);
emitter->output = Qnil;
return (VALUE)emitter;
}
@@ -460,7 +453,7 @@
rb_yaml_emitter_t *remitter = RYAMLEmitter(self);
remitter->output = output;
- yaml_emitter_t *emitter = remitter->emitter;
+ yaml_emitter_t *emitter = &remitter->emitter;
if (!NIL_P(output))
{
if (CLASS_OF(output) == rb_cByteString)
@@ -497,7 +490,7 @@
rb_yaml_emitter_stream(VALUE self, SEL sel)
{
yaml_event_t ev;
- yaml_emitter_t *emitter = RYAMLEmitter(self)->emitter;
+ yaml_emitter_t *emitter = &RYAMLEmitter(self)->emitter;
// RADAR: allow the encoding to be configurable
yaml_stream_start_event_initialize(&ev, YAML_UTF8_ENCODING);
@@ -517,7 +510,7 @@
rb_yaml_emitter_document(VALUE self, SEL sel, int argc, VALUE *argv)
{
yaml_event_t ev;
- yaml_emitter_t *emitter = RYAMLEmitter(self)->emitter;
+ yaml_emitter_t *emitter = &RYAMLEmitter(self)->emitter;
VALUE impl_beg = Qnil, impl_end = Qnil;
rb_scan_args(argc, argv, "02", &impl_beg, &impl_end);
if(NIL_P(impl_beg)) { impl_beg = Qfalse; }
@@ -538,7 +531,7 @@
rb_yaml_emitter_sequence(VALUE self, SEL sel, VALUE taguri, VALUE style)
{
yaml_event_t ev;
- yaml_emitter_t *emitter = RYAMLEmitter(self)->emitter;
+ yaml_emitter_t *emitter = &RYAMLEmitter(self)->emitter;
yaml_char_t *tag = (yaml_char_t*)RSTRING_PTR(taguri);
yaml_sequence_start_event_initialize(&ev, NULL, tag, 1, YAML_ANY_SEQUENCE_STYLE);
yaml_emitter_emit(emitter, &ev);
@@ -554,7 +547,7 @@
rb_yaml_emitter_mapping(VALUE self, SEL sel, VALUE taguri, VALUE style)
{
yaml_event_t ev;
- yaml_emitter_t *emitter = RYAMLEmitter(self)->emitter;
+ yaml_emitter_t *emitter = &RYAMLEmitter(self)->emitter;
yaml_char_t *tag = (yaml_char_t*)RSTRING_PTR(taguri);
yaml_mapping_start_event_initialize(&ev, NULL, tag, 1, YAML_ANY_MAPPING_STYLE);
yaml_emitter_emit(emitter, &ev);
@@ -570,7 +563,7 @@
rb_yaml_emitter_scalar(VALUE self, SEL sel, VALUE taguri, VALUE val, VALUE style)
{
yaml_event_t ev;
- yaml_emitter_t *emitter = RYAMLEmitter(self)->emitter;
+ yaml_emitter_t *emitter = &RYAMLEmitter(self)->emitter;
yaml_char_t *output = (yaml_char_t*)RSTRING_PTR(val);
int can_omit_tag = 0;
yaml_char_t *tag = rb_yaml_tag_or_null(taguri, &can_omit_tag);
@@ -599,21 +592,50 @@
static void
rb_yaml_emitter_finalize(void *rcv, SEL sel)
{
- yaml_emitter_t *emitter;
- Data_Get_Struct(rcv, yaml_emitter_t, emitter);
- yaml_emitter_close(emitter);
+ rb_yaml_emitter_t *emitter = RYAMLEmitter(rcv);
+ yaml_emitter_delete(&emitter->emitter);
+
if (rb_yaml_emitter_finalize_super != NULL)
{
((void(*)(void *, SEL))rb_yaml_emitter_finalize_super)(rcv, sel);
}
}
+static VALUE
+rb_yaml_resolver_alloc(VALUE klass, SEL sel)
+{
+ NEWOBJ(resolver, struct rb_yaml_resolver_s);
+ OBJSETUP(resolver, klass, T_OBJECT);
+ resolver->tags = NULL;
+ return (VALUE)resolver;
+}
+
+static VALUE
+rb_yaml_resolver_initialize(VALUE self, SEL sel)
+{
+ rb_yaml_resolver_t *resolver = RYAMLResolver(self);
+ CFMutableDictionaryRef d = CFDictionaryCreateMutable(NULL, 15,
+ &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ GC_WB(&resolver->tags, CFMakeCollectable(d));
+ return self;
+}
+
+static VALUE
+rb_yaml_resolver_add_type(VALUE self, SEL sel, VALUE key, VALUE handler)
+{
+ if(!NIL_P(key)) {
+ CFMutableDictionaryRef d = RYAMLResolver(self)->tags;
+ CFDictionarySetValue(d, (const void*)key, (const void*)handler);
+ }
+ return Qnil;
+}
+
+
void
Init_libyaml()
{
id_plain = rb_intern("plain");
id_quote2 = rb_intern("quote2");
- id_tags_ivar = rb_intern("@tags");
sel_to_yaml = sel_registerName("to_yaml:");
sel_call = sel_registerName("call:");
@@ -641,9 +663,10 @@
rb_yaml_parser_finalize_super = rb_objc_install_method2((Class)rb_cParser, "finalize", (IMP)rb_yaml_parser_finalize);
rb_cResolver = rb_define_class_under(rb_mLibYAML, "Resolver", rb_cObject);
- rb_define_attr(rb_cResolver, "tags", 1, 1);
+ rb_objc_define_method(*(VALUE *)rb_cResolver, "alloc", rb_yaml_resolver_alloc, 0);
rb_objc_define_method(rb_cResolver, "initialize", rb_yaml_resolver_initialize, 0);
//rb_objc_define_method(rb_cResolver, "transfer", rb_yaml_resolver_transfer, 1);
+ rb_objc_define_method(rb_cResolver, "add_type", rb_yaml_resolver_add_type, 2);
//rb_objc_define_method(rb_cResolver, "add_domain_type", rb_yaml_resolver_add_domain_type, 2);
//rb_objc_define_method(rb_cResolver, "add_ruby_type", rb_yaml_resolver_add_ruby_type, 1);
//rb_objc_define_method(rb_cResolver, "add_builtin_type", rb_yaml_resolver_add_builtin_type, 1);
Modified: MacRuby/trunk/lib/yaml/rubytypes.rb
===================================================================
--- MacRuby/trunk/lib/yaml/rubytypes.rb 2009-08-06 09:18:40 UTC (rev 2241)
+++ MacRuby/trunk/lib/yaml/rubytypes.rb 2009-08-06 17:59:51 UTC (rev 2242)
@@ -15,7 +15,7 @@
klass.define_method(:taguri) do
@taguri || tag
end
- YAML::LibYAML::DEFAULT_RESOLVER.tags[tag] = klass
+ YAML::LibYAML::DEFAULT_RESOLVER.add_type(tag, self)
end
yaml_as "tag:ruby.yaml.org,2002:object"
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090806/e90f34af/attachment-0001.html>
More information about the macruby-changes
mailing list