strip.c 17.4 KB
Newer Older
Camil Staps's avatar
Camil Staps committed
1 2 3 4
#include <stdlib.h>
#include <string.h>

#include "abc_instructions.h"
5
#include "bcgen_instructions.h"
6 7 8 9
#include "bytecode.h"
#include "strip.h"
#include "util.h"

10 11 12
enum data_label_type {
	DLT_NORMAL,
	DLT_STRING,
13 14
	DLT_STRING_WITH_DESCRIPTOR,
	DLT_CAF
15 16 17
};

struct s_label { /* source label */
18 19
	int32_t offset;
	char *name;
20 21
	struct label *bcgen_label;
	enum data_label_type label_type;
Camil Staps's avatar
Camil Staps committed
22 23
};

24
struct s_relocation { /* source relocation */
Camil Staps's avatar
Camil Staps committed
25 26
	int32_t relocation_offset;
	uint32_t relocation_label;
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
	struct s_label *relocation_belongs_to_label;
};

struct label_queue { /* source labels that are to be activated */
	uint32_t writer;
	uint32_t reader;
	uint32_t size;
	struct s_label *labels[0];
};

struct incoming_labels {
	uint32_t label_id;
	struct incoming_labels *next;
};

struct code_index { /* auxiliary information about code indices */
	int32_t byte_index; /* index in width-optimised bytecode */
	struct incoming_labels *incoming_labels;
45 46
};

47 48
static struct program *pgrm;

49
static uint8_t *code;
50
static struct code_index *code_indices;
51 52
static uint64_t *data;

Camil Staps's avatar
Camil Staps committed
53
static uint32_t n_labels;
54
static uint32_t n_global_labels;
55
static struct s_label *labels;
Camil Staps's avatar
Camil Staps committed
56 57

static uint32_t code_reloc_size;
58
static struct s_relocation *code_relocations;
Camil Staps's avatar
Camil Staps committed
59
static uint32_t data_reloc_size;
60
static struct s_relocation *data_relocations;
Camil Staps's avatar
Camil Staps committed
61

62
struct label_queue *queue;
Camil Staps's avatar
Camil Staps committed
63

64 65
static int export_all_labels;
static int include_symbol_table=0;
66
static int export_label(const char *label) {
67
	if (export_all_labels)
68 69 70 71 72 73 74 75 76 77 78 79 80
		return 1;
	else if (!strcmp(label, "__ARRAY__"))
		return 1;
	else if (!strcmp(label, "__STRING__"))
		return 1;
	else if (!strcmp(label, "INT") || !strcmp(label, "dINT"))
		return 1;
	else if (!strcmp(label, "BOOL"))
		return 1;
	else if (!strcmp(label, "CHAR"))
		return 1;
	else if (!strcmp(label, "REAL"))
		return 1;
81 82 83 84 85
	else if (!include_symbol_table)
		return 0;
	else if (!label[0])
		return 0;
	else if (!strncmp(label, "_internal", 9))
86
		return 0;
87 88
	else
		return 1;
89 90
}

Camil Staps's avatar
Camil Staps committed
91
static void init_label_queue(void) {
92 93 94 95 96 97
	queue=safe_malloc(sizeof(struct label_queue)+2*sizeof(char*));
	queue->writer=0;
	queue->reader=0;
	queue->size=2;
}

Camil Staps's avatar
Camil Staps committed
98
static void add_label_to_queue(struct s_label *label) {
99 100 101 102 103
	if (label->bcgen_label!=NULL)
		return;

	if (label->name[0]!='\0') {
		label->bcgen_label=enter_label(label->name);
104 105
		if (export_label(label->name))
			make_label_global(label->bcgen_label);
106 107
	} else
		label->bcgen_label=new_internal_label();
108 109 110 111 112 113 114 115 116 117 118 119

	queue->labels[queue->writer++]=label;
	queue->writer%=queue->size;

	if (queue->writer==queue->reader) {
		queue->writer=queue->size;
		queue->size*=2;
		queue->reader=0;
		queue=safe_realloc(queue, sizeof(struct label_queue)+queue->size*sizeof(struct s_label*));
	}
}

Camil Staps's avatar
Camil Staps committed
120
static struct s_label *next_label_from_queue(void) {
121 122 123 124 125 126 127
	if (queue->reader==queue->writer)
		return NULL;
	struct s_label *label=queue->labels[queue->reader];
	queue->reader++;
	queue->reader%=queue->size;
	return label;
}
Camil Staps's avatar
Camil Staps committed
128 129 130 131 132 133 134 135 136

