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.
"""
import sys, os, re, linecache, inspect, textwrap
import sys, os, re, linecache, inspect, textwrap, types as pytypes
from collections import OrderedDict, defaultdict
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(),
begin_loc=begin_loc, end_loc=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('`')
repr_loc = self._add(repr(value))
unquote_loc = self._add('`')
@ -734,17 +735,21 @@ class Stitcher:
self.functions[function] = function_type
return function_type
def _quote_rpc(self, function, loc):
signature = inspect.signature(function)
def _quote_rpc(self, callee, loc):
ret_type = builtins.TNone()
if signature.return_annotation is not inspect.Signature.empty:
ret_type = self._extract_annot(function, signature.return_annotation,
"return type", loc, is_syscall=False)
if isinstance(callee, pytypes.BuiltinFunctionType):
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:
ret_type = builtins.TNone()
assert False
function_type = types.TRPC(ret_type, service=self.object_map.store(function))
self.functions[function] = function_type
function_type = types.TRPC(ret_type, service=self.object_map.store(callee))
self.functions[callee] = function_type
return function_type
def _quote_function(self, function, loc):

View File

@ -412,7 +412,8 @@ class LLVMIRGenerator:
for obj_id in self.object_map:
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
elif isinstance(obj_ref, type):
_, typ = self.type_map[obj_ref]

View File

@ -349,7 +349,7 @@ class CommGeneric:
else:
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 = [], {}
while True:
value = self._receive_rpc_value(object_map)
@ -447,7 +447,7 @@ class CommGeneric:
else:
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()
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.test.hardware_testbench import ExperimentCase
@ -97,6 +99,10 @@ class _RPC(EnvExperiment):
def args1kwargs2(self):
return self.kwargs("X", a="A", b=1)
@kernel
def builtin(self):
sleep(1.0)
class RPCTest(ExperimentCase):
def test_args(self):
exp = self.create(_RPC)
@ -107,6 +113,7 @@ class RPCTest(ExperimentCase):
self.assertEqual(exp.kwargs1(), 1)
self.assertEqual(exp.kwargs2(), 2)
self.assertEqual(exp.args1kwargs2(), 2)
exp.builtin()
class _Payload1MB(EnvExperiment):