porffor 0.35.0 → 0.35.1

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.
@@ -45,4 +45,78 @@ export const __Porffor_strcmp = (a: any, b: any): boolean => {
45
45
  return true;
46
46
  }
47
47
  }
48
+ };
49
+
50
+ export const __Porffor_strcat = (a: any, b: any): any => {
51
+ // a and b must be string or bytestring
52
+
53
+ const al: i32 = Porffor.wasm.i32.load(a, 0, 0);
54
+ const bl: i32 = Porffor.wasm.i32.load(b, 0, 0);
55
+
56
+ if (Porffor.wasm`local.get ${a+1}` == Porffor.TYPES.bytestring) {
57
+ if (Porffor.wasm`local.get ${b+1}` == Porffor.TYPES.bytestring) {
58
+ // bytestring, bytestring
59
+ const out: bytestring = Porffor.allocateBytes(4 + al + bl);
60
+
61
+ // out.length = a.length + b.length
62
+ Porffor.wasm.i32.store(out, al + bl, 0, 0);
63
+
64
+ // copy left (fast memcpy)
65
+ Porffor.wasm.memory.copy(Porffor.wasm`local.get ${out}` + 4, Porffor.wasm`local.get ${a}` + 4, al, 0, 0);
66
+
67
+ // copy right (fast memcpy)
68
+ Porffor.wasm.memory.copy(Porffor.wasm`local.get ${out}` + 4 + al, Porffor.wasm`local.get ${b}` + 4, bl, 0, 0);
69
+
70
+ return out;
71
+ } else {
72
+ // bytestring, string
73
+ const out: string = Porffor.allocateBytes(4 + (al + bl) * 2);
74
+
75
+ // out.length = a.length + b.length
76
+ Porffor.wasm.i32.store(out, al + bl, 0, 0);
77
+
78
+ // copy left (slow bytestring -> string)
79
+ for (let i: i32 = 0; i < al; i++) {
80
+ Porffor.wasm.i32.store16(Porffor.wasm`local.get ${out}` + i*2, Porffor.wasm.i32.load8_u(Porffor.wasm`local.get ${a}` + i, 0, 4), 0, 4);
81
+ }
82
+
83
+ // copy right (fast memcpy)
84
+ Porffor.wasm.memory.copy(Porffor.wasm`local.get ${out}` + 4 + al*2, Porffor.wasm`local.get ${b}` + 4, bl * 2, 0, 0);
85
+
86
+ return out;
87
+ }
88
+ } else {
89
+ if (Porffor.wasm`local.get ${b+1}` == Porffor.TYPES.bytestring) {
90
+ // string, bytestring
91
+ const out: string = Porffor.allocateBytes(4 + (al + bl) * 2);
92
+
93
+ // out.length = a.length + b.length
94
+ Porffor.wasm.i32.store(out, al + bl, 0, 0);
95
+
96
+ // copy left (fast memcpy)
97
+ Porffor.wasm.memory.copy(Porffor.wasm`local.get ${out}` + 4, Porffor.wasm`local.get ${a}` + 4, al * 2, 0, 0);
98
+
99
+ // copy right (slow bytestring -> string)
100
+ let ptr: i32 = Porffor.wasm`local.get ${out}` + al*2;
101
+ for (let i: i32 = 0; i < bl; i++) {
102
+ Porffor.wasm.i32.store16(ptr + i*2, Porffor.wasm.i32.load8_u(Porffor.wasm`local.get ${b}` + i, 0, 4), 0, 4);
103
+ }
104
+
105
+ return out;
106
+ } else {
107
+ // string, string
108
+ const out: string = Porffor.allocateBytes(4 + (al + bl) * 2);
109
+
110
+ // out.length = a.length + b.length
111
+ Porffor.wasm.i32.store(out, al + bl, 0, 0);
112
+
113
+ // copy left (fast memcpy)
114
+ Porffor.wasm.memory.copy(Porffor.wasm`local.get ${out}` + 4, Porffor.wasm`local.get ${a}` + 4, al * 2, 0, 0);
115
+
116
+ // copy right (fast memcpy)
117
+ Porffor.wasm.memory.copy(Porffor.wasm`local.get ${out}` + 4 + al*2, Porffor.wasm`local.get ${b}` + 4, bl * 2, 0, 0);
118
+
119
+ return out;
120
+ }
121
+ }
48
122
  };
