diff --git a/src/boot/errors.r b/src/boot/errors.r index 6c9f4f8cbc..3fe988b54b 100644 --- a/src/boot/errors.r +++ b/src/boot/errors.r @@ -190,6 +190,7 @@ Access: [ permission-denied: [{permission denied}] process-not-found: [{process not found:} :arg1] + symbol-not-found: [{symbol not found:} :arg1] ] Command: [ diff --git a/src/boot/words.r b/src/boot/words.r index b443c79718..751aa88a62 100644 --- a/src/boot/words.r +++ b/src/boot/words.r @@ -190,6 +190,7 @@ pointer addr raw-memory raw-size +extern rebval ;routine diff --git a/src/core/t-struct.c b/src/core/t-struct.c index cf28273140..005b0f53ba 100644 --- a/src/core/t-struct.c +++ b/src/core/t-struct.c @@ -436,6 +436,37 @@ static void parse_attr (REBVAL *blk, REBINT *raw_size, REBUPT *raw_addr) Trap_Arg(attr); } break; + case SYM_EXTERN: + ++ attr; + + if (*raw_addr != 0) /* raw-memory is exclusive with extern */ + Trap_Arg(attr); + + if (!IS_BLOCK(attr) + || VAL_LEN(attr) != 2) { + Trap_Arg(attr); + } else { + REBVAL *lib; + REBVAL *sym; + void *addr; + + lib = VAL_BLK_SKIP(attr, 0); + sym = VAL_BLK_SKIP(attr, 1); + + if (!IS_LIBRARY(lib)) + Trap_Arg(attr); + if (IS_CLOSED_LIB(VAL_LIB_HANDLE(lib))) + Trap0(RE_BAD_LIBRARY); + if (!ANY_BINSTR(sym)) + Trap_Arg(sym); + + addr = OS_FIND_FUNCTION(LIB_FD(VAL_LIB_HANDLE(lib)), VAL_DATA(sym)); + if (!addr) + Trap1(RE_SYMBOL_NOT_FOUND, sym); + + *raw_addr = (REBUPT)addr; + } + break; /* case SYM_ALIGNMENT: ++ attr;