static inline int instruction_ends_block(int16_t instr) {
	switch (instr) {
		case Cjmp:
		case Cjmp_ap1:
		case Cjmp_ap2:
		case Cjmp_ap3:
		case Cjmp_ap4:
		case Cjmp_ap5:
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
		case Cjmp_ap6:
		case Cjmp_ap7:
		case Cjmp_ap8:
		case Cjmp_ap9:
		case Cjmp_ap10:
		case Cjmp_ap11:
		case Cjmp_ap12:
		case Cjmp_ap13:
		case Cjmp_ap14:
		case Cjmp_ap15:
		case Cjmp_ap16:
		case Cjmp_ap17:
		case Cjmp_ap18:
		case Cjmp_ap19:
		case Cjmp_ap20:
		case Cjmp_ap21:
		case Cjmp_ap22:
		case Cjmp_ap23:
		case Cjmp_ap24:
		case Cjmp_ap25:
		case Cjmp_ap26:
		case Cjmp_ap27:
		case Cjmp_ap28:
		case Cjmp_ap29:
		case Cjmp_ap30:
		case Cjmp_ap31:
		case Cjmp_ap32:
Camil Staps's avatar
Camil Staps committed
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
		case Cjmp_eval:
		case Cjmp_eval_upd:
		case Cpop_a_jmp:
		case Cpop_b_jmp:

		case Cfill_a01_pop_rtn:
		case Cpop_a_rtn:
		case Cpop_ab_rtn:
		case Cpop_b_rtn:
		case Crtn:

		case Cadd_arg0:
		case Cadd_arg1:
		case Cadd_arg2:
		case Cadd_arg3:
		case Cadd_arg4:
		case Cadd_arg5:
		case Cadd_arg6:
		case Cadd_arg7:
		case Cadd_arg8:
		case Cadd_arg9:
		case Cadd_arg10:
		case Cadd_arg11:
		case Cadd_arg12:
		case Cadd_arg13:
		case Cadd_arg14:
		case Cadd_arg15:
		case Cadd_arg16:
		case Cadd_arg17:
		case Cadd_arg18:
		case Cadd_arg19:
		case Cadd_arg20:
		case Cadd_arg21:
		case Cadd_arg22:
		case Cadd_arg23:
		case Cadd_arg24:
		case Cadd_arg25:
		case Cadd_arg26:
		case Cadd_arg27:
		case Cadd_arg28:
		case Cadd_arg29:
		case Cadd_arg30:
		case Cadd_arg31:

		case Chalt:

			return 1;

		default:
			return 0;
	}
}

Camil Staps's avatar
Camil Staps committed
217
static struct s_relocation *find_relocation_by_offset(struct s_relocation *relocs, uint32_t n_relocs, uint32_t offset) {
218 219 220 221 222 223 224 225 226 227
	int l=0;
	int r=n_relocs-1;
	while (l<=r) {
		int i=(l+r)/2;
		if (relocs[i].relocation_offset<offset)
			l=i+1;
		else if (relocs[i].relocation_offset>offset)
			r=i-1;
		else
			return &relocs[i];
Camil Staps's avatar
Camil Staps committed
228
	}
229
	return NULL;
230
}
Camil Staps's avatar
Camil Staps committed
231

