compiler: allow RPCing builtin functions.

Fixes #366.
This commit is contained in:
whitequark 2016-04-26 01:31:17 +00:00
parent 1464bae6b7
commit a88425b66b
4 changed files with 26 additions and 13 deletions

View File

@ -5,7 +5,7 @@ the references to the host objects and translates the functions
annotated as ``@kernel`` when they are referenced. annotated as ``@kernel`` when they are referenced.
""" """
import sys, os, re, linecache, inspect, textwrap import sys, os, re, linecache, inspect, textwrap, types as pytypes
from collections import OrderedDict, defaultdict from collections import OrderedDict, defaultdict
from pythonparser import ast, algorithm, source, diagnostic, parse_buffer from pythonparser import ast, algorithm, source, diagnostic, parse_buffer
@ -102,7 +102,8 @@ class ASTSynthesizer:
return asttyped.ListT(elts=elts, ctx=None, type=builtins.TList(), return asttyped.ListT(elts=elts, ctx=None, type=builtins.TList(),
begin_loc=begin_loc, end_loc=end_loc, begin_loc=begin_loc, end_loc=end_loc,
loc=begin_loc.join(end_loc)) loc=begin_loc.join(end_loc))
elif inspect.isfunction(value) or inspect.ismethod(value): elif inspect.isfunction(value) or inspect.ismethod(value) or \
isinstance(value, pytypes.BuiltinFunctionType):
quote_loc = self._add('`') quote_loc = self._add('`')
repr_loc = self._add(repr(value)) repr_loc = self._add(repr(value))
unquote_loc = self._add('`') unquote_loc = self._add('`')
@ -734,17 +735,21 @@ class Stitcher:
self.functions[function] = function_type self.functions[function] = function_type
return function_type return function_type
def _quote_rpc(self, function, loc): def _quote_rpc(self, callee, loc):
signature = inspect.signature(function)
if signature.return_annotation is not inspect.Signature.empty:
ret_type = self._extract_annot(function, signature.return_annotation,
"return type", loc, is_syscall=False)
else:
ret_type = builtins.TNone() ret_type = builtins.TNone()
function_type = types.TRPC(ret_type, service=self.object_map.store(function)) if isinstance(callee, pytypes.BuiltinFunctionType):
self.functions[function] = function_type pass
elif isinstance(callee, pytypes.FunctionType):
signature = inspect.signature(callee)
if signature.return_annotation is not inspect.Signature.empty:
ret_type = self._extract_annot(callee, signature.return_annotation,
"return type", loc, is_syscall=False)
else:
assert False
function_type = types.TRPC(ret_type, service=self.object_map.store(callee))
self.functions[callee] = function_type
return function_type return function_type
def _quote_function(self, function, loc): def _quote_function(self, function, loc):

View File

@ -412,7 +412,8 @@ class LLVMIRGenerator:
for obj_id in self.object_map: for obj_id in self.object_map:
obj_ref = self.object_map.retrieve(obj_id) obj_ref = self.object_map.retrieve(obj_id)
if isinstance(obj_ref, (pytypes.FunctionType, pytypes.MethodType)): if isinstance(obj_ref, (pytypes.FunctionType, pytypes.MethodType,
pytypes.BuiltinFunctionType)):
continue continue
elif isinstance(obj_ref, type): elif isinstance(obj_ref, type):
_, typ = self.type_map[obj_ref] _, typ = self.type_map[obj_ref]

View File

@ -349,7 +349,7 @@ class CommGeneric:
else: else:
raise IOError("Unknown RPC value tag: {}".format(repr(tag))) raise IOError("Unknown RPC value tag: {}".format(repr(tag)))
def _receive_rpc_args(self, object_map, defaults): def _receive_rpc_args(self, object_map):
args, kwargs = [], {} args, kwargs = [], {}
while True: while True:
value = self._receive_rpc_value(object_map) value = self._receive_rpc_value(object_map)
@ -447,7 +447,7 @@ class CommGeneric:
else: else:
service = object_map.retrieve(service_id) service = object_map.retrieve(service_id)
args, kwargs = self._receive_rpc_args(object_map, service.__defaults__) args, kwargs = self._receive_rpc_args(object_map)
return_tags = self._read_bytes() return_tags = self._read_bytes()
logger.debug("rpc service: [%d]%r %r %r -> %s", service_id, service, args, kwargs, return_tags) logger.debug("rpc service: [%d]%r %r %r -> %s", service_id, service, args, kwargs, return_tags)

View File

@ -1,3 +1,5 @@
from time import sleep
from artiq.experiment import * from artiq.experiment import *
from artiq.test.hardware_testbench import ExperimentCase from artiq.test.hardware_testbench import ExperimentCase
@ -97,6 +99,10 @@ class _RPC(EnvExperiment):
def args1kwargs2(self): def args1kwargs2(self):
return self.kwargs("X", a="A", b=1) return self.kwargs("X", a="A", b=1)
@kernel
def builtin(self):
sleep(1.0)
class RPCTest(ExperimentCase): class RPCTest(ExperimentCase):
def test_args(self): def test_args(self):
exp = self.create(_RPC) exp = self.create(_RPC)
@ -107,6 +113,7 @@ class RPCTest(ExperimentCase):
self.assertEqual(exp.kwargs1(), 1) self.assertEqual(exp.kwargs1(), 1)
self.assertEqual(exp.kwargs2(), 2) self.assertEqual(exp.kwargs2(), 2)
self.assertEqual(exp.args1kwargs2(), 2) self.assertEqual(exp.args1kwargs2(), 2)
exp.builtin()
class _Payload1MB(EnvExperiment): class _Payload1MB(EnvExperiment):