@@ -35,4 +35,25 @@ export const __Porffor_compareStrings = (a: any, b: any): boolean => {
35
35
  }
36
36
 
37
37
  return Porffor.strcmp(a, b);
38
+ };
39
+
40
+ export const __Porffor_concatStrings = (a: any, b: any): boolean => {
41
+ let at: i32 = Porffor.rawType(a);
42
+ let bt: i32 = Porffor.rawType(b);
43
+
44
+ if ((at | 0b10000000) != Porffor.TYPES.bytestring) {
45
+ // a is not string or bytestring
46
+ // todo/perf: just use a.toString()?
47
+ a = ecma262.ToString(a);
48
+ at = Porffor.rawType(a);
49
+ }
50
+
51
+ if ((bt | 0b10000000) != Porffor.TYPES.bytestring) {
52
+ // b is not string or bytestring
53
+ // todo/perf: just use b.toString()?
54
+ b = ecma262.ToString(b);
55
+ bt = Porffor.rawType(b);
56
+ }
57
+
58
+ return Porffor.strcat(a, b);
38
59
  };
@@ -1079,14 +1079,21 @@ export const __ByteString_prototype_trim = (_this: bytestring) => {
1079
1079
 
1080
1080
 
1081
1081
  export const __String_prototype_concat = (_this: string, ...vals: any[]) => {
1082
- // todo/perf: rewrite to use memory.copy?
1083
- let out: string = Porffor.allocate();
1084
- out += _this;
1082
+ let out = Porffor.allocate();
1083
+ Porffor.clone(_this, out);
1084
+
1085
+ // override type to string
1086
+ Porffor.wasm`
1087
+ i32.const 67 ;; string
1088
+ local.set ${out+1}`;
1085
1089
 
1086
1090
  const valsLen: i32 = vals.length;
1087
1091
  for (let i: i32 = 0; i < valsLen; i++) {
1088
- let x: any;
1089
1092
  Porffor.wasm`
1093
+ local.get ${out}
1094
+ f64.convert_i32_u
1095
+ local.get ${out+1}
1096
+
1090
1097
  local.get ${vals}
1091
1098
  local.get ${i}
1092
1099
  i32.const 9
@@ -1101,26 +1108,31 @@ i32.mul
1101
1108
  i32.add
1102
1109
  i32.load8_u 0 12
1103
1110
 
1104
- call __ecma262_ToString
1105
- local.set ${x+1}
1111
+ call __Porffor_concatStrings
1112
+ local.set ${out+1}
1106
1113
  i32.trunc_sat_f64_u
1107
- local.set ${x}`;
1108
-
1109
- out += x;
1114
+ local.set ${out}`;
1110
1115
  }
1111
1116
 
1112
1117
  return out;
1113
1118
  };
1114
1119
 
1115
1120
  export const __ByteString_prototype_concat = (_this: bytestring, ...vals: any[]) => {
1116
- // todo/perf: rewrite to use memory.copy?
1117
- let out: string = Porffor.allocate();
1118
- out += _this;
1121
+ let out = Porffor.allocate();
1122
+ Porffor.clone(_this, out);
1123
+
1124
+ // override type to bytestring
1125
+ Porffor.wasm`
1126
+ i32.const 195 ;; bytestring
1127
+ local.set ${out+1}`;
1119
1128
 
1120
1129
  const valsLen: i32 = vals.length;
1121
1130
  for (let i: i32 = 0; i < valsLen; i++) {
1122
- let x: any;
1123
1131
  Porffor.wasm`
1132
+ local.get ${out}
1133
+ f64.convert_i32_u
1134
+ local.get ${out+1}
1135
+
1124
1136
  local.get ${vals}
1125
1137
  local.get ${i}
1126
1138
  i32.const 9
@@ -1135,12 +1147,10 @@ i32.mul
1135
1147
  i32.add
1136
1148
  i32.load8_u 0 12
1137
1149
 
1138
- call __ecma262_ToString
1139
- local.set ${x+1}
1150
+ call __Porffor_concatStrings
1151
+ local.set ${out+1}
1140
1152
  i32.trunc_sat_f64_u
1141
- local.set ${x}`;
1142
-
1143
- out += x;
1153
+ local.set ${out}`;
1144
1154
  }
1145
1155
 
1146
1156
  return out;