Beispiel #1
0
def compile_clvm_text(text, search_paths):
    ir_src = reader.read_ir(text)
    assembled_sexp = binutils.assemble_from_ir(ir_src)

    input_sexp = assembled_sexp.to((assembled_sexp, []))
    run_program = stage_2.run_program_for_search_paths(search_paths)
    cost, result = run_program(stage_2.run, input_sexp)
    return result
Beispiel #2
0
 def conversion(text):
     try:
         ir_sexp = reader.read_ir(text)
         sexp = binutils.assemble_from_ir(ir_sexp)
     except SyntaxError as ex:
         print("%s" % ex.msg)
         return None, None
     return sexp, sexp.as_bin().hex()
Beispiel #3
0
def read_ir(args=sys.argv):
    parser = argparse.ArgumentParser(
        description='Read script and tokenize to IR.')
    parser.add_argument("script", help="script in hex or uncompiled text")

    args = parser.parse_args(args=args[1:])

    sexp = reader.read_ir(args.script)
    blob = stream_to_bin(lambda f: sexp_to_stream(sexp, f))
    print(blob.hex())
Beispiel #4
0
def compile_clvm(input_path, output_path):
    if newer(input_path, output_path):
        log.info("clvmcc %s -o %s" % (input_path, output_path))
        with open(input_path) as f:
            text = f.read()
        ir_src = reader.read_ir(text)
        assembled_sexp = binutils.assemble_from_ir(ir_src)

        input_sexp = assembled_sexp.to((assembled_sexp, []))
        cost, result = stage_2.run_program(stage_2.run, input_sexp)
        hex = result.as_bin().hex()

        with open(output_path, "w") as f:
            f.write(hex)
    else:
        log.info("skipping %s, compiled recently" % input_path)

    return output_path
def test_reader_1():
    sexp = reader.read_ir("(100 0x0100)")
    print(sexp)

    sexp = reader.read_ir("100")
    print(sexp)

    sexp = reader.read_ir("0x0100")
    print(sexp)

    sexp = reader.read_ir("0x100")
    print(sexp)

    sexp = reader.read_ir('"100"')
    print(sexp)

    sexp = reader.read_ir("foo")
    print(sexp)

    sexp = reader.read_ir('(c (quote 100) (c (quote "foo") (quote ())))')
    print(sexp)

    sexp = reader.read_ir("(c . foo)")
    print(sexp)
def test_reader_1():
    sexp = reader.read_ir('(100 0x0100)')
    print(sexp)

    sexp = reader.read_ir('100')
    print(sexp)

    sexp = reader.read_ir('0x0100')
    print(sexp)

    sexp = reader.read_ir('0x100')
    print(sexp)

    sexp = reader.read_ir('"100"')
    print(sexp)

    sexp = reader.read_ir('foo')
    print(sexp)

    sexp = reader.read_ir('(c (q 100) (c (q "foo") (q ())))')
    print(sexp)

    sexp = reader.read_ir('(c . foo)')
    print(sexp)
Beispiel #7
0
def opc(args=sys.argv):
    parser = argparse.ArgumentParser(description='Compile a clvm script.')
    parser.add_argument("-H",
                        "--script_hash",
                        action="store_true",
                        help="Show sha256 script hash")
    parser.add_argument("path_or_code",
                        nargs="*",
                        type=path_or_code,
                        help="path to clvm script, or literal script")

    args = parser.parse_args(args=args[1:])

    for text in args.path_or_code:
        try:
            ir_sexp = reader.read_ir(text)
            sexp = binutils.assemble_from_ir(ir_sexp)
        except SyntaxError as ex:
            print("%s" % ex.msg)
            continue
        compiled_script = sexp.as_bin()
        if args.script_hash:
            print(hashlib.sha256(compiled_script).hexdigest())
        print(compiled_script.hex())
Beispiel #8
0
def do_test(sexp_text):
    ir_sexp = reader.read_ir(sexp_text)
    sexp_text_normalized = writer.write_ir(ir_sexp)
    ir_sexp_2 = reader.read_ir(sexp_text)
    sexp_text_normalized_2 = writer.write_ir(ir_sexp_2)
    assert sexp_text_normalized == sexp_text_normalized_2
Beispiel #9
0
def do_read(args):
    filename = args.first().as_atom()
    s = open(filename).read()
    ir_sexp = args.to(read_ir(s))
    sexp = assemble_from_ir(ir_sexp)
    return 1, sexp
