ext/oj/fast.c in oj-3.13.23 vs ext/oj/fast.c in oj-3.14.0

- old
+ new

@@ -72,11 +72,11 @@ static void next_non_white(ParseInfo pi); static char *read_quoted_value(ParseInfo pi); static void skip_comment(ParseInfo pi); static VALUE protect_open_proc(VALUE x); -static VALUE parse_json(VALUE clas, char *json, bool given, bool allocated); +static VALUE parse_json(VALUE clas, char *json, bool given); static void each_leaf(Doc doc, VALUE self); static int move_step(Doc doc, const char *path, int loc); static Leaf get_doc_leaf(Doc doc, const char *path); static Leaf get_leaf(Leaf *stack, Leaf *lp, const char *path); static void each_value(Doc doc, Leaf leaf); @@ -649,11 +649,12 @@ doc->batches = doc->batches->next; if (&doc->batch0 != b) { xfree(b); } } - // xfree(f); + xfree(doc->json); + xfree(doc); } } static VALUE protect_open_proc(VALUE x) { ParseInfo pi = (ParseInfo)x; @@ -669,11 +670,10 @@ static void free_doc_cb(void *x) { Doc doc = (Doc)x; if (0 != doc) { - xfree(doc->json); doc_free(doc); } } static void mark_leaf(Leaf leaf) { @@ -747,24 +747,19 @@ }, 0, 0, }; -static VALUE parse_json(VALUE clas, char *json, bool given, bool allocated) { +static VALUE parse_json(VALUE clas, char *json, bool given) { struct _parseInfo pi; volatile VALUE result = Qnil; Doc doc; int ex = 0; volatile VALUE self; - // TBD are both needed? is stack allocation ever needed? + doc = RB_ALLOC_N(struct _doc, 1); - if (given) { - doc = ALLOCA_N(struct _doc, 1); - } else { - doc = ALLOC(struct _doc); - } // skip UTF-8 BOM if present if (0xEF == (uint8_t)*json && 0xBB == (uint8_t)json[1] && 0xBF == (uint8_t)json[2]) { pi.str = json + 3; } else { pi.str = json; @@ -785,22 +780,24 @@ } else { pi.stack_min = 0; // indicates not to check stack limit } } #endif + doc->json = json; self = TypedData_Wrap_Struct(clas, &oj_doc_type, doc); doc->self = self; - doc->json = json; DATA_PTR(doc->self) = doc; result = rb_protect(protect_open_proc, (VALUE)&pi, &ex); if (given || 0 != ex) { DATA_PTR(doc->self) = NULL; + // TBD is this needed? + /* doc_free(pi.doc); - if (allocated && 0 != ex) { // will jump so caller will not free + if (0 != ex) { // will jump so caller will not free xfree(json); } - rb_gc_enable(); + */ } else { result = doc->self; } if (0 != ex) { rb_jump_tag(ex); @@ -1090,31 +1087,23 @@ static VALUE doc_open(VALUE clas, VALUE str) { char * json; size_t len; volatile VALUE obj; int given = rb_block_given_p(); - int allocate; Check_Type(str, T_STRING); len = (int)RSTRING_LEN(str) + 1; - allocate = (SMALL_JSON < len || !given); - if (allocate) { - json = ALLOC_N(char, len); - } else { - json = ALLOCA_N(char, len); - } - // It should not be necessaary to stop GC but if it is not stopped and a - // large string is parsed that string is corrupted or freed during - // parsing. I'm not sure what is going on exactly but disabling GC avoids - // the issue. - rb_gc_disable(); + json = RB_ALLOC_N(char, len); + memcpy(json, StringValuePtr(str), len); - obj = parse_json(clas, json, given, allocate); - rb_gc_enable(); - if (given && allocate) { + obj = parse_json(clas, json, given); + // TBD is this needed + /* + if (given) { xfree(json); } + */ return obj; } /* @overload open_file(filename) { |doc| ... } => Object * @@ -1140,41 +1129,37 @@ char * json; FILE * f; size_t len; volatile VALUE obj; int given = rb_block_given_p(); - int allocate; Check_Type(filename, T_STRING); path = StringValuePtr(filename); if (0 == (f = fopen(path, "r"))) { rb_raise(rb_eIOError, "%s", strerror(errno)); } fseek(f, 0, SEEK_END); len = ftell(f); - allocate = (SMALL_JSON < len || !given); - if (allocate) { - json = ALLOC_N(char, len + 1); - } else { - json = ALLOCA_N(char, len + 1); - } + json = RB_ALLOC_N(char, len + 1); + fseek(f, 0, SEEK_SET); if (len != fread(json, 1, len, f)) { fclose(f); rb_raise(rb_const_get_at(Oj, rb_intern("LoadError")), "Failed to read %lu bytes from %s.", (unsigned long)len, path); } fclose(f); json[len] = '\0'; - rb_gc_disable(); - obj = parse_json(clas, json, given, allocate); - rb_gc_enable(); - if (given && allocate) { + obj = parse_json(clas, json, given); + // TBD is this needed + /* + if (given) { xfree(json); } + */ return obj; } static int esc_strlen(const char *s) { int cnt = 0; @@ -1654,14 +1639,12 @@ */ static VALUE doc_close(VALUE self) { Doc doc = self_doc(self); rb_gc_unregister_address(&doc->self); - DATA_PTR(doc->self) = 0; + DATA_PTR(doc->self) = NULL; if (0 != doc) { - xfree(doc->json); doc_free(doc); - xfree(doc); } return Qnil; } #if 0 // hack to keep the doc generator happy