Skip to content

Commit ee51a89

Browse files
committed
Refactor printf/scanf
1 parent c6256a4 commit ee51a89

File tree

5 files changed

+55
-59
lines changed

5 files changed

+55
-59
lines changed

playground/umka.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/umka_expr.c

+4-18
Original file line numberDiff line numberDiff line change
@@ -794,8 +794,7 @@ static void parseBuiltinIOCall(Compiler *comp, Type **type, Const *constant, Bui
794794
if (constant)
795795
comp->error.handler(comp->error.context, "Function is not allowed in constant expressions");
796796

797-
// printf() parameters: count, stream, format, value, type
798-
// scanf() parameters: count, stream, format, value
797+
// Parameters: count, stream, format, value
799798

800799
// Count (number of characters for printf(), number of items for scanf())
801800
genPushIntConst(&comp->gen, 0);
@@ -827,31 +826,18 @@ static void parseBuiltinIOCall(Compiler *comp, Type **type, Const *constant, Bui
827826
if (builtin == BUILTIN_PRINTF || builtin == BUILTIN_FPRINTF || builtin == BUILTIN_SPRINTF)
828827
{
829828
typeAssertCompatibleBuiltin(&comp->types, *type, builtin, (*type)->kind != TYPE_VOID);
830-
genPushGlobalPtr(&comp->gen, *type); // Push type
831-
genCallBuiltin(&comp->gen, (*type)->kind, builtin);
832-
genPop(&comp->gen); // Remove type
829+
genCallTypedBuiltin(&comp->gen, *type, builtin);
833830
}
834831
else // BUILTIN_SCANF, BUILTIN_FSCANF, BUILTIN_SSCANF
835832
{
836833
typeAssertCompatibleBuiltin(&comp->types, *type, builtin, (*type)->kind == TYPE_PTR && (typeOrdinal((*type)->base) || typeReal((*type)->base) || (*type)->base->kind == TYPE_STR));
837-
genCallBuiltin(&comp->gen, (*type)->base->kind, builtin);
834+
genCallTypedBuiltin(&comp->gen, (*type)->base, builtin);
838835
}
839-
genPop(&comp->gen); // Remove parameter
840-
841836
} // while
842837

843838
// The rest of format string
844839
genPushIntConst(&comp->gen, 0);
845-
if (builtin == BUILTIN_PRINTF || builtin == BUILTIN_FPRINTF || builtin == BUILTIN_SPRINTF)
846-
{
847-
genPushGlobalPtr(&comp->gen, comp->voidType); // Push type
848-
genCallBuiltin(&comp->gen, TYPE_VOID, builtin);
849-
genPop(&comp->gen); // Remove type
850-
}
851-
else
852-
genCallBuiltin(&comp->gen, TYPE_VOID, builtin);
853-
854-
genPop(&comp->gen); // Remove parameter
840+
genCallTypedBuiltin(&comp->gen, comp->voidType, builtin);
855841

856842
genPop(&comp->gen); // Remove format string
857843

src/umka_gen.c

+10
Original file line numberDiff line numberDiff line change
@@ -771,6 +771,16 @@ void genCallBuiltin(CodeGen *gen, TypeKind typeKind, BuiltinFunc builtin)
771771
}
772772

773773

