Exemple #1
0
void SuFunction::dotParams(Value self) {
	SuInstance* ob = val_cast<SuInstance*>(self);
	if (!ob)
		return;
	Value* args = GETSP() - nparams + 1;
	for (int i = 0; i < nparams; ++i)
		if (flags[i] & DOT) {
			auto name = symstr(locals[i]);
			if (flags[i] & PUB) {
				char* s = STRDUPA(name);
				*s = toupper(*s);
				name = s;
			} else // private
				name = CATSTR3(className, "_", name);
			ob->putdata(name, args[i]);
		}
}
Exemple #2
0
char* Func::params() const {
	OstreamStr out;
	out << "(";
	short j = 0;
	for (int i = 0; i < nparams; ++i) {
		if (i != 0)
			out << ",";
		if (i == nparams - rest)
			out << "@";
		if (flags && (flags[i] & DYN))
			out << "_";
		out << symstr(locals[i]);
		if (i >= nparams - ndefaults - rest && i < nparams - rest)
			out << "=" << literals[j++];
	}
	out << ")";
	return out.str();
}
Exemple #3
0
	SuBlock(Frame* f, int p, int fi, int n) : frame(f), fn(f->fn), pc(p), first(fi),
		persisted(false)
		{
		verify(frame->fn); // i.e. not a primitive
		if (n != BLOCK_REST)
			nparams = n;
		else
			{
			nparams = 1;
			rest = true;
			}
		literals = frame->fn->literals;
		locals = frame->fn->locals + first;
		// strip '_' prefix off params (first time)
		// if compile used a different way to hide block params this wouldn't be needed
		for (int i = 0; i < nparams; ++i)
			{
			auto s = symstr(locals[i]);
			if (*s != '_')
				break ; // already stripped previously
			locals[i] = ::symnum(s + 1);
			}
		}
