source: webkit/trunk/JavaScriptCore/kjs/testkjs.cpp@ 10634

Last change on this file since 10634 was 10563, checked in by mjs, 20 years ago

Reviewed by Geoff.

  • fixed <rdar://problem/4214783> REGRESSION: kjs_fast_malloc crash due to lack of locking on multiple threads (seen selecting volumes in the installer)

Make sure to lock using the InterpreterLock class in all places that need it
(including anything that uses the collector, the parser, the protect count hash table,
and anything that allocates via fast_malloc).

Also added assertions to ensure that the locking rules are followed for the relevant
resources.

  • Makefile.am:
  • bindings/NP_jsobject.cpp: (identifierFromNPIdentifier): (_NPN_Invoke): (_NPN_Evaluate): (_NPN_GetProperty): (_NPN_SetProperty): (_NPN_RemoveProperty): (_NPN_HasProperty): (_NPN_HasMethod): (_NPN_SetException):
  • bindings/jni/jni_jsobject.cpp: (JSObject::call): (JSObject::eval): (JSObject::getMember): (JSObject::setMember): (JSObject::removeMember): (JSObject::getSlot): (JSObject::setSlot): (JSObject::toString): (JSObject::convertJObjectToValue):
  • bindings/objc/WebScriptObject.mm: (-[WebScriptObject callWebScriptMethod:withArguments:]): (-[WebScriptObject evaluateWebScript:]): (-[WebScriptObject setValue:forKey:]): (-[WebScriptObject valueForKey:]): (-[WebScriptObject removeWebScriptKey:]): (-[WebScriptObject stringRepresentation]): (-[WebScriptObject webScriptValueAtIndex:]): (-[WebScriptObject setWebScriptValueAtIndex:value:]): (+[WebScriptObject _convertValueToObjcValue:KJS::originExecutionContext:Bindings::executionContext:Bindings::]):
  • bindings/runtime.cpp: (Instance::createRuntimeObject):
  • bindings/runtime_root.h:
  • bindings/testbindings.cpp: (main):
  • bindings/testbindings.mm: (main):
  • kjs/fast_malloc.cpp: (KJS::kjs_fast_malloc): (KJS::kjs_fast_calloc): (KJS::kjs_fast_free): (KJS::kjs_fast_realloc):
  • kjs/fast_malloc.h:
  • kjs/identifier.h:
  • kjs/internal.cpp: (InterpreterImp::InterpreterImp): (InterpreterImp::clear): (InterpreterImp::mark): (InterpreterImp::checkSyntax): (InterpreterImp::evaluate):
  • kjs/internal.h: (KJS::InterpreterImp::globalObject):
  • kjs/interpreter.cpp: (Interpreter::evaluate):
  • kjs/interpreter.h: (KJS::InterpreterLock::InterpreterLock): (KJS::InterpreterLock::~InterpreterLock):
  • kjs/nodes.h:
  • kjs/protect.h: (KJS::ProtectedValue::ProtectedValue): (KJS::ProtectedValue::~ProtectedValue): (KJS::ProtectedValue::operator=): (KJS::ProtectedObject::ProtectedObject): (KJS::ProtectedObject::~ProtectedObject): (KJS::ProtectedObject::operator=): (KJS::ProtectedReference::ProtectedReference): (KJS::ProtectedReference::~ProtectedReference): (KJS::ProtectedReference::operator=):
  • kjs/protected_object.h:
  • kjs/protected_values.cpp: (KJS::ProtectedValues::getProtectCount): (KJS::ProtectedValues::increaseProtectCount): (KJS::ProtectedValues::decreaseProtectCount):
  • kjs/string_object.cpp: (StringObjectImp::StringObjectImp):
  • kjs/testkjs.cpp: (main):
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.3 KB
Line 
1// -*- c-basic-offset: 2 -*-
2/*
3 * This file is part of the KDE libraries
4 * Copyright (C) 1999-2000 Harri Porten ([email protected])
5 * Copyright (C) 2004 Apple Computer, Inc.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public License
18 * along with this library; see the file COPYING.LIB. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
21 *
22 */
23
24#include <stdio.h>
25#include <stdlib.h>
26#include <string.h>
27
28#include "value.h"
29#include "object.h"
30#include "types.h"
31#include "interpreter.h"
32#include "collector.h"
33
34using namespace KJS;
35
36class TestFunctionImp : public ObjectImp {
37public:
38 TestFunctionImp(int i, int length);
39 virtual bool implementsCall() const { return true; }
40 virtual ValueImp *callAsFunction(ExecState *exec, ObjectImp *thisObj, const List &args);
41
42 enum { Print, Debug, Quit, GC };
43
44private:
45 int id;
46};
47
48TestFunctionImp::TestFunctionImp(int i, int length) : ObjectImp(), id(i)
49{
50 putDirect(lengthPropertyName,length,DontDelete|ReadOnly|DontEnum);
51}
52
53ValueImp *TestFunctionImp::callAsFunction(ExecState *exec, ObjectImp */*thisObj*/, const List &args)
54{
55 switch (id) {
56 case Print:
57 case Debug:
58 fprintf(stderr,"--> %s\n",args[0]->toString(exec).ascii());
59 return Undefined();
60 case Quit:
61 exit(0);
62 return Undefined();
63 case GC:
64 Interpreter::lock();
65 Collector::collect();
66 Interpreter::unlock();
67 break;
68 default:
69 break;
70 }
71
72 return Undefined();
73}
74
75class VersionFunctionImp : public ObjectImp {
76public:
77 VersionFunctionImp() : ObjectImp() {}
78 virtual bool implementsCall() const { return true; }
79 virtual ValueImp *callAsFunction(ExecState *exec, ObjectImp *thisObj, const List &args);
80};
81
82ValueImp *VersionFunctionImp::callAsFunction(ExecState */*exec*/, ObjectImp */*thisObj*/, const List &/*args*/)
83{
84 // We need this function for compatibility with the Mozilla JS tests but for now
85 // we don't actually do any version-specific handling
86 return Undefined();
87}
88
89class GlobalImp : public ObjectImp {
90public:
91 virtual UString className() const { return "global"; }
92};
93
94int main(int argc, char **argv)
95{
96 // expecting a filename
97 if (argc < 2) {
98 fprintf(stderr, "You have to specify at least one filename\n");
99 return -1;
100 }
101
102 bool ret = true;
103 {
104 InterpreterLock lock;
105
106 ObjectImp *global(new GlobalImp());
107
108 // create interpreter
109 Interpreter interp(global);
110 // add debug() function
111 global->put(interp.globalExec(), "debug", new TestFunctionImp(TestFunctionImp::Debug, 1));
112 // add "print" for compatibility with the mozilla js shell
113 global->put(interp.globalExec(), "print", new TestFunctionImp(TestFunctionImp::Print, 1));
114 // add "quit" for compatibility with the mozilla js shell
115 global->put(interp.globalExec(), "quit", new TestFunctionImp(TestFunctionImp::Quit, 0));
116 // add "gc" for compatibility with the mozilla js shell
117 global->put(interp.globalExec(), "gc", new TestFunctionImp(TestFunctionImp::GC, 0));
118 // add "version" for compatibility with the mozilla js shell
119 global->put(interp.globalExec(), "version", new VersionFunctionImp());
120
121 for (int i = 1; i < argc; i++) {
122 int code_len = 0;
123 int code_alloc = 1024;
124 char *code = (char*)malloc(code_alloc);
125
126 const char *file = argv[i];
127 if (strcmp(file, "-f") == 0)
128 continue;
129 FILE *f = fopen(file, "r");
130 if (!f) {
131 fprintf(stderr, "Error opening %s.\n", file);
132 return 2;
133 }
134
135 while (!feof(f) && !ferror(f)) {
136 size_t len = fread(code+code_len,1,code_alloc-code_len,f);
137 code_len += len;
138 if (code_len >= code_alloc) {
139 code_alloc *= 2;
140 code = (char*)realloc(code,code_alloc);
141 }
142 }
143 code = (char*)realloc(code,code_len+1);
144 code[code_len] = '\0';
145
146 // run
147 Completion comp(interp.evaluate(file, 1, code));
148
149 fclose(f);
150
151 if (comp.complType() == Throw) {
152 ExecState *exec = interp.globalExec();
153 ValueImp *exVal = comp.value();
154 char *msg = exVal->toString(exec).ascii();
155 int lineno = -1;
156 if (exVal->isObject()) {
157 ValueImp *lineVal = static_cast<ObjectImp *>(exVal)->get(exec,"line");
158 if (lineVal->isNumber())
159 lineno = int(lineVal->toNumber(exec));
160 }
161 if (lineno != -1)
162 fprintf(stderr,"Exception, line %d: %s\n",lineno,msg);
163 else
164 fprintf(stderr,"Exception: %s\n",msg);
165 ret = false;
166 }
167 else if (comp.complType() == ReturnValue) {
168 char *msg = comp.value()->toString(interp.globalExec()).ascii();
169 fprintf(stderr,"Return value: %s\n",msg);
170 }
171
172 free(code);
173 }
174 } // end block, so that interpreter gets deleted
175
176 if (ret)
177 fprintf(stderr, "OK.\n");
178
179#ifdef KJS_DEBUG_MEM
180 Interpreter::finalCheck();
181#endif
182 return ret ? 0 : 3;
183}
Note: See TracBrowser for help on using the repository browser.