774+
void genCallTypedBuiltin(CodeGen *gen, Type *type, BuiltinFunc builtin)
775+
{
776+
if (!optimizeCallBuiltin(gen, type->kind, builtin))
777+
{
778+
const Instruction instr = {.opcode = OP_CALL_BUILTIN, .tokKind = TOK_NONE, .type = type, .operand.builtinVal = builtin};
779+
genAddInstr(gen, &instr);
780+
}
781+
}
782+
783+
774784
void genReturn(CodeGen *gen, int paramSlots)
775785
{
776786
const Instruction instr = {.opcode = OP_RETURN, .tokKind = TOK_NONE, .typeKind = TYPE_NONE, .operand.intVal = paramSlots};

src/umka_gen.h

+10-9
Original file line numberDiff line numberDiff line change
@@ -91,15 +91,16 @@ void genAssertRange (CodeGen *gen, TypeKind typeKind);
9191
void genWeakenPtr (CodeGen *gen);
9292
void genStrengthenPtr(CodeGen *gen);
9393

94-
void genGoto (CodeGen *gen, int dest);
95-
void genGotoIf(CodeGen *gen, int dest);
96-
void genGotoIfNot(CodeGen *gen, int dest);
97-
98-
void genCall (CodeGen *gen, int entry);
99-
void genCallIndirect(CodeGen *gen, int paramSlots);
100-
void genCallExtern (CodeGen *gen, void *entry);
101-
void genCallBuiltin (CodeGen *gen, TypeKind typeKind, BuiltinFunc builtin);
102-
void genReturn (CodeGen *gen, int paramSlots);
94+
void genGoto (CodeGen *gen, int dest);
95+
void genGotoIf (CodeGen *gen, int dest);
96+
void genGotoIfNot (CodeGen *gen, int dest);
97+
98+
void genCall (CodeGen *gen, int entry);
99+
void genCallIndirect (CodeGen *gen, int paramSlots);
100+
void genCallExtern (CodeGen *gen, void *entry);
101+
void genCallBuiltin (CodeGen *gen, TypeKind typeKind, BuiltinFunc builtin);
102+
void genCallTypedBuiltin (CodeGen *gen, Type *type, BuiltinFunc builtin);
103+
void genReturn (CodeGen *gen, int paramSlots);
103104

104105
void genEnterFrame(CodeGen *gen, int localVarSlots);
105106
void genLeaveFrame(CodeGen *gen);

src/umka_vm.c

+30-31
Original file line numberDiff line numberDiff line change
@@ -1687,16 +1687,23 @@ static FORCE_INLINE int doPrintSlot(bool string, void *stream, int maxLen, const
16871687
}
16881688

16891689

1690-
static FORCE_INLINE void doBuiltinPrintf(Fiber *fiber, HeapPages *pages, bool console, bool string, Error *error)
1690+
enum
16911691
{
1692-
enum {STACK_OFFSET_COUNT = 4, STACK_OFFSET_STREAM = 3, STACK_OFFSET_FORMAT = 2, STACK_OFFSET_VALUE = 1, STACK_OFFSET_TYPE = 0};
1692+
STACK_OFFSET_COUNT = 3,
1693+
STACK_OFFSET_STREAM = 2,
1694+
STACK_OFFSET_FORMAT = 1,
1695+
STACK_OFFSET_VALUE = 0
1696+
};
16931697

1698+
1699+
static FORCE_INLINE void doBuiltinPrintf(Fiber *fiber, HeapPages *pages, bool console, bool string, Error *error)
1700+
{
16941701
const int prevLen = fiber->top[STACK_OFFSET_COUNT].intVal;
16951702
void *stream = console ? stdout : fiber->top[STACK_OFFSET_STREAM].ptrVal;
16961703
const char *format = (const char *)fiber->top[STACK_OFFSET_FORMAT].ptrVal;
16971704
Slot value = fiber->top[STACK_OFFSET_VALUE];
1698-
Type *type = (Type *)fiber->top[STACK_OFFSET_TYPE].ptrVal;
16991705

1706+
Type *type = fiber->code[fiber->ip].type;
17001707
TypeKind typeKind = type->kind;
17011708

17021709
if (!string && (!stream || (!fiber->fileSystemEnabled && !console)))
@@ -1815,6 +1822,8 @@ static FORCE_INLINE void doBuiltinPrintf(Fiber *fiber, HeapPages *pages, bool co
18151822
fiber->top[STACK_OFFSET_COUNT].intVal += len;
18161823
fiber->top[STACK_OFFSET_STREAM].ptrVal = stream;
18171824

1825+
fiber->top++; // Remove value
1826+
18181827
if (isCurFormatBufInHeap)
18191828
free(curFormat);
18201829

@@ -1825,11 +1834,12 @@ static FORCE_INLINE void doBuiltinPrintf(Fiber *fiber, HeapPages *pages, bool co
18251834

18261835
static FORCE_INLINE void doBuiltinScanf(Fiber *fiber, HeapPages *pages, bool console, bool string, Error *error)
18271836
{
1828-
enum {STACK_OFFSET_COUNT = 3, STACK_OFFSET_STREAM = 2, STACK_OFFSET_FORMAT = 1, STACK_OFFSET_VALUE = 0};
1829-
18301837
void *stream = console ? stdin : (void *)fiber->top[STACK_OFFSET_STREAM].ptrVal;
18311838
const char *format = (const char *)fiber->top[STACK_OFFSET_FORMAT].ptrVal;
1832-
TypeKind typeKind = fiber->code[fiber->ip].typeKind;
1839+
Slot value = fiber->top[STACK_OFFSET_VALUE];
1840+
1841+
Type *type = fiber->code[fiber->ip].type;
1842+
TypeKind typeKind = type->kind;
18331843

18341844
if (!stream || (!fiber->fileSystemEnabled && !console && !string))
18351845
error->runtimeHandler(error->context, VM_RUNTIME_ERROR, "scanf() source is null");
@@ -1863,14 +1873,14 @@ static FORCE_INLINE void doBuiltinScanf(Fiber *fiber, HeapPages *pages, bool con
18631873
cnt = fsscanf(string, stream, curFormat, &len);
18641874
else
18651875
{
1866-
if (!fiber->top->ptrVal)
1876+
if (!value.ptrVal)
18671877
error->runtimeHandler(error->context, VM_RUNTIME_ERROR, "scanf() destination is null");
18681878

18691879
// Strings need special handling, as the required buffer size is unknown
18701880
if (typeKind == TYPE_STR)
18711881
{
18721882
char *src = fsscanfString(string, stream, &len);
1873-
char **dest = (char **)fiber->top->ptrVal;
1883+
char **dest = (char **)value.ptrVal;
18741884

18751885
// Decrease old string ref count
18761886
Type destType = {.kind = TYPE_STR};
@@ -1884,14 +1894,16 @@ static FORCE_INLINE void doBuiltinScanf(Fiber *fiber, HeapPages *pages, bool con
18841894
cnt = (*dest)[0] ? 1 : 0;
18851895
}
18861896
else
1887-
cnt = fsscanf(string, stream, curFormat, (void *)fiber->top->ptrVal, &len);
1897+
cnt = fsscanf(string, stream, curFormat, (void *)value.ptrVal, &len);
18881898
}
18891899

18901900
fiber->top[STACK_OFFSET_FORMAT].ptrVal = (char *)fiber->top[STACK_OFFSET_FORMAT].ptrVal + formatLen;
18911901
fiber->top[STACK_OFFSET_COUNT].intVal += cnt;
18921902
if (string)
18931903
fiber->top[STACK_OFFSET_STREAM].ptrVal = (char *)fiber->top[STACK_OFFSET_STREAM].ptrVal + len;
18941904

1905+
fiber->top++; // Remove value
1906+
18951907
if (isCurFormatBufInHeap)
18961908
free(curFormat);
18971909
}
@@ -3761,7 +3773,12 @@ int vmAsm(int ip, Instruction *code, DebugInfo *debugPerInstr, char *buf, int si
37613773
if (instr->tokKind != TOK_NONE)
37623774
chars += snprintf(buf + chars, nonneg(size - chars), " %s", lexSpelling(instr->tokKind));
37633775

3764-
if (instr->typeKind != TYPE_NONE)
3776+
if (instr->type)
3777+
{
3778+
char typeBuf[DEFAULT_STR_LEN + 1];
3779+
chars += snprintf(buf + chars, nonneg(size - chars), " %s", typeSpelling(instr->type, typeBuf));
3780+
}
3781+
else if (instr->typeKind != TYPE_NONE)
37653782
chars += snprintf(buf + chars, nonneg(size - chars), " %s", typeKindSpelling(instr->typeKind));
37663783

37673784
switch (instr->opcode)
@@ -3786,6 +3803,7 @@ int vmAsm(int ip, Instruction *code, DebugInfo *debugPerInstr, char *buf, int si
37863803
case OP_ZERO:
37873804
case OP_ASSIGN:
37883805
case OP_BINARY:
3806+
case OP_CHANGE_REF_CNT_LOCAL:
37893807
case OP_GET_FIELD_PTR:
37903808
case OP_GOTO:
37913809
case OP_GOTO_IF:
@@ -3801,29 +3819,10 @@ int vmAsm(int ip, Instruction *code, DebugInfo *debugPerInstr, char *buf, int si
38013819
}
38023820
case OP_PUSH_LOCAL_PTR_ZERO:
38033821
case OP_GET_ARRAY_PTR: chars += snprintf(buf + chars, nonneg(size - chars), " %d %d", (int)instr->operand.int32Val[0], (int)instr->operand.int32Val[1]); break;
3822+
case OP_CHANGE_REF_CNT_GLOBAL:
38043823
case OP_CALL_EXTERN: chars += snprintf(buf + chars, nonneg(size - chars), " %p", instr->operand.ptrVal); break;
38053824
case OP_CALL_BUILTIN: chars += snprintf(buf + chars, nonneg(size - chars), " %s", builtinSpelling[instr->operand.builtinVal]); break;
3806-
case OP_CHANGE_REF_CNT:
3807-
case OP_CHANGE_REF_CNT_ASSIGN:
3808-
case OP_GET_MAP_PTR:
3809-
case OP_ASSERT_TYPE:
3810-
{
3811-
char typeBuf[DEFAULT_STR_LEN + 1];
3812-
chars += snprintf(buf + chars, nonneg(size - chars), " %s", typeSpelling(instr->type, typeBuf));
3813-
break;
3814-
}
3815-
case OP_CHANGE_REF_CNT_GLOBAL:
3816-
{
3817-
char typeBuf[DEFAULT_STR_LEN + 1];
3818-
chars += snprintf(buf + chars, nonneg(size - chars), " %p %s", instr->operand.ptrVal, typeSpelling(instr->type, typeBuf));
3819-
break;
3820-
}
3821-
case OP_CHANGE_REF_CNT_LOCAL:
3822-
{
3823-
char typeBuf[DEFAULT_STR_LEN + 1];
3824-
chars += snprintf(buf + chars, nonneg(size - chars), " %lld %s", (long long int)instr->operand.intVal, typeSpelling(instr->type, typeBuf));
3825-
break;
3826-
}
3825+
38273826
default: break;
38283827
}
38293828

0 commit comments

Comments
 (0)