functionalscript 0.0.464 → 0.0.465

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/com/cpp/com.hpp CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  #include <cstdint>
4
4
  #include <cstddef>
5
+ #include <atomic>
6
+ #include <iostream>
5
7
 
6
8
  #if defined(__aarch64__) || defined(__amd64__)
7
9
  #define COM_STDCALL
@@ -13,13 +15,55 @@
13
15
 
14
16
  namespace com
15
17
  {
18
+ constexpr uint64_t byteswap(uint64_t v)
19
+ {
20
+ v = v >> 8 & 0x00FF00FF00FF00FF |
21
+ v << 8 & 0xFF00FF00FF00FF00;
22
+ v = v >> 16 & 0x0000FFFF0000FFFF |
23
+ v << 16 & 0xFFFF0000FFFF0000;
24
+ return v >> 32 | v << 32;
25
+ }
26
+
16
27
  class GUID
17
28
  {
18
29
  public:
19
- uint64_t hi;
20
30
  uint64_t lo;
31
+ uint64_t hi;
32
+ constexpr GUID(uint64_t const lo, uint64_t const hi) noexcept
33
+ : lo(lo << 48 & 0xFFFF'0000'0000'0000 |
34
+ lo << 16 & 0x0000'FFFF'0000'0000 |
35
+ lo >> 32),
36
+ hi(byteswap(hi))
37
+ {
38
+ }
39
+ constexpr bool operator==(GUID const b) const noexcept
40
+ {
41
+ return lo == b.lo && hi == b.hi;
42
+ }
43
+ constexpr bool operator!=(GUID const b) const noexcept
44
+ {
45
+ return !(*this == b);
46
+ }
21
47
  };
22
48
 
49
+ inline void guid_part(std::ostream &os, uint64_t const v)
50
+ {
51
+ for (int i = 64; i > 0;)
52
+ {
53
+ i -= 4;
54
+ char const c = (v >> i) & 0xF;
55
+ char const x = c < 10 ? c + '0' : c + ('A' - 10);
56
+ os << x;
57
+ }
58
+ }
59
+
60
+ inline std::ostream &operator<<(std::ostream &os, GUID const &self)
61
+ {
62
+ guid_part(os, self.lo);
63
+ guid_part(os, self.hi);
64
+ return os;
65
+ }
66
+
23
67
  typedef uint32_t HRESULT;
24
68
 
25
69
  static HRESULT const E_NOINTERFACE = 0x80004002;
@@ -37,11 +81,11 @@ namespace com
37
81
  virtual ULONG COM_STDCALL Release() noexcept = 0;
38
82
  };
39
83
 
40
- template<class I>
84
+ template <class I>
41
85
  class ref
42
86
  {
43
87
  public:
44
- explicit ref(I &other) noexcept : p(other.p)
88
+ explicit ref(I &other) noexcept : p(other)
45
89
  {
46
90
  p.AddRef();
47
91
  }
@@ -52,24 +96,52 @@ namespace com
52
96
  {
53
97
  p.Release();
54
98
  }
99
+
55
100
  private:
56
101
  I &p;
57
102
  };
58
103
 
59
- template<class I>
60
- class implementation: public I
104
+ constexpr static GUID const iunknown_guid =
105
+ GUID(0x00000000'0000'0000, 0xC000'000000000046);
106
+
107
+ template <class I>
108
+ constexpr GUID interface_guid();
109
+
110
+ template <class T>
111
+ class implementation : public T
61
112
  {
113
+ private:
62
114
  HRESULT COM_STDCALL QueryInterface(GUID const &riid, IUnknown **const ppvObject) noexcept override
63
115
  {
64
- return E_NOINTERFACE;
116
+ if (riid != iunknown_guid && riid != T::guid)
117
+ {
118
+ return E_NOINTERFACE;
119
+ }
120
+ add_ref();
121
+ *ppvObject = this;
122
+ return S_OK;
65
123
  }
124
+
125
+ ULONG add_ref() noexcept
126
+ {
127
+ return counter.fetch_add(1);
128
+ }
129
+
66
130
  ULONG COM_STDCALL AddRef() noexcept override
67
131
  {
68
- return 0;
132
+ return add_ref() + 1;
69
133
  }
134
+
70
135
  ULONG COM_STDCALL Release() noexcept override
71
136
  {
72
- return 0;
137
+ auto const c = counter.fetch_sub(1) - 1;
138
+ if (c == 0)
139
+ {
140
+ delete this;
141
+ }
142
+ return c;
73
143
  }
144
+
145
+ std::atomic<ULONG> counter;
74
146
  };
75
147
  }
