Exemple #1
0
static char callcode(currentstats_t*stats, int pos, int stack, int scope)
{
    while(pos<stats->num) {
        if(stats->stack[pos].flags&FLAG_SEEN) {
            if(stats->stack[pos].stackpos != stack ||
               stats->stack[pos].scopepos != scope) {
                //dumpstack(stats);
                stats->stack[pos].flags |= FLAG_ERROR;
                fprintf(stderr, "Stack mismatch at pos %d\n", pos);
                fprintf(stderr, "Should be: %d:%d, is: %d:%d\n", stack, scope,
                    stats->stack[pos].stackpos, stats->stack[pos].scopepos);
               
                /* return error here if we do verification */
                //return 0;
            }
            return 1;
        }
    
        stats->stack[pos].flags |= FLAG_SEEN;
        stats->stack[pos].stackpos = stack;
        stats->stack[pos].scopepos = scope;

        code_t*c = stats->stack[pos].code;
        opcode_t*op = opcode_get(c->opcode);
        
        //printf("Walking %s at position %d, stack=%d, scope=%d\n", op->name, pos, stack, scope);

        stack += stack_minus(c);

        if(stack<0) {
            stats->stack[pos].flags |= FLAG_ERROR;
            fprintf(stderr, "error: stack underflow at %d (%s)\n", pos, op->name);
           
            /* if we would do true verification (if we would be a vm), this is 
               where we would return the error 
               return 0;
             */
        }

        stack += op->stack_plus;
        scope += op->scope_stack_plus;

        if(stack > stats->maxstack)
            stats->maxstack = stack;
        if(scope > stats->maxscope)
            stats->maxscope = scope;

        if(op->flags & OP_SET_DXNS)
            stats->flags |= FLAGS_SET_DXNS;
        if(op->flags & OP_NEED_ACTIVATION)
            stats->flags |= FLAGS_ACTIVATION;

        if(c->opcode == OPCODE_NEWCLASS) {
            abc_class_t*cls = (abc_class_t*)(c->data[0]);
            if(scope > cls->init_scope_depth)
                cls->init_scope_depth = scope;
        }
        if(c->opcode == OPCODE_NEWFUNCTION) {
            abc_method_t*m = (abc_method_t*)(c->data[0]);
            if(m->body && scope > m->body->init_scope_depth)
                m->body->init_scope_depth = scope;
        }
        
        if(op->flags & OP_REGISTER) {
            char*p = op->params;
            int pos = 0;
            char ok=0;
            while(*p) {
                if(*p=='r') {
                    handleregister(stats, (ptroff_t)c->data[pos]);
                    ok = 1;
                }
                p++;
            }
            if(!ok) {
                handleregister(stats, c->opcode&3);
            }
        }
        if(op->flags&OP_RETURN) {
            if(OP_RETURN==0x48/*returnvalue*/) {
                if(stack!=1) {
                    stats->stack[pos].flags |= FLAG_ERROR;
                    fprintf(stderr, "return(value) with stackposition %d\n", stack);
                }
            } else if(OP_RETURN==0x47) {
                if(stack!=0) {
                    stats->stack[pos].flags |= FLAG_ERROR;
                    fprintf(stderr, "return(void) with stackposition %d\n", stack);
                }
            }
        }
        if(op->flags & (OP_THROW|OP_RETURN))
            return 1;
        if(op->flags & OP_JUMP) {
            if(!c->branch) {
                stats->stack[pos].flags |= FLAG_ERROR;
                fprintf(stderr, "Error: Invalid jump target in instruction %s at position %d.\n", op->name, pos);
                return 0;
            }
            c = c->branch;
            pos = c->pos;
            continue;
        }
        if(op->flags & OP_BRANCH) {
            if(!c->branch) {
                stats->stack[pos].flags |= FLAG_ERROR;
                fprintf(stderr, "Error: Invalid jump target in instruction %s at position %d\n", op->name, pos);
                return 0;
            }
            int newpos = c->branch->pos;
            if(!callcode(stats, newpos, stack, scope))
                return 0;
        }
        if(op->flags & OP_LOOKUPSWITCH) {
            lookupswitch_t*l = c->data[0];
            if(!l->def) {
                stats->stack[pos].flags |= FLAG_ERROR;
                fprintf(stderr, "Error: Invalid jump target in instruction %s at position %d\n", op->name, pos);
                return 0;
            }
            if(!callcode(stats, l->def->pos, stack, scope))
                return 0;
            code_list_t*t = l->targets;
            while(t) {
                if(!t->code) {
                    stats->stack[pos].flags |= FLAG_ERROR;
                    fprintf(stderr, "Error: Invalid jump target in instruction %s at position %d\n", op->name, pos);
                    return 0;
                }
                if(!callcode(stats, t->code->pos, stack, scope))
                    return 0;
                t = t->next;
            }
        }
    
        pos++;
        if(pos<stats->num) {
            assert(c->next == stats->stack[pos].code);
        }
    }
    return 1;
}
Exemple #2
0
void program_loop()
{
	char *line = NULL;
	size_t line_size = 0;
	int start_from = 0;
	char *token = NULL;

	while(true) {
		printf("%d > ", num_stack_items());
		line_size = getline(&line, &line_size, stdin);
		if (line_size == -1) break;

		while (true) {
			token = get_next_token(line, line_size, &start_from);
			if (token == NULL) {
				break;
			}
			else if (strcmp(token, ".s") == 0) {
				stack_show();
				continue;
			}
			else if (strcmp(token, ".") == 0) {
				stack_dot();
				continue;
			}
			else if (strcmp(token, ".dropall") == 0) {
				stack_dropall();
				continue;
			}
			else if (strcmp(token, "+") == 0) {
				stack_plus();
				continue;
			}
			else if (strcmp(token, "-") == 0) {
				stack_minus();
				continue;
			}
			else if (strcmp(token, ".swap") == 0) {
				stack_swap();
				continue;
			}
			else if (strcmp(token, ".dup") == 0) {
				stack_dup();
				continue;
			}
			else if (strcmp(token, ".over") == 0) {
				stack_over();
				continue;
			}
			else if (strcmp(token, ".drop") == 0) {
				stack_pop();
				continue;
			}
			else if (strcmp(token, ".rot") == 0) {
				stack_rot();
				continue;
			}
			else if (strcmp(token, ".-rot") == 0) {
				stack_rot();
				stack_rot();
				continue;
			}
			else if (strcmp(token, "!") == 0) {
				set_variable();
				continue;
			}
			else if (strcmp(token, "$") == 0) {
				get_variable();
				continue;
			}
			else if (token[0] == '$' && token[1] == '$') {
				eprintf("error: variable name can't begin with $.\n");
				continue;
			}
			else if (token[0] == '$' && token[1] == '.') {
				/* Put literals in for stack operations. */
				/* shift everything after $ over one */
				for (int i = 0; i < BUFSIZE-1; ++i) {
					token[i] = token[i+1];
				}
				stack_push(token);
				continue;
			}
			else if (token[0] == '$') {
				/* shift everything after $ over one */
				for (int i = 0; i < BUFSIZE-1; ++i) {
					token[i] = token[i+1];
				}
				stack_push(token);
				get_variable();
				continue;
			}
			else if (strcmp(token, ";") == 0) {
				stack_execute();
				continue;
			}
			else if (strcmp(token, ".cd") == 0) {
				stack_cd();
				continue;
			}
			else if (token[0] == '.' && strlen(token) > 1) {
				/* shift everything after . over one */
				for (int i = 0; i < BUFSIZE-1; ++i) {
					token[i] = token[i+1];
				}
				stack_push(token);
				stack_execute();
				continue;
			}
			stack_push(token);
		}
		start_from = 0;
	}
}