Skip to content

Commit d20ca79

Browse files
committed
fix: check if initializer returned a different value compared to self
1 parent 6a6e6dd commit d20ca79

Some content is hidden

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

65 files changed

+1740
-1359
lines changed

include/ClassMember.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ class ObjCClassMember {
5151
MDSectionOffset offset, napi_value constructor);
5252

5353
static napi_value JSCall(napi_env env, napi_callback_info cbinfo);
54+
static napi_value JSCallInit(napi_env env, napi_callback_info cbinfo);
5455
static napi_value JSGetter(napi_env env, napi_callback_info cbinfo);
5556
static napi_value JSSetter(napi_env env, napi_callback_info cbinfo);
5657

metadata/include/IR.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ class MemberDecl {
215215
std::vector<ParameterDecl> parameters;
216216
std::string methodSelector;
217217
bool isVariadic;
218+
bool isInit = false;
218219

219220
// Property
220221
TypeSpec propertyType;

metadata/include/Metadata.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ enum MDMemberFlag : uint8_t {
9393
mdMemberStatic = 1 << 3,
9494
mdMemberMethod = 1 << 4,
9595
mdMemberReturnOwned = 1 << 5,
96+
mdMemberIsInit = 1 << 6,
9697
mdMemberNext = 1 << 7,
9798
};
9899

metadata/metadata.ios.nsmd

2.46 KB
Binary file not shown.

metadata/metadata.macos.nsmd

3.81 KB
Binary file not shown.

metadata/src/IR/Member.cpp

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,6 @@ MemberDecl::MemberDecl(CXCursor cursor,
2020
name = jsifySelector(methodSelector);
2121
clang_disposeString(cxname);
2222

23-
if ((isStatic && (name == "alloc" || name == "new")) ||
24-
(!isStatic && name == "init")) {
25-
returnType.kind = kTypeInstanceObject;
26-
return;
27-
}
28-
2923
auto argc = clang_Cursor_getNumArguments(cursor);
3024

3125
for (int i = 0; i < argc; i++) {
@@ -45,6 +39,19 @@ MemberDecl::MemberDecl(CXCursor cursor,
4539
parameters.emplace_back(param);
4640
}
4741

42+
isVariadic = clang_Cursor_isVariadic(cursor);
43+
44+
if (isStatic && (name.find("alloc") == 0 || name == "new")) {
45+
returnType.kind = kTypeInstanceObject;
46+
return;
47+
}
48+
49+
if (!isStatic && name.find("init") == 0) {
50+
isInit = true;
51+
returnType.kind = kTypeInstanceObject;
52+
return;
53+
}
54+
4855
returnType =
4956
TypeSpec(clang_getCursorResultType(cursor), classTypeParameters);
5057

@@ -56,8 +63,6 @@ MemberDecl::MemberDecl(CXCursor cursor,
5663
returnType.isNullable = true;
5764
}
5865

59-
isVariadic = clang_Cursor_isVariadic(cursor);
60-
6166
break;
6267
}
6368

metadata/src/MetadataWriter/Member.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ MDMember *MDMetadataWriter::memberFromDecl(MemberDecl &decl) {
5454
if (isSelectorOwned(decl.methodSelector))
5555
member->flags = (MDMemberFlag)(member->flags | mdMemberReturnOwned);
5656

57+
if (decl.isInit) {
58+
member->flags = (MDMemberFlag)(member->flags | mdMemberIsInit);
59+
}
60+
5761
MDSignature *mdSignature = new MDSignature();
5862
mdSignature->returnType = getTypeInfo(decl.returnType);
5963
for (auto param : decl.parameters) {

src/ClassMember.mm

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,18 @@
1414

1515
namespace objc_bridge {
1616

17+
napi_value JS_NSObject_alloc(napi_env env, napi_callback_info cbinfo) {
18+
napi_value jsThis;
19+
napi_get_cb_info(env, cbinfo, nullptr, nullptr, &jsThis, nullptr);
20+
21+
id self;
22+
napi_unwrap(env, jsThis, (void **)&self);
23+
24+
id result = [self alloc];
25+
return ObjCBridgeState::InstanceData(env)->getObject(env, result, jsThis,
26+
kOwnedObject);
27+
}
28+
1729
void ObjCClassMember::defineMembers(napi_env env, ObjCClassMemberMap &memberMap,
1830
MDSectionOffset offset,
1931
napi_value constructor) {
@@ -108,7 +120,9 @@
108120
napi_property_descriptor property = {
109121
.utf8name = name.c_str(),
110122
.name = nil,
111-
.method = ObjCClassMember::JSCall,
123+
.method = (flags & metagen::mdMemberIsInit) != 0
124+
? ObjCClassMember::JSCallInit
125+
: ObjCClassMember::JSCall,
112126
.getter = nil,
113127
.setter = nil,
114128
.value = nil,
@@ -118,6 +132,10 @@
118132
.data = &kv.first->second,
119133
};
120134

135+
if (name == "alloc") {
136+
property.method = JS_NSObject_alloc;
137+
}
138+
121139
napi_define_properties(env, jsObject, 1, &property);
122140
}
123141
}
@@ -173,6 +191,71 @@ inline void objcNativeCall(napi_env env, napi_value jsThis, MethodCif *cif,
173191
}
174192
}
175193

194+
napi_value ObjCClassMember::JSCallInit(napi_env env,
195+
napi_callback_info cbinfo) {
196+
napi_value jsThis;
197+
ObjCClassMember *method;
198+
199+
napi_get_cb_info(env, cbinfo, nullptr, nullptr, &jsThis, (void **)&method);
200+
201+
id self = nil;
202+
napi_unwrap(env, jsThis, (void **)&self);
203+
if (self == nil) {
204+
napi_throw_error(env, nullptr, "self is nil");
205+
return nullptr;
206+
}
207+
208+
MethodCif *cif = method->methodCif;
209+
if (cif == nullptr) {
210+
cif = method->methodCif = method->bridgeState->getMethodCif(
211+
env, method->methodOrGetter.signatureOffset);
212+
}
213+
214+
size_t argc = cif->argc;
215+
napi_get_cb_info(env, cbinfo, &argc, cif->argv, &jsThis, nullptr);
216+
217+
void *avalues[cif->cif.nargs];
218+
219+
avalues[0] = (void *)&self;
220+
avalues[1] = (void *)&method->methodOrGetter.selector;
221+
222+
bool shouldFreeAny = false;
223+
bool shouldFree[cif->argc];
224+
225+
if (cif->argc > 0) {
226+
for (unsigned int i = 0; i < cif->argc; i++) {
227+
shouldFree[i] = false;
228+
avalues[i + 2] = cif->avalues[i + 2];
229+
cif->argTypes[i]->toNative(env, cif->argv[i], avalues[i + 2],
230+
&shouldFree[i], &shouldFreeAny);
231+
}
232+
}
233+
234+
id rvalue;
235+
236+
objcNativeCall(env, jsThis, cif, self, avalues, &rvalue);
237+
238+
for (unsigned int i = 0; i < cif->argc; i++) {
239+
if (shouldFree[i]) {
240+
cif->argTypes[i]->free(env, *((void **)avalues[i + 2]));
241+
}
242+
}
243+
244+
napi_value constructor = jsThis;
245+
if (!method->classMethod)
246+
napi_get_named_property(env, jsThis, "constructor", &constructor);
247+
248+
napi_value result =
249+
method->bridgeState->getObject(env, rvalue, constructor, kUnownedObject);
250+
251+
if (rvalue != self) {
252+
[self retain];
253+
[rvalue release];
254+
}
255+
256+
return result;
257+
}
258+
176259
napi_value ObjCClassMember::JSCall(napi_env env, napi_callback_info cbinfo) {
177260
napi_value jsThis;
178261
ObjCClassMember *method;

src/Object.mm

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,6 @@ void finalize_objc_object_borrowed(napi_env, void *data, void *hint) {
7171
bridgeState->objectRefs.erase(object);
7272
}
7373

74-
Class UIPlaceholderColorClass = objc_getClass("UIPlaceholderColor");
75-
7674
napi_value ObjCBridgeState::getObject(napi_env env, id obj,
7775
napi_value constructor,
7876
ObjectOwnership ownership) {
@@ -100,10 +98,6 @@ void finalize_objc_object_borrowed(napi_env, void *data, void *hint) {
10098
return nullptr;
10199
}
102100

103-
if (cls == UIPlaceholderColorClass) {
104-
ownership = kBorrowedObject;
105-
}
106-
107101
bool isClass = false;
108102

109103
if (class_isMetaClass(cls)) {
@@ -305,7 +299,6 @@ napi_value findConstructorForObject(napi_env env, ObjCBridgeState *bridgeState,
305299
void ObjCBridgeState::unregisterObject(id object) noexcept {
306300
if (objectRefs.contains(object)) {
307301
objectRefs.erase(object);
308-
// NSLog(@"release object: %@", object);
309302
[object release];
310303
}
311304
}

types/ios/AVFAudio.d.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,15 @@ declare const AVAudioVoiceProcessingOtherAudioDuckingLevel: {
9898
Max: 30,
9999
};
100100

101+
declare const AVAudioSessionRenderingMode: {
102+
NotApplicable: 0,
103+
MonoStereo: 1,
104+
Surround: 2,
105+
SpatialAudio: 3,
106+
DolbyAudio: 4,
107+
DolbyAtmos: 5,
108+
};
109+
101110
declare const AVAudioSessionRecordPermission: {
102111
Undetermined: 1970168948,
103112
Denied: 1684369017,
@@ -488,6 +497,8 @@ declare class AVAudioSession extends NSObject {
488497
setPrefersNoInterruptionsFromSystemAlertsError(inValue: boolean, outError: interop.PointerConvertible): boolean;
489498

490499
readonly prefersNoInterruptionsFromSystemAlerts: boolean;
500+
501+
readonly renderingMode: interop.Enum<typeof AVAudioSessionRenderingMode>;
491502
}
492503

493504
declare class AVAudioMixingDestination extends NSObject implements AVAudioMixing {

0 commit comments

Comments
 (0)