blob: deea8c33cdf8b121cb06696398ea3f2a74a621d7 [file] [log] [blame]
Ethan Nicholas26a9aad2018-03-27 14:10:52 -04001/*
2 * Copyright 2018 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef SKSL_STANDALONE
9
Ethan Nicholasae9633b2019-05-24 12:46:34 -040010#include "include/core/SkPoint3.h"
Brian Osman80164412019-06-07 13:00:23 -040011#include "src/sksl/SkSLByteCode.h"
Brian Osman07c117b2019-05-23 12:51:06 -070012#include "src/sksl/SkSLByteCodeGenerator.h"
Ethan Nicholas91164d12019-05-15 15:29:54 -040013#include "src/sksl/SkSLExternalValue.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050014#include "src/sksl/SkSLInterpreter.h"
Brian Osman80164412019-06-07 13:00:23 -040015
16#include <vector>
Ethan Nicholas26a9aad2018-03-27 14:10:52 -040017
18namespace SkSL {
Brian Osman80164412019-06-07 13:00:23 -040019namespace Interpreter {
Ethan Nicholas26a9aad2018-03-27 14:10:52 -040020
Mike Klein76346ac2019-05-17 11:57:10 -050021template <typename T>
22static T unaligned_load(const void* ptr) {
23 T val;
24 memcpy(&val, ptr, sizeof(val));
25 return val;
26}
Ethan Nicholas0e9401d2019-03-21 11:05:37 -040027
Mike Kleine7007382019-05-21 08:36:32 -050028#define READ8() (*(ip++))
Mike Klein76346ac2019-05-17 11:57:10 -050029#define READ16() (ip += 2, unaligned_load<uint16_t>(ip - 2))
30#define READ32() (ip += 4, unaligned_load<uint32_t>(ip - 4))
Ethan Nicholas0e9401d2019-03-21 11:05:37 -040031
Brian Osman3e833e12019-05-23 13:23:24 -070032#define VECTOR_DISASSEMBLE(op, text) \
Ethan Nicholas48a75aa2019-05-16 17:15:56 -040033 case ByteCodeInstruction::op: printf(text); break; \
34 case ByteCodeInstruction::op##2: printf(text "2"); break; \
35 case ByteCodeInstruction::op##3: printf(text "3"); break; \
36 case ByteCodeInstruction::op##4: printf(text "4"); break;
37
Brian Osman1e855b22019-05-29 15:21:52 -040038#define VECTOR_MATRIX_DISASSEMBLE(op, text) \
39 case ByteCodeInstruction::op: printf(text); break; \
40 case ByteCodeInstruction::op##2: printf(text "2"); break; \
41 case ByteCodeInstruction::op##3: printf(text "3"); break; \
42 case ByteCodeInstruction::op##4: printf(text "4"); break; \
43 case ByteCodeInstruction::op##N: printf(text "N %d", READ8()); break;
44
Brian Osman3e833e12019-05-23 13:23:24 -070045static const uint8_t* disassemble_instruction(const uint8_t* ip) {
46 switch ((ByteCodeInstruction) READ16()) {
Brian Osman1e855b22019-05-29 15:21:52 -040047 VECTOR_MATRIX_DISASSEMBLE(kAddF, "addf")
Brian Osman3e833e12019-05-23 13:23:24 -070048 VECTOR_DISASSEMBLE(kAddI, "addi")
Brian Osman32c526b2019-06-03 16:13:52 -040049 case ByteCodeInstruction::kAndB: printf("andb"); break;
Brian Osman3e833e12019-05-23 13:23:24 -070050 case ByteCodeInstruction::kBranch: printf("branch %d", READ16()); break;
51 case ByteCodeInstruction::kCall: printf("call %d", READ8()); break;
52 case ByteCodeInstruction::kCallExternal: {
53 int argumentCount = READ8();
54 int returnCount = READ8();
55 int externalValue = READ8();
56 printf("callexternal %d, %d, %d", argumentCount, returnCount, externalValue);
57 break;
58 }
59 VECTOR_DISASSEMBLE(kCompareIEQ, "compareieq")
60 VECTOR_DISASSEMBLE(kCompareINEQ, "compareineq")
Brian Osman1e855b22019-05-29 15:21:52 -040061 VECTOR_MATRIX_DISASSEMBLE(kCompareFEQ, "comparefeq")
62 VECTOR_MATRIX_DISASSEMBLE(kCompareFNEQ, "comparefneq")
Brian Osman3e833e12019-05-23 13:23:24 -070063 VECTOR_DISASSEMBLE(kCompareFGT, "comparefgt")
64 VECTOR_DISASSEMBLE(kCompareFGTEQ, "comparefgteq")
65 VECTOR_DISASSEMBLE(kCompareFLT, "compareflt")
66 VECTOR_DISASSEMBLE(kCompareFLTEQ, "compareflteq")
67 VECTOR_DISASSEMBLE(kCompareSGT, "comparesgt")
68 VECTOR_DISASSEMBLE(kCompareSGTEQ, "comparesgteq")
69 VECTOR_DISASSEMBLE(kCompareSLT, "compareslt")
70 VECTOR_DISASSEMBLE(kCompareSLTEQ, "compareslteq")
71 VECTOR_DISASSEMBLE(kCompareUGT, "compareugt")
72 VECTOR_DISASSEMBLE(kCompareUGTEQ, "compareugteq")
73 VECTOR_DISASSEMBLE(kCompareULT, "compareult")
74 VECTOR_DISASSEMBLE(kCompareULTEQ, "compareulteq")
75 case ByteCodeInstruction::kConditionalBranch:
76 printf("conditionalbranch %d", READ16());
77 break;
78 VECTOR_DISASSEMBLE(kConvertFtoI, "convertftoi")
79 VECTOR_DISASSEMBLE(kConvertStoF, "convertstof")
80 VECTOR_DISASSEMBLE(kConvertUtoF, "convertutof")
81 VECTOR_DISASSEMBLE(kCos, "cos")
Brian Osman1e855b22019-05-29 15:21:52 -040082 VECTOR_MATRIX_DISASSEMBLE(kDivideF, "dividef")
Brian Osman3e833e12019-05-23 13:23:24 -070083 VECTOR_DISASSEMBLE(kDivideS, "divideS")
84 VECTOR_DISASSEMBLE(kDivideU, "divideu")
Brian Osman1e855b22019-05-29 15:21:52 -040085 VECTOR_MATRIX_DISASSEMBLE(kDup, "dup")
Brian Osman3e833e12019-05-23 13:23:24 -070086 case ByteCodeInstruction::kLoad: printf("load %d", READ8()); break;
87 case ByteCodeInstruction::kLoad2: printf("load2 %d", READ8()); break;
88 case ByteCodeInstruction::kLoad3: printf("load3 %d", READ8()); break;
89 case ByteCodeInstruction::kLoad4: printf("load4 %d", READ8()); break;
90 case ByteCodeInstruction::kLoadGlobal: printf("loadglobal %d", READ8()); break;
91 case ByteCodeInstruction::kLoadGlobal2: printf("loadglobal2 %d", READ8()); break;
92 case ByteCodeInstruction::kLoadGlobal3: printf("loadglobal3 %d", READ8()); break;
93 case ByteCodeInstruction::kLoadGlobal4: printf("loadglobal4 %d", READ8()); break;
94 case ByteCodeInstruction::kLoadSwizzle: {
95 int target = READ8();
96 int count = READ8();
97 printf("loadswizzle %d %d", target, count);
98 for (int i = 0; i < count; ++i) {
99 printf(", %d", READ8());
100 }
101 break;
102 }
103 case ByteCodeInstruction::kLoadSwizzleGlobal: {
104 int target = READ8();
105 int count = READ8();
106 printf("loadswizzleglobal %d %d", target, count);
107 for (int i = 0; i < count; ++i) {
108 printf(", %d", READ8());
109 }
110 break;
111 }
112 case ByteCodeInstruction::kLoadExtended: printf("loadextended %d", READ8()); break;
113 case ByteCodeInstruction::kLoadExtendedGlobal: printf("loadextendedglobal %d", READ8());
114 break;
Brian Osman29e013d2019-05-28 17:16:03 -0400115 case ByteCodeInstruction::kMatrixToMatrix: {
116 int srcCols = READ8();
117 int srcRows = READ8();
118 int dstCols = READ8();
119 int dstRows = READ8();
120 printf("matrixtomatrix %dx%d %dx%d", srcCols, srcRows, dstCols, dstRows);
121 break;
122 }
Brian Osman909231c2019-05-29 15:34:36 -0400123 case ByteCodeInstruction::kMatrixMultiply: {
124 int lCols = READ8();
125 int lRows = READ8();
126 int rCols = READ8();
127 printf("matrixmultiply %dx%d %dx%d", lCols, lRows, rCols, lCols);
128 break;
129 }
Ethan Nicholasae9633b2019-05-24 12:46:34 -0400130 VECTOR_DISASSEMBLE(kMix, "mix")
Brian Osman1e855b22019-05-29 15:21:52 -0400131 VECTOR_MATRIX_DISASSEMBLE(kMultiplyF, "multiplyf")
Brian Osman3e833e12019-05-23 13:23:24 -0700132 VECTOR_DISASSEMBLE(kMultiplyI, "multiplyi")
Brian Osman1e855b22019-05-29 15:21:52 -0400133 VECTOR_MATRIX_DISASSEMBLE(kNegateF, "negatef")
Brian Osman3e833e12019-05-23 13:23:24 -0700134 VECTOR_DISASSEMBLE(kNegateI, "negatei")
Brian Osman32c526b2019-06-03 16:13:52 -0400135 case ByteCodeInstruction::kNot: printf("not"); break;
136 case ByteCodeInstruction::kOrB: printf("orb"); break;
Brian Osman1e855b22019-05-29 15:21:52 -0400137 VECTOR_MATRIX_DISASSEMBLE(kPop, "pop")
Brian Osman3e833e12019-05-23 13:23:24 -0700138 case ByteCodeInstruction::kPushImmediate: {
139 uint32_t v = READ32();
140 union { uint32_t u; float f; } pun = { v };
141 printf("pushimmediate %s", (to_string(v) + "(" + to_string(pun.f) + ")").c_str());
142 break;
143 }
144 case ByteCodeInstruction::kReadExternal: printf("readexternal %d", READ8()); break;
145 case ByteCodeInstruction::kReadExternal2: printf("readexternal2 %d", READ8()); break;
146 case ByteCodeInstruction::kReadExternal3: printf("readexternal3 %d", READ8()); break;
147 case ByteCodeInstruction::kReadExternal4: printf("readexternal4 %d", READ8()); break;
148 VECTOR_DISASSEMBLE(kRemainderF, "remainderf")
149 VECTOR_DISASSEMBLE(kRemainderS, "remainders")
150 VECTOR_DISASSEMBLE(kRemainderU, "remainderu")
151 case ByteCodeInstruction::kReturn: printf("return %d", READ8()); break;
Brian Osman29e013d2019-05-28 17:16:03 -0400152 case ByteCodeInstruction::kScalarToMatrix: {
153 int cols = READ8();
154 int rows = READ8();
155 printf("scalartomatrix %dx%d", cols, rows);
156 break;
157 }
Brian Osman3e833e12019-05-23 13:23:24 -0700158 VECTOR_DISASSEMBLE(kSin, "sin")
159 VECTOR_DISASSEMBLE(kSqrt, "sqrt")
160 case ByteCodeInstruction::kStore: printf("store %d", READ8()); break;
161 case ByteCodeInstruction::kStore2: printf("store2 %d", READ8()); break;
162 case ByteCodeInstruction::kStore3: printf("store3 %d", READ8()); break;
163 case ByteCodeInstruction::kStore4: printf("store4 %d", READ8()); break;
164 case ByteCodeInstruction::kStoreGlobal: printf("storeglobal %d", READ8()); break;
165 case ByteCodeInstruction::kStoreGlobal2: printf("storeglobal2 %d", READ8()); break;
166 case ByteCodeInstruction::kStoreGlobal3: printf("storeglobal3 %d", READ8()); break;
167 case ByteCodeInstruction::kStoreGlobal4: printf("storeglobal4 %d", READ8()); break;
168 case ByteCodeInstruction::kStoreSwizzle: {
169 int target = READ8();
170 int count = READ8();
171 printf("storeswizzle %d %d", target, count);
172 for (int i = 0; i < count; ++i) {
173 printf(", %d", READ8());
174 }
175 break;
176 }
177 case ByteCodeInstruction::kStoreSwizzleGlobal: {
178 int target = READ8();
179 int count = READ8();
180 printf("storeswizzleglobal %d %d", target, count);
181 for (int i = 0; i < count; ++i) {
182 printf(", %d", READ8());
183 }
184 break;
185 }
186 case ByteCodeInstruction::kStoreSwizzleIndirect: {
187 int count = READ8();
188 printf("storeswizzleindirect %d", count);
189 for (int i = 0; i < count; ++i) {
190 printf(", %d", READ8());
191 }
192 break;
193 }
194 case ByteCodeInstruction::kStoreSwizzleIndirectGlobal: {
195 int count = READ8();
196 printf("storeswizzleindirectglobal %d", count);
197 for (int i = 0; i < count; ++i) {
198 printf(", %d", READ8());
199 }
200 break;
201 }
202 case ByteCodeInstruction::kStoreExtended: printf("storeextended %d", READ8()); break;
203 case ByteCodeInstruction::kStoreExtendedGlobal: printf("storeextendedglobal %d", READ8());
204 break;
Brian Osman1e855b22019-05-29 15:21:52 -0400205 VECTOR_MATRIX_DISASSEMBLE(kSubtractF, "subtractf")
Brian Osman3e833e12019-05-23 13:23:24 -0700206 VECTOR_DISASSEMBLE(kSubtractI, "subtracti")
207 case ByteCodeInstruction::kSwizzle: {
208 printf("swizzle %d, ", READ8());
209 int count = READ8();
210 printf("%d", count);
211 for (int i = 0; i < count; ++i) {
212 printf(", %d", READ8());
213 }
214 break;
215 }
216 VECTOR_DISASSEMBLE(kTan, "tan")
217 case ByteCodeInstruction::kWriteExternal: printf("writeexternal %d", READ8()); break;
218 case ByteCodeInstruction::kWriteExternal2: printf("writeexternal2 %d", READ8()); break;
219 case ByteCodeInstruction::kWriteExternal3: printf("writeexternal3 %d", READ8()); break;
220 case ByteCodeInstruction::kWriteExternal4: printf("writeexternal4 %d", READ8()); break;
221 default: printf("unknown(%d)\n", *(ip - 1)); SkASSERT(false);
222 }
223 return ip;
224}
225
Brian Osman80164412019-06-07 13:00:23 -0400226void Disassemble(const ByteCodeFunction* f) {
227 const uint8_t* ip = f->fCode.data();
228 while (ip < f->fCode.data() + f->fCode.size()) {
229 printf("%d: ", (int) (ip - f->fCode.data()));
Brian Osman3e833e12019-05-23 13:23:24 -0700230 ip = disassemble_instruction(ip);
Ethan Nicholas0e9401d2019-03-21 11:05:37 -0400231 printf("\n");
Ethan Nicholas26a9aad2018-03-27 14:10:52 -0400232 }
233}
234
Mike Klein459aed12019-05-21 15:46:36 -0500235#define VECTOR_BINARY_OP(base, field, op) \
Mike Kleine7007382019-05-21 08:36:32 -0500236 case ByteCodeInstruction::base ## 4: \
Mike Klein459aed12019-05-21 15:46:36 -0500237 sp[-4] = sp[-4].field op sp[0].field; \
Mike Kleine7007382019-05-21 08:36:32 -0500238 POP(); \
239 /* fall through */ \
240 case ByteCodeInstruction::base ## 3: { \
241 int count = (int) ByteCodeInstruction::base - (int) inst - 1; \
Mike Klein459aed12019-05-21 15:46:36 -0500242 sp[count] = sp[count].field op sp[0].field; \
Mike Kleine7007382019-05-21 08:36:32 -0500243 POP(); \
244 } /* fall through */ \
245 case ByteCodeInstruction::base ## 2: { \
246 int count = (int) ByteCodeInstruction::base - (int) inst - 1; \
Mike Klein459aed12019-05-21 15:46:36 -0500247 sp[count] = sp[count].field op sp[0].field; \
Mike Kleine7007382019-05-21 08:36:32 -0500248 POP(); \
249 } /* fall through */ \
250 case ByteCodeInstruction::base: { \
251 int count = (int) ByteCodeInstruction::base - (int) inst - 1; \
Mike Klein459aed12019-05-21 15:46:36 -0500252 sp[count] = sp[count].field op sp[0].field; \
Mike Kleine7007382019-05-21 08:36:32 -0500253 POP(); \
254 break; \
255 }
Ethan Nicholasaeb71ce2019-05-20 09:55:44 -0400256
Brian Osman1e855b22019-05-29 15:21:52 -0400257#define VECTOR_MATRIX_BINARY_OP(base, field, op) \
258 VECTOR_BINARY_OP(base, field, op) \
259 case ByteCodeInstruction::base ## N: { \
260 int count = READ8(); \
261 for (int i = count; i > 0; --i) { \
262 sp[-count] = sp[-count].field op sp[0].field; \
263 POP(); \
264 } \
265 break; \
266 }
267
Ethan Nicholasae9633b2019-05-24 12:46:34 -0400268#define VECTOR_BINARY_FN(base, field, fn) \
269 case ByteCodeInstruction::base ## 4: \
270 sp[-4] = fn(sp[-4].field, sp[0].field); \
271 POP(); \
272 /* fall through */ \
273 case ByteCodeInstruction::base ## 3: { \
274 int target = (int) ByteCodeInstruction::base - (int) inst - 1; \
275 sp[target] = fn(sp[target].field, sp[0].field); \
276 POP(); \
277 } /* fall through */ \
278 case ByteCodeInstruction::base ## 2: { \
279 int target = (int) ByteCodeInstruction::base - (int) inst - 1; \
280 sp[target] = fn(sp[target].field, sp[0].field); \
281 POP(); \
282 } /* fall through */ \
283 case ByteCodeInstruction::base: { \
284 int target = (int) ByteCodeInstruction::base - (int) inst - 1; \
285 sp[target] = fn(sp[target].field, sp[0].field); \
286 POP(); \
287 break; \
Mike Kleine7007382019-05-21 08:36:32 -0500288 }
Ethan Nicholas0e9401d2019-03-21 11:05:37 -0400289
Mike Klein459aed12019-05-21 15:46:36 -0500290#define VECTOR_UNARY_FN(base, fn, field) \
291 case ByteCodeInstruction::base ## 4: sp[-3] = fn(sp[-3].field); \
292 case ByteCodeInstruction::base ## 3: sp[-2] = fn(sp[-2].field); \
293 case ByteCodeInstruction::base ## 2: sp[-1] = fn(sp[-1].field); \
294 case ByteCodeInstruction::base: sp[ 0] = fn(sp[ 0].field); \
Ethan Nicholas82162ee2019-05-21 16:05:08 -0400295 break;
296
Brian Osman226668a2019-05-14 16:47:30 -0400297struct StackFrame {
298 const uint8_t* fCode;
299 const uint8_t* fIP;
300 Interpreter::Value* fStack;
301};
302
Ethan Nicholasae9633b2019-05-24 12:46:34 -0400303static float mix(float start, float end, float t) {
304 return start * (1 - t) + end * t;
305}
306
Brian Osman80164412019-06-07 13:00:23 -0400307void innerRun(const ByteCode* byteCode, const ByteCodeFunction* f, Value* stack, Value* outReturn,
308 Value globals[], int globalCount) {
309 Value* sp = stack + f->fParameterCount + f->fLocalCount - 1;
Mike Kleine7007382019-05-21 08:36:32 -0500310
311 auto POP = [&] { SkASSERT(sp >= stack); return *(sp--); };
312 auto PUSH = [&](Value v) { SkASSERT(sp + 1 >= stack); *(++sp) = v; };
313
Brian Osman80164412019-06-07 13:00:23 -0400314 const uint8_t* code = f->fCode.data();
Ethan Nicholasdfcad062019-05-07 12:53:34 -0400315 const uint8_t* ip = code;
Brian Osman226668a2019-05-14 16:47:30 -0400316 std::vector<StackFrame> frames;
317
Ethan Nicholas7e603db2019-05-03 12:57:47 -0400318 for (;;) {
Ethan Nicholasdfcad062019-05-07 12:53:34 -0400319#ifdef TRACE
Brian Osman3e833e12019-05-23 13:23:24 -0700320 printf("at %3d ", (int) (ip - code));
321 disassemble_instruction(ip);
322 printf("\n");
Ethan Nicholasdfcad062019-05-07 12:53:34 -0400323#endif
Brian Osmane85b6a52019-05-22 14:50:59 -0700324 ByteCodeInstruction inst = (ByteCodeInstruction) READ16();
Ethan Nicholas9764ebd2019-05-01 14:43:54 -0400325 switch (inst) {
Mike Kleinc1999982019-05-21 13:03:49 -0500326 VECTOR_BINARY_OP(kAddI, fSigned, +)
Brian Osman1e855b22019-05-29 15:21:52 -0400327 VECTOR_MATRIX_BINARY_OP(kAddF, fFloat, +)
Brian Osman32c526b2019-06-03 16:13:52 -0400328 case ByteCodeInstruction::kAndB:
329 sp[-1] = sp[-1].fBool && sp[0].fBool;
330 POP();
331 break;
Ethan Nicholas82162ee2019-05-21 16:05:08 -0400332
Ethan Nicholas48a75aa2019-05-16 17:15:56 -0400333 case ByteCodeInstruction::kBranch:
Ethan Nicholasdfcad062019-05-07 12:53:34 -0400334 ip = code + READ16();
Ethan Nicholas9764ebd2019-05-01 14:43:54 -0400335 break;
Ethan Nicholas82162ee2019-05-21 16:05:08 -0400336
Brian Osman226668a2019-05-14 16:47:30 -0400337 case ByteCodeInstruction::kCall: {
338 // Precursor code has pushed all parameters to the stack. Update our bottom of
339 // stack to point at the first parameter, and our sp to point past those parameters
340 // (plus space for locals).
Mike Kleine7007382019-05-21 08:36:32 -0500341 int target = READ8();
Brian Osman80164412019-06-07 13:00:23 -0400342 const ByteCodeFunction* fun = byteCode->fFunctions[target].get();
Brian Osman226668a2019-05-14 16:47:30 -0400343 frames.push_back({ code, ip, stack });
344 ip = code = fun->fCode.data();
345 stack = sp - fun->fParameterCount + 1;
346 sp = stack + fun->fParameterCount + fun->fLocalCount - 1;
347 break;
348 }
Ethan Nicholas82162ee2019-05-21 16:05:08 -0400349
Ethan Nicholas9e6a3932019-05-17 16:31:21 -0400350 case ByteCodeInstruction::kCallExternal: {
351 int argumentCount = READ8();
352 int returnCount = READ8();
Mike Kleine7007382019-05-21 08:36:32 -0500353 int target = READ8();
Brian Osman80164412019-06-07 13:00:23 -0400354 ExternalValue* v = byteCode->fExternalValues[target];
Ethan Nicholas9e6a3932019-05-17 16:31:21 -0400355 sp -= argumentCount - 1;
Mike Kleine7007382019-05-21 08:36:32 -0500356
357 Value tmp[4];
358 SkASSERT(returnCount <= (int)SK_ARRAY_COUNT(tmp));
Ethan Nicholas9e6a3932019-05-17 16:31:21 -0400359 v->call(sp, tmp);
360 memcpy(sp, tmp, returnCount * sizeof(Value));
361 sp += returnCount - 1;
362 break;
363 }
Ethan Nicholas82162ee2019-05-21 16:05:08 -0400364
Mike Kleinc1999982019-05-21 13:03:49 -0500365 VECTOR_BINARY_OP(kCompareIEQ, fSigned, ==)
Brian Osman1e855b22019-05-29 15:21:52 -0400366 VECTOR_MATRIX_BINARY_OP(kCompareFEQ, fFloat, ==)
Mike Kleinc1999982019-05-21 13:03:49 -0500367 VECTOR_BINARY_OP(kCompareINEQ, fSigned, !=)
Brian Osman1e855b22019-05-29 15:21:52 -0400368 VECTOR_MATRIX_BINARY_OP(kCompareFNEQ, fFloat, !=)
Mike Kleinc1999982019-05-21 13:03:49 -0500369 VECTOR_BINARY_OP(kCompareSGT, fSigned, >)
370 VECTOR_BINARY_OP(kCompareUGT, fUnsigned, >)
371 VECTOR_BINARY_OP(kCompareFGT, fFloat, >)
372 VECTOR_BINARY_OP(kCompareSGTEQ, fSigned, >=)
373 VECTOR_BINARY_OP(kCompareUGTEQ, fUnsigned, >=)
374 VECTOR_BINARY_OP(kCompareFGTEQ, fFloat, >=)
375 VECTOR_BINARY_OP(kCompareSLT, fSigned, <)
376 VECTOR_BINARY_OP(kCompareULT, fUnsigned, <)
377 VECTOR_BINARY_OP(kCompareFLT, fFloat, <)
378 VECTOR_BINARY_OP(kCompareSLTEQ, fSigned, <=)
379 VECTOR_BINARY_OP(kCompareULTEQ, fUnsigned, <=)
380 VECTOR_BINARY_OP(kCompareFLTEQ, fFloat, <=)
Ethan Nicholas82162ee2019-05-21 16:05:08 -0400381
Mike Kleine7007382019-05-21 08:36:32 -0500382 case ByteCodeInstruction::kConditionalBranch: {
383 int target = READ16();
Ethan Nicholasdfcad062019-05-07 12:53:34 -0400384 if (POP().fBool) {
Mike Kleine7007382019-05-21 08:36:32 -0500385 ip = code + target;
Ethan Nicholas9764ebd2019-05-01 14:43:54 -0400386 }
387 break;
Mike Kleine7007382019-05-21 08:36:32 -0500388 }
Ethan Nicholas82162ee2019-05-21 16:05:08 -0400389
390 case ByteCodeInstruction::kConvertFtoI4: sp[-3].fSigned = (int)sp[-3].fFloat;
391 case ByteCodeInstruction::kConvertFtoI3: sp[-2].fSigned = (int)sp[-2].fFloat;
392 case ByteCodeInstruction::kConvertFtoI2: sp[-1].fSigned = (int)sp[-1].fFloat;
393 case ByteCodeInstruction::kConvertFtoI: sp[ 0].fSigned = (int)sp[ 0].fFloat;
394 break;
395
396 case ByteCodeInstruction::kConvertStoF4: sp[-3].fFloat = sp[-3].fSigned;
397 case ByteCodeInstruction::kConvertStoF3: sp[-2].fFloat = sp[-2].fSigned;
398 case ByteCodeInstruction::kConvertStoF2: sp[-1].fFloat = sp[-1].fSigned;
399 case ByteCodeInstruction::kConvertStoF : sp[ 0].fFloat = sp[ 0].fSigned;
400 break;
401
402 case ByteCodeInstruction::kConvertUtoF4: sp[-3].fFloat = sp[-3].fUnsigned;
403 case ByteCodeInstruction::kConvertUtoF3: sp[-2].fFloat = sp[-2].fUnsigned;
404 case ByteCodeInstruction::kConvertUtoF2: sp[-1].fFloat = sp[-1].fUnsigned;
405 case ByteCodeInstruction::kConvertUtoF : sp[ 0].fFloat = sp[ 0].fUnsigned;
406 break;
407
Mike Klein459aed12019-05-21 15:46:36 -0500408 VECTOR_UNARY_FN(kCos, cosf, fFloat)
Ethan Nicholas82162ee2019-05-21 16:05:08 -0400409
Ethan Nicholasae9633b2019-05-24 12:46:34 -0400410 case ByteCodeInstruction::kCross: {
411 SkPoint3 cross = SkPoint3::CrossProduct(SkPoint3::Make(sp[-5].fFloat,
412 sp[-4].fFloat,
413 sp[-3].fFloat),
414 SkPoint3::Make(sp[-2].fFloat,
415 sp[-1].fFloat,
416 sp[ 0].fFloat));
417 sp -= 3;
418 sp[-2] = cross.fX;
419 sp[-1] = cross.fY;
420 sp[ 0] = cross.fZ;
421 break;
422 }
423
Mike Kleinc1999982019-05-21 13:03:49 -0500424 VECTOR_BINARY_OP(kDivideS, fSigned, /)
425 VECTOR_BINARY_OP(kDivideU, fUnsigned, /)
Brian Osman1e855b22019-05-29 15:21:52 -0400426 VECTOR_MATRIX_BINARY_OP(kDivideF, fFloat, /)
Mike Kleine7007382019-05-21 08:36:32 -0500427
428 case ByteCodeInstruction::kDup4: PUSH(sp[(int)ByteCodeInstruction::kDup - (int)inst]);
429 case ByteCodeInstruction::kDup3: PUSH(sp[(int)ByteCodeInstruction::kDup - (int)inst]);
430 case ByteCodeInstruction::kDup2: PUSH(sp[(int)ByteCodeInstruction::kDup - (int)inst]);
431 case ByteCodeInstruction::kDup : PUSH(sp[(int)ByteCodeInstruction::kDup - (int)inst]);
432 break;
433
Brian Osman07c117b2019-05-23 12:51:06 -0700434 case ByteCodeInstruction::kDupN: {
435 int count = READ8();
436 memcpy(sp + 1, sp - count + 1, count * sizeof(Value));
437 sp += count;
438 break;
439 }
440
Mike Kleine7007382019-05-21 08:36:32 -0500441 case ByteCodeInstruction::kLoad4: sp[4] = stack[*ip + 3];
442 case ByteCodeInstruction::kLoad3: sp[3] = stack[*ip + 2];
443 case ByteCodeInstruction::kLoad2: sp[2] = stack[*ip + 1];
444 case ByteCodeInstruction::kLoad : sp[1] = stack[*ip + 0];
445 ++ip;
446 sp += (int)inst - (int)ByteCodeInstruction::kLoad + 1;
447 break;
448
Brian Osman80164412019-06-07 13:00:23 -0400449 case ByteCodeInstruction::kLoadGlobal4: sp[4] = globals[*ip + 3];
450 case ByteCodeInstruction::kLoadGlobal3: sp[3] = globals[*ip + 2];
451 case ByteCodeInstruction::kLoadGlobal2: sp[2] = globals[*ip + 1];
452 case ByteCodeInstruction::kLoadGlobal : sp[1] = globals[*ip + 0];
Mike Kleine7007382019-05-21 08:36:32 -0500453 ++ip;
Brian Osman07c117b2019-05-23 12:51:06 -0700454 sp += (int)inst -
455 (int)ByteCodeInstruction::kLoadGlobal + 1;
Mike Kleine7007382019-05-21 08:36:32 -0500456 break;
457
Brian Osman07c117b2019-05-23 12:51:06 -0700458 case ByteCodeInstruction::kLoadExtended: {
459 int count = READ8();
460 int src = POP().fSigned;
461 memcpy(sp + 1, &stack[src], count * sizeof(Value));
462 sp += count;
463 break;
464 }
465
466 case ByteCodeInstruction::kLoadExtendedGlobal: {
467 int count = READ8();
468 int src = POP().fSigned;
Brian Osman80164412019-06-07 13:00:23 -0400469 SkASSERT(src + count <= globalCount);
470 memcpy(sp + 1, &globals[src], count * sizeof(Value));
Brian Osman07c117b2019-05-23 12:51:06 -0700471 sp += count;
472 break;
473 }
474
Mike Kleine7007382019-05-21 08:36:32 -0500475 case ByteCodeInstruction::kLoadSwizzle: {
476 int src = READ8();
477 int count = READ8();
Ethan Nicholas9764ebd2019-05-01 14:43:54 -0400478 for (int i = 0; i < count; ++i) {
Ethan Nicholas48a75aa2019-05-16 17:15:56 -0400479 PUSH(stack[src + *(ip + i)]);
Ethan Nicholas9764ebd2019-05-01 14:43:54 -0400480 }
Ethan Nicholas7e603db2019-05-03 12:57:47 -0400481 ip += count;
Ethan Nicholas9764ebd2019-05-01 14:43:54 -0400482 break;
Mike Kleine7007382019-05-21 08:36:32 -0500483 }
Ethan Nicholas82162ee2019-05-21 16:05:08 -0400484
Mike Kleine7007382019-05-21 08:36:32 -0500485 case ByteCodeInstruction::kLoadSwizzleGlobal: {
486 int src = READ8();
Mike Kleine7007382019-05-21 08:36:32 -0500487 int count = READ8();
Brian Osmanb7451292019-05-15 13:02:13 -0400488 for (int i = 0; i < count; ++i) {
Brian Osman80164412019-06-07 13:00:23 -0400489 SkASSERT(src + *(ip + i) < globalCount);
490 PUSH(globals[src + *(ip + i)]);
Brian Osmanb7451292019-05-15 13:02:13 -0400491 }
492 ip += count;
493 break;
Mike Kleine7007382019-05-21 08:36:32 -0500494 }
Ethan Nicholas82162ee2019-05-21 16:05:08 -0400495
Brian Osman29e013d2019-05-28 17:16:03 -0400496 case ByteCodeInstruction::kMatrixToMatrix: {
497 int srcCols = READ8();
498 int srcRows = READ8();
499 int dstCols = READ8();
500 int dstRows = READ8();
501 SkASSERT(srcCols >= 2 && srcCols <= 4);
502 SkASSERT(srcRows >= 2 && srcRows <= 4);
503 SkASSERT(dstCols >= 2 && dstCols <= 4);
504 SkASSERT(dstRows >= 2 && dstRows <= 4);
505 SkMatrix44 m;
506 for (int c = srcCols - 1; c >= 0; --c) {
507 for (int r = srcRows - 1; r >= 0; --r) {
508 m.set(r, c, POP().fFloat);
509 }
510 }
511 for (int c = 0; c < dstCols; ++c) {
512 for (int r = 0; r < dstRows; ++r) {
513 PUSH(m.get(r, c));
514 }
515 }
516 break;
517 }
518
Brian Osman909231c2019-05-29 15:34:36 -0400519 case ByteCodeInstruction::kMatrixMultiply: {
520 int lCols = READ8();
521 int lRows = READ8();
522 int rCols = READ8();
523 int rRows = lCols;
524 float tmp[16] = { 0.0f };
525 float* B = &(sp - (rCols * rRows) + 1)->fFloat;
526 float* A = B - (lCols * lRows);
527 for (int c = 0; c < rCols; ++c) {
528 for (int r = 0; r < lRows; ++r) {
529 for (int j = 0; j < lCols; ++j) {
530 tmp[c*lRows + r] += A[j*lRows + r] * B[c*rRows + j];
531 }
532 }
533 }
534 sp -= (lCols * lRows) + (rCols * rRows);
535 memcpy(sp + 1, tmp, rCols * lRows * sizeof(Value));
536 sp += (rCols * lRows);
537 break;
538 }
539
Ethan Nicholasae9633b2019-05-24 12:46:34 -0400540 // stack looks like: X1 Y1 Z1 W1 X2 Y2 Z2 W2 T
541 case ByteCodeInstruction::kMix4:
542 sp[-5] = mix(sp[-5].fFloat, sp[-1].fFloat, sp[0].fFloat);
543 // fall through
544 case ByteCodeInstruction::kMix3: {
545 int count = (int) inst - (int) ByteCodeInstruction::kMix + 1;
546 int target = 2 - count * 2;
547 sp[target] = mix(sp[target].fFloat, sp[2 - count].fFloat, sp[0].fFloat);
548 // fall through
549 }
550 case ByteCodeInstruction::kMix2: {
551 int count = (int) inst - (int) ByteCodeInstruction::kMix + 1;
552 int target = 1 - count * 2;
553 sp[target] = mix(sp[target].fFloat, sp[1 - count].fFloat, sp[0].fFloat);
554 // fall through
555 }
556 case ByteCodeInstruction::kMix: {
557 int count = (int) inst - (int) ByteCodeInstruction::kMix + 1;
558 int target = -count * 2;
559 sp[target] = mix(sp[target].fFloat, sp[-count].fFloat, sp[0].fFloat);
560 sp -= 1 + count;
561 break;
562 }
563
Mike Kleinc1999982019-05-21 13:03:49 -0500564 VECTOR_BINARY_OP(kMultiplyI, fSigned, *)
Brian Osman1e855b22019-05-29 15:21:52 -0400565 VECTOR_MATRIX_BINARY_OP(kMultiplyF, fFloat, *)
Ethan Nicholas82162ee2019-05-21 16:05:08 -0400566
Ethan Nicholas48a75aa2019-05-16 17:15:56 -0400567 case ByteCodeInstruction::kNot:
Mike Kleine7007382019-05-21 08:36:32 -0500568 sp[0].fBool = !sp[0].fBool;
Ethan Nicholas9764ebd2019-05-01 14:43:54 -0400569 break;
Mike Kleine7007382019-05-21 08:36:32 -0500570
Mike Kleinc1999982019-05-21 13:03:49 -0500571 case ByteCodeInstruction::kNegateF4: sp[-3] = -sp[-3].fFloat;
572 case ByteCodeInstruction::kNegateF3: sp[-2] = -sp[-2].fFloat;
573 case ByteCodeInstruction::kNegateF2: sp[-1] = -sp[-1].fFloat;
574 case ByteCodeInstruction::kNegateF : sp[ 0] = -sp[ 0].fFloat;
Mike Kleine7007382019-05-21 08:36:32 -0500575 break;
576
Brian Osman1e855b22019-05-29 15:21:52 -0400577 case ByteCodeInstruction::kNegateFN: {
578 int count = READ8();
579 for (int i = count - 1; i >= 0; --i) {
580 sp[-i] = -sp[-i].fFloat;
581 }
582 break;
583 }
584
Mike Kleinc1999982019-05-21 13:03:49 -0500585 case ByteCodeInstruction::kNegateI4: sp[-3] = -sp[-3].fSigned;
586 case ByteCodeInstruction::kNegateI3: sp[-2] = -sp[-2].fSigned;
587 case ByteCodeInstruction::kNegateI2: sp[-1] = -sp[-1].fSigned;
588 case ByteCodeInstruction::kNegateI : sp[ 0] = -sp [0].fSigned;
Mike Kleine7007382019-05-21 08:36:32 -0500589 break;
590
Brian Osman32c526b2019-06-03 16:13:52 -0400591 case ByteCodeInstruction::kOrB:
592 sp[-1] = sp[-1].fBool || sp[0].fBool;
593 POP();
594 break;
Brian Osman16e6fd52019-05-29 11:19:00 -0400595
Mike Kleine7007382019-05-21 08:36:32 -0500596 case ByteCodeInstruction::kPop4: POP();
597 case ByteCodeInstruction::kPop3: POP();
598 case ByteCodeInstruction::kPop2: POP();
599 case ByteCodeInstruction::kPop : POP();
600 break;
601
Brian Osman07c117b2019-05-23 12:51:06 -0700602 case ByteCodeInstruction::kPopN:
603 sp -= READ8();
604 break;
605
Ethan Nicholas9764ebd2019-05-01 14:43:54 -0400606 case ByteCodeInstruction::kPushImmediate:
Mike Kleine7007382019-05-21 08:36:32 -0500607 PUSH(READ32());
Ethan Nicholas9764ebd2019-05-01 14:43:54 -0400608 break;
Ethan Nicholas82162ee2019-05-21 16:05:08 -0400609
Ethan Nicholas48a75aa2019-05-16 17:15:56 -0400610 case ByteCodeInstruction::kReadExternal: // fall through
611 case ByteCodeInstruction::kReadExternal2: // fall through
612 case ByteCodeInstruction::kReadExternal3: // fall through
Mike Kleine7007382019-05-21 08:36:32 -0500613 case ByteCodeInstruction::kReadExternal4: {
614 int src = READ8();
Brian Osman80164412019-06-07 13:00:23 -0400615 byteCode->fExternalValues[src]->read(sp + 1);
Mike Kleine7007382019-05-21 08:36:32 -0500616 sp += (int) inst - (int) ByteCodeInstruction::kReadExternal + 1;
Ethan Nicholas91164d12019-05-15 15:29:54 -0400617 break;
Mike Kleine7007382019-05-21 08:36:32 -0500618 }
Ethan Nicholas82162ee2019-05-21 16:05:08 -0400619
Mike Kleinc1999982019-05-21 13:03:49 -0500620 VECTOR_BINARY_FN(kRemainderF, fFloat, fmodf)
621 VECTOR_BINARY_OP(kRemainderS, fSigned, %)
622 VECTOR_BINARY_OP(kRemainderU, fUnsigned, %)
Ethan Nicholas82162ee2019-05-21 16:05:08 -0400623
Mike Kleine7007382019-05-21 08:36:32 -0500624 case ByteCodeInstruction::kReturn: {
625 int count = READ8();
Brian Osman226668a2019-05-14 16:47:30 -0400626 if (frames.empty()) {
627 if (outReturn) {
628 memcpy(outReturn, sp - count + 1, count * sizeof(Value));
629 }
630 return;
631 } else {
632 // When we were called, 'stack' was positioned at the old top-of-stack (where
633 // our parameters were placed). So copy our return values to that same spot.
634 memmove(stack, sp - count + 1, count * sizeof(Value));
635
636 // Now move the stack pointer to the end of the just-pushed return values,
637 // and restore everything else.
638 const StackFrame& frame(frames.back());
639 sp = stack + count - 1;
640 stack = frame.fStack;
641 code = frame.fCode;
642 ip = frame.fIP;
643 frames.pop_back();
644 break;
Ethan Nicholas9764ebd2019-05-01 14:43:54 -0400645 }
Mike Kleine7007382019-05-21 08:36:32 -0500646 }
647
Brian Osman29e013d2019-05-28 17:16:03 -0400648 case ByteCodeInstruction::kScalarToMatrix: {
649 int cols = READ8();
650 int rows = READ8();
651 Value v = POP();
652 for (int c = 0; c < cols; ++c) {
653 for (int r = 0; r < rows; ++r) {
654 PUSH(c == r ? v : 0.0f);
655 }
656 }
657 break;
658 }
659
Mike Klein459aed12019-05-21 15:46:36 -0500660 VECTOR_UNARY_FN(kSin, sinf, fFloat)
661 VECTOR_UNARY_FN(kSqrt, sqrtf, fFloat)
Ethan Nicholas82162ee2019-05-21 16:05:08 -0400662
Mike Kleine7007382019-05-21 08:36:32 -0500663 case ByteCodeInstruction::kStore4: stack[*ip + 3] = POP();
664 case ByteCodeInstruction::kStore3: stack[*ip + 2] = POP();
665 case ByteCodeInstruction::kStore2: stack[*ip + 1] = POP();
666 case ByteCodeInstruction::kStore : stack[*ip + 0] = POP();
667 ++ip;
668 break;
669
Brian Osman80164412019-06-07 13:00:23 -0400670 case ByteCodeInstruction::kStoreGlobal4: globals[*ip + 3] = POP();
671 case ByteCodeInstruction::kStoreGlobal3: globals[*ip + 2] = POP();
672 case ByteCodeInstruction::kStoreGlobal2: globals[*ip + 1] = POP();
673 case ByteCodeInstruction::kStoreGlobal : globals[*ip + 0] = POP();
Mike Kleine7007382019-05-21 08:36:32 -0500674 ++ip;
675 break;
676
Brian Osman07c117b2019-05-23 12:51:06 -0700677 case ByteCodeInstruction::kStoreExtended: {
678 int count = READ8();
679 int target = POP().fSigned;
680 memcpy(&stack[target], sp - count + 1, count * sizeof(Value));
681 sp -= count;
682 break;
683 }
684 case ByteCodeInstruction::kStoreExtendedGlobal: {
685 int count = READ8();
686 int target = POP().fSigned;
Brian Osman80164412019-06-07 13:00:23 -0400687 SkASSERT(target + count <= globalCount);
688 memcpy(&globals[target], sp - count + 1, count * sizeof(Value));
Brian Osman07c117b2019-05-23 12:51:06 -0700689 sp -= count;
690 break;
691 }
692
Mike Kleine7007382019-05-21 08:36:32 -0500693 case ByteCodeInstruction::kStoreSwizzle: {
694 int target = READ8();
695 int count = READ8();
Ethan Nicholas9764ebd2019-05-01 14:43:54 -0400696 for (int i = count - 1; i >= 0; --i) {
Ethan Nicholasdfcad062019-05-07 12:53:34 -0400697 stack[target + *(ip + i)] = POP();
Ethan Nicholas9764ebd2019-05-01 14:43:54 -0400698 }
Brian Osman1091f022019-05-16 09:42:16 -0400699 ip += count;
700 break;
Mike Kleine7007382019-05-21 08:36:32 -0500701 }
Ethan Nicholas82162ee2019-05-21 16:05:08 -0400702
Mike Kleine7007382019-05-21 08:36:32 -0500703 case ByteCodeInstruction::kStoreSwizzleGlobal: {
704 int target = READ8();
705 int count = READ8();
Brian Osman1091f022019-05-16 09:42:16 -0400706 for (int i = count - 1; i >= 0; --i) {
Brian Osman80164412019-06-07 13:00:23 -0400707 globals[target + *(ip + i)] = POP();
Brian Osman1091f022019-05-16 09:42:16 -0400708 }
Ethan Nicholas7e603db2019-05-03 12:57:47 -0400709 ip += count;
Ethan Nicholas9764ebd2019-05-01 14:43:54 -0400710 break;
Mike Kleine7007382019-05-21 08:36:32 -0500711 }
Brian Osman07c117b2019-05-23 12:51:06 -0700712 case ByteCodeInstruction::kStoreSwizzleIndirect: {
713 int target = POP().fSigned;
714 int count = READ8();
715 for (int i = count - 1; i >= 0; --i) {
716 stack[target + *(ip + i)] = POP();
717 }
718 ip += count;
719 break;
720 }
721 case ByteCodeInstruction::kStoreSwizzleIndirectGlobal: {
722 int target = POP().fSigned;
723 int count = READ8();
724 for (int i = count - 1; i >= 0; --i) {
Brian Osman80164412019-06-07 13:00:23 -0400725 globals[target + *(ip + i)] = POP();
Brian Osman07c117b2019-05-23 12:51:06 -0700726 }
727 ip += count;
728 break;
729 }
Ethan Nicholas82162ee2019-05-21 16:05:08 -0400730
Mike Kleinc1999982019-05-21 13:03:49 -0500731 VECTOR_BINARY_OP(kSubtractI, fSigned, -)
Brian Osman1e855b22019-05-29 15:21:52 -0400732 VECTOR_MATRIX_BINARY_OP(kSubtractF, fFloat, -)
Ethan Nicholas82162ee2019-05-21 16:05:08 -0400733
Mike Kleine7007382019-05-21 08:36:32 -0500734 case ByteCodeInstruction::kSwizzle: {
735 Value tmp[4];
Ethan Nicholas7e603db2019-05-03 12:57:47 -0400736 for (int i = READ8() - 1; i >= 0; --i) {
Ethan Nicholas48a75aa2019-05-16 17:15:56 -0400737 tmp[i] = POP();
Ethan Nicholas9764ebd2019-05-01 14:43:54 -0400738 }
Ethan Nicholas7e603db2019-05-03 12:57:47 -0400739 for (int i = READ8() - 1; i >= 0; --i) {
Ethan Nicholas48a75aa2019-05-16 17:15:56 -0400740 PUSH(tmp[READ8()]);
Ethan Nicholas9764ebd2019-05-01 14:43:54 -0400741 }
742 break;
Mike Kleine7007382019-05-21 08:36:32 -0500743 }
Ethan Nicholas82162ee2019-05-21 16:05:08 -0400744
Mike Klein459aed12019-05-21 15:46:36 -0500745 VECTOR_UNARY_FN(kTan, tanf, fFloat)
Ethan Nicholas82162ee2019-05-21 16:05:08 -0400746
Ethan Nicholas48a75aa2019-05-16 17:15:56 -0400747 case ByteCodeInstruction::kWriteExternal: // fall through
748 case ByteCodeInstruction::kWriteExternal2: // fall through
749 case ByteCodeInstruction::kWriteExternal3: // fall through
Mike Kleine7007382019-05-21 08:36:32 -0500750 case ByteCodeInstruction::kWriteExternal4: {
751 int count = (int) inst - (int) ByteCodeInstruction::kWriteExternal + 1;
752 int target = READ8();
Brian Osman80164412019-06-07 13:00:23 -0400753 byteCode->fExternalValues[target]->write(sp - count + 1);
Ethan Nicholas48a75aa2019-05-16 17:15:56 -0400754 sp -= count;
Ethan Nicholas9764ebd2019-05-01 14:43:54 -0400755 break;
Mike Kleine7007382019-05-21 08:36:32 -0500756 }
Ethan Nicholas82162ee2019-05-21 16:05:08 -0400757
Ethan Nicholas9764ebd2019-05-01 14:43:54 -0400758 default:
Mike Kleine7007382019-05-21 08:36:32 -0500759 SkDEBUGFAILF("unsupported instruction %d\n", (int) inst);
Ethan Nicholas9764ebd2019-05-01 14:43:54 -0400760 }
761#ifdef TRACE
Mike Kleine7007382019-05-21 08:36:32 -0500762 int stackSize = (int) (sp - stack + 1);
763 printf("STACK(%d):", stackSize);
Ethan Nicholas82162ee2019-05-21 16:05:08 -0400764 for (int i = 0; i < stackSize; ++i) {
Brian Osmane85b6a52019-05-22 14:50:59 -0700765 printf(" %d(%g)", stack[i].fSigned, stack[i].fFloat);
Ethan Nicholasdfcad062019-05-07 12:53:34 -0400766 }
767 printf("\n");
Ethan Nicholas9764ebd2019-05-01 14:43:54 -0400768#endif
Ethan Nicholas0e9401d2019-03-21 11:05:37 -0400769 }
Ethan Nicholas26a9aad2018-03-27 14:10:52 -0400770}
771
Brian Osman80164412019-06-07 13:00:23 -0400772void Run(const ByteCode* byteCode, const ByteCodeFunction* f, Value args[], Value* outReturn,
773 Value uniforms[], int uniformCount) {
774#ifdef TRACE
775 disassemble(f);
776#endif
777 Value smallStack[128];
778 std::unique_ptr<Value[]> largeStack;
779 Value* stack = smallStack;
780 if ((int)SK_ARRAY_COUNT(smallStack) < f->fStackCount) {
781 largeStack.reset(new Value[f->fStackCount]);
782 stack = largeStack.get();
783 }
784
785 if (f->fParameterCount) {
786 memcpy(stack, args, f->fParameterCount * sizeof(Value));
787 }
788
789 SkASSERT(uniformCount == (int)byteCode->fInputSlots.size());
790 Value smallGlobals[32];
791 std::unique_ptr<Value[]> largeGlobals;
792 Value* globals = smallGlobals;
793 if ((int)SK_ARRAY_COUNT(smallGlobals) < byteCode->fGlobalCount) {
794 largeGlobals.reset(new Value[byteCode->fGlobalCount]);
795 globals = largeGlobals.get();
796 }
797 for (uint8_t slot : byteCode->fInputSlots) {
798 globals[slot] = *uniforms++;
799 }
800 innerRun(byteCode, f, stack, outReturn, globals, byteCode->fGlobalCount);
801
802 for (const auto& p : f->fParameters) {
803 if (p.fIsOutParameter) {
804 memcpy(args, stack, p.fSlotCount * sizeof(Value));
805 }
806 args += p.fSlotCount;
807 stack += p.fSlotCount;
808 }
809}
810
811} // namespace Interpreter
812} // namespace SkSL
Ethan Nicholas26a9aad2018-03-27 14:10:52 -0400813
814#endif