Ejemplo n.º 1
0
/*
	Destroy all operating structures assocaited with the symtab pointer passed in.
*/
extern void jw_nuke( void* st ) {
	char* 	buf;					// pointer to the original json to free
	if( st == NULL ) {
		return;
	}

	sym_foreach_class( st, 0, nix_things, NULL );			// free anything that the symtab references
	sym_free( st );											// free the symtab itself
}
Ejemplo n.º 2
0
void
test_mem_sar_get_range
(void)
{
   sym_t * sym = sym_new_dna();
   test_assert_critical(sym != NULL);

   txt_t * txt = txt_new(sym);
   test_assert_critical(txt != NULL);
   test_assert(txt_append("TAGCNTCGACA", txt) == 0);
   test_assert(txt_commit_seq("seq0",txt) == 0);
   test_assert(txt_commit_rc(txt) == 0);

   sar_t * sar = sar_build(txt);
   test_assert_critical(sar != NULL);

   int64_t * sa_buf = malloc(30*sizeof(int64_t));
   test_assert_critical(sa_buf != NULL);

   redirect_stderr();
   // Set alloc failure rate to 0.1.
   set_alloc_failure_rate_to(0.1);
   for (int i = 0; i < 100; i++) {
      sar_get_range(0,10,sa_buf,sar);
      sar_get_range(10,5,sa_buf,sar);
      sar_get_range(19,30,sa_buf,sar);
   }
   reset_alloc();

   // Set alloc countdown 0->10.
   for (int i = 0; i <= 10; i++) {
      set_alloc_failure_countdown_to(i);
      sar_get_range(0,10,sa_buf,sar);
      sar_get_range(10,5,sa_buf,sar);
      sar_get_range(19,30,sa_buf,sar);
   }
   reset_alloc();

   free(sa_buf);
   sar_free(sar);
   txt_free(txt);
   sym_free(sym);
   unredirect_stderr();
}
Ejemplo n.º 3
0
void
test_mem_sar_file
(void)
{
   sym_t * sym = sym_new_dna();
   test_assert_critical(sym != NULL);

   txt_t * txt = txt_new(sym);
   test_assert_critical(txt != NULL);
   test_assert(txt_append("TAGCNTCGACA", txt) == 0);
   test_assert(txt_commit_seq("seq0",txt) == 0);
   test_assert(txt_commit_rc(txt) == 0);

   sar_t * sar = sar_build(txt);
   test_assert_critical(sar != NULL);

   sar_t * sar_i;

   redirect_stderr();
   // Set alloc failure rate to 0.1.
   set_alloc_failure_rate_to(0.1);
   for (int i = 0; i < 100; i++) {
      sar_file_write("test30.sar", sar);
      sar_i = sar_file_read("test30.sar");
      sar_free(sar_i);
   }
   reset_alloc();

   // Set alloc countdown 0->10.
   for (int i = 0; i <= 10; i++) {
      set_alloc_failure_countdown_to(i);
      sar_file_write("test30.sar", sar);
      sar_i = sar_file_read("test30.sar");
      sar_free(sar_i);
   }
   reset_alloc();

   sar_free(sar);
   txt_free(txt);
   sym_free(sym);
   unredirect_stderr();
}
Ejemplo n.º 4
0
static void asm_free_labels(TCCState *st)
{
    Sym *s, *s1;
    Section *sec;
    
    for(s = st->asm_labels; s != NULL; s = s1) {
        s1 = s->prev;
        /* define symbol value in object file */
        if (s->r) {
            if (s->r == SHN_ABS)
                sec = SECTION_ABS;
            else
                sec = st->sections[s->r];
            put_extern_sym2(s, sec, s->jnext, 0, 0);
        }
        /* remove label */
        table_ident[s->v - TOK_IDENT]->sym_label = NULL;
        sym_free(s);
    }
    st->asm_labels = NULL;
}
Ejemplo n.º 5
0
/*
	Real work for parsing an object ({...}) from the json.   Called by jw_new() and 
	recurses to deal with sub-objects.
*/
void* parse_jobject( void* st, char *json, char* prefix ) {
	jthing_t	*jtp; 			// json thing that we just created
	int 	i;
	int 	n;					
	char	*name;				// name in the json
	char	*data;				// data string from the json
	jthing_t*	jarray;			// array of jthings we'll coonstruct
	int		size;
	int		osize;
	int		njtokens; 			// tokens actually sussed out
	jsmn_parser jp;				// 'parser' object
	jsmntok_t *jtokens;			// pointer to tokens returned by the parser
	char	pname[1024];		// name with prefix
	char	wbuf[256];			// temp buf to build a working name in
	char*	dstr;				// dup'd string

	jsmn_init( &jp );			// does this have a failure mode?

	jtokens = (jsmntok_t *) malloc( sizeof( *jtokens ) * MAX_THINGS );
	if( jtokens == NULL ) {
		fprintf( stderr, "abort: cannot allocate tokens array\n" );
		exit( 1 );
	}

	njtokens = jsmn_parse( &jp, json, strlen( json ), jtokens, MAX_THINGS );

	if( jtokens[0].type != JSMN_OBJECT ) {				// if it's not an object then we can't parse it.
		fprintf( stderr, "warn: badly formed json; initial opening bracket ({) not detected\n" );
		return NULL;
	}

	/* DEBUG
	for( i = 1; i < njtokens-1; i++ ) {					// we'll silently skip the last token if its "name" without a value
		fprintf( stderr, ">>> %4d: size=%d start=%d end=%d %s\n", i, jtokens[i].size, jtokens[i].start, jtokens[i].end, extract( json, &jtokens[i] ) );
	}
	*/

	for( i = 1; i < njtokens-1; i++ ) {					// we'll silently skip the last token if its "name" without a value
		if( jtokens[i].type != JSMN_STRING ) {
			fprintf( stderr, "warn: badly formed json [%d]; expected name (string) found type=%d %s\n", i, jtokens[i].type, extract( json, &jtokens[i] ) );
			sym_free( st );
			return NULL;
		}
		name = extract( json, &jtokens[i] );
		if( *prefix != 0 ) {
			snprintf( pname, sizeof( pname ), "%s.%s", prefix, name );
			name = pname;
		}

		size = jtokens[i].size;

		i++;										// at the data token now
		switch( jtokens[i].type ) {
			case JSMN_UNDEFINED: 
				fprintf( stderr, "warn: element [%d] in json is undefined\n", i );
				break;

    		case JSMN_OBJECT:				// save object in two ways: as an object 'blob' and in the current symtab using name as a base (original)
				dstr = strdup( extract( json, &jtokens[i] ) );
				snprintf( wbuf, sizeof( wbuf ), "%s_json", name );	// must stash the json string in the symtab for clean up during nuke	
				sym_fmap( st, (unsigned char *) wbuf, 0, dstr );
				parse_jobject( st, dstr, name );					// recurse to add the object as objectname.xxxx elements
				
				jtp = mk_thing( st, name, jtokens[i].type );		// create thing and reference it in current symtab
				if( jtp == NULL ) {
					fprintf( stderr, "warn: memory alloc error processing element [%d] in json\n", i );
					free( dstr );
					sym_free( st );
					return NULL;
				}
				jtp->v.pv = (void *) sym_alloc( 255 );						// object is just a blob
				if( jtp->v.pv == NULL ) {
					fprintf( stderr, "error: [%d] symtab for object blob could not be allocated\n", i );
					sym_free( st );
					free( dstr );
					return NULL;
				}
				dstr = strdup( extract( json, &jtokens[i] ) );
				sym_fmap( jtp->v.pv, (unsigned char *) JSON_SYM_NAME, 0, dstr );		// must stash json so it is freed during nuke()
				parse_jobject( jtp->v.pv,  dstr, "" );							// recurse acorss the string and build a new symtab

				size = jtokens[i].end;											// done with them, we need to skip them 
				i++;
				while( i < njtokens-1  &&  jtokens[i].end < size ) {
					//fprintf( stderr, "\tskip: [%d] object element start=%d end=%d (%s)\n", i, jtokens[i].start, jtokens[i].end, extract( json, &jtokens[i])  );
					i++;
				} 

				i--;						// must allow loop to bump past the last
				break;

    		case JSMN_ARRAY:
				size = jtokens[i].size;		// size is burried here, and not with the name
				jtp = mk_thing( st, name, jtokens[i].type );

				i++;						// first thing is the whole array string which I don't grock the need for, but it's their code...
				if( jtp == NULL ) {
					fprintf( stderr, "warn: memory alloc error processing element [%d] in json\n", i );
					sym_free( st );
					return NULL;
				}
				jarray = jtp->v.pv = (jsmntok_t *) malloc( sizeof( *jarray ) * size );		// allocate the array
				memset( jarray, 0, sizeof( *jarray ) * size );
				jtp->nele = size;

				for( n = 0; n < size; n++ ) {								// for each array element
					jarray[n].prim_type	 = PT_UNKNOWN;						// assume not primative type
					switch( jtokens[i+n].type ) {
						case JSMN_UNDEFINED:
							fprintf( stderr, "warn: [%d] array element %d is not valid type (undefined) is not string or primative\n", i, n );
							fprintf( stderr, "\tstart=%d end=%d\n", jtokens[i+n].start, jtokens[i+n].end );
							break;

						case JSMN_OBJECT:
							jarray[n].v.pv = (void *) sym_alloc( 255 );
							if( jarray[n].v.pv == NULL ) {
								fprintf( stderr, "error: [%d] array element %d size=%d could not allocate symtab\n", i, n, jtokens[i+n].size );
								sym_free( st );
								return NULL;
							}

							jarray[n].jsmn_type = JSMN_OBJECT;
							parse_jobject( jarray[n].v.pv,  extract( json, &jtokens[i+n]  ), "" );		// recurse acorss the string and build a new symtab
							osize = jtokens[i+n].end;									// done with them, we need to skip them 
							i++;
							while( i+n < njtokens-1  &&  jtokens[n+i].end < osize ) {
								//fprintf( stderr, "\tskip: [%d] object element start=%d end=%d (%s)\n", i, jtokens[i].start, jtokens[i].end, extract( json, &jtokens[i])  );
								i++;
							}
							i--;					// allow incr at loop end
							break;

						case JSMN_ARRAY:
							fprintf( stderr, "warn: [%d] array element %d is not valid type (array) is not string or primative\n", i, n );
							n += jtokens[i+n].size;			// this should skip the nested array
							break;

						case JSMN_STRING:
							data = extract( json, &jtokens[i+n] );
							jarray[n].v.pv = (void *) data;
							jarray[n].jsmn_type = JSMN_STRING;
							break;

						case JSMN_PRIMITIVE:
							data = extract( json, &jtokens[i+n] );
							switch( *data ) {
								case 0:
									jarray[n].prim_type	 = PT_VALUE;
									jarray[n].v.fv = 0;
									break;

								case 'T':
								case 't':
									jarray[n].v.fv = 1;
									jarray[n].prim_type	 = PT_BOOL;
									break;

								case 'F':
								case 'f':
									jarray[n].prim_type	 = PT_BOOL;
									jarray[n].v.fv = 0;
									break;

								case 'N':										// assume null, nil, or some variant
								case 'n':
									jarray[n].prim_type	 = PT_NULL;
									jarray[n].v.fv = 0;
									break;

								default:
									jarray[n].prim_type	 = PT_VALUE;
									jarray[n].v.fv = strtof( data, NULL ); 		// store all numerics as float
									break;
							}

							jarray[n].jsmn_type = JSMN_PRIMITIVE;
							break;
						
						default:
							fprintf( stderr, "warn: [%d] array element %d is not valid type (unknown=%d) is not string or primative\n", i, n, jtokens[i].type  );
							sym_free( st );
							return NULL;
							break;
					}
				}

				i += size - 1;		// must allow loop to push to next
				break;

    		case JSMN_STRING:
				data = extract( json, &jtokens[i] );
				jtp = mk_thing( st, name, jtokens[i].type );
				if( jtp == NULL ) {
					fprintf( stderr, "warn: memory alloc error processing element [%d] in json\n", i );
					sym_free( st );
					return NULL;
				}
				jtp->v.pv =  (void *) data;						// just point into the large json string
				break;

    		case JSMN_PRIMITIVE:
				data = extract( json, &jtokens[i] );
				jtp = mk_thing( st, name, jtokens[i].type );
				if( jtp == NULL ) {
					fprintf( stderr, "warn: memory alloc error processing element [%d] in json\n", i );
					sym_free( st );
					return NULL;
				}
				switch( *data ) {								// assume T|t is true and F|f is false
					case 0:
						jtp->v.fv = 0;
						jtp->prim_type = PT_VALUE;
						break;

					case 'T':
					case 't':
						jtp->prim_type = PT_BOOL;
						jtp->v.fv = 1; 
						break;

					case 'F':
					case 'f':
						jtp->prim_type = PT_BOOL;
						jtp->v.fv = 0; 
						break;

					case 'N':									// Null or some form of that
					case 'n':
						jtp->prim_type = PT_NULL;
						jtp->v.fv = 0; 
						break;

					default:
						jtp->prim_type = PT_VALUE;
						jtp->v.fv = strtof( data, NULL ); 		// store all numerics as float
						break;
				}
				break;

			default:
				fprintf( stderr, "unknown type at %d\n", i );
				break;
		}
	}

	free( jtokens );
	return st;
}
Ejemplo n.º 6
0
void gcode(void) {
  int i, n, t, r, stacksize, addr, pc, disp, rel, errs, more, func_start;
  Branch *b, *bn;

  // Generate function prolog
  func_start = cur_text_section->data_offset;
  if (!func_naked) {
    // Align local size to word
    stacksize = (-loc + 3) & -4;

    if (stacksize >= 4096) {
      // Generate stack guard since parameters can cross page boundary
      Sym *sym = external_global_sym(TOK___chkstk, &func_old_type, 0);
      gen(0xb8); // mov stacksize, %eax
      genword(stacksize);
      gen(0xe8);  // call __chkstk, (does the stackframe too)
      put_reloc(cur_text_section, sym, cur_text_section->data_offset, R_386_PC32);
      genword(-4);
    } else {
      if (do_debug || loc || !func_noargs) {
        gen(0x55); // push %ebp
        gen(0x89); // mov %esp, %ebp
        gen(0xe5);
      }
      if (stacksize > 0) {
        if (stacksize == (char) stacksize) {
          gen(0x83);  // sub esp, stacksize
          gen(0xec);
          gen(stacksize);
        } else {
          gen(0x81);  // sub esp, stacksize
          gen(0xec);
          genword(stacksize);
        }
      }
    }
    
    // Save callee-saved registers used by function.
    for (r = 0; r < NB_REGS; ++r) {
      if ((reg_classes[r] & RC_SAVE) && (regs_used & (1 << r))) {
        gen(0x50 + r); // push r
      }
    }
  }

  // Optimize jumps
  more = 1;
  while (more) {
    more = 0;

    for (i = 0; i < br; ++i) {
      b = branch + i;
      if (b->type == CodeLabel) b->target = 0;
      if (b->type != CodeJump) continue;

      t = skip_nops(b->target, 1);
      if (branch[t].type == CodeJump && !branch[t].param && b->target != branch[t].target) {
        // Eliminate jump to jump
        b->target = branch[t].target;
        more = 1;
        continue;
      }

      // Find next non-nop
      n = i + 1;
      while (branch[n].type == CodeNop || branch[n].type == CodeLine) n++;
      bn = branch + n;
      if (b->ind != bn->ind) continue;

      if (!b->param && bn->type == CodeJump) {
        // Eliminate dead jump instruction
        bn->type = CodeNop;
        more = 1;
        continue;
      }

      if (b->target > i && b->target <= n) {
        // Eliminate jump to next instruction
        b->type = CodeNop;
        more = 1;
        continue;
      }
      
      t = skip_nops(n + 1, 0);
      if (bn->type == CodeJump && !bn->param && b->target == t && bn->ind == branch[t].ind) {
        // Optimize inverted jump
        if (b->param) b->param ^= 1;
        b->target = bn->target;
        bn->type = CodeNop;
        more = 1;
        continue;
      }
    }

    // Eliminate unused labels
    for (i = 0; i < br; ++i) {
      b = branch + i;
      if (b->type == CodeJump) branch[b->target].target++;
    }
    for (i = 0; i < br; ++i) {
      b = branch + i;
      if (b->type == CodeLabel && !b->target && !b->sym) {
        // Remove label with no references
        b->type = CodeNop;
        more = 1;
      }
    }
  }

  // Assign addresses to branch points, assuming only long jumps
  addr = cur_text_section->data_offset;
  pc = 0;
  for (i = 0; i < br; ++i) {
    b = branch + i;
    addr += b->ind - pc;
    b->addr = addr;
    switch (b->type) {
      case CodeJump:
        addr += 5;
        if (b->param != 0) addr++;
        break;
        
      case CodeAlign:
        // Use convervative estimate for short/long jump estimation
        addr += b->param - 1;
        break;
    }
    pc = b->ind;
  }
  
  // Find jumps which can be encoded as short jumps
  for (i = 0; i < br; ++i) {
    b = branch + i;
    if (b->type == CodeJump) {
      disp = branch[b->target].addr - b->addr - 2;
      if (b->param) disp--;
      if (disp == (char) disp) b->type = CodeShortJump;
    }
  }

  // Assign final addresses to branch points
  addr = cur_text_section->data_offset;
  pc = 0;
  for (i = 0; i < br; ++i) {
    b = branch + i;
    addr += b->ind - pc;
    b->addr = addr;
    switch (b->type) {
      case CodeJump:
        addr += 5;
        if (b->param) addr++;
        break;

      case CodeShortJump:
        addr += 2;
        break;
      
      case CodeAlign:
        addr = (addr + b->param - 1) & -b->param;
        break;
    }
    pc = b->ind;
  }

  // Generate code blocks
  pc = 0;
  errs = 0;
  for (i = 0; i < br; ++i) {
    b = branch + i;
    
    // Output code block before branch point
    if (b->ind != pc) {
      genblk(code + pc, b->ind - pc);
      pc = b->ind;
    }

    switch (b->type) {
      case CodeLabel:
        // Export label if symbol defined
        if (b->sym) {
          put_extern_sym_ex(b->sym, cur_text_section, b->addr, 0, 0);
          sym_free(b->sym);
        }
        break;

      case CodeJump:
        // Generate long jump instruction
        if (branch[b->target].type != CodeLabel) {
          printf("internal error: jump %d to non-label %d\n", i, b->target);
          errs++;
        }
        if (b->param > 0xff) error("invalid displacement");
        if (b->param == 0) {
          gen(0xe9);
          genword(branch[b->target].addr - (b->addr + 5));
        } else {
          gen(0x0f);
          gen(b->param - 0x10);
          genword(branch[b->target].addr - (b->addr + 6));
        }
        break;

      case CodeShortJump:
        // Generate short jump instruction
        if (branch[b->target].type != CodeLabel) {
          printf("internal error: jump %d to non-label %d\n", i, b->target);
          errs++;
        }
        if (b->param == 0) {
          gen(0xeb);
        } else {
          gen(b->param - 0x20);
        }
        gen(branch[b->target].addr - (b->addr + 2));
        break;

      case CodeReloc:
        if (b->param) {
          rel = R_386_PC32;
        } else {
          rel = R_386_32;
        }
        put_elf_reloc(symtab_section, cur_text_section, b->addr, rel, b->target);
        break;
        
      case CodeAlign:
        i = addr;
        while (i & (b->param - 1)) {
          gen(b->target);
          i++;
        }
        break;

      case CodeLine:
        put_stabn(N_SLINE, 0, b->target, b->addr - func_start);
        break;
    }
  }

  // Generate function epilog
  if (!func_naked) {
    // Restore callee-saved registers used by function.
    for (r = NB_REGS; r >= 0; --r) {
      if ((reg_classes[r] & RC_SAVE) && (regs_used & (1 << r))) {
        gen(0x58 + r); // pop r
      }
    }

    if (do_debug || loc || !func_noargs) gen(0xc9); // leave

    // Generate return
    if (func_ret_sub == 0) {
      gen(0xc3); // ret
    } else {
      gen(0xc2); // ret n
      gen(func_ret_sub);
      gen(func_ret_sub >> 8);
    }
  }

#ifdef DEBUG_BRANCH
  printf("\nbranch table for %s\n", func_name);
  printf(" #   t targ parm    ind      addr\n");
  printf("---- - ---- ----- -------- --------\n");
  for (i = 0; i < br; ++i) {
    b = branch + i;
    printf("%04d %c %04d %04x %08x %08x", i, "SLJjRANlE"[b->type], b->target, b->param, b->ind, b->addr);
    if (branch[i].sym) {
      printf(" sym=%s", get_tok_str(b->sym->v, NULL));
    }
    printf("\n");
  }
  printf("\n");
#endif

  if (errs) error("internal error: code generation");
}
Ejemplo n.º 7
0
Archivo: main.c Proyecto: inste/jane
int main(int argc, char ** argv) {
	
	char * test;
	int i;
	struct WorkFlow * wf;
	rb_tree * symtab, * functab;
	
	struct Symbol * s, * q;
	
	test = malloc(1024);
	
	memstat_init();
//	jmm_init();
	symtab = symtable_init();
	functab = functable_init();
	
	stdlib_arythm_register(functab);
	
	strcpy(test, "rcmp(rcmp(33, 34), rcmp(34, 35)) + 8");
	
	if (inf_check_brackets(test))
		printf("Correct!\n");
	
	wf = inf_transform_to_reverse_postfix(functab, test);

	puts(test);
	for(i = 0; i < wf->count; ++i) {
		printf("%d ", wf->ops[i].id);
	}
	puts("");
	for(i = 0; i < wf->count; ++i) {
		switch (wf->ops[i].id) {
			case SYM_NUM:		printf("%s", (char *)wf->ops[i].data); break;
			case SYM_SYMBOL:	printf("%s", (char *)wf->ops[i].data); break;
			case SYM_OPS_ADD:	printf("+"); break;
			case SYM_OPS_SUB:	printf("-"); break;
			case SYM_OPS_MUL:	printf("*"); break;
			case SYM_OPS_DIV:	printf("/"); break;
			case SYM_OPS_EXP:	printf("^"); break;
			case SYM_FUNC:		printf("%s", (char *)wf->ops[i].data); break;
			default:			break;
		}
		printf(" ");
	}
	puts("");
	
	
	
	s = process_postfix_workflow(wf, symtab, functab);
	
	printf("%s = %ld/%ld\n", test, ((struct Rational *)s->data)->num, ((struct Rational *)s->data)->denom);
	
	sym_rational_normalize(s);
	
	printf("%s = %ld/%ld\n", test, ((struct Rational *)s->data)->num, ((struct Rational *)s->data)->denom);
	
	workflow_free(wf);
//	sym_free(s);
	
	
	strcpy(test, "(7*2)/12");
	wf = inf_transform_to_reverse_postfix(functab, test);
	q = process_postfix_workflow(wf, symtab, functab);
	
	printf("%s = %ld/%ld\n", test, ((struct Rational *)q->data)->num, ((struct Rational *)q->data)->denom);
	
	if (sym_rational_is_eq(s, q))
		printf("They are equal\n");
	
	sym_free(q);
	sym_free(s);
	workflow_free(wf);
	free(test);
	

	functable_shutdown(functab);
	symtable_shutdown(symtab);

	memstat_shutdown();
	
	return 0;
}