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
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()
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())
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)
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())
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
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
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)
def assemble(s): symbols = read_ir(s) return assemble_from_ir(symbols)
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
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)
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)