232 233
static void activate_label(struct s_label *label) {
	struct s_relocation *reloc;
234 235
	if (label->bcgen_label->label_offset!=-1)
		return;
Camil Staps's avatar
Camil Staps committed
236

237 238 239
	if (label->offset==-1) {
		return;
	} else if (label->offset & 1) { /* data */
240 241 242 243 244 245
		uint64_t *block=&data[(label->offset-1)>>2];
		uint32_t arity=block[0];

		switch (label->label_type) {
			case DLT_NORMAL:
				if ((arity & 0xffff) > 256) { /* record */
246
					uint64_t *type_string=&block[2];
247 248 249 250 251 252

					store_data_l(block[-2]);
					store_data_l(block[-1]);
					label->bcgen_label->label_offset=(pgrm->data_size<<2)+1;
					store_data_l(block[0]);

253
					store_string((char*)type_string,type_string[-1]-1,1);
254 255 256 257 258 259 260 261

					int n_desc_labels=0;
					for (char *ts=(char*)type_string; *ts; ts++)
						if (*ts=='{')
							n_desc_labels++;
					uint64_t *desc_labels=&block[2+(type_string[-1]+sizeof(uint64_t)-1)/sizeof(uint64_t)];
					for (; n_desc_labels; n_desc_labels--) {
						reloc=find_relocation_by_offset(data_relocations, data_reloc_size, desc_labels-data);
262 263
						add_label_to_queue(&labels[reloc->relocation_label]);
						add_data_relocation(labels[reloc->relocation_label].bcgen_label, pgrm->data_size);
264 265 266 267 268
						store_data_l(*desc_labels++);
					}

					uint64_t *name_string=desc_labels+1;
					store_string((char*)name_string,name_string[-1],0);
269
				} else if ((arity & 0xffff) > 0 && (arity>>16)==0) { /* string */
270 271
					label->bcgen_label->label_offset=(pgrm->data_size<<2)+1;
					store_string((char*)&block[1], block[0], 0);
272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293
				} else { /* no record */
					arity>>=3+16;

					if (arity==0) { /* desc0, descn or string */
						if (block[0]==0 || block[0]==1 || (block[0]>>16)>0) { /* desc0 or descn */
							store_data_l(block[-3]);
							store_data_l(block[-2]);
							reloc=find_relocation_by_offset(data_relocations, data_reloc_size, &block[-1]-data);
							add_label_to_queue(&labels[reloc->relocation_label]);
							add_data_relocation(labels[reloc->relocation_label].bcgen_label, pgrm->data_size);
							store_data_l(block[-1]);
							label->bcgen_label->label_offset=(pgrm->data_size<<2)+1;
							store_data_l(block[0]);
							store_data_l(block[1]);
							if (block[2]!=0) { /* descn */
								store_string((char*)&block[3], block[2], 0);
							} else { /* desc0 */
								store_data_l(block[2]);
								store_string((char*)&block[4], block[3], 0);
							}
						} else { /* string */
							store_string((char*)&block[1], block[0], 0);
294
						}
295
					} else { /* descs or normal descriptor */
296 297 298 299 300 301 302
						store_data_l(block[-2]);
						reloc=find_relocation_by_offset(data_relocations, data_reloc_size, &block[-1]-data);
						add_label_to_queue(&labels[reloc->relocation_label]);
						add_data_relocation(labels[reloc->relocation_label].bcgen_label, pgrm->data_size);
						store_data_l(block[-1]);
						label->bcgen_label->label_offset=(pgrm->data_size<<2)+1;

303 304
						int include_last_words=1;

305 306 307 308 309 310 311
						if (arity==1 && (block[1]>>2) > 0) { /* descs */
							store_data_l(block[0]);
							store_data_l(block[1]);
						} else {
							for (int i=0; i<arity; i++) {
								store_data_l(block[i*2]);
								reloc=find_relocation_by_offset(data_relocations, data_reloc_size, &block[i*2+1]-data);
312 313 314 315 316 317
								if (reloc==NULL && i==0) { /* descn */
									store_data_l(block[1]);
									store_string((char*)&block[3], block[2], 0);
									include_last_words=0;
									break;
								}
318 319 320 321
								add_label_to_queue(&labels[reloc->relocation_label]);
								add_data_relocation(labels[reloc->relocation_label].bcgen_label, pgrm->data_size);
								store_data_l(block[i*2+1]);
							}
322 323
						}

324 325 326 327 328 329
						if (include_last_words) {
							store_data_l(block[2*arity]);
							store_data_l(block[2*arity+1]);
							store_data_l(block[2*arity+2]);
							store_string((char*)&block[2*arity+4],block[2*arity+3],0);
						}
330
					}
Camil Staps's avatar
Camil Staps committed
331
				}
332 333 334 335 336 337 338 339 340 341 342 343 344
				break;
			case DLT_STRING:
				label->bcgen_label->label_offset=(pgrm->data_size<<2)+1;
				store_string((char*)&block[1], block[0], 0);
				break;
			case DLT_STRING_WITH_DESCRIPTOR:
				label->bcgen_label->label_offset=(pgrm->data_size<<2)+1;
				reloc=find_relocation_by_offset(data_relocations, data_reloc_size, block-data);
				add_label_to_queue(&labels[reloc->relocation_label]);
				add_data_relocation(labels[reloc->relocation_label].bcgen_label, pgrm->data_size);
				store_data_l(block[0]);
				store_string((char*)&block[2], block[1], 0);
				break;
345 346 347 348 349 350 351 352 353 354 355 356 357
			case DLT_CAF:
				{
					int s=block[-1];
					if (s==0) {
						s=block[-2];
						store_data_l(block[-2]);
					}
					store_data_l(block[-1]);
					label->bcgen_label->label_offset=(pgrm->data_size<<2)+1;
					for (; s; s--)
						store_data_l(0);
				}
				break;
Camil Staps's avatar
Camil Staps committed
358
		}
359
	} else { /* code */
Camil Staps's avatar
Camil Staps committed
360
		int ci=label->offset>>2;
361

362
		/* since the label may point to the middle of a block, first find the beginning */
363 364
		do {
			do { ci--; } while (ci>=0 && code_indices[ci].byte_index==-1);
365 366
		} while (ci>0 && !instruction_ends_block(*(int16_t*)&code[code_indices[ci].byte_index]));
		if (ci>0)
367
			do { ci++; } while (code_indices[ci].byte_index==-1);
368 369
		else
			ci=0;
370

371
		uint8_t *code_block=&code[code_indices[ci].byte_index];
Camil Staps's avatar
Camil Staps committed
372

373
		while (1) {
374
			for (struct incoming_labels *ilabs=code_indices[ci].incoming_labels; ilabs!=NULL; ilabs=ilabs->next) {
375 376 377 378
				struct s_label *lab=&labels[ilabs->label_id];
				if (lab->bcgen_label==NULL) {
					if (lab->name[0] != '\0') {
						lab->bcgen_label=enter_label(lab->name);
379
						if (export_label(lab->name))
380
							make_label_global(lab->bcgen_label);
381
					} else
382
						lab->bcgen_label=new_label_at_offset(pgrm->code_size<<2);
383
				} else if (lab->bcgen_label->label_offset!=-1 && lab->bcgen_label->label_offset!=(pgrm->code_size<<2)) {
384
					EPRINTF("Error: overwriting label '%s'\n",lab->bcgen_label->label_name);
385
					EXIT(NULL,1);
386 387 388 389
				}
				lab->bcgen_label->label_offset=pgrm->code_size<<2;
			}

Camil Staps's avatar
Camil Staps committed
390
			int16_t instr=*(int16_t*)code_block;
391
			store_code_elem(2, instr);
Camil Staps's avatar
Camil Staps committed
392 393 394 395 396 397
			code_block+=2;
			const char *type=instruction_type(instr);
			ci++;
			for (; *type; type++) {
				switch (*type) {
					case 'c': /* Char */
398
						store_code_elem(1, *(uint8_t*)code_block);
Camil Staps's avatar
Camil Staps committed
399 400 401 402 403 404
						code_block+=1;
						break;
					case 'I': /* Instruction */
					case 'n': /* Stack index */
					case 'N': /* Stack index, optimised to byte width */
					case 'a': /* Arity */
405
						store_code_elem(2, *(uint16_t*)code_block);
Camil Staps's avatar
Camil Staps committed
406 407 408
						code_block+=2;
						break;
					case 'l': /* Label */
409
						reloc=find_relocation_by_offset(code_relocations, code_reloc_size, ci);
Camil Staps's avatar
Camil Staps committed
410 411 412 413 414 415 416
						/* Only labels in .n/.nu directives (i.e., CA_data_*)
						 * may be NULL; otherwise, throw an error. */
						if (instr<CA_data_IIIla && reloc==NULL) {
							EPRINTF("Error: label for %s was NULL\n",instruction_name(instr));
							EXIT(NULL,1);
						}
						if (reloc!=NULL) {
417 418 419
							add_label_to_queue(&labels[reloc->relocation_label]);
							add_code_relocation(labels[reloc->relocation_label].bcgen_label, pgrm->code_size);
						}
420 421
						store_code_elem(2, *(uint32_t*)code_block);
						code_block+=2;
Camil Staps's avatar
Camil Staps committed
422
						break;
423 424 425 426 427
					case 'C': /* CAF label */
						reloc=find_relocation_by_offset(code_relocations, code_reloc_size, ci);
						add_label_to_queue(&labels[reloc->relocation_label]);
						labels[reloc->relocation_label].label_type=DLT_CAF;
						add_code_relocation(labels[reloc->relocation_label].bcgen_label, pgrm->code_size);
428 429
						store_code_elem(2, *(uint32_t*)code_block);
						code_block+=2;
430
						break;
431 432 433 434 435 436
					case 'S': /* String with __STRING__ label */
					case 's': /* Plain string label */
						reloc=find_relocation_by_offset(code_relocations, code_reloc_size, ci);
						add_label_to_queue(&labels[reloc->relocation_label]);
						labels[reloc->relocation_label].label_type=*type=='S' ? DLT_STRING_WITH_DESCRIPTOR : DLT_STRING;
						add_code_relocation(labels[reloc->relocation_label].bcgen_label, pgrm->code_size);
437 438
						store_code_elem(2, *(uint32_t*)code_block);
						code_block+=2;
Camil Staps's avatar
Camil Staps committed
439 440 441
						break;
					case 'r': /* Real */
					case 'i': /* Int */
442
						store_code_elem(8, *(uint64_t*)code_block);
Camil Staps's avatar
Camil Staps committed
443 444 445 446
						code_block+=8;
						break;
					default:
						EPRINTF("error in activate_label\n");
447
						EXIT(NULL,-1);
Camil Staps's avatar
Camil Staps committed
448 449 450
				}
				ci++;
			}
451 452 453

			if (instruction_ends_block(instr))
				break;
Camil Staps's avatar
Camil Staps committed
454 455 456 457
		}
	}
}