@@ -5,7 +5,7 @@ const obj = require('../../types/object/module.f.cjs')
5
5
  const list = require('../../types/list/module.f.cjs')
6
6
  const { map, flatMap, flat } = list
7
7
  const { join } = require('../../types/string/module.f.cjs')
8
- const { entries } = Object
8
+ const { entries } = Object
9
9
 
10
10
  /** @type {(name: string) => (body: text.Block) => text.Block} */
11
11
  const struct = name => body => [`struct ${name}`, '{', body, '};']
@@ -70,12 +70,20 @@ const cpp = name => lib => {
70
70
  const mapMethod = map(method)
71
71
 
72
72
  /** @type {(i: types.Interface) => text.Block} */
73
- const defInterface = i => mapMethod(entries(i.interface))
73
+ const defInterface = ({ guid, interface: i }) => {
74
+ const g = guid.replaceAll('-', '');
75
+ const lo = g.substring(0, 16);
76
+ const hi = g.substring(16);
77
+ return flat([
78
+ [`constexpr static ::com::GUID const guid = ::com::GUID(0x${lo}, 0x${hi});`],
79
+ mapMethod(entries(i))
80
+ ])
81
+ }
74
82
 
75
83
  /** @type {(kv: obj.Entry<types.Definition>) => text.Block} */
76
84
  const def = ([name, d]) => d.interface === undefined
77
85
  ? struct(name)(defStruct(d))
78
- : struct(`${name}: ::com::IUnknown`)(defInterface(d))
86
+ : struct(`${name} : ::com::IUnknown`)(defInterface(d))
79
87
 
80
88
  /** @type {(kv: obj.Entry<types.Definition>) => text.Block} */
81
89
  const forward = ([name]) => [`struct ${name};`]
@@ -19,8 +19,9 @@ const f = () =>
19
19
  ' {\n' +
20
20
  ' ::com::ref<IMy> M;\n' +
21
21
  ' };\n' +
22
- ' struct IMy: ::com::IUnknown\n' +
22
+ ' struct IMy : ::com::IUnknown\n' +
23
23
  ' {\n' +
24
+ ' constexpr static ::com::GUID const guid = ::com::GUID(0xC66FB2702D8049AD, 0xBB6E88C1F90B805D);\n' +
24
25
  ' virtual Slice COM_STDCALL GetSlice() noexcept = 0;\n' +
25
26
  ' virtual void COM_STDCALL SetSlice(Slice slice) noexcept = 0;\n' +
26
27
  ' virtual ::com::BOOL* COM_STDCALL GetUnsafe() noexcept = 0;\n' +
@@ -46,9 +46,9 @@ const flags = platform => {
46
46
  case 'win32':
47
47
  return []
48
48
  case 'linux':
49
- return ['-lstdc++']
49
+ return ['-lstdc++', '-fPIC']
50
50
  default:
51
- return ['-std=c++11', '-lc++']
51
+ return ['-std=c++17', '-lc++']
52
52
  }
53
53
  }
54
54
 
@@ -13,7 +13,7 @@ extern "C" int c_get()
13
13
  return 43;
14
14
  }
15
15
 
16
- class Impl: public com::implementation<My::IMy>
16
+ class Impl: public My::IMy
17
17
  {
18
18
  My::Slice COM_STDCALL GetSlice() noexcept override
19
19
  {
@@ -41,5 +41,5 @@ class Impl: public com::implementation<My::IMy>
41
41
  DLL_EXPORT
42
42
  extern "C" My::IMy* c_my_create()
43
43
  {
44
- return new Impl();
44
+ return new ::com::implementation<Impl>();
45
45
  }
@@ -10,10 +10,15 @@ static extern IMy rust_my_create();
10
10
  [DllImport("testc")]
11
11
  static extern int c_get();
12
12
 
13
+ [DllImport("testc")]
14
+ static extern IMy c_my_create();
15
+
13
16
  // See https://aka.ms/new-console-template for more information
14
17
  Console.WriteLine("Hello, World!");
15
18
  Console.WriteLine(get());
16
19
  Console.WriteLine(c_get());
17
20
 
18
21
  var x = rust_my_create();
19
- x.SetSlice(new Slice { Start = null, Size = (UIntPtr)44 });
22
+ x.SetSlice(new Slice { Start = null, Size = (UIntPtr)44 });
23
+
24
+ var y = c_my_create();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "functionalscript",
3
- "version": "0.0.464",
3
+ "version": "0.0.465",
4
4
  "description": "FunctionalScript is a functional subset of JavaScript",
5
5
  "main": "module.f.cjs",
6
6
  "scripts": {