blob: feb21b72d02e40708a4a84d51bec3714f395d96c [file] [log] [blame]
/*
* Copyright (C) 2004 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "BridgeJSC.h"
#include <Foundation/Foundation.h>
#include "JSObject.h"
#include "JSCJSValue.h"
#import <WebKit/WebScriptObject.h>
#include "interpreter.h"
#include "runtime_object.h"
#include <stdio.h>
#include <string.h>
#include "types.h"
#define LOG(formatAndArgs...) { \
fprintf (stderr, "%s: ", __PRETTY_FUNCTION__); \
fprintf(stderr, formatAndArgs); \
}
@interface MySecondInterface : NSObject
{
double doubleValue;
}
- init;
@end
@implementation MySecondInterface
- init
{
LOG ("\n");
doubleValue = 666.666;
return self;
}
@end
@interface MyFirstInterface : NSObject
{
int myInt;
MySecondInterface *mySecondInterface;
id jsobject;
NSString *string;
}
- (int)getInt;
- (void)setInt: (int)anInt;
- (MySecondInterface *)getMySecondInterface;
- (void)logMessage:(NSString *)message;
- (void)setJSObject:(id)jsobject;
@end
@implementation MyFirstInterface
+ (NSString *)webScriptNameForSelector:(SEL)aSelector
{
if (aSelector == @selector(logMessage:))
return @"logMessage";
if (aSelector == @selector(logMessages:))
return @"logMessages";
if (aSelector == @selector(logMessage:prefix:))
return @"logMessageWithPrefix";
return nil;
}
+ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector
{
return NO;
}
+ (BOOL)isKeyExcludedFromWebScript:(const char *)name
{
return NO;
}
/*
- (id)invokeUndefinedMethodFromWebScript:(NSString *)name withArguments:(NSArray *)args
{
NSLog (@"Call to undefined method %@", name);
NSLog (@"%d args\n", [args count]);
int i;
for (i = 0; i < [args count]; i++) {
NSLog (@"%d: %@\n", i, [args objectAtIndex:i]);
}
return @"success";
}
*/
/*
- (id)valueForUndefinedKey:(NSString *)key
{
NSLog (@"%s: key = %@", __PRETTY_FUNCTION__, key);
return @"aValue";
}
*/
- (void)setValue:(id)value forUndefinedKey:(NSString *)key
{
NSLog (@"%s: key = %@", __PRETTY_FUNCTION__, key);
}
- init
{
LOG ("\n");
mySecondInterface = [[MySecondInterface alloc] init];
return self;
}
- (void)dealloc
{
LOG ("\n");
[mySecondInterface release];
[super dealloc];
}
- (int)getInt
{
LOG ("myInt = %d\n", myInt);
return myInt;
}
- (void)setInt: (int)anInt
{
LOG ("anInt = %d\n", anInt);
myInt = anInt;
}
- (NSString *)getString
{
return string;
}
- (MySecondInterface *)getMySecondInterface
{
LOG ("\n");
return mySecondInterface;
}
- (void)logMessage:(NSString *)message
{
printf ("%s\n", [message lossyCString]);
}
- (void)logMessages:(id)messages
{
int i, count = [[messages valueForKey:@"length"] intValue];
for (i = 0; i < count; i++)
printf ("%s\n", [[messages webScriptValueAtIndex:i] lossyCString]);
}
- (void)logMessage:(NSString *)message prefix:(NSString *)prefix
{
printf ("%s:%s\n", [prefix lossyCString], [message lossyCString]);
}
- (void)setJSObject:(id)jso
{
[jsobject autorelease];
jsobject = [jso retain];
}
- (void)callJSObject:(int)arg1 :(int)arg2
{
id foo1 = [jsobject callWebScriptMethod:@"call" withArguments:[NSArray arrayWithObjects:jsobject, [NSNumber numberWithInt:arg1], [NSNumber numberWithInt:arg2], nil]];
printf ("foo (via call) = %s\n", [[foo1 description] lossyCString] );
id foo2 = [jsobject callWebScriptMethod:@"apply" withArguments:[NSArray arrayWithObjects:jsobject, [NSArray arrayWithObjects:[NSNumber numberWithInt:arg1], [NSNumber numberWithInt:arg2], nil], nil]];
printf ("foo (via apply) = %s\n", [[foo2 description] lossyCString] );
}
@end
using namespace JSC;
using namespace JSC::Bindings;
class GlobalImp : public ObjectImp {
public:
virtual String className() const { return "global"; }
};
#define BufferSize 200000
static char code[BufferSize];
const char *readJavaScriptFromFile (const char *file)
{
FILE *f = fopen(file, "r");
if (!f) {
fprintf(stderr, "Error opening %s.\n", file);
return 0;
}
int num = fread(code, 1, BufferSize, f);
code[num] = '\0';
if(num >= BufferSize)
fprintf(stderr, "Warning: File may have been too long.\n");
fclose(f);
return code;
}
int main(int argc, char **argv)
{
// expecting a filename
if (argc < 2) {
fprintf(stderr, "You have to specify at least one filename\n");
return -1;
}
bool ret = true;
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
JSLock lock;
// create interpreter w/ global object
Object global(new GlobalImp());
Interpreter interp;
interp.setGlobalObject(global);
JSGlobalObject* lexicalGlobalObject = interp.globalObject();
MyFirstInterface *myInterface = [[MyFirstInterface alloc] init];
global.put(lexicalGlobalObject, Identifier::fromString(lexicalGlobalObject, "myInterface"), Instance::createRuntimeObject(Instance::ObjectiveCLanguage, (void *)myInterface));
for (int i = 1; i < argc; i++) {
const char *code = readJavaScriptFromFile(argv[i]);
if (code) {
// run
Completion comp(interp.evaluate(code));
if (comp.complType() == Throw) {
Value exVal = comp.value();
char *msg = exVal.toString(lexicalGlobalObject).ascii();
int lineno = -1;
if (exVal.type() == ObjectType) {
Value lineVal = Object::dynamicCast(exVal).get(lexicalGlobalObject, Identifier::fromString(lexicalGlobalObject, "line"));
if (lineVal.type() == NumberType)
lineno = int(lineVal.toNumber(lexicalGlobalObject));
}
if (lineno != -1)
fprintf(stderr,"Exception, line %d: %s\n",lineno,msg);
else
fprintf(stderr,"Exception: %s\n",msg);
ret = false;
}
else if (comp.complType() == ReturnValue) {
char *msg = comp.value().toString(interp.globalObject()).ascii();
fprintf(stderr,"Return value: %s\n",msg);
}
}
}
[myInterface release];
[pool drain];
} // end block, so that Interpreter and global get deleted
return ret ? 0 : 3;
}