458 459
static struct s_label *find_label_by_name(const char *name) {
	int l=0;
460
	int r=n_global_labels-1;
461 462 463 464 465 466 467 468 469 470
	while (l<=r) {
		int i=(l+r)/2;
		struct s_label *label=&labels[i];
		int c=strcmp(label->name, name);
		if (c<0)
			l=i+1;
		else if (c>0)
			r=i-1;
		else
			return label;
Camil Staps's avatar
Camil Staps committed
471
	}
472
	EPRINTF("error in find_label_by_name (%s)\n",name);
473
	EXIT(NULL,1);
474
	return NULL;
475 476
}

477 478 479 480
void prepare_strip_bytecode(uint32_t *bytecode,
		int _include_symbol_table, int activate_start_label) {
	include_symbol_table=_include_symbol_table;
	export_all_labels=0;
481

482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500
	if (bytecode[0]!=ABC_MAGIC_NUMBER) {
		EPRINTF("file to strip does not start with right magic number\n");
		EXIT(NULL,-1);
	}
	code=&((uint8_t*)bytecode)[bytecode[1]+8];
	if (bytecode[2]!=ABC_VERSION) {
		EPRINTF("file to strip ABC* version does not match\n");
		EXIT(NULL,-1);
	}

	uint32_t code_size=bytecode[3];
	/*uint32_t words_in_strings=bytecode[4];*/
	uint32_t strings_size=bytecode[5];
	uint32_t data_size=bytecode[6];
	n_labels=bytecode[7];
	/*uint32_t global_label_string_count=bytecode[8];*/
	code_reloc_size=bytecode[9];
	data_reloc_size=bytecode[10];
	uint32_t start_label_id=bytecode[11];
Camil Staps's avatar
Camil Staps committed
501

502
	code_indices=safe_malloc(sizeof(struct code_index)*code_size);
503 504 505 506 507

	int ci=0;
	int i=0;
	while (ci<code_size) {
		uint16_t instr=*(uint16_t*)&code[i];
508 509 510
		code_indices[ci].byte_index=i;
		code_indices[ci].incoming_labels=NULL;
		ci++;
511
		i+=2;
Camil Staps's avatar
Camil Staps committed
512
		const char *type=instruction_type(instr);
513
		for (; *type; type++) {
514 515 516
			code_indices[ci].byte_index=-1;
			code_indices[ci].incoming_labels=NULL;
			ci++;
517 518 519 520 521 522 523 524 525
			switch (*type) {
				case 'c': /* Char */
					i+=1;
					break;
				case 'I': /* Instruction */
				case 'n': /* Stack index */
				case 'N': /* Stack index, optimised to byte width */
				case 'a': /* Arity */
				case 'l': /* Label */
526
				case 'C': /* CAF label */
527 528
				case 'S': /* String label */
				case 's': /* String label */
529
					i+=2;
530 531 532 533 534 535 536
					break;
				case 'r': /* Real */
				case 'i': /* Int */
					i+=8;
					break;
				default:
					EPRINTF("error in strip_bytecode\n");
537
					EXIT(NULL,-1);
538 539 540 541 542 543 544 545 546
			}
		}
	}

	bytecode=(uint32_t*)&code[i];
	bytecode+=strings_size;
	data=(uint64_t*)bytecode;
	bytecode=(uint32_t*)&data[data_size];

547 548 549
	init_label_queue();
	pgrm=initialize_code();

550
	char *labels_in_bytecode=(char*)bytecode;
551
	labels=safe_malloc(sizeof(struct s_label)*n_labels);
552
	for (int i=0; i<n_labels; i++) {
Camil Staps's avatar
Camil Staps committed
553 554
		labels[i].offset=*(int32_t*)labels_in_bytecode;
		labels[i].name=&labels_in_bytecode[4];
555 556
		if (labels[i].name[0]!='\0')
			n_global_labels=i;
557 558 559 560 561 562 563 564
		labels[i].bcgen_label=NULL;
		labels[i].label_type=DLT_NORMAL;
		if (!(labels[i].offset & 1)) {
			struct incoming_labels *ilabs=safe_malloc(sizeof(struct incoming_labels));
			ilabs->next=code_indices[labels[i].offset>>2].incoming_labels;
			ilabs->label_id=i;
			code_indices[labels[i].offset>>2].incoming_labels=ilabs;
		}
565 566 567 568
		if (activate_start_label && i==start_label_id) {
			add_label_to_queue(&labels[i]);
			code_start(labels[i].name);
		}
569 570 571
		labels_in_bytecode+=4;
		while (*labels_in_bytecode++);
	}
Camil Staps's avatar
Camil Staps committed
572 573
	bytecode=(uint32_t*)labels_in_bytecode;

574
	code_relocations=safe_malloc(sizeof(struct s_relocation)*code_reloc_size);
Camil Staps's avatar
Camil Staps committed
575 576 577 578 579 580
	for (int i=0; i<code_reloc_size; i++) {
		code_relocations[i].relocation_offset=bytecode[0];
		code_relocations[i].relocation_label=bytecode[1];
		code_relocations[i].relocation_belongs_to_label=NULL;
		bytecode+=2;
	}
581
	data_relocations=safe_malloc(sizeof(struct s_relocation)*data_reloc_size);
Camil Staps's avatar
Camil Staps committed
582 583 584 585 586 587
	for (int i=0; i<data_reloc_size; i++) {
		data_relocations[i].relocation_offset=bytecode[0];
		data_relocations[i].relocation_label=bytecode[1];
		data_relocations[i].relocation_belongs_to_label=NULL;
		bytecode+=2;
	}
588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604

	/* Give unnamed labels a name when there is a label with the same offset to
	 * avoid generating superfluous labels. */
	for (int ci=0; ci<code_size; ci++) {
		if (code_indices[ci].byte_index==-1)
			continue;
		char *name=NULL;
		for (struct incoming_labels *ilabs=code_indices[ci].incoming_labels; ilabs!=NULL; ilabs=ilabs->next)
			if (labels[ilabs->label_id].name[0]!='\0') {
				name=labels[ilabs->label_id].name;
				break;
			}
		if (name!=NULL)
			for (struct incoming_labels *ilabs=code_indices[ci].incoming_labels; ilabs!=NULL; ilabs=ilabs->next)
				if (labels[ilabs->label_id].name[0]=='\0')
					labels[ilabs->label_id].name=name;
	}
605
}
Camil Staps's avatar
Camil Staps committed
606

607
char *finish_strip_bytecode(uint32_t *result_size) {
608
	struct s_label *label;
609
	while ((label=next_label_from_queue())!=NULL)
610
		activate_label(label);
Camil Staps's avatar
Camil Staps committed
611

612 613 614
	return write_program_to_string(result_size);
}

615
void strip_bytecode(int _include_symbol_table,
616
		uint32_t *bytecode, struct clean_string **descriptors,
617
		uint32_t *result_size, char **result) {
618 619
	prepare_strip_bytecode(bytecode, _include_symbol_table, 0);
	export_all_labels=1;
620 621 622 623

	for (int i=0; i<((BC_WORD*)descriptors)[-2]; i++)
		add_label_to_queue(find_label_by_name(descriptors[i]->cs_characters));

624
	*result=finish_strip_bytecode(result_size);
625
}