Changeset 70
- Timestamp:
- 01/20/07 10:41:16 (22 months ago)
- Location:
- NEWT0/trunk/contrib
- Files:
-
- 4 modified
-
NativeCalls/Makefile (modified) (2 diffs)
-
NativeCalls/NativeCalls.c (modified) (22 diffs)
-
NativeCalls/native.newt (modified) (3 diffs)
-
NewtObjC/Makefile (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
NEWT0/trunk/contrib/NativeCalls/Makefile
r31 r70 5 5 core = $(srcdir)/newt_core 6 6 7 LIBFFI_PREFIX = /opt/local 7 prefix = /opt/local 8 exec_prefix = ${prefix} 9 sitedir = ${prefix}/lib/newt0 10 libffidir = ${prefix} 8 11 9 DEBUG = # -g 10 INCS = -I$(srcdir) -I$(core)/incs -I$(LIBFFI_PREFIX)/include 12 CC = gcc 13 AR = ar 14 RANLIB = ranlib 15 YACC = bison -y -d 16 LEX = flex 17 DEFS = -DHAVE_CONFIG_H 18 LIBS = 19 DLEXT = dylib 20 EXEEXT = 21 LDIMPORT = 22 DEBUG = -g 23 LDFLAGS = $(DEBUG) -O2 24 LDSHARED = $(CC) -dynamic -bundle -undefined suppress -flat_namespace 25 26 INCS = -I$(srcdir) -I$(core)/incs -I$(libffidir)/include 11 27 EXTLIBS = 12 28 13 14 include $(proj)/platform/$(shell uname) 15 16 LIBFFI = $(LIBFFI_PREFIX)/lib/libffi.a 29 LIBFFI = $(libffidir)/lib/libffi.a 17 30 18 31 NEWTLIBNAME = NativeCalls 19 NEWTEXLIB = $(build)/$(NEWTLIBNAME).$( NEWTLIBSUFFIX)32 NEWTEXLIB = $(build)/$(NEWTLIBNAME).$(DLEXT) 20 33 21 34 LIBOBJ = $(build)/$(NEWTLIBNAME).o 22 CFLAGS += -Wall -DDYLIBSUFFIX='"$(NEWTLIBSUFFIX)"'35 CFLAGS += $(DEBUG) -Wall -DDYLIBSUFFIX='"$(DLEXT)"' 23 36 24 37 .c.o: … … 37 50 $(CC) $(CFLAGS) $(INCS) -c $< -o $@ 38 51 52 install:: 53 install -d -m 755 $(DESTDIR)$(sitedir) 54 install -m 644 $(NEWTEXLIB) $(DESTDIR)$(sitedir) 55 39 56 clean: 40 57 rm -rf $(NEWTEXLIB) -
NEWT0/trunk/contrib/NativeCalls/NativeCalls.c
r55 r70 62 62 void* fPointer; 63 63 } SStorage; 64 65 typedef struct SBufferZone { 66 int fNumberBuffers; 67 void** fBufferTable; 68 } SBufferZone; 69 70 /** 71 * Allocate an empty storage buffer. 72 * 73 * @param outBuffer on output, allocated buffer. 74 */ 75 void 76 AllocateBuffer(SBufferZone* outBuffer) 77 { 78 outBuffer->fNumberBuffers = 0; 79 outBuffer->fBufferTable = (void**) malloc(0); 80 } 81 82 /** 83 * Release a storage buffer. 84 * 85 * @param ioBuffer buffer to release. 86 */ 87 void 88 ReleaseBuffer(SBufferZone* ioBuffer) 89 { 90 /* Iterate on all buffers */ 91 int indexBuffers; 92 int nbBuffers = ioBuffer->fNumberBuffers; 93 void** cursor = ioBuffer->fBufferTable; 94 95 for (indexBuffers = 0; indexBuffers < nbBuffers; indexBuffers++) 96 { 97 free(*cursor); 98 *cursor++; 99 } 100 101 free(ioBuffer->fBufferTable); 102 ioBuffer->fNumberBuffers = 0; 103 ioBuffer->fBufferTable = NULL; 104 } 105 106 /** 107 * Allocate a segment in a buffer. 108 * 109 * @param ioBuffer buffer in which to allocate the segment. 110 * @param inSize segment size. 111 */ 112 void* 113 AllocateBufferSegment(SBufferZone* ioBuffer, int inSize) 114 { 115 void* theResult = malloc(inSize); 116 int newBufferCount = ++ioBuffer->fNumberBuffers; 117 ioBuffer->fBufferTable = 118 realloc(ioBuffer->fBufferTable, newBufferCount * sizeof(void*)); 119 ioBuffer->fBufferTable[newBufferCount - 1] = theResult; 120 121 return theResult; 122 } 64 123 65 124 /** … … 304 363 theResult = NewtMakeReal( inValue->fLongDouble ); 305 364 } else if (NewtSymbolEqual(inNSType, NSSYM(string))) { 306 theResult = NewtMakeString((char*) inValue->fPointer, false); 365 if (inValue->fPointer) { 366 theResult = NewtMakeString((char*) inValue->fPointer, false); 367 } else { 368 theResult = kNewtRefNIL; 369 } 307 370 } else if (NewtSymbolEqual(inNSType, NSSYM(pointer))) { 308 theResult = PointerToBinary(inValue->fPointer); 371 if (inValue->fPointer) { 372 theResult = PointerToBinary(inValue->fPointer); 373 } else { 374 theResult = kNewtRefNIL; 375 } 309 376 } else { 310 377 theResult = kNewtRefNIL; … … 364 431 } 365 432 366 /** 367 * From a type (in NS format), and a value, set the ffi type and cast the 368 * value. 369 * 370 * @param inNSType ns type. 371 * @param inNSValue ns value. 372 * @param outFFIType ffi type. 373 * @param outFFIValue ffi value. 374 * @return \c true if the type and value were cast, \c false otherwise, if 375 * there was a typing error (the exception would have already been thrown then). 376 */ 433 /* forward declaration */ 377 434 bool 378 435 CastTypeAndValue( … … 380 437 newtRefArg inNSValue, 381 438 ffi_type** outFFIType, 382 SStorage* outFFIValue) 383 { 439 void* outFFIValue, 440 size_t* outValueSize, 441 SBufferZone* ioStorage); 442 443 /** 444 * From an array of types (in NS format), and an array of values, set the ffi 445 * types and cast the values. 446 * 447 * @param inNbArgs number of args. 448 * @param inNSTypes ns types. 449 * @param inNSValues ns values. 450 * @param outFFITypes ffi types (allocated in the buffer). 451 * @param outFFIValues ffi values (allocated in the buffer). 452 * @param ioStorage storage buffer. 453 * @return \c true if the type and value were cast, \c false otherwise, if 454 * there was a typing error (the exception would have already been thrown then). 455 */ 456 bool 457 CastTypesAndValues( 458 int inNbArgs, 459 newtRefVar inNSTypes, 460 newtRefVar inNSValues, 461 ffi_type*** outFFITypes, 462 void*** outFFIValues, 463 void** outStorage, 464 SBufferZone* ioStorage) 465 { 466 ffi_type** ffiArgsTypes; 467 void** argsValues; 468 SStorage* argsStorage; 469 void* cursorStorage; 470 int indexArgs; 471 int ffitypes_size = (inNbArgs + 1) * sizeof(ffi_type*); 472 int storage_size = inNbArgs * sizeof(SStorage); 473 bool typeError = false; 474 475 /* build the ffi lists */ 476 ffiArgsTypes = (ffi_type**) AllocateBufferSegment(ioStorage, ffitypes_size); 477 bzero(ffiArgsTypes, ffitypes_size); 478 argsValues = (void**) AllocateBufferSegment(ioStorage, sizeof(void*) * inNbArgs); 479 argsStorage = (SStorage*) AllocateBufferSegment(ioStorage, storage_size); 480 bzero(argsStorage, storage_size); 481 cursorStorage = argsStorage; 482 483 for (indexArgs = 0; indexArgs < inNbArgs; indexArgs++) 484 { 485 newtRefVar theType, theValue; 486 size_t theSize; 487 488 theType = NewtGetArraySlot(inNSTypes, indexArgs); 489 theValue = NewtGetArraySlot(inNSValues, indexArgs); 490 /* use the storage */ 491 argsValues[indexArgs] = cursorStorage; 492 if (!CastTypeAndValue( 493 theType, 494 theValue, 495 &ffiArgsTypes[indexArgs], 496 cursorStorage, 497 &theSize, 498 ioStorage)) 499 { 500 typeError = true; 501 break; 502 } 503 cursorStorage = (void*) (((char*) cursorStorage) + theSize); 504 } 505 506 *outFFITypes = ffiArgsTypes; 507 if (outFFIValues) 508 { 509 *outFFIValues = argsValues; 510 } 511 if (outStorage) 512 { 513 *outStorage = argsStorage; 514 } 515 516 return !typeError; 517 } 518 519 /** 520 * From a type (in NS format), and a value, set the ffi type and cast the 521 * value. 522 * 523 * @param inNSType ns type. 524 * @param inNSValue ns value. 525 * @param outFFIType ffi type. 526 * @param outFFIValue ffi value. 527 * @param ioStorage storage buffer. 528 * @return \c true if the type and value were cast, \c false otherwise, if 529 * there was a typing error (the exception would have already been thrown then). 530 */ 531 bool 532 CastTypeAndValue( 533 newtRefArg inNSType, 534 newtRefArg inNSValue, 535 ffi_type** outFFIType, 536 void* outFFIValue, 537 size_t* outValueSize, 538 SBufferZone* ioStorage) 539 { 540 size_t theSize = 0; 384 541 bool theResult = true; 385 542 386 if (NewtSymbolEqual(inNSType, NSSYM(uint8))) 387 { 543 if (NewtRefIsArray(inNSType)) 544 { 545 // Structure. 546 int nbVals = NewtArrayLength(inNSType); 547 if (nbVals != NewtArrayLength(inNSValue)) 548 { 549 theResult = false; 550 } else { 551 ffi_type** theTypes; 552 void* theValues; 553 theResult = CastTypesAndValues( 554 nbVals, 555 inNSType, 556 inNSValue, 557 &theTypes, 558 NULL, 559 &theValues, 560 ioStorage); 561 if (theResult) { 562 // Make the record. 563 ffi_type* theType = (ffi_type*) 564 AllocateBufferSegment(ioStorage, sizeof(ffi_type)); 565 *outFFIType = theType; 566 theType->size = 0; 567 theType->alignment = 0; 568 theType->type = FFI_TYPE_STRUCT; 569 theType->elements = theTypes; 570 *((void**) outFFIValue) = theValues; 571 theSize = sizeof(void*); 572 } 573 } 574 } else if (NewtSymbolEqual(inNSType, NSSYM(uint8))) { 388 575 *outFFIType = &ffi_type_uint8; 389 576 if (NewtRefIsInteger(inNSValue)) 390 577 { 391 outFFIValue->fInt8=578 *((uint8_t*) outFFIValue) = 392 579 (uint8_t) NewtRefToInteger(inNSValue); 580 theSize = sizeof(uint8_t); 393 581 } else { 394 582 (void) NewtThrow(kNErrNotAnInteger, inNSValue); … … 399 587 if (NewtRefIsInteger(inNSValue)) 400 588 { 401 outFFIValue->fInt8=589 *((uint8_t*) outFFIValue) = 402 590 (uint8_t) (int8_t) NewtRefToInteger(inNSValue); 591 theSize = sizeof(uint8_t); 403 592 } else { 404 593 (void) NewtThrow(kNErrNotAnInteger, inNSValue); … … 409 598 if (NewtRefIsInteger(inNSValue)) 410 599 { 411 outFFIValue->fInt16=600 *((uint16_t*) outFFIValue) = 412 601 (uint16_t) NewtRefToInteger(inNSValue); 602 theSize = sizeof(uint16_t); 413 603 } else { 414 604 (void) NewtThrow(kNErrNotAnInteger, inNSValue); … … 419 609 if (NewtRefIsInteger(inNSValue)) 420 610 { 421 outFFIValue->fInt16=611 *((uint16_t*) outFFIValue) = 422 612 (uint16_t) (int16_t) NewtRefToInteger(inNSValue); 613 theSize = sizeof(uint16_t); 423 614 } else { 424 615 (void) NewtThrow(kNErrNotAnInteger, inNSValue); … … 429 620 if (NewtRefIsInteger(inNSValue)) 430 621 { 431 outFFIValue->fInt32=622 *((uint32_t*) outFFIValue) = 432 623 (uint32_t) NewtRefToInteger(inNSValue); 624 theSize = sizeof(uint32_t); 433 625 } else { 434 626 (void) NewtThrow(kNErrNotAnInteger, inNSValue); … … 439 631 if (NewtRefIsInteger(inNSValue)) 440 632 { 441 outFFIValue->fInt32=633 *((uint32_t*) outFFIValue) = 442 634 (uint32_t) (int32_t) NewtRefToInteger(inNSValue); 635 theSize = sizeof(uint32_t); 443 636 } else { 444 637 (void) NewtThrow(kNErrNotAnInteger, inNSValue); … … 449 642 if (NewtRefIsInteger(inNSValue)) 450 643 { 451 outFFIValue->fInt64=644 *((uint64_t*) outFFIValue) = 452 645 (uint64_t) NewtRefToInteger(inNSValue); 646 theSize = sizeof(uint64_t); 453 647 } else { 454 648 (void) NewtThrow(kNErrNotAnInteger, inNSValue); … … 459 653 if (NewtRefIsInteger(inNSValue)) 460 654 { 461 outFFIValue->fInt64=655 *((uint64_t*) outFFIValue) = 462 656 (uint64_t) (int64_t) NewtRefToInteger(inNSValue); 657 theSize = sizeof(uint64_t); 463 658 } else { 464 659 (void) NewtThrow(kNErrNotAnInteger, inNSValue); … … 469 664 if (NewtRefIsReal(inNSValue)) 470 665 { 471 outFFIValue->fFloat=666 *((float*) outFFIValue) = 472 667 (float) NewtRefToReal(inNSValue); 668 theSize = sizeof(float); 473 669 } else { 474 670 (void) NewtThrow(kNErrNotAReal, inNSValue); … … 479 675 if (NewtRefIsReal(inNSValue)) 480 676 { 481 outFFIValue->fDouble=677 *((double*) outFFIValue) = 482 678 (double) NewtRefToReal(inNSValue); 679 theSize = sizeof(double); 483 680 } else { 484 681 (void) NewtThrow(kNErrNotAReal, inNSValue); … … 489 686 if (NewtRefIsReal(inNSValue)) 490 687 { 491 outFFIValue->fLongDouble=688 *((long double*) outFFIValue) = 492 689 (long double) NewtRefToReal(inNSValue); 690 theSize = sizeof(long double); 493 691 } else { 494 692 (void) NewtThrow(kNErrNotAReal, inNSValue); … … 500 698 if (NewtRefIsString(inNSValue)) 501 699 { 502 outFFIValue->fPointer=700 *((void**) outFFIValue) = 503 701 (void*) NewtRefToString(inNSValue); 702 theSize = sizeof(void*); 504 703 } else { 505 704 (void) NewtThrow(kNErrNotAString, inNSValue); … … 511 710 if (NewtRefIsBinary(inNSValue)) 512 711 { 513 outFFIValue->fPointer=712 *((void**) outFFIValue) = 514 713 (void*) NewtRefToBinary(inNSValue); 714 theSize = sizeof(void*); 515 715 } else { 516 716 (void) NewtThrow(kNErrNotABinaryObject, inNSValue); … … 521 721 if (NewtRefIsInteger(inNSValue)) 522 722 { 523 outFFIValue->fPointer=723 *((void**) outFFIValue) = 524 724 (void*) NewtRefToInteger(inNSValue); 725 theSize = sizeof(void*); 525 726 } else if (NewtRefIsBinary(inNSValue)) { 526 outFFIValue->fPointer=727 *((void**) outFFIValue) = 527 728 BinaryToPointer(inNSValue); 729 theSize = sizeof(void*); 528 730 } else { 529 731 (void) NewtThrow(kNErrNotABinaryObject, inNSValue); … … 535 737 } 536 738 739 if (outValueSize) 740 { 741 *outValueSize = theSize; 742 } 743 537 744 return theResult; 538 }539 540 /**541 * Provided with an array of FFI types, frees it recursively, handling542 * structures in it. Last item in the array should be NULL. The pointer is543 * freed as well. This function is recursive.544 *545 * @param inTypes types array to free.546 */547 void548 FreeFFITypes(ffi_type** inTypes)549 {550 ffi_type** cursor = inTypes;551 while (*cursor)552 {553 if ((*cursor)->type == FFI_TYPE_STRUCT)554 {555 /* Iterate recursively in this structure. */556 ffi_type** elements = (*cursor)->elements;557 if (elements)558 {559 FreeFFITypes(elements);560 }561 }562 563 cursor++;564 }565 566 /* free the array */567 free( inTypes );568 745 } 569 746 … … 577 754 ffi_type** ffiArgsTypes; 578 755 void** argsValues; 579 SStorage* argsStorage; 580 int indexArgs; 756 SBufferZone storage; 581 757 int nbArgs; 582 758 SStorage result; … … 641 817 642 818 /* build the ffi lists */ 643 ffiArgsTypes = (ffi_type**) calloc( (nbArgs + 1), sizeof(ffi_type*) ); 644 argsValues = (void**) malloc( sizeof(void*) * nbArgs ); 645 argsStorage = (SStorage*) malloc( sizeof(SStorage) * nbArgs ); 646 647 for (indexArgs = 0; indexArgs < nbArgs; indexArgs++) 648 { 649 newtRefVar theType, theValue; 650 651 theType = NewtGetArraySlot(argTypes, indexArgs); 652 theValue = NewtGetArraySlot(inArgs, indexArgs); 653 /* use the storage */ 654 argsValues[indexArgs] = &argsStorage[indexArgs]; 655 if (!CastTypeAndValue( 656 theType, 657 theValue, 658 &ffiArgsTypes[indexArgs], 659 &argsStorage[indexArgs])) 660 { 661 typeError = true; 662 break; 663 } 664 } 819 AllocateBuffer(&storage); 820 CastTypesAndValues(nbArgs, argTypes, inArgs, &ffiArgsTypes, &argsValues, NULL, &storage); 665 821 666 822 if (!typeError) … … 689 845 } 690 846 691 FreeFFITypes(ffiArgsTypes); 692 free(argsValues); 693 free(argsStorage); 847 ReleaseBuffer(&storage); 694 848 695 849 return resultRef; … … 769 923 * 'iobinary binary ffi_type_pointer not available for result 770 924 * 'pointer int or binary ffi_type_pointer 771 * 772 * Structures aren't supported yet.925 * [array] array ffi_type_struct not available for result 926 * 773 927 * string and iostring are identical (strings are I/O). Same with binary and 774 928 * iobinary. This may change in the future. -
NEWT0/trunk/contrib/NativeCalls/native.newt
r55 r70 21 21 {name: "socket", 22 22 args: ['sint32, 'sint32, 'sint32], 23 result: 'sint32}); 24 /* 25 -- This is on BSD systems. On some systems, there is no sin_len field. 26 struct sockaddr_in { 27 uint8_t sin_len; // length of structure (16) 28 sa_family_t sin_family; // AF_INET 29 in_port_t sin_port; // 16-bit TCP or UDP port number 30 // network byte ordered 31 struct in_addr sin_addr; // 32-bit IPv4 address 32 // network byte ordered 33 char sin_zero[8]; // unused 34 }; 35 */ 36 libc:DefGlobalFn( 37 '|libc.bind_ipv4|, 38 {name: "bind", 39 args: ['sint32, ['uint8, 'uint8, 'uint16, 'uint8, 'uint8, 'uint8, 'uint8, 'uint8, 'uint8, 'uint8, 'uint8, 'uint8, 'uint8, 'uint8, 'uint8], 'sint32], 40 result: 'sint32}); 41 libc:DefGlobalFn( 42 '|libc.connect_ipv4|, 43 {name: "connect", 44 args: ['sint32, ['uint8, 'uint8, 'uint16, 'uint8, 'uint8, 'uint8, 'uint8, 'uint8, 'uint8, 'uint8, 'uint8, 'uint8, 'uint8, 'uint8, 'uint8], 'sint32], 45 result: 'sint32}); 46 libc:DefGlobalFn( 47 '|libc.write|, 48 {name: "write", 49 args: ['sint32, 'string, 'sint32], 50 result: 'sint32}); 51 libc:DefGlobalFn( 52 '|libc.read|, 53 {name: "read", 54 args: ['sint32, 'string, 'sint32], 23 55 result: 'sint32}); 24 56 libc:DefGlobalFn( … … 93 125 Print("socket returned an error (" & GetErrno() & ")\n"); 94 126 end else begin 95 // To bind the socket, I need to support structures. 96 // ... 97 Print("socket fd: " & socket & "\n"); 127 try 128 Print("socket fd: " & socket & "\n"); 129 130 result := |libc.bind_ipv4|(socket, [ 131 16 /* length */, 132 AF_INET, 133 0, /* port: any */ 134 0, 0, 0, 0, /* address: any */ 135 0, 0, 0, 0, /* zero */ 136 0, 0, 0, 0 /* zero */], 16); 137 138 if (result < 0) then 139 begin 140 Throw('|evt.native-errno;type.ref.string|, "bind"); 141 end; 142 143 result := |libc.connect_ipv4|(socket, [ 144 16 /* length */, 145 AF_INET, 146 80, 147 66, 249, 89, 104, /* address */ // Google. 148 0, 0, 0, 0, /* zero */ 149 0, 0, 0, 0 /* zero */], 16); 150 151 if (result < 0) then 152 begin 153 Throw('|evt.native-errno;type.ref.string|, "connect"); 154 end; 155 156 result := |libc.write|(socket, "GET / HTTP/1.0\n\n", 16); 157 158 if (result < 0) then 159 begin 160 Throw('|evt.native-errno;type.ref.string|, "write"); 161 end; 162 163 local data := MakeBinary(512, 'string); 164 result := |libc.read|(socket, data, 512); 165 P(data); 166 167 if (result < 0) then 168 begin 169 Throw('|evt.native-errno;type.ref.string|, "read"); 170 end; 171 172 onexception |evt.native-errno| do 173 begin 174 Print("An error occurred with function " & 175 CurrentException().data & " (" & 176 GetErrno() & ")\n"); 177 end; 98 178 99 179 // Close the socket. … … 102 182 if (result < 0) then 103 183 begin 104 Print("close returned an error (" & errno& ")\n");184 Print("close returned an error (" & GetErrno() & ")\n"); 105 185 end; 106 186 end; -
NEWT0/trunk/contrib/NewtObjC/Makefile
r31 r70 5 5 core = $(srcdir)/newt_core 6 6 7 prefix = /opt/local 8 exec_prefix = ${prefix} 9 sitedir = ${prefix}/lib/newt0 10 libffidir = ${prefix} 11 12 CC = gcc 13 AR = ar 14 RANLIB = ranlib 15 YACC = bison -y -d 16 LEX = flex 17 DEFS = -DHAVE_CONFIG_H 18 LIBS = 19 DLEXT = dylib 20 EXEEXT = 21 LDIMPORT =