Beispiel #10
0
def launch_tool(args, tool_name, default_stage=0):
    parser = argparse.ArgumentParser(description='Execute a clvm script.')
    parser.add_argument("-s",
                        "--stage",
                        type=stage_import,
                        help="stage number to include",
                        default=stage_import(default_stage))
    parser.add_argument(
        "-v",
        "--verbose",
        action="store_true",
        help="Display resolve of all reductions, for debugging")
    parser.add_argument("-c", "--cost", action="store_true", help="Show cost")
    parser.add_argument("-m", "--max-cost", type=int, help="Maximum cost")
    parser.add_argument("-d",
                        "--dump",
                        action="store_true",
                        help="dump hex version of final output")
    parser.add_argument("-y",
                        "--symbol-table",
                        type=pathlib.Path,
                        help=".SYM file generated by compiler")
    parser.add_argument(
        "-i",
        "--include",
        type=pathlib.Path,
        help="add a search path for included files",
        action="append",
        default=[],
    )
    parser.add_argument("path_or_code",
                        type=path_or_code,
                        help="path to clvm script, or literal script")
    parser.add_argument("args",
                        type=reader.read_ir,
                        help="arguments",
                        nargs="?",
                        default=reader.read_ir("()"))

    args = parser.parse_args(args=args[1:])

    if hasattr(args.stage, "run_program_for_search_paths"):
        run_program = args.stage.run_program_for_search_paths(args.include)
    else:
        run_program = args.stage.run_program

    src_text = args.path_or_code
    src_sexp = reader.read_ir(src_text)
    assembled_sexp = binutils.assemble_from_ir(src_sexp)

    pre_eval_f = None
    symbol_table = None

    log_entries = []

    if args.symbol_table:
        with open(args.symbol_table) as f:
            symbol_table = json.load(f)
        pre_eval_f = make_trace_pre_eval(log_entries, symbol_table)
    elif args.verbose:
        pre_eval_f = make_trace_pre_eval(log_entries)

    run_script = getattr(args.stage, tool_name)

    cost = 0
    try:
        output = "(didn't finish)"
        env = binutils.assemble_from_ir(args.args)
        input_sexp = to_sexp_f((assembled_sexp, env))
        cost, result = run_program(run_script,
                                   input_sexp,
                                   max_cost=args.max_cost,
                                   pre_eval_f=pre_eval_f)
        if args.cost:
            print("cost = %d" % cost)
        if args.dump:
            blob = as_bin(lambda f: sexp_to_stream(result, f))
            output = blob.hex()
        else:
            output = binutils.disassemble(result)
    except EvalError as ex:
        output = "FAIL: %s %s" % (ex, binutils.disassemble(ex._sexp))
        result = ex._sexp
        return -1
    except Exception as ex:
        result = src_sexp
        output = str(ex)
        raise
    finally:
        print(output)
        if args.verbose or symbol_table:
            print()
            trace_to_text(log_entries, binutils.disassemble, symbol_table)
Beispiel #11
0
def assemble(s):
    symbols = read_ir(s)
    return assemble_from_ir(symbols)
Beispiel #12
0
def test_tokenize_comments():
    script_source = "(equal 7 (+ 5 ;foo bar\n   2))"
    expected_output = "(equal 7 (+ 5 2))"
    t = read_ir(script_source)
    s = write_ir(t)
    assert s == expected_output
Beispiel #13
0
        yield f" {a}"

    if max_args == 1:
        return

    # 2 arguments
    for a0 in arguments():
        for a1 in arguments():
            yield f" {a0} {a1}"

    if max_args == 2:
        return

    # 3 arguments
    for a0 in arguments():
        for a1 in arguments():
            for a2 in arguments():
                yield f" {a0} {a1} {a2}"


for op, max_args in OPERATORS:
    for args in gen_args(max_args):
        prg = f"({op}{args})"
        ir_sexp = reader.read_ir(prg)
        prg = binutils.assemble_from_ir(ir_sexp).as_bin()
        h = hashlib.sha1()
        h.update(prg)
        name = h.digest().hex()
        with open(f"corpus/fuzz_run_program/{name}", "wb+") as f:
            f.write(prg)
