Skip to content

Commit 4c8f74b

Browse files
committed
Added an object pool to hold strong reference to all JawaObjectRef.
Use NSPointerArray and NSMapTable in JawaArray and JawaObject respectively to hold weak references. No GC yet.
1 parent b7d637d commit 4c8f74b

File tree

9 files changed

+149
-50
lines changed

9 files changed

+149
-50
lines changed

JawaScriptExecutive-iOS/JawaArray.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ extern NSMutableDictionary* arrayPrototype;
1717
{
1818

1919
}
20-
@property NSMutableArray* elements;
20+
@property NSPointerArray* elements;
2121

2222
-(id) initIn:(JawaExecutor *)ex;
2323
-(NSString*) description;

JawaScriptExecutive-iOS/JawaArray.m

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ -(id)initIn:(JawaExecutor *)ex {
1818
self = [super init];
1919
if (self) {
2020
_prototype = arrayPrototype;
21-
_elements = [[NSMutableArray alloc]init];
21+
_elements = [NSPointerArray weakObjectsPointerArray];
2222
_executor = ex;
2323
}
2424
return self;
@@ -61,15 +61,15 @@ -(NSMutableString*) toJSON:(NSMutableString*)ret {
6161
}
6262

6363
-(void)append:(JawaObjectRef*)element {
64-
// Need weak references stored in NSArray.
65-
NSValue* weakRef = [NSValue valueWithNonretainedObject:element];
66-
[self.elements addObject:weakRef];
64+
// Need weak references (raw pointer) stored in the array.
65+
[self.elements addPointer:(__bridge void * _Nullable)(element)];
66+
//printf("count : %ld", CFGetRetainCount((__bridge CFTypeRef)element));
6767
}
6868

6969
-(JawaObjectRef*)at:(int)index {
7070
if (index < 0 || index >= [self.elements count])
7171
return nil;
72-
return [self.elements objectAtIndex:index];
72+
return [self.elements pointerAtIndex:index];
7373
}
7474

7575
-(JawaObjectRef*)invokeBuiltin:(NSString*)funcName {

JawaScriptExecutive-iOS/JawaExecutor.h

Lines changed: 11 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -79,18 +79,28 @@ typedef NS_ENUM(NSInteger, ASTType) {
7979
};
8080

8181
#define PR_statements @"0"
82+
#define PR_valueType @"1"
8283
#define PR_arguments @"2"
8384
#define PR_id @"3"
84-
85+
#define PR_key @"4"
86+
#define PR_expr @"5"
87+
#define PR_properties @"6"
8588
#define PR_elements @"7"
8689
#define PR_literal @"8"
90+
#define PR_constructor @"9"
8791
#define PR_object @"10"
8892
#define PR_property @"11"
8993
#define PR_function @"12"
94+
#define PR_subExpression @"13"
95+
#define PR_op @"14"
9096
#define PR_ops @"15"
9197
#define PR_subExpressions @"16"
98+
#define PR_condition @"17"
9299
#define PR_onTrue @"18"
93100
#define PR_onFalse @"19"
101+
#define PR_left @"20"
102+
#define PR_right @"21"
103+
#define PR_expressions @"22"
94104
#define PR_params @"23"
95105
#define PR_body @"24"
96106
#define PR_test @"25"
@@ -103,43 +113,4 @@ typedef NS_ENUM(NSInteger, ASTType) {
103113
#define PR_argument @"32"
104114
#define PR_declarations @"33"
105115

106-
typedef NS_ENUM(NSInteger, PropType) {
107-
PR_valueType,
108-
109-
110-
PR_key,
111-
112-
PR_expr,
113-
PR_properties,
114-
115-
116-
PR_constructor,
117-
118-
119-
120-
PR_subExpression,
121-
PR_op,
122-
123-
124-
PR_condition,
125-
126-
127-
PR_left,
128-
PR_right,
129-
PR_expressions,
130-
131-
132-
133-
134-
135-
136-
137-
138-
139-
140-
141-
142-
143-
};
144-
145116
#endif /* JawaExecutor_h */

JawaScriptExecutive-iOS/JawaExecutor.m

Lines changed: 113 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ -(id)init {
2828
_isFromCallExpression = false;
2929
// TODO: Add externalCallback
3030

31+
jawaObjectPool = [[NSMutableArray alloc]init];
32+
3133
arrayPrototype = [[NSMutableDictionary alloc]init];
3234
stringPrototype = [[NSMutableDictionary alloc]init];
3335
objectPrototype = [[NSMutableDictionary alloc]init];
@@ -89,6 +91,116 @@ -(NSMutableDictionary*)invoke:(NSString *)funcName with:(NSMutableDictionary*)as
8991
return retJSON;
9092
}
9193

94+
-(JawaObjectRef*)evalAssignmentExpression:(NSDictionary*)ast {
95+
printf("Running ASSIGNMENT_EXPRESSION");
96+
JawaObjectRef* left = [self evaluate:[ast objectForKey:PR_left]];
97+
NSString* op = [[[ast objectForKey:PR_op]componentsSeparatedByString:@","]objectAtIndex:1];
98+
JawaObjectRef* right = [self evaluate:[ast objectForKey:PR_right]];
99+
100+
if ([op isEqualToString:@"="]) {
101+
if (left != nil) {
102+
left.object = right != nil ? [right transfer] : nil;
103+
return left;
104+
} else {
105+
NSDictionary* leftExpr = [ast objectForKey:PR_left];
106+
JawaObjectRef* obj = [self evaluate:[leftExpr objectForKey:PR_object]];
107+
if (obj != nil) {
108+
int t = ((NSNumber*)[leftExpr objectForKey:@"t"]).intValue;
109+
if (t == STATIC_MEMBER_EXPRESSION) {
110+
if ([obj.object isMemberOfClass:[JawaObject class]]) {
111+
NSString* property = [[leftExpr objectForKey:PR_property]objectForKey:PR_id];
112+
[(JawaObject*)obj.object setProp:property with:right];
113+
return right;
114+
}
115+
} else if (t == COMPUTED_MEMBER_EXPRESSION) {
116+
if ([obj.object isMemberOfClass:[JawaObject class]]) {
117+
JawaObjectRef* computed = [self evaluate:[leftExpr objectForKey:PR_property]];
118+
if (computed == nil)
119+
[NSException raise:@"JawaScript Runtime Exception" format:@"Computed member for object is null"];
120+
NSString* property = [computed description];
121+
[(JawaObject*)obj.object setProp:property with:right];
122+
return right;
123+
}
124+
}
125+
}
126+
}
127+
[NSException raise:@"JawaScript Runtime Exception" format:@"Left operand of = is null."];
128+
} else if ([op isEqualToString:@"+="]) {
129+
if (left == nil)
130+
[NSException raise:@"JawaScript Runtime Exception" format:@"Left operand of += is null"];
131+
if (right == nil)
132+
[NSException raise:@"JawaScript Runtime Exception" format:@"Right operand of += is null"];
133+
if ([left.object isMemberOfClass:[NSMutableString class]]) {
134+
NSMutableString* l = [NSMutableString stringWithString:[left.object description]];
135+
NSString* r = [right description];
136+
[l appendString:r];
137+
left.object = [JawaObjectRef RefWithString:l in:self];
138+
} else if ([left.object isMemberOfClass:[NSDecimalNumber class]] &&
139+
[right.object isMemberOfClass:[NSDecimalNumber class]]) {
140+
double l = ((NSDecimalNumber*)left.object).doubleValue;
141+
double r = ((NSDecimalNumber*)right.object).doubleValue;
142+
left.object = [JawaObjectRef RefWithNumber:l + r in:self];
143+
} else {
144+
[NSException raise:@"JawaScript Runtime Exception" format:@"Invalid type for +="];
145+
}
146+
} else if ([op isEqualToString:@"-="] ||
147+
[op isEqualToString:@"*="] ||
148+
[op isEqualToString:@"/="] ||
149+
[op isEqualToString:@"%="]) {
150+
if (left == nil)
151+
[NSException raise:@"JawaScript Runtime Exception" format:@"Left operand of assignment is null"];
152+
if (right == nil)
153+
[NSException raise:@"JawaScript Runtime Exception" format:@"Right operand of assignment is null"];
154+
if ([left.object isMemberOfClass:[NSDecimalNumber class]] &&
155+
[right.object isMemberOfClass:[NSDecimalNumber class]]) {
156+
double l = ((NSDecimalNumber*)left.object).doubleValue;
157+
double r = ((NSDecimalNumber*)right.object).doubleValue;
158+
unsigned char c = [op characterAtIndex:0];
159+
switch (c) {
160+
case '-':
161+
left.object = [JawaObjectRef RefWithNumber:l - r in:self];
162+
break;
163+
case '*':
164+
left.object = [JawaObjectRef RefWithNumber:l * r in:self];
165+
break;
166+
case '/':
167+
left.object = [JawaObjectRef RefWithNumber:l / r in:self];
168+
break;
169+
case '%':
170+
left.object = [JawaObjectRef RefWithNumber:(long)l % (long)r in:self];
171+
break;
172+
}
173+
} else {
174+
[NSException raise:@"JawaScript Runtime Exception" format:@"Invalid type for assignment"];
175+
}
176+
} else if ([op isEqualToString:@"|="] ||
177+
[op isEqualToString:@"&="]) {
178+
if (left == nil)
179+
[NSException raise:@"JawaScript Runtime Exception" format:@"Left operand of |=,&= is null"];
180+
if (right == nil)
181+
[NSException raise:@"JawaScript Runtime Exception" format:@"Right operand of |=,&= is null"];
182+
if ([left.object isMemberOfClass:[NSDecimalNumber class]] &&
183+
[right.object isMemberOfClass:[NSDecimalNumber class]]) {
184+
long long l = ((NSDecimalNumber*)left.object).longLongValue;
185+
long long r = ((NSDecimalNumber*)right.object).longLongValue;
186+
unsigned char c = [op characterAtIndex:0];
187+
switch (c) {
188+
case '&':
189+
left.object = [JawaObjectRef RefWithNumber:l & r in:self];
190+
break;
191+
case '|':
192+
left.object = [JawaObjectRef RefWithNumber:l | r in:self];
193+
break;
194+
}
195+
} else {
196+
[NSException raise:@"JawaScript Runtime Exception" format:@"Invalid type for &=, |="];
197+
}
198+
} else {
199+
[NSException raise:@"JawaScript Runtime Exception" format:@"%@ not implemented yet", op];
200+
}
201+
return nil;
202+
}
203+
92204
-(JawaObjectRef*)evalStaticMemberExpression:(NSDictionary*)ast {
93205
printf("Running STATIC_MEMBER_EXPRESSION\n");
94206
JawaObjectRef* object = [self evaluate:[ast objectForKey:PR_object]];
@@ -575,7 +687,7 @@ -(JawaObjectRef*)evaluate:(NSDictionary *)tree {
575687
case SEQUENCE_EXPRESSION:
576688
break;
577689
case ASSIGNMENT_EXPRESSION:
578-
break;
690+
return [self evalAssignmentExpression:tree];
579691
case CONDITIONAL_EXPRESSION:
580692
break;
581693
case LOGICAL_OR_EXPRESSION:

JawaScriptExecutive-iOS/JawaObject.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ extern NSMutableDictionary* objectPrototype;
1717
{
1818

1919
}
20-
@property (strong) NSMutableDictionary* properties;
20+
@property (strong) NSMapTable* properties;
2121
@property (strong) NSMutableDictionary* prototype;
2222
@property (weak) JawaExecutor* executor;
2323

JawaScriptExecutive-iOS/JawaObject.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ @implementation JawaObject
1717
-(id) initIn:(JawaExecutor *)ex {
1818
self = [super init];
1919
if (self) {
20-
_properties = [[NSMutableDictionary alloc] init];
20+
_properties = [NSMapTable strongToWeakObjectsMapTable];
2121
_prototype = objectPrototype;
2222
_executor = ex;
2323
}

JawaScriptExecutive-iOS/JawaObjectProtected.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
@interface JawaObject () {
1313
@protected
14-
NSMutableDictionary* _properties;
14+
NSMapTable* _properties;
1515
NSMutableDictionary* _prototype;
1616
__weak JawaExecutor* _executor;
1717
}

JawaScriptExecutive-iOS/JawaObjectRef.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
@class JawaFunc;
1616
@class JawaObject;
1717

18+
extern NSMutableArray* jawaObjectPool;
19+
1820
@interface JawaObjectRef : NSObject
1921
{
2022

@@ -34,6 +36,7 @@
3436
-(id)initWithJawaObject:(JawaObject*)obj;
3537
-(NSString*)description;
3638
-(id)transfer;
39+
-(void)dealloc;
3740

3841
+(id)RefIn:(JawaExecutor*)ex;
3942
+(id)RefWithNumber:(double)number in:(JawaExecutor*)ex;

JawaScriptExecutive-iOS/JawaObjectRef.m

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,16 @@
1212
#import "JawaFunc.h"
1313
#import "JawaObjectRef.h"
1414

15+
NSMutableArray* jawaObjectPool;
16+
1517
@implementation JawaObjectRef
1618

1719
-(id)initIn:(JawaExecutor*)ex {
1820
self = [super init];
1921
if (self) {
2022
_object = NULL;
2123
_executor = ex;
24+
[jawaObjectPool addObject:self];
2225
}
2326
return self;
2427
}
@@ -28,6 +31,7 @@ -(id)initWithNumber:(double)number in:(JawaExecutor*)ex {
2831
if (self) {
2932
_object = [NSDecimalNumber numberWithDouble:number];
3033
_executor = ex;
34+
[jawaObjectPool addObject:self];
3135
}
3236
return self;
3337
}
@@ -37,6 +41,7 @@ -(id)initWithString:(NSString*)string in:(JawaExecutor*)ex {
3741
if (self) {
3842
_object = [NSMutableString stringWithString:string];
3943
_executor = ex;
44+
[jawaObjectPool addObject:self];
4045
}
4146
return self;
4247
}
@@ -46,6 +51,7 @@ -(id)initWithBoolean:(bool)tf in:(JawaExecutor*)ex {
4651
if (self) {
4752
_object = [NSNumber numberWithBool:tf];
4853
_executor = ex;
54+
[jawaObjectPool addObject:self];
4955
}
5056
return self;
5157
}
@@ -55,6 +61,7 @@ -(id)initWithJawaArray:(JawaArray*)array {
5561
if (self) {
5662
_object = array;
5763
_executor = array.executor;
64+
[jawaObjectPool addObject:self];
5865
}
5966
return self;
6067
}
@@ -65,6 +72,7 @@ -(id)initWithJawaFunc:(JawaFunc*)func {
6572
_object = func;
6673
_appliedOn = nil;
6774
_executor = func.executor;
75+
[jawaObjectPool addObject:self];
6876
}
6977
return self;
7078
}
@@ -75,6 +83,7 @@ -(id)initWithJawaFunc:(JawaFunc*)func on:(JawaObjectRef*)obj {
7583
_object = func;
7684
_appliedOn = obj;
7785
_executor = func.executor;
86+
[jawaObjectPool addObject:self];
7887
}
7988
return self;
8089
}
@@ -84,6 +93,7 @@ -(id)initWithJawaObject:(JawaObject*)obj {
8493
if (self) {
8594
_object = obj;
8695
_executor = obj.executor;
96+
[jawaObjectPool addObject:self];
8797
}
8898
return self;
8999
}
@@ -113,6 +123,9 @@ -(id)transfer {
113123
} else
114124
return self.object;
115125
}
126+
-(void)dealloc {
127+
printf("Releasing %s\n", [[self description]cStringUsingEncoding:NSUTF8StringEncoding]);
128+
}
116129

117130
+(id)RefIn:(JawaExecutor *)ex {
118131
return [[self alloc] initIn:ex];

0 commit comments

Comments
 (0)