Skip to content

Commit 392d64f

Browse files
committed
begin work on proxied native objects, and also implementing getters/setters for native props in custom classes and more
1 parent f9762a3 commit 392d64f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+20145
-83062
lines changed

bench/main.js

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,14 @@
11
import "objc";
22
import { bench, run } from "mitata";
33

4-
{
5-
const arr = NSArray.array();
6-
7-
let total = 0;
8-
let n = 1e6;
9-
10-
for (let i = 0; i < n; i++) {
11-
const start = performance.now();
12-
arr.count;
13-
total += performance.now() - start;
14-
}
15-
16-
console.log("ns/iter:", total * 1e6 / n);
17-
}
18-
194
const arr = NSMutableArray.arrayWithCapacity(100);
205

21-
const arr2 = new Proxy(arr, {
22-
get: (target, prop) => {
23-
return target[prop];
24-
},
25-
});
26-
276
bench("noop", () => {});
287

298
bench("[arr count] (dynamic, ffi)", () => {
309
arr.count;
3110
});
3211

33-
bench("[arr count] (dynamic, proxy)", () => {
34-
arr2.count;
35-
});
36-
3712
await run({
3813
avg: true, // enable/disable avg column (default: true)
3914
json: false, // enable/disable json output (default: false)

examples/foundation.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,9 @@ const ref2 = new interop.Reference(interop.types.uint32, backing);
2020
console.log(ref2, ref2.value);
2121
ref2.value = 3;
2222
console.log(ref2, ref2.value);
23+
24+
const arr = NSMutableArray.arrayWithCapacity(1);
25+
// console.log(arr[0]);
26+
arr.insertObjectAtIndex(NSObject.new(), 0);
27+
console.log(arr[0]);
28+
console.log(arr);

include/ClassMember.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ class MethodDescriptor {
2222

2323
MDSectionOffset signatureOffset;
2424
std::string encoding;
25+
bool isProperty = false;
2526

2627
MethodDescriptor() {}
2728

@@ -67,7 +68,10 @@ class ObjCClassMember {
6768
methodOrGetter(MethodDescriptor(getterSelector, getterOffset)),
6869
setter(MethodDescriptor(setterSelector, setterOffset)),
6970
returnOwned((flags & metagen::mdMemberReturnOwned) != 0),
70-
classMethod((flags & metagen::mdMemberStatic) != 0) {}
71+
classMethod((flags & metagen::mdMemberStatic) != 0) {
72+
methodOrGetter.isProperty = true;
73+
setter.isProperty = true;
74+
}
7175

7276
ObjCBridgeState *bridgeState;
7377
MethodDescriptor methodOrGetter;

include/Closure.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,15 @@ class Closure {
1919
Closure(std::string typeEncoding, bool isBlock);
2020
Closure(MDMetadataReader *reader, MDSectionOffset offset,
2121
bool isBlock = false, std::string *encoding = nullptr,
22-
bool isMethod = false);
22+
bool isMethod = false, bool isGetter = false, bool isSetter = false);
2323

2424
~Closure();
2525

2626
napi_env env;
2727
napi_ref thisConstructor;
2828
napi_ref func = nullptr;
29+
bool isGetter = false;
30+
bool isSetter = false;
2931
std::string propertyName;
3032
napi_threadsafe_function tsfn;
3133

include/ObjCBridge.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ class ObjCBridgeState {
7171
MethodCif *getMethodCif(napi_env env, Method method);
7272
MethodCif *getMethodCif(napi_env env, MDSectionOffset offset);
7373

74+
napi_value proxyNativeObject(napi_env env, napi_value object,
75+
bool isArray = false);
76+
7477
napi_value getObject(napi_env env, id object, napi_value constructor,
7578
ObjectOwnership ownership = kUnownedObject);
7679
napi_value getObject(napi_env env, id object,
@@ -111,6 +114,7 @@ class ObjCBridgeState {
111114

112115
napi_ref pointerClass;
113116
napi_ref referenceClass;
117+
napi_ref createNativeProxy;
114118

115119
std::unordered_map<MDSectionOffset, ObjCClass *> classes;
116120
std::unordered_map<MDSectionOffset, ObjCProtocol *> protocols;

include/Object.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#ifndef OBJECT_H
2+
#define OBJECT_H
3+
4+
#include "ObjCBridge.h"
5+
6+
namespace objc_bridge {
7+
8+
void initProxyFactory(napi_env env, ObjCBridgeState *bridgeState);
9+
10+
} // namespace objc_bridge
11+
12+
#endif /* OBJECT_H */

metadata/metadata.ios.nsmd

-1010 KB
Binary file not shown.

runtime/include/Performance.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#ifndef PERFORMANCE_H
2+
#define PERFORMANCE_H
3+
4+
#include "js_native_api.h"
5+
6+
namespace charon {
7+
8+
class Performance {
9+
public:
10+
static void init(napi_env env);
11+
12+
static napi_value constructor(napi_env env, napi_callback_info cbinfo);
13+
14+
static napi_value now(napi_env env, napi_callback_info cbinfo);
15+
};
16+
17+
} // namespace charon
18+
19+
#endif // PERFORMANCE_H

runtime/src/Performance.cpp

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#include "Performance.h"
2+
#include "mach/mach_time.h"
3+
4+
namespace charon {
5+
6+
void Performance::init(napi_env env) {
7+
napi_value global, Performance, performance;
8+
9+
napi_get_global(env, &global);
10+
11+
const napi_property_descriptor properties[] = {
12+
{
13+
.utf8name = "now",
14+
.name = nullptr,
15+
.method = now,
16+
.getter = nullptr,
17+
.setter = nullptr,
18+
.value = nullptr,
19+
.attributes = napi_default,
20+
.data = nullptr,
21+
},
22+
};
23+
24+
napi_define_class(env, "Performance", NAPI_AUTO_LENGTH,
25+
Performance::constructor, nullptr, 1, properties,
26+
&Performance);
27+
28+
napi_new_instance(env, Performance, 0, nullptr, &performance);
29+
30+
const napi_property_descriptor globalProperties[] = {
31+
{
32+
.utf8name = "performance",
33+
.name = nullptr,
34+
.method = nullptr,
35+
.getter = nullptr,
36+
.setter = nullptr,
37+
.value = performance,
38+
.attributes = napi_default,
39+
.data = nullptr,
40+
},
41+
};
42+
43+
napi_define_properties(env, global, 1, globalProperties);
44+
}
45+
46+
napi_value Performance::constructor(napi_env env, napi_callback_info cbinfo) {
47+
napi_value thisArg;
48+
napi_get_cb_info(env, cbinfo, nullptr, nullptr, &thisArg, nullptr);
49+
50+
return thisArg;
51+
}
52+
53+
napi_value Performance::now(napi_env env, napi_callback_info cbinfo) {
54+
uint64_t time = mach_absolute_time();
55+
mach_timebase_info_data_t timebase;
56+
mach_timebase_info(&timebase);
57+
double nanoseconds =
58+
(double)time * (double)timebase.numer / (double)timebase.denom;
59+
double milliseconds = nanoseconds / 1000000.0;
60+
61+
napi_value result;
62+
napi_create_double(env, milliseconds, &result);
63+
return result;
64+
}
65+
66+
} // namespace charon

runtime/src/Runtime.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "Runtime.h"
22
#include "Console.h"
3+
#include "Performance.h"
34
#include <iostream>
45

56
namespace charon {
@@ -23,6 +24,7 @@ Runtime::Runtime() {
2324
runtime->createNapiEnv(&env);
2425

2526
Console::init(env);
27+
Performance::init(env);
2628

2729
const char *metadata_path = std::getenv("METADATA_PATH");
2830
objc_bridge_init(env, metadata_path);

0 commit comments

Comments
 (0)