Beispiel #14
0
def launch_tool(args, tool_name, default_stage=0):
    sys.setrecursionlimit(20000)
    parser = argparse.ArgumentParser(description='Execute a clvm script.')
    parser.add_argument(
        "--strict",
        action="store_true",
        help="Unknown opcodes are always fatal errors in strict mode")
    parser.add_argument(
        "-x",
        "--hex",
        action="store_true",
        help="Read program and environment as hexadecimal bytecode")
    parser.add_argument("-s",
                        "--stage",
                        type=stage_import,
                        help="stage number to include",
                        default=stage_import(default_stage))
    parser.add_argument(
        "-v",
        "--verbose",
        action="store_true",
        help="Display resolve of all reductions, for debugging")
    parser.add_argument(
        "-t",
        "--table",
        action="store_true",
        help="Print diagnostic table of reductions, for debugging")
    parser.add_argument("-c", "--cost", action="store_true", help="Show cost")
    parser.add_argument("--time",
                        action="store_true",
                        help="Print execution time")
    parser.add_argument("-m",
                        "--max-cost",
                        type=int,
                        default=11000000000,
                        help="Maximum cost")
    parser.add_argument("-d",
                        "--dump",
                        action="store_true",
                        help="dump hex version of final output")
    parser.add_argument("--quiet",
                        action="store_true",
                        help="Suppress printing the program result")
    parser.add_argument("-y",
                        "--symbol-table",
                        type=pathlib.Path,
                        help=".SYM file generated by compiler")
    parser.add_argument("-n",
                        "--no-keywords",
                        action="store_true",
                        help="Output result as data, not as a program")
    parser.add_argument("--backend",
                        type=str,
                        help="force use of 'rust' or 'python' backend")
    parser.add_argument(
        "-i",
        "--include",
        type=pathlib.Path,
        help="add a search path for included files",
        action="append",
        default=[],
    )
    parser.add_argument("path_or_code",
                        type=path_or_code,
                        help="filepath to clvm script, or a literal script")

    parser.add_argument("env",
                        nargs="?",
                        type=path_or_code,
                        help="clvm script environment, as clvm src, or hex")

    args = parser.parse_args(args=args[1:])

    keywords = {} if args.no_keywords else KEYWORD_FROM_ATOM

    if hasattr(args.stage, "run_program_for_search_paths"):
        run_program = args.stage.run_program_for_search_paths(args.include)
    else:
        run_program = args.stage.run_program

    input_serialized = None
    input_sexp = None

    time_start = time.perf_counter()
    if args.hex:
        assembled_serialized = bytes.fromhex(args.path_or_code)
        if not args.env:
            args.env = "80"
        env_serialized = bytes.fromhex(args.env)
        time_read_hex = time.perf_counter()

        input_serialized = b"\xff" + assembled_serialized + env_serialized
    else:

        src_text = args.path_or_code
        try:
            src_sexp = reader.read_ir(src_text)
        except SyntaxError as ex:
            print("FAIL: %s" % (ex))
            return -1
        assembled_sexp = binutils.assemble_from_ir(src_sexp)
        if not args.env:
            args.env = "()"
        env_ir = reader.read_ir(args.env)
        env = binutils.assemble_from_ir(env_ir)
        time_assemble = time.perf_counter()

        input_sexp = to_sexp_f((assembled_sexp, env))

    pre_eval_f = None
    symbol_table = None

    log_entries = []

    if args.symbol_table:
        with open(args.symbol_table) as f:
            symbol_table = json.load(f)
        pre_eval_f = make_trace_pre_eval(log_entries, symbol_table)
    elif args.verbose or args.table:
        pre_eval_f = make_trace_pre_eval(log_entries)

    run_script = getattr(args.stage, tool_name)

    cost = 0
    cost_offset = calculate_cost_offset(run_program, run_script)
    try:
        output = "(didn't finish)"

        use_rust = (
            (tool_name != "run") and not pre_eval_f
            and (args.backend == "rust" or
                 (deserialize_and_run_program2 and args.backend != "python")))
        max_cost = max(
            0, args.max_cost - cost_offset if args.max_cost != 0 else 0)
        if use_rust:
            if input_serialized is None:
                input_serialized = input_sexp.as_bin()

            run_script = run_script.as_bin()
            time_parse_input = time.perf_counter()

            # build the opcode look-up table
            # this should eventually be subsumed by "Dialect" api

            native_opcode_names_by_opcode = dict(
                ("op_%s" % OP_REWRITE.get(k, k), op)
                for op, k in KEYWORD_FROM_ATOM.items() if k not in "qa.")
            cost, result = deserialize_and_run_program2(
                run_script,
                input_serialized,
                KEYWORD_TO_ATOM["q"][0],
                KEYWORD_TO_ATOM["a"][0],
                native_opcode_names_by_opcode,
                max_cost,
                STRICT_MODE if args.strict else 0,
            )
            time_done = time.perf_counter()
            result = SExp.to(result)
        else:
            if input_sexp is None:
                input_sexp = sexp_from_stream(io.BytesIO(input_serialized),
                                              to_sexp_f)

            time_parse_input = time.perf_counter()
            cost, result = run_program(run_script,
                                       input_sexp,
                                       max_cost=max_cost,
                                       pre_eval_f=pre_eval_f,
                                       strict=args.strict)
            time_done = time.perf_counter()
        if args.cost:
            cost += cost_offset if cost > 0 else 0
            print("cost = %d" % cost)
        if args.time:
            if args.hex:
                print('read_hex: %f' % (time_read_hex - time_start))
            else:
                print('assemble_from_ir: %f' % (time_assemble - time_start))
                print('to_sexp_f: %f' % (time_parse_input - time_assemble))
            print('run_program: %f' % (time_done - time_parse_input))
        if args.dump:
            blob = as_bin(lambda f: sexp_to_stream(result, f))
            output = blob.hex()
        elif args.quiet:
            output = ''
        else:
            output = binutils.disassemble(result, keywords)
    except EvalError as ex:
        result = to_sexp_f(ex._sexp)
        output = "FAIL: %s %s" % (ex, binutils.disassemble(result, keywords))
        return -1
    except Exception as ex:
        output = str(ex)
        raise
    finally:
        print(output)
        if args.verbose or symbol_table:
            print()
            trace_to_text(log_entries, binutils.disassemble, symbol_table)
        if args.table:
            trace_to_table(log_entries, binutils.disassemble, symbol_table)