Skip to content

Commit

Permalink
reduced use of stack
Browse files Browse the repository at this point in the history
  • Loading branch information
ohler55 committed May 18, 2013
1 parent 5242052 commit c142c9c
Show file tree
Hide file tree
Showing 7 changed files with 561 additions and 552 deletions.
2 changes: 1 addition & 1 deletion ext/ox/attr.h
Expand Up @@ -33,7 +33,7 @@


#include "ox.h" #include "ox.h"


#define ATTR_STACK_INC 16 #define ATTR_STACK_INC 8


typedef struct _Attr { typedef struct _Attr {
const char *name; const char *name;
Expand Down
53 changes: 24 additions & 29 deletions ext/ox/gen_load.c
Expand Up @@ -92,12 +92,12 @@ create_doc(PInfo pi) {
VALUE doc; VALUE doc;
VALUE nodes; VALUE nodes;


pi->h = pi->helpers; helper_stack_init(&pi->helpers);
doc = rb_obj_alloc(ox_document_clas); doc = rb_obj_alloc(ox_document_clas);
nodes = rb_ary_new(); nodes = rb_ary_new();
rb_ivar_set(doc, ox_attributes_id, rb_hash_new()); rb_ivar_set(doc, ox_attributes_id, rb_hash_new());
rb_ivar_set(doc, ox_nodes_id, nodes); rb_ivar_set(doc, ox_nodes_id, nodes);
pi->h->obj = nodes; helper_stack_push(&pi->helpers, 0, nodes, NoCode);
pi->obj = doc; pi->obj = doc;
} }


Expand All @@ -108,10 +108,9 @@ create_prolog_doc(PInfo pi, const char *target, Attr attrs) {
VALUE nodes; VALUE nodes;
VALUE sym; VALUE sym;


if (0 != pi->h) { /* top level object */ if (!helper_stack_empty(&pi->helpers)) { /* top level object */
rb_raise(rb_eSyntaxError, "Prolog must be the first element in an XML document.\n"); rb_raise(rb_eSyntaxError, "Prolog must be the first element in an XML document.\n");
} }
pi->h = pi->helpers;
doc = rb_obj_alloc(ox_document_clas); doc = rb_obj_alloc(ox_document_clas);
ah = rb_hash_new(); ah = rb_hash_new();
for (; 0 != attrs->name; attrs++) { for (; 0 != attrs->name; attrs++) {
Expand Down Expand Up @@ -165,7 +164,7 @@ create_prolog_doc(PInfo pi, const char *target, Attr attrs) {
nodes = rb_ary_new(); nodes = rb_ary_new();
rb_ivar_set(doc, ox_attributes_id, ah); rb_ivar_set(doc, ox_attributes_id, ah);
rb_ivar_set(doc, ox_nodes_id, nodes); rb_ivar_set(doc, ox_nodes_id, nodes);
pi->h->obj = nodes; helper_stack_push(&pi->helpers, 0, nodes, ArrayCode);
pi->obj = doc; pi->obj = doc;
} }


Expand Down Expand Up @@ -201,13 +200,13 @@ nomode_instruct(PInfo pi, const char *target, Attr attrs, const char *content) {
if (0 == strcmp("object", attrs->value)) { if (0 == strcmp("object", attrs->value)) {
pi->pcb = ox_obj_callbacks; pi->pcb = ox_obj_callbacks;
pi->obj = Qnil; pi->obj = Qnil;
pi->h = 0; helper_stack_init(&pi->helpers);
} else if (0 == strcmp("generic", attrs->value)) { } else if (0 == strcmp("generic", attrs->value)) {
pi->pcb = ox_gen_callbacks; pi->pcb = ox_gen_callbacks;
} else if (0 == strcmp("limited", attrs->value)) { } else if (0 == strcmp("limited", attrs->value)) {
pi->pcb = ox_limited_callbacks; pi->pcb = ox_limited_callbacks;
pi->obj = Qnil; pi->obj = Qnil;
pi->h = 0; helper_stack_init(&pi->helpers);
} else { } else {
rb_raise(rb_eSyntaxError, "%s is not a valid processing instruction mode.\n", attrs->value); rb_raise(rb_eSyntaxError, "%s is not a valid processing instruction mode.\n", attrs->value);
} }
Expand Down Expand Up @@ -235,10 +234,10 @@ add_doctype(PInfo pi, const char *docType) {
} }
#endif #endif
rb_ivar_set(n, ox_at_value_id, s); rb_ivar_set(n, ox_at_value_id, s);
if (0 == pi->h) { /* top level object */ if (helper_stack_empty(&pi->helpers)) { /* top level object */
create_doc(pi); create_doc(pi);
} }
rb_ary_push(pi->h->obj, n); rb_ary_push(helper_stack_peek(&pi->helpers)->obj, n);
} }


static void static void
Expand All @@ -256,10 +255,10 @@ add_comment(PInfo pi, const char *comment) {
} }
#endif #endif
rb_ivar_set(n, ox_at_value_id, s); rb_ivar_set(n, ox_at_value_id, s);
if (0 == pi->h) { /* top level object */ if (helper_stack_empty(&pi->helpers)) { /* top level object */
create_doc(pi); create_doc(pi);
} }
rb_ary_push(pi->h->obj, n); rb_ary_push(helper_stack_peek(&pi->helpers)->obj, n);
} }