Exemple #4
0
static void
make_peekdata_ops(peekdata_data& dt, const std::string& s)
{
  std::auto_ptr<peekdata_ops> pops(new peekdata_ops());
  std::string tok;
  for (size_t i = 0; i < s.size(); ++i) {
    char ch = s[i];
    if (ch == ',') {
      pops->opsrcs.push_back(tok);
      tok.clear();
    } else {
      tok.push_back(ch);
    }
  }
  pops->opsrcs.push_back(tok);
  for (size_t i = 0; i < pops->opsrcs.size(); ++i) {
    const std::string& src = pops->opsrcs[i];
    if (src.empty()) {
      dt.err = "invalid op [" + src + "]";
      return;
    }
    peekdata_op *op = 0;
    if (src == "add") {
      op = new peekdata_op_binop<std::plus<unsigned long>, false>();
    } else if (src == "sub") {
      op = new peekdata_op_binop<std::minus<unsigned long>, false>();
    } else if (src == "mul") {
      op = new peekdata_op_binop<std::multiplies<unsigned long>, false>();
    } else if (src == "div") {
      op = new peekdata_op_binop<std::divides<unsigned long>, true>();
    } else if (src == "mod") {
      op = new peekdata_op_binop<std::modulus<unsigned long>, true>();
    } else if (src == "and") {
      op = new peekdata_op_binop<std::bit_and<unsigned long>, false>();
    } else if (src == "or") {
      op = new peekdata_op_binop<std::bit_or<unsigned long>, false>();
    } else if (src == "xor") {
      op = new peekdata_op_binop<std::bit_xor<unsigned long>, false>();
    } else if (src == "land") {
      op = new peekdata_op_binop<std::logical_and<unsigned long>, false>();
    } else if (src == "lor") {
      op = new peekdata_op_binop<std::logical_or<unsigned long>, false>();
    } else if (src == "eq") {
      op = new peekdata_op_binop<std::equal_to<unsigned long>, false>();
    } else if (src == "ne") {
      op = new peekdata_op_binop<std::not_equal_to<unsigned long>, false>();
    } else if (src == "gt") {
      op = new peekdata_op_binop<std::greater<unsigned long>, false>();
    } else if (src == "ge") {
      op = new peekdata_op_binop<std::greater_equal<unsigned long>, false>();
    } else if (src == "lt") {
      op = new peekdata_op_binop<std::less<unsigned long>, false>();
    } else if (src == "le") {
      op = new peekdata_op_binop<std::less_equal<unsigned long>, false>();
    } else if (src.substr(0, 4) == "outd") {
      op = new peekdata_op_out_decimal(read_longval(src, 4));
    } else if (src.substr(0, 4) == "outh") {
      op = new peekdata_op_out_hexadecimal(read_longval(src, 4));
    } else if (src.substr(0, 4) == "outs") {
      op = new peekdata_op_out_string(read_longval(src, 4));
    } else if (src.substr(0, 5) == "outsz") {
      op = new peekdata_op_out_nulterm_string(read_longval(src, 5));
    } else if (src.substr(0, 5) == "ind") {
      op = new peekdata_op_in_decimal(read_longval(src, 3));
    } else if (src.substr(0, 5) == "inh") {
      op = new peekdata_op_in_hexadecimal(read_longval(src, 3));
    } else if (src.substr(0, 2) == "ld") {
      op = new peekdata_op_peek(strtoul(src.c_str() + 2, 0, 0));
    } else if (src.substr(0, 2) == "cp") {
      op = new peekdata_op_copy(strtoul(src.c_str() + 2, 0, 0));
    } else if (src.substr(0, 2) == "po") {
      op = new peekdata_op_pop(strtoul(src.c_str() + 2, 0, 0));
    } else if (src[0] == 'j') {
      op = new peekdata_op_jmp<false>(strtol(src.c_str() + 1, 0, 0));
    } else if (src.substr(0, 2) == "cj") {
      op = new peekdata_op_jmp<true>(strtol(src.c_str() + 2, 0, 0));
    } else if (src[0] >= '0' && src[0] <= '9') {
      op = new peekdata_op_ulong(strtoul(src.c_str(), 0, 0));
    } else if (src[0] == '@') {
      std::string symstr(src.c_str() + 1);
      dt.syms[symstr];
      op = new peekdata_op_sym(symstr);
    } else if (src == "tr") {
      dt.trace_flag = true;
    } else if (src.substr(0, 4) == "elim") {
      dt.exec_limit = strtoul(src.c_str() + 4, 0, 0);
    } else if (src.substr(0, 4) == "slim") {
      dt.string_limit = strtoul(src.c_str() + 4, 0, 0);
    } else {
      dt.err = "invalid op [" + src + "]";
    }
    if (op != 0) {
      pops->ops.push_back(op);
    }
  }
  dt.ops = pops;
}
Exemple #5
0
void Func::args(short nargs, short nargnames, short* argnames, int each) {
	Value* args = GETSP() - nargs + 1;
	short unamed = nargs - nargnames - (each == -1 ? 0 : 1);
	short i, j;

	if (!rest && unamed > nparams)
		except("too many arguments to " << this);

	verify(!rest || nparams == 1);    // rest must be only param
	verify(each == -1 || nargs == 1); // each must be only arg

	if (nparams > nargs)
		// expand stack (before filling it)
		SETSP(GETSP() + nparams - nargs);

	if (each != -1 && rest) {
		args[0] = args[0].object()->slice(each);
	} else if (rest) {
		// put args into object
		SuObject* ob = new SuObject();
		// un-named
		for (i = 0; i < unamed; ++i)
			ob->add(args[i]);
		// named
		for (j = 0; i < nargs; ++i, ++j)
			ob->put(symbol(argnames[j]), args[i]);
		args[0] = ob;
	} else if (each != -1) {
		SuObject* ob = args[0].object();

		if (ob->vecsize() > nparams + each)
			except("too many arguments to " << this << " vecsize "
											<< ob->vecsize() << " each " << each
											<< " nparams " << nparams);

		// un-named members
		for (i = 0; i < nparams; ++i)
			args[i] = ob->get(i + each);
		// named members
		verify(locals);
		for (i = 0; i < nparams; ++i)
			if (Value x = ob->get(symbol(locals[i])))
				args[i] = x;
	} else if (nargnames > 0) {
		// shuffle named args to match params
		const int maxargnames = 100;
		Value tmp[maxargnames];

		// move named args aside
		verify(nargnames < maxargnames);
		for (i = 0; i < nargnames; ++i)
			tmp[i] = args[unamed + i];

		// initialized remaining params
		for (i = unamed; i < nparams; ++i)
			args[i] = Value();

		// fill in params with named args
		verify(locals);
		for (i = 0; i < nparams; ++i)
			for (j = 0; j < nargnames; ++j)
				if (locals[i] == argnames[j])
					args[i] = tmp[j];
	} else {
		// initialized remaining params
		for (i = unamed; i < nparams; ++i)
			args[i] = Value();
	}

	// fill in dynamic implicits
	if (flags) {
		for (i = 0; i < nparams; ++i)
			if (!args[i] && (flags[i] & DYN)) {
				int sn = ::symnum(CATSTRA("_", symstr(locals[i])));
				args[i] = dynamic(sn);
			}
	}

	// fill in defaults
	if (ndefaults > 0) {
		verify(literals);
		for (j = nparams - ndefaults, i = 0; i < ndefaults; ++i, ++j)
			if (!args[j])
				args[j] = literals[i];
	}

	if (nargs > nparams)
		// shrink stack (after processing args)
		SETSP(GETSP() + nparams - nargs);

	// check that all parameters now have values
	verify(locals);
	for (i = 0; i < nparams; ++i)
		if (!args[i])
			except("missing argument(s) to " << this);
}
Exemple #6
0
int SuFunction::disasm1(Ostream& out, int ci) {
	verify(locals);
	verify(literals);
	out << "\t\t\t\t\t" << setw(3) << ci << "  ";
	short op = code[ci++];
	//	out << hex << setw(3) << op << " " << dec;
	out << opcodes[op] << " ";
	if (op == I_SUPER) {
		out << globals(TARGET(ci));
		ci += 2;
	} else if (op == I_EACH)
		out << (int) code[ci++];
	else if (op == I_BLOCK) {
		out << ci + 2 + TARGET(ci);
		ci += 2;
		int first = code[ci++];
		int nargs = code[ci++];
		for (int i = 0; i < nargs; ++i)
			out << " " << 1 + symstr(locals[first + i]);
	} else if (op == I_PUSH_INT) {
		out << TARGET(ci);
		ci += 2;
	} else if (op < 16 || op == I_BOOL)
		;
	else if (op < I_PUSH) {
		switch (op & 0xf0) {
		case I_PUSH_LITERAL:
			out << literals[op & 15];
			break;
		case I_PUSH_AUTO:
			out << symstr(locals[op & 15]);
			break;
		case I_EQ_AUTO:
		case I_EQ_AUTO_POP:
			out << symstr(locals[op & 7]);
			break;
		case I_CALL_GLOBAL:
			out << globals(TARGET(ci)) << " " << (op & 7);
			ci += 2;
			break;
		case I_CALL_MEM:
		case I_CALL_MEM_SELF:
			out << mem(ci) << " " << (op & 7);
			break;
		default:
			break;
		}
	} else if ((op & 0xf8) == I_PUSH) {
		switch (op & 7) {
		case LITERAL:
			out << literals[varint(code, ci)];
			break;
		case AUTO:
		case DYNAMIC:
			out << symstr(locals[code[ci++]]);
			break;
		case MEM:
		case MEM_SELF:
			out << mem(ci);
			break;
		case GLOBAL:
			out << globals(TARGET(ci));
			ci += 2;
			break;
		default:
			break;
		}
	} else if ((op & 0xf8) == I_CALL) {
		switch (op & 7) {
		case AUTO:
		case DYNAMIC:
			out << symstr(locals[code[ci++]]);
			break;
		case MEM:
		case MEM_SELF:
			out << mem(ci);
			ci += 2;
			break;
		case GLOBAL:
			out << globals(TARGET(ci));
			ci += 2;
			break;
		default:
			break;
		}
		out << " " << (short) code[ci++];
		short nargnames = code[ci++];
		out << " " << nargnames;
		for (int i = 0; i < nargnames; ++i) {
			out << " " << symstr(TARGET(ci));
			ci += 2;
		}
	} else if ((op & 0xf8) == I_JUMP || op == I_TRY || op == I_CATCH) {
		out << ci + 2 + TARGET(ci);
		ci += 2;
		if (op == I_TRY)
			out << " " << literals[varint(code, ci)];
	} else if (I_ADDEQ <= op && op < I_ADD) {
		switch ((op & 0x70) >> 4) {
		case AUTO:
		case DYNAMIC:
			out << symstr(locals[code[ci++]]);
			break;
		case MEM:
		case MEM_SELF:
			out << mem(ci);
			break;
		default:
			break;
		}
	}
	out << "\n";
	return ci;
}