git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
C++: go back to single arity closures stored in 'any'
b64dad8Andy Arvanitis
pcc/include/purescript.cc−18
@@ -84,24 +84,6 @@ auto any::operator()(const any& arg) const -> any {
84 return (*variant.f)(arg);
84 return (*variant.f)(arg);
85}
85}
86
86
87−auto any::operator()(const any& arg1, const any& arg2) const -> any {
88− const any& variant = unthunkVariant(*this);
89− if (variant.type == Type::Closure) {
90− return (*variant.l)(arg1, arg2);
91− }
92− assert(variant.type == Type::Function);
93− return (*variant.f)(arg1)(arg2);
94−}
95−
96−auto any::operator()(const any& arg1, const any& arg2, const any& arg3) const -> any {
97− const any& variant = unthunkVariant(*this);
98− if (variant.type == Type::Closure) {
99− return (*variant.l)(arg1, arg2, arg3);
100− }
101− assert(variant.type == Type::Function);
102− return (*variant.f)(arg1)(arg2)(arg3);
103−}
104−
105auto any::operator()(const as_thunk) const -> const any& {
87auto any::operator()(const as_thunk) const -> const any& {
106 assert(type == Type::Thunk);
88 assert(type == Type::Thunk);
107 return (*t)(unthunk);
89 return (*t)(unthunk);
pcc/include/purescript.hh−65
@@ -101,8 +101,6 @@ class any {
101 class closure {
101 class closure {
102 public:
102 public:
103 virtual auto operator()(const any&) const -> any = 0;
103 virtual auto operator()(const any&) const -> any = 0;
104− virtual auto operator()(const any&, const any&) const -> any = 0;
105− virtual auto operator()(const any&, const any&, const any&) const -> any = 0;
106 virtual ~closure() {}
104 virtual ~closure() {}
107 };
105 };
108
106
@@ -114,52 +112,6 @@ class any {
114 auto operator()(const any& arg) const -> any {
112 auto operator()(const any& arg) const -> any {
115 return lambda(arg);
113 return lambda(arg);
116 }
114 }
117− auto operator()(const any& arg1, const any& arg2) const -> any {
118− return lambda(arg1)(arg2);
119− }
120− auto operator()(const any& arg1, const any& arg2, const any& arg3) const -> any {
121− return lambda(arg1)(arg2)(arg3);
122− }
123− };
124−
125− template <typename T>
126− class _closure2 : public closure {
127− const T lambda;
128− public:
129− _closure2(const T& l) noexcept : lambda(l) {}
130− auto operator()(const any& arg1) const -> any {
131− return [=](const any& arg2) -> any {
132− return lambda(arg1, arg2);
133− };
134− }
135− auto operator()(const any& arg1, const any& arg2) const -> any {
136− return lambda(arg1, arg2);
137− }
138− auto operator()(const any& arg1, const any& arg2, const any& arg3) const -> any {
139− return lambda(arg1, arg2)(arg3);
140− }
141− };
142−
143− template <typename T>
144− class _closure3 : public closure {
145− const T lambda;
146− public:
147− _closure3(const T& l) noexcept : lambda(l) {}
148− auto operator()(const any& arg1) const -> any {
149− return [=](const any& arg2) -> any {
150− return [=](const any& arg3) -> any {
151− return lambda(arg1, arg2, arg3);
152− };
153− };
154− }
155− auto operator()(const any& arg1, const any& arg2) const -> any {
156− return [=](const any& arg3) -> any {
157− return lambda(arg1, arg2, arg3);
158− };
159− }
160− auto operator()(const any& arg1, const any& arg2, const any& arg3) const -> any {
161− return lambda(arg1, arg2, arg3);
162− }
163 };
115 };
164
116
165 class eff_fn {
117 class eff_fn {
@@ -243,19 +195,6 @@ class any {
243 any(const T& val, typename std::enable_if<std::is_assignable<std::function<any(const any&)>,T>::value>::type* = 0)
195 any(const T& val, typename std::enable_if<std::is_assignable<std::function<any(const any&)>,T>::value>::type* = 0)
244 : type(Type::Closure), is_shared(true), l(make_shared<_closure<T>>(val)) {}
196 : type(Type::Closure), is_shared(true), l(make_shared<_closure<T>>(val)) {}
245
197
246− template <typename T, typename = typename std::enable_if<!std::is_same<any,T>::value &&
247− !std::is_convertible<T,fn>::value>::type>
248− any(const T& val, typename std::enable_if<std::is_assignable<std::function<any(const any&,
249− const any&)>,T>::value>::type* = 0)
250− : type(Type::Closure), is_shared(true), l(make_shared<_closure2<T>>(val)) {}
251−
252− template <typename T, typename = typename std::enable_if<!std::is_same<any,T>::value &&
253− !std::is_convertible<T,fn>::value>::type>
254− any(const T& val, typename std::enable_if<std::is_assignable<std::function<any(const any&,
255− const any&,
256− const any&)>,T>::value>::type* = 0)
257− : type(Type::Closure), is_shared(true), l(make_shared<_closure3<T>>(val)) {}
258−
259 template <typename T>
198 template <typename T>
260 any(const T& val, typename std::enable_if<std::is_assignable<std::function<any()>,T>::value>::type* = 0)
199 any(const T& val, typename std::enable_if<std::is_assignable<std::function<any()>,T>::value>::type* = 0)
261 : type(Type::EffFunction), is_shared(true), e(make_shared<_eff_fn<T>>(val)) {}
200 : type(Type::EffFunction), is_shared(true), e(make_shared<_eff_fn<T>>(val)) {}
@@ -360,11 +299,7 @@ class any {
360 }
299 }
361
300
362 auto operator()(const any&) const -> any;
301 auto operator()(const any&) const -> any;
363− auto operator()(const any&, const any&) const -> any;
364− auto operator()(const any&, const any&, const any&) const -> any;
365−
366 auto operator()(const as_thunk) const -> const any&;
302 auto operator()(const as_thunk) const -> const any&;
367−
368 auto operator()() const -> any;
303 auto operator()() const -> any;
369
304
370 operator long() const;
305 operator long() const;
src/Language/PureScript/CodeGen/Cpp.hs+1−16
@@ -448,18 +448,7 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
448 return . CppObjectLiteral $
448 return . CppObjectLiteral $
449 zip
449 zip
450 ((sort $ superClassDictionaryNames constraints) ++ (fst <$> fns))
450 ((sort $ superClassDictionaryNames constraints) ++ (fst <$> fns))
451− (arity2or3 <$> args')
451+ args'
452− where
453− -- For arity 2/3 optimization
454− arity2or3 :: Cpp -> Cpp
455− arity2or3 (CppLambda cs [a1] rty
456− (CppBlock [CppReturn (CppLambda _ [a2] _
457− (CppBlock [CppReturn (CppLambda _ [a3] _ ret)]))])) =
458− CppLambda cs [a1, a2, a3] rty ret
459− arity2or3 (CppLambda cs [a1] rty
460− (CppBlock [CppReturn (CppLambda _ [a2] _ ret)])) =
461− CppLambda cs [a1, a2] rty ret
462− arity2or3 cpp' = cpp'
463 Var ann (Qualified (Just mn') ident)
452 Var ann (Qualified (Just mn') ident)
464 | argcnt <- maybe 0 countArgs ty,
453 | argcnt <- maybe 0 countArgs ty,
465 argcnt > 1 -> do
454 argcnt > 1 -> do
@@ -477,10 +466,6 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
477 ty | (_, _, Just t, _) <- ann = Just t
466 ty | (_, _, Just t, _) <- ann = Just t
478 | Just (t, _, _) <- M.lookup (mn', ident) (E.names env) = Just t
467 | Just (t, _, _) <- M.lookup (mn', ident) (E.names env) = Just t
479 | otherwise = Nothing
468 | otherwise = Nothing
480− Accessor (_, _, Nothing, Nothing) _ (Var _ (Qualified Nothing (Ident _)))
481− | length args' == 2 || length args' == 3 -> do -- arity 2 optimization
482− f' <- valueToCpp f
483− return $ CppApp f' args'
484 _ ->
469 _ ->
485 flip (foldl (\fn a -> CppApp fn [a])) args' <$> valueToCpp f
470 flip (foldl (\fn a -> CppApp fn [a])) args' <$> valueToCpp f
486
471