static void static void
Expand All @@ -277,10 +276,10 @@ add_cdata(PInfo pi, const char *cdata, size_t len) {
} }
#endif #endif
rb_ivar_set(n, ox_at_value_id, s); rb_ivar_set(n, ox_at_value_id, s);
if (0 == pi->h) { /* top level object */ if (helper_stack_empty(&pi->helpers)) { /* top level object */
create_doc(pi); create_doc(pi);
} }
rb_ary_push(pi->h->obj, n); rb_ary_push(helper_stack_peek(&pi->helpers)->obj, n);
} }


static void static void
Expand All @@ -296,10 +295,10 @@ add_text(PInfo pi, char *text, int closed) {
rb_funcall(s, ox_force_encoding_id, 1, pi->options->rb_enc); rb_funcall(s, ox_force_encoding_id, 1, pi->options->rb_enc);
} }
#endif #endif
if (0 == pi->h) { /* top level object */ if (helper_stack_empty(&pi->helpers)) { /* top level object */
create_doc(pi); create_doc(pi);
} }
rb_ary_push(pi->h->obj, s); rb_ary_push(helper_stack_peek(&pi->helpers)->obj, s);
} }


static void static void
Expand Down Expand Up @@ -376,29 +375,25 @@ add_element(PInfo pi, const char *ename, Attr attrs, int hasChildren) {
} }
rb_ivar_set(e, ox_attributes_id, ah); rb_ivar_set(e, ox_attributes_id, ah);
} }
if (0 == pi->h) { /* top level object */ if (helper_stack_empty(&pi->helpers)) { /* top level object */
pi->h = pi->helpers; pi->obj = e;
pi->obj = e;
} else { } else {
rb_ary_push(pi->h->obj, e); rb_ary_push(helper_stack_peek(&pi->helpers)->obj, e);
pi->h++;
} }
if (hasChildren) { if (hasChildren) {
VALUE nodes = rb_ary_new(); VALUE nodes = rb_ary_new();


rb_ivar_set(e, ox_nodes_id, nodes); rb_ivar_set(e, ox_nodes_id, nodes);
pi->h->obj = nodes; helper_stack_push(&pi->helpers, 0, nodes, NoCode);
} else {
helper_stack_push(&pi->helpers, 0, Qnil, NoCode); // will be popped in end_element
} }
} }


static void static void
end_element(PInfo pi, const char *ename) { end_element(PInfo pi, const char *ename) {
if (0 != pi->h) { if (!helper_stack_empty(&pi->helpers)) {
if (pi->helpers < pi->h) { helper_stack_pop(&pi->helpers);
pi->h--;
} else {
pi->h = 0;
}
} }
} }


Expand Down Expand Up @@ -488,8 +483,8 @@ add_instruct(PInfo pi, const char *name, Attr attrs, const char *content) {
} }
rb_ivar_set(inst, ox_attributes_id, ah); rb_ivar_set(inst, ox_attributes_id, ah);
} }
if (0 == pi->h) { /* top level object */ if (helper_stack_empty(&pi->helpers)) { /* top level object */
create_doc(pi); create_doc(pi);
} }
rb_ary_push(pi->h->obj, inst); rb_ary_push(helper_stack_peek(&pi->helpers)->obj, inst);
} }
9 changes: 8 additions & 1 deletion ext/ox/helper.h
Expand Up @@ -60,6 +60,11 @@ helper_stack_empty(HelperStack stack) {
return (stack->head == stack->tail); return (stack->head == stack->tail);
} }


inline static int
helper_stack_depth(HelperStack stack) {
return (stack->tail - stack->head);
}

inline static void inline static void
helper_stack_cleanup(HelperStack stack) { helper_stack_cleanup(HelperStack stack) {
if (stack->base != stack->head) { if (stack->base != stack->head) {
Expand All @@ -68,7 +73,7 @@ helper_stack_cleanup(HelperStack stack) {
} }
} }


inline static void inline static Helper
helper_stack_push(HelperStack stack, ID var, VALUE obj, Type type) { helper_stack_push(HelperStack stack, ID var, VALUE obj, Type type) {
if (stack->end <= stack->tail) { if (stack->end <= stack->tail) {
size_t len = stack->end - stack->head; size_t len = stack->end - stack->head;
Expand All @@ -87,6 +92,8 @@ helper_stack_push(HelperStack stack, ID var, VALUE obj, Type type) {
stack->tail->obj = obj; stack->tail->obj = obj;
stack->tail->type = type; stack->tail->type = type;
stack->tail++; stack->tail++;

return stack->tail - 1;
} }


inline static Helper inline static Helper
Expand Down

0 comments on commit c142c9c

Please